/* * Copyright (c) 1998-2017 by Richard A. Wilkes. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, version 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This Source Code Form is "Incompatible With Secondary Licenses", as * defined by the Mozilla Public License, version 2.0. */ package com.trollworks.gcs.notes; import com.trollworks.gcs.app.GCSImages; import com.trollworks.gcs.character.GURPSCharacter; import com.trollworks.gcs.common.DataFile; import com.trollworks.gcs.common.LoadState; import com.trollworks.gcs.widgets.outline.ListRow; import com.trollworks.gcs.widgets.outline.RowEditor; import com.trollworks.toolkit.annotation.Localize; import com.trollworks.toolkit.io.xml.XMLReader; import com.trollworks.toolkit.io.xml.XMLWriter; import com.trollworks.toolkit.ui.image.StdImage; import com.trollworks.toolkit.ui.widget.outline.Column; import com.trollworks.toolkit.utility.Localization; import com.trollworks.toolkit.utility.text.Text; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; /** A note. */ public class Note extends ListRow { @Localize("Note") private static String DEFAULT_NAME; static { Localization.initialize(); } private static final int CURRENT_VERSION = 1; /** The XML tag used for items. */ public static final String TAG_NOTE = "note"; //$NON-NLS-1$ /** The XML tag used for containers. */ public static final String TAG_NOTE_CONTAINER = "note_container"; //$NON-NLS-1$ private static final String TAG_TEXT = "text"; //$NON-NLS-1$ /** The prefix used in front of all IDs for the notes. */ public static final String PREFIX = GURPSCharacter.CHARACTER_PREFIX + "note."; //$NON-NLS-1$ /** The field ID for text changes. */ public static final String ID_TEXT = PREFIX + "Text"; //$NON-NLS-1$ /** The field ID for when the row hierarchy changes. */ public static final String ID_LIST_CHANGED = PREFIX + "ListChanged"; //$NON-NLS-1$ private String mText; /** * Creates a new note. * * @param dataFile The data file to associate it with. * @param isContainer Whether or not this row allows children. */ public Note(DataFile dataFile, boolean isContainer) { super(dataFile, isContainer); mText = ""; //$NON-NLS-1$ } /** * Creates a clone of an existing note and associates it with the specified data file. * * @param dataFile The data file to associate it with. * @param note The note to clone. * @param deep Whether or not to clone the children, grandchildren, etc. */ public Note(DataFile dataFile, Note note, boolean deep) { super(dataFile, note); mText = note.mText; if (deep) { int count = note.getChildCount(); for (int i = 0; i < count; i++) { addChild(new Note(dataFile, (Note) note.getChild(i), true)); } } } /** * Loads a note and associates it with the specified data file. * * @param dataFile The data file to associate it with. * @param reader The XML reader to load from. * @param state The {@link LoadState} to use. */ public Note(DataFile dataFile, XMLReader reader, LoadState state) throws IOException { this(dataFile, TAG_NOTE_CONTAINER.equals(reader.getName())); load(reader, state); } @Override public boolean isEquivalentTo(Object obj) { if (obj == this) { return true; } if (obj instanceof Note && super.isEquivalentTo(obj)) { return mText.equals(((Note) obj).mText); } return false; } @Override public String getLocalizedName() { return DEFAULT_NAME; } @Override public String getListChangedID() { return ID_LIST_CHANGED; } @Override public String getXMLTagName() { return canHaveChildren() ? TAG_NOTE_CONTAINER : TAG_NOTE; } @Override public int getXMLTagVersion() { return CURRENT_VERSION; } @Override public String getRowType() { return DEFAULT_NAME; } @Override protected void prepareForLoad(LoadState state) { super.prepareForLoad(state); mText = ""; //$NON-NLS-1$ } @Override protected void loadSubElement(XMLReader reader, LoadState state) throws IOException { String name = reader.getName(); if (TAG_TEXT.equals(name)) { mText = Text.standardizeLineEndings(reader.readText()); } else if (!state.mForUndo && (TAG_NOTE.equals(name) || TAG_NOTE_CONTAINER.equals(name))) { addChild(new Note(mDataFile, reader, state)); } else { super.loadSubElement(reader, state); } } @Override protected void saveSelf(XMLWriter out, boolean forUndo) { out.simpleTagNotEmpty(TAG_TEXT, mText); } /** @return The description. */ public String getDescription() { return mText; } /** * @param description The description to set. * @return Whether it was modified. */ public boolean setDescription(String description) { if (!mText.equals(description)) { mText = description; notifySingle(ID_TEXT); return true; } return false; } @Override public boolean contains(String text, boolean lowerCaseOnly) { if (getDescription().toLowerCase().indexOf(text) != -1) { return true; } return super.contains(text, lowerCaseOnly); } @Override public Object getData(Column column) { return NoteColumn.values()[column.getID()].getData(this); } @Override public String getDataAsText(Column column) { return NoteColumn.values()[column.getID()].getDataAsText(this); } @Override public String toString() { return getDescription(); } @Override public StdImage getIcon(boolean large) { return GCSImages.getNoteIcons().getImage(large ? 64 : 16); } @Override public RowEditor<? extends ListRow> createEditor() { return new NoteEditor(this); } @Override public void fillWithNameableKeys(HashSet<String> set) { // No nameables } @Override public void applyNameableKeys(HashMap<String, String> map) { // No nameables } }