/*
* 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.preferences;
import com.trollworks.gcs.character.Profile;
import com.trollworks.toolkit.annotation.Localize;
import com.trollworks.toolkit.ui.UIUtilities;
import com.trollworks.toolkit.ui.image.StdImage;
import com.trollworks.toolkit.ui.layout.Alignment;
import com.trollworks.toolkit.ui.layout.FlexColumn;
import com.trollworks.toolkit.ui.layout.FlexComponent;
import com.trollworks.toolkit.ui.layout.FlexGrid;
import com.trollworks.toolkit.ui.layout.FlexRow;
import com.trollworks.toolkit.ui.layout.FlexSpacer;
import com.trollworks.toolkit.ui.preferences.PreferencePanel;
import com.trollworks.toolkit.ui.preferences.PreferencesWindow;
import com.trollworks.toolkit.ui.scale.Scales;
import com.trollworks.toolkit.ui.widget.StdFileDialog;
import com.trollworks.toolkit.utility.Dice;
import com.trollworks.toolkit.utility.FileType;
import com.trollworks.toolkit.utility.Localization;
import com.trollworks.toolkit.utility.PathUtils;
import com.trollworks.toolkit.utility.Preferences;
import com.trollworks.toolkit.utility.text.Enums;
import com.trollworks.toolkit.utility.text.Numbers;
import com.trollworks.toolkit.utility.text.Text;
import com.trollworks.toolkit.utility.units.LengthUnits;
import com.trollworks.toolkit.utility.units.WeightUnits;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.Document;
/** The sheet preferences panel. */
public class SheetPreferences extends PreferencePanel implements ActionListener, DocumentListener, ItemListener {
@Localize("Sheet")
@Localize(locale = "de", value = "Charakterblatt")
@Localize(locale = "ru", value = "Лист")
@Localize(locale = "es", value = "Hoja de Personaje")
private static String SHEET;
@Localize("Player")
@Localize(locale = "de", value = "Spieler")
@Localize(locale = "ru", value = "Игрок")
@Localize(locale = "es", value = "Jugador")
private static String PLAYER;
@Localize("The player name to use when a new character sheet is created")
@Localize(locale = "de", value = "Der Spielername, der verwendet wird, wenn ein neues Charakterblatt erstellt wird.")
@Localize(locale = "ru", value = "Имя игрока при создании нового листа персонажа")
@Localize(locale = "es", value = "Nombre del jugador que se usará cuando se cree una nueva hoja de personaje")
private static String PLAYER_TOOLTIP;
@Localize("Campaign")
@Localize(locale = "de", value = "Kampagne")
@Localize(locale = "ru", value = "Компания")
@Localize(locale = "es", value = "Campaña")
private static String CAMPAIGN;
@Localize("The campaign to use when a new character sheet is created")
@Localize(locale = "de", value = "Die Kampagne, die verwendet wird, wenn ein neues Charakterblatt erstellt wird.")
@Localize(locale = "ru", value = "Название компании при создании нового листа персонаж")
@Localize(locale = "es", value = "Nombre de la campaña que se usará cuando se cree una nueva hoja de personaje")
private static String CAMPAIGN_TOOLTIP;
@Localize("Tech Level")
@Localize(locale = "de", value = "Techlevel")
@Localize(locale = "ru", value = "Технологический уровень")
@Localize(locale = "es", value = "Nivel Tecnológico")
private static String TECH_LEVEL;
@Localize("<html><body>TL0: Stone Age (Prehistory and later)<br>TL1: Bronze Age (3500 B.C.+)<br>TL2: Iron Age (1200 B.C.+)<br>TL3: Medieval (600 A.D.+)<br>TL4: Age of Sail (1450+)<br>TL5: Industrial Revolution (1730+)<br>TL6: Mechanized Age (1880+)<br>TL7: Nuclear Age (1940+)<br>TL8: Digital Age (1980+)<br>TL9: Microtech Age (2025+?)<br>TL10: Robotic Age (2070+?)<br>TL11: Age of Exotic Matter<br>TL12: Anything Goes</body></html>")
@Localize(locale = "de", value = "<html><body>TL0: Steinzeit (Vorzeit und älter)<br>TL1: Bronzezeit (ab 3500 v.Chr.)<br>TL2: Eisenzeit (ab 1200 v. Chr.)<br>TL3: Mittelalter(ab 600 n. Chr.)<br>TL4: Renaissance / Kolonialzeitalter (ab 1450)<br>TL5: Industrielle Revolution (ab 1730)<br>TL6: Zeitalter der Mechanik (ab 1880)<br>TL7: Ära der Kernkraft (ab 1940)<br>TL8: Ära der Digitalisierung (ab 1980)<br>TL9: Ära der Mikrotechnik (ab 2025?)<br>TL10: Ära der Robotik (ab 2070?)<br>TL11: Ära der Exotischen Materie<br>TL12: Was ihr wollt!</body></html>")
@Localize(locale = "ru", value = "<html><body>ТУ0: Каменный век<br>ТУ1: Бронзовый век<br>ТУ2: Железный век<br>ТУ3: Средневековье<br>ТУ4: Эпоха парусов<br>ТУ5: Промышленный переворот<br>ТУ6: Эпоха механики<br>ТУ7: Атомная эпоха<br>ТУ8: Цифровая эпоха<br>ТУ9: Эпоха микротехники<br>ТУ10: Эпоха роботизации<br>ТУ11: Эпоха экзотических материалов<br>ТУ12: Всё, что угодно</body></html>")
@Localize(locale = "es", value = "<html><body>TL0: Edad de Piedra (Prehistoria y anterior)<br>TL1: Edad de Bronce (3500 a. C.+)<br>TL2: Edad de Hierro (1200 a. C.+)<br>TL3: Edad Media (600 a. C.+)<br>TL4: Era del Renacimiento (1450+)<br>TL5: Revolución Industrial(1730+)<br>TL6: Era de la Mecanización(1880+)<br>TL7: Era Nuclear(1940+)<br>TL8: Era Digital(1980+)<br>TL9: Era de la Microtecnología(¿2025+?)<br>TL10: Era de la Robótica(¿2070+?)<br>TL11: Era del Dominio de la Materia<br>TL12: Más allá</body></html>")
private static String TECH_LEVEL_TOOLTIP;
@Localize("Initial Points")
@Localize(locale = "de", value = "Charakterpunkte")
@Localize(locale = "ru", value = "Начальные очки")
@Localize(locale = "es", value = "Puntos Iniciales")
private static String INITIAL_POINTS;
@Localize("The initial number of character points to start with")
@Localize(locale = "de", value = "Die Zahl der Charakterpunkte, mit denen der Charakter startet.")
@Localize(locale = "ru", value = "Первоначальное количество очков персонажа")
@Localize(locale = "es", value = "Cantidad inicial de puntos de parsonaje")
private static String INITIAL_POINTS_TOOLTIP;
@Localize("Select A Portrait")
@Localize(locale = "de", value = "Wähle ein Charakterbild")
@Localize(locale = "ru", value = "Выберите изображение")
@Localize(locale = "es", value = "Selecciona un retrato")
private static String SELECT_PORTRAIT;
@Localize("Use optional (house) rule: Will and Perception are not based upon IQ")
@Localize(locale = "de", value = "Verwende die optionale (Haus-) Regel: Wille und Wahrnehmung basieren nicht auf IQ")
@Localize(locale = "ru", value = "Использовать опциональное (домашнее) правило: Воля и Восприятие не основаны на интеллекте (ИН)")
@Localize(locale = "es", value = "Usar regla opcional (no oficial): Voluntad y Percepción no se basan en Inteligencia (CI)")
private static String OPTIONAL_IQ_RULES;
@Localize("Use optional rule \"Multiplicative Modifiers\" from PW102 (note: changes point value)")
@Localize(locale = "de", value = "Verwende die optionale Regel \"Multiplicative Modifiers\" aus PW102 (Hinweis: Verändert den Punktwert)")
@Localize(locale = "ru", value = "Использовать необязательное правило \"Накопительные модификаторы\" из PW102 (прим.: изменяет количество очков)")
@Localize(locale = "es", value = "Usar regla opcional: \"Modificadores Multiplicadores\", véase PW102 (Nota: cambia el valor en puntos)")
private static String OPTIONAL_MODIFIER_RULES;
@Localize("Use optional rule \"Modifying Dice + Adds\" from B269")
@Localize(locale = "de", value = "Verwende die optionale Regel \"Verändere Würfel und Zugabe\" aus B269 (\"Modifying Dice + Adds\")")
@Localize(locale = "ru", value = "Использовать необязательное правило \"Замена модификаторов кубиками\" из B269")
@Localize(locale = "es", value = "Usar regla opcional: \"Modificando dado + incrementos\", véase B269")
private static String OPTIONAL_DICE_RULES;
@Localize("Use optional strength rules from the \"Knowing Your Own Strength\" Pyramid article")
private static String OPTIONAL_STRENGTH_RULES;
@Localize("for the initial scale when opening character sheets, templates and lists")
private static String UI_SCALE_POST;
@Localize("HTML Template Override")
@Localize(locale = "de", value = "Alternative HTML-Vorlage")
@Localize(locale = "ru", value = "Переопределить HTML-шаблон")
@Localize(locale = "es", value = "Ignorar la plantilla HTML")
private static String HTML_TEMPLATE_OVERRIDE;
@Localize("Choose\u2026")
@Localize(locale = "de", value = "wählen\u2026")
@Localize(locale = "ru", value = "Выбрать\u2026")
@Localize(locale = "es", value = "Elegir\u2026")
private static String HTML_TEMPLATE_PICKER;
@Localize("Specify a file to use as the template when exporting to HTML")
@Localize(locale = "de", value = "Wähle die Datei, die als Vorlage für den HTML-Export verwendet werden soll.")
@Localize(locale = "ru", value = "Использовать указанный файл шаблона при экспорте в HTML")
@Localize(locale = "es", value = "Especifica que archivose usará como plantilla cuando se exporta a formato HTML")
private static String HTML_TEMPLATE_OVERRIDE_TOOLTIP;
@Localize("Select A HTML Template")
@Localize(locale = "de", value = "Wähle eine HTML-Vorlage")
@Localize(locale = "ru", value = "Выберите HTML-шаблон")
@Localize(locale = "es", value = "Selecionar una plantilla HTML")
private static String SELECT_HTML_TEMPLATE;
@Localize("Use platform native print dialogs (settings cannot be saved)")
@Localize(locale = "de", value = "Verwende Druckdialoge des Betriebssystems (Einstellungen können nicht gespeichert werden)")
@Localize(locale = "ru", value = "Использовать диалоги печати родные для ОС (в этом случае не сохраняются настройки диалогов)")
@Localize(locale = "es", value = "Usar los diálogos de impresión del sistema operativo (No pueden guardarse las preferencias)")
private static String NATIVE_PRINTER;
@Localize("<html><body>Whether or not the native print dialogs should be used.<br>Choosing this option will prevent the program from saving<br>and restoring print settings with the document.</body></html>")
@Localize(locale = "de", value = "<html><body>Ob die Druckdialoge des Betriebssystems verwendet werden sollen.<br>Das Auswählen dieser Option wird das Programm daran hindern,<br>die Druckeinstellungen im Dokument zu speichern und werderherzustellen.</body></html>")
@Localize(locale = "ru", value = "<html><body>Использовать родные диалоги печати ОС.<br>При выборе этого параметра программа не будет сохранять<br>настройки печати документа.</body></html>")
@Localize(locale = "es", value = "<html><body>Indica si se usan o no los diálogos de impresión del sistema operativo.<br>Si se selecciona esta opción, el programa no podrá salvar<br>y restaurar configuración del documento.</body></html>")
private static String NATIVE_PRINTER_TOOLTIP;
@Localize("Automatically name new characters")
@Localize(locale = "de", value = "Neue Charaktere automatisch benennen")
@Localize(locale = "ru", value = "Автоматически называть новых персонажей")
@Localize(locale = "es", value = "Dar nombre automáticamente a los personajes nuevos")
private static String AUTO_NAME;
@Localize("The units to use for display of generated lengths")
@Localize(locale = "de", value = "Die Einheit, in der die berechnete Länge angezeigt wird.")
@Localize(locale = "ru", value = "Единицы измерения создаваемых длин")
@Localize(locale = "es", value = "Unidades en las que mostrar longitudes")
private static String LENGTH_UNITS_TOOLTIP;
@Localize("The units to use for display of generated weights")
@Localize(locale = "de", value = "Die Einheit, in der das berechnete Gewicht angezeigt wird.")
@Localize(locale = "ru", value = "Единицы измерения создаваемых весов")
@Localize(locale = "es", value = "Unidades en las que mostrar pesos")
private static String WEIGHT_UNITS_TOOLTIP;
@Localize("Use")
@Localize(locale = "de", value = "Verwende")
@Localize(locale = "ru", value = "Использовать")
@Localize(locale = "es", value = "usar")
private static String USE;
@Localize("and")
@Localize(locale = "de", value = "und")
@Localize(locale = "ru", value = "и")
@Localize(locale = "es", value = "y")
private static String AND;
@Localize("for display of generated units")
@Localize(locale = "de", value = "zur Anzeige berechneter Werte")
@Localize(locale = "ru", value = "для отображения созданных единиц измерения")
@Localize(locale = "es", value = "para mostrar las unidades generadas")
private static String FOR_UNIT_DISPLAY;
@Localize("Character point total display includes unspent points")
@Localize(locale = "de", value = "Die Gesamtpunktzahl des Charakters enthält die noch nicht ausgegebenen Punkte")
@Localize(locale = "ru", value = "Показывать в общих очках персонажа неизрасходованные (заработанные)")
@Localize(locale = "es", value = "Total de puntos de personaje, que incluye los puntos no consumidos")
private static String TOTAL_POINTS_INCLUDES_UNSPENT_POINTS;
@Localize("Use GURPS Metric rules for height, weight, encumbrance and lifting things")
@Localize(locale = "de", value = "Benutze GURPS Metrisch-Regeln für Höhe, Gewicht, Belastung und Heben von Gegenständen")
@Localize(locale = "ru", value = "Использовать метрическую систему по правилам GURPS для роста, веса, нагрузки и грузоподъёмности")
@Localize(locale = "es", value = "Usar las reglas de métrica de GURPS para altura, peso, carga y levantar objetos")
private static String USE_METRIC_RULES;
@Localize("All Readable Image Files")
private static String ALL_READABLE_IMAGE_FILES;
@Localize("JPEG Files")
private static String JPEG_FILES;
@Localize("GIF Files")
private static String GIF_FILES;
@Localize("GURPS Calculator Key")
private static String GURPS_CALCULATOR_KEY;
@Localize("Find mine")
private static String WHERE_OBTAIN;
@Localize("Unable to open {0}")
private static String UNABLE_TO_OPEN_URL;
static {
Localization.initialize();
}
static final String MODULE = "Sheet"; //$NON-NLS-1$
private static final String OPTIONAL_DICE_RULES_KEY = "UseOptionDiceRules"; //$NON-NLS-1$
/** The optional dice rules preference key. */
public static final String OPTIONAL_DICE_RULES_PREF_KEY = Preferences.getModuleKey(MODULE, OPTIONAL_DICE_RULES_KEY);
private static final boolean DEFAULT_OPTIONAL_DICE_RULES = false;
private static final String OPTIONAL_IQ_RULES_KEY = "UseOptionIQRules"; //$NON-NLS-1$
/** The optional IQ rules preference key. */
public static final String OPTIONAL_IQ_RULES_PREF_KEY = Preferences.getModuleKey(MODULE, OPTIONAL_IQ_RULES_KEY);
private static final boolean DEFAULT_OPTIONAL_IQ_RULES = false;
private static final String OPTIONAL_MODIFIER_RULES_KEY = "UseOptionModifierRules"; //$NON-NLS-1$
/** The optional modifier rules preference key. */
public static final String OPTIONAL_MODIFIER_RULES_PREF_KEY = Preferences.getModuleKey(MODULE, OPTIONAL_MODIFIER_RULES_KEY);
private static final boolean DEFAULT_OPTIONAL_MODIFIER_RULES = false;
private static final String OPTIONAL_STRENGTH_RULES_KEY = "UseOptionalStrengthRules"; //$NON-NLS-1$
/** The optional Strength rules preference key. */
public static final String OPTIONAL_STRENGTH_RULES_PREF_KEY = Preferences.getModuleKey(MODULE, OPTIONAL_STRENGTH_RULES_KEY);
private static final boolean DEFAULT_OPTIONAL_STRENGTH_RULES = false;
private static final String AUTO_NAME_KEY = "AutoNameNewCharacters"; //$NON-NLS-1$
/** The auto-naming preference key. */
public static final String AUTO_NAME_PREF_KEY = Preferences.getModuleKey(MODULE, AUTO_NAME_KEY);
private static final boolean DEFAULT_AUTO_NAME = true;
private static final String LENGTH_UNITS_KEY = "LengthUnits"; //$NON-NLS-1$
/** The default length units preference key. */
public static final String LENGTH_UNITS_PREF_KEY = Preferences.getModuleKey(MODULE, LENGTH_UNITS_KEY);
private static final LengthUnits DEFAULT_LENGTH_UNITS = LengthUnits.FT_IN;
private static final String WEIGHT_UNITS_KEY = "WeightUnits"; //$NON-NLS-1$
/** The default weight units preference key. */
public static final String WEIGHT_UNITS_PREF_KEY = Preferences.getModuleKey(MODULE, WEIGHT_UNITS_KEY);
private static final WeightUnits DEFAULT_WEIGHT_UNITS = WeightUnits.LB;
private static final String TOTAL_POINTS_DISPLAY_KEY = "TotalPointsIncludesUnspentPoints"; //$NON-NLS-1$
/** The total points includes unspent points preference key. */
public static final String TOTAL_POINTS_DISPLAY_PREF_KEY = Preferences.getModuleKey(MODULE, TOTAL_POINTS_DISPLAY_KEY);
private static final boolean DEFAULT_TOTAL_POINTS_DISPLAY = true;
private static final String GURPS_METRIC_RULES_KEY = "UseGurpsMetricRules"; //$NON-NLS-1$
/** The GURPS Metric preference key. */
public static final String GURPS_METRIC_RULES_PREF_KEY = Preferences.getModuleKey(MODULE, GURPS_METRIC_RULES_KEY);
private static final boolean DEFAULT_GURPS_METRIC_RULES = true;
private static final Scales DEFAULT_SCALE = Scales.ACTUAL_SIZE;
private static final String SCALE_KEY = "UIScale"; //$NON-NLS-1$
private static final String INITIAL_POINTS_KEY = "InitialPoints"; //$NON-NLS-1$
private static final int DEFAULT_INITIAL_POINTS = 100;
private JTextField mPlayerName;
private JTextField mCampaign;
private JTextField mTechLevel;
private JTextField mInitialPoints;
private PortraitPreferencePanel mPortrait;
private JComboBox<Scales> mUIScaleCombo;
private JComboBox<String> mLengthUnitsCombo;
private JComboBox<String> mWeightUnitsCombo;
private JCheckBox mUseOptionalDiceRules;
private JCheckBox mUseOptionalIQRules;
private JCheckBox mUseOptionalModifierRules;
private JCheckBox mUseOptionalStrengthRules;
private JCheckBox mIncludeUnspentPointsInTotal;
private JCheckBox mUseGurpsMetricRules;
private JCheckBox mAutoName;
/** Initializes the services controlled by these preferences. */
public static void initialize() {
adjustOptionalDiceRulesProperty(areOptionalDiceRulesUsed());
}
/** @return The default length units to use. */
public static LengthUnits getLengthUnits() {
return Enums.extract(Preferences.getInstance().getStringValue(MODULE, LENGTH_UNITS_KEY), LengthUnits.values(), DEFAULT_LENGTH_UNITS);
}
/** @return The default weight units to use. */
public static WeightUnits getWeightUnits() {
return Enums.extract(Preferences.getInstance().getStringValue(MODULE, WEIGHT_UNITS_KEY), WeightUnits.values(), DEFAULT_WEIGHT_UNITS);
}
private static void adjustOptionalDiceRulesProperty(boolean use) {
Dice.setConvertModifiersToExtraDice(use);
}
/** @return Whether the optional dice rules from B269 are in use. */
public static boolean areOptionalDiceRulesUsed() {
return Preferences.getInstance().getBooleanValue(MODULE, OPTIONAL_DICE_RULES_KEY, DEFAULT_OPTIONAL_DICE_RULES);
}
/**
* @return Whether the optional IQ rules (Will & Perception are not based on IQ) are in use.
*/
public static boolean areOptionalIQRulesUsed() {
return Preferences.getInstance().getBooleanValue(MODULE, OPTIONAL_IQ_RULES_KEY, DEFAULT_OPTIONAL_IQ_RULES);
}
/** @return Whether the optional modifier rules from PW102 are in use. */
public static boolean areOptionalModifierRulesUsed() {
return Preferences.getInstance().getBooleanValue(MODULE, OPTIONAL_MODIFIER_RULES_KEY, DEFAULT_OPTIONAL_MODIFIER_RULES);
}
/** @return Whether the optional strength rules (KYOS) are in use. */
public static boolean areOptionalStrengthRulesUsed() {
return Preferences.getInstance().getBooleanValue(MODULE, OPTIONAL_STRENGTH_RULES_KEY, DEFAULT_OPTIONAL_STRENGTH_RULES);
}
/**
* @return Whether the character's total points are displayed with or without including earned
* (but unspent) points.
*/
public static boolean shouldIncludeUnspentPointsInTotalPointDisplay() {
return Preferences.getInstance().getBooleanValue(MODULE, TOTAL_POINTS_DISPLAY_KEY, DEFAULT_TOTAL_POINTS_DISPLAY);
}
/** @return Whether the GURPS Metrics rules are used for weight and height conversion. */
public static boolean areGurpsMetricRulesUsed() {
return Preferences.getInstance().getBooleanValue(MODULE, GURPS_METRIC_RULES_KEY, DEFAULT_GURPS_METRIC_RULES);
}
/** @return Whether a new character should be automatically named. */
public static boolean isNewCharacterAutoNamed() {
return Preferences.getInstance().getBooleanValue(MODULE, AUTO_NAME_KEY, DEFAULT_AUTO_NAME);
}
/** @return The {@link Scales} to use when opening a new scalable file. */
public static Scales getInitialUIScale() {
double value = Preferences.getInstance().getDoubleValue(MODULE, SCALE_KEY, DEFAULT_SCALE.getScale().getScale());
for (Scales one : Scales.values()) {
if (one.getScale().getScale() == value) {
return one;
}
}
return Scales.ACTUAL_SIZE;
}
/** @return The initial points to start a new character with. */
public static int getInitialPoints() {
return Preferences.getInstance().getIntValue(MODULE, INITIAL_POINTS_KEY, DEFAULT_INITIAL_POINTS);
}
/**
* Creates a new {@link SheetPreferences}.
*
* @param owner The owning {@link PreferencesWindow}.
*/
public SheetPreferences(PreferencesWindow owner) {
super(SHEET, owner);
FlexColumn column = new FlexColumn();
FlexGrid grid = new FlexGrid();
column.add(grid);
int rowIndex = 0;
mPortrait = createPortrait();
FlexComponent comp = new FlexComponent(mPortrait, Alignment.LEFT_TOP, Alignment.LEFT_TOP);
grid.add(comp, rowIndex, 0, 4, 1);
grid.add(createFlexLabel(PLAYER, PLAYER_TOOLTIP), rowIndex, 1);
mPlayerName = createTextField(PLAYER_TOOLTIP, Profile.getDefaultPlayerName());
grid.add(mPlayerName, rowIndex++, 2);
grid.add(createFlexLabel(CAMPAIGN, CAMPAIGN_TOOLTIP), rowIndex, 1);
mCampaign = createTextField(CAMPAIGN_TOOLTIP, Profile.getDefaultCampaign());
grid.add(mCampaign, rowIndex++, 2);
grid.add(createFlexLabel(TECH_LEVEL, TECH_LEVEL_TOOLTIP), rowIndex, 1);
mTechLevel = createTextField(TECH_LEVEL_TOOLTIP, Profile.getDefaultTechLevel());
grid.add(mTechLevel, rowIndex++, 2);
grid.add(createFlexLabel(INITIAL_POINTS, INITIAL_POINTS_TOOLTIP), rowIndex, 1);
mInitialPoints = createTextField(INITIAL_POINTS_TOOLTIP, Integer.toString(getInitialPoints()));
grid.add(mInitialPoints, rowIndex++, 2);
grid.add(new FlexSpacer(0, 0, false, true), rowIndex, 1);
grid.add(new FlexSpacer(0, 0, true, true), rowIndex, 2);
addSeparator(column);
FlexRow row = new FlexRow();
row.add(createLabel(USE, null));
mLengthUnitsCombo = createLengthUnitsPopup();
row.add(mLengthUnitsCombo);
row.add(createLabel(AND, null));
mWeightUnitsCombo = createWeightUnitsPopup();
row.add(mWeightUnitsCombo);
row.add(createLabel(FOR_UNIT_DISPLAY, null));
column.add(row);
mAutoName = createCheckBox(AUTO_NAME, null, isNewCharacterAutoNamed());
column.add(mAutoName);
mUseOptionalIQRules = createCheckBox(OPTIONAL_IQ_RULES, null, areOptionalIQRulesUsed());
column.add(mUseOptionalIQRules);
mUseOptionalModifierRules = createCheckBox(OPTIONAL_MODIFIER_RULES, null, areOptionalModifierRulesUsed());
column.add(mUseOptionalModifierRules);
mUseOptionalDiceRules = createCheckBox(OPTIONAL_DICE_RULES, null, areOptionalDiceRulesUsed());
column.add(mUseOptionalDiceRules);
mUseOptionalStrengthRules = createCheckBox(OPTIONAL_STRENGTH_RULES, null, areOptionalStrengthRulesUsed());
column.add(mUseOptionalStrengthRules);
mIncludeUnspentPointsInTotal = createCheckBox(TOTAL_POINTS_INCLUDES_UNSPENT_POINTS, null, shouldIncludeUnspentPointsInTotalPointDisplay());
column.add(mIncludeUnspentPointsInTotal);
mUseGurpsMetricRules = createCheckBox(USE_METRIC_RULES, null, areGurpsMetricRulesUsed());
column.add(mUseGurpsMetricRules);
row = new FlexRow();
row.add(createLabel(USE, null));
mUIScaleCombo = createUIScalePopup();
row.add(mUIScaleCombo);
row.add(createLabel(UI_SCALE_POST, null, SwingConstants.LEFT));
column.add(row);
column.add(new FlexSpacer(0, 0, false, true));
column.apply(this);
}
private FlexComponent createFlexLabel(String title, String tooltip) {
return new FlexComponent(createLabel(title, tooltip), Alignment.RIGHT_BOTTOM, Alignment.CENTER);
}
private PortraitPreferencePanel createPortrait() {
PortraitPreferencePanel panel = new PortraitPreferencePanel(Profile.getPortraitFromPortraitPath(Profile.getDefaultPortraitPath()));
panel.addActionListener(this);
add(panel);
return panel;
}
private JComboBox<Scales> createUIScalePopup() {
JComboBox<Scales> combo = new JComboBox<>(Scales.values());
setupCombo(combo, null);
combo.setSelectedItem(getInitialUIScale());
combo.addActionListener(this);
combo.setMaximumRowCount(combo.getItemCount());
UIUtilities.setOnlySize(combo, combo.getPreferredSize());
return combo;
}
private JComboBox<String> createLengthUnitsPopup() {
JComboBox<String> combo = new JComboBox<>();
setupCombo(combo, LENGTH_UNITS_TOOLTIP);
for (LengthUnits unit : LengthUnits.values()) {
combo.addItem(unit.getDescription());
}
combo.setSelectedIndex(getLengthUnits().ordinal());
combo.addActionListener(this);
combo.setMaximumRowCount(combo.getItemCount());
UIUtilities.setOnlySize(combo, combo.getPreferredSize());
return combo;
}
private JComboBox<String> createWeightUnitsPopup() {
JComboBox<String> combo = new JComboBox<>();
setupCombo(combo, WEIGHT_UNITS_TOOLTIP);
for (WeightUnits unit : WeightUnits.values()) {
combo.addItem(unit.getDescription());
}
combo.setSelectedIndex(getWeightUnits().ordinal());
combo.addActionListener(this);
combo.setMaximumRowCount(combo.getItemCount());
UIUtilities.setOnlySize(combo, combo.getPreferredSize());
return combo;
}
private JTextField createTextField(String tooltip, String value) {
JTextField field = new JTextField(value);
field.setToolTipText(Text.wrapPlainTextForToolTip(tooltip));
field.getDocument().addDocumentListener(this);
Dimension size = field.getPreferredSize();
Dimension maxSize = field.getMaximumSize();
maxSize.height = size.height;
field.setMaximumSize(maxSize);
add(field);
return field;
}
public static File choosePortrait() {
List<FileNameExtensionFilter> filters = new ArrayList<>();
filters.add(new FileNameExtensionFilter(ALL_READABLE_IMAGE_FILES, FileType.PNG_EXTENSION, FileType.JPEG_EXTENSION, "jpeg", FileType.GIF_EXTENSION)); //$NON-NLS-1$
filters.add(FileType.getPngFilter());
filters.add(FileType.getJpegFilter());
filters.add(FileType.getGifFilter());
return StdFileDialog.showOpenDialog(null, SELECT_PORTRAIT, filters);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == mPortrait) {
File file = choosePortrait();
if (file != null) {
setPortrait(PathUtils.getFullPath(file));
}
} else if (source == mUIScaleCombo) {
Preferences.getInstance().setValue(MODULE, SCALE_KEY, ((Scales) mUIScaleCombo.getSelectedItem()).getScale().getScale());
} else if (source == mLengthUnitsCombo) {
Preferences.getInstance().setValue(MODULE, LENGTH_UNITS_KEY, Enums.toId(LengthUnits.values()[mLengthUnitsCombo.getSelectedIndex()]));
} else if (source == mWeightUnitsCombo) {
Preferences.getInstance().setValue(MODULE, WEIGHT_UNITS_KEY, Enums.toId(WeightUnits.values()[mWeightUnitsCombo.getSelectedIndex()]));
}
adjustResetButton();
}
@Override
public void reset() {
mPlayerName.setText(System.getProperty("user.name")); //$NON-NLS-1$
mCampaign.setText(""); //$NON-NLS-1$
mTechLevel.setText(Profile.DEFAULT_TECH_LEVEL);
mInitialPoints.setText(Integer.toString(DEFAULT_INITIAL_POINTS));
setPortrait(Profile.DEFAULT_PORTRAIT);
mUIScaleCombo.setSelectedItem(DEFAULT_SCALE);
mLengthUnitsCombo.setSelectedIndex(DEFAULT_LENGTH_UNITS.ordinal());
mWeightUnitsCombo.setSelectedIndex(DEFAULT_WEIGHT_UNITS.ordinal());
mAutoName.setSelected(DEFAULT_AUTO_NAME);
mUseOptionalDiceRules.setSelected(DEFAULT_OPTIONAL_DICE_RULES);
mUseOptionalIQRules.setSelected(DEFAULT_OPTIONAL_IQ_RULES);
mUseOptionalModifierRules.setSelected(DEFAULT_OPTIONAL_MODIFIER_RULES);
mUseOptionalStrengthRules.setSelected(DEFAULT_OPTIONAL_STRENGTH_RULES);
mIncludeUnspentPointsInTotal.setSelected(DEFAULT_TOTAL_POINTS_DISPLAY);
mUseGurpsMetricRules.setSelected(DEFAULT_GURPS_METRIC_RULES);
}
@Override
public boolean isSetToDefaults() {
return Profile.getDefaultPlayerName().equals(System.getProperty("user.name")) && Profile.getDefaultCampaign().equals("") && Profile.getDefaultPortraitPath().equals(Profile.DEFAULT_PORTRAIT) && Profile.getDefaultTechLevel().equals(Profile.DEFAULT_TECH_LEVEL) && getInitialPoints() == DEFAULT_INITIAL_POINTS && getInitialUIScale() == DEFAULT_SCALE && areOptionalDiceRulesUsed() == DEFAULT_OPTIONAL_DICE_RULES && areOptionalIQRulesUsed() == DEFAULT_OPTIONAL_IQ_RULES && areOptionalModifierRulesUsed() == DEFAULT_OPTIONAL_MODIFIER_RULES && areOptionalStrengthRulesUsed() == DEFAULT_OPTIONAL_STRENGTH_RULES && isNewCharacterAutoNamed() == DEFAULT_AUTO_NAME; //$NON-NLS-1$ //$NON-NLS-2$
}
private void setPortrait(String path) {
StdImage image = Profile.getPortraitFromPortraitPath(path);
Profile.setDefaultPortraitPath(path);
mPortrait.setPortrait(image);
}
@Override
public void changedUpdate(DocumentEvent event) {
Document document = event.getDocument();
if (mPlayerName.getDocument() == document) {
Profile.setDefaultPlayerName(mPlayerName.getText());
} else if (mCampaign.getDocument() == document) {
Profile.setDefaultCampaign(mCampaign.getText());
} else if (mTechLevel.getDocument() == document) {
Profile.setDefaultTechLevel(mTechLevel.getText());
} else if (mInitialPoints.getDocument() == document) {
Preferences.getInstance().setValue(MODULE, INITIAL_POINTS_KEY, Numbers.extractInteger(mInitialPoints.getText(), 0, true));
}
adjustResetButton();
}
@Override
public void insertUpdate(DocumentEvent event) {
changedUpdate(event);
}
@Override
public void removeUpdate(DocumentEvent event) {
changedUpdate(event);
}
@Override
public void itemStateChanged(ItemEvent event) {
Object source = event.getSource();
if (source == mUseOptionalDiceRules) {
boolean checked = mUseOptionalDiceRules.isSelected();
adjustOptionalDiceRulesProperty(checked);
Preferences.getInstance().setValue(MODULE, OPTIONAL_DICE_RULES_KEY, checked);
} else if (source == mUseOptionalIQRules) {
Preferences.getInstance().setValue(MODULE, OPTIONAL_IQ_RULES_KEY, mUseOptionalIQRules.isSelected());
} else if (source == mUseOptionalModifierRules) {
Preferences.getInstance().setValue(MODULE, OPTIONAL_MODIFIER_RULES_KEY, mUseOptionalModifierRules.isSelected());
} else if (source == mUseOptionalStrengthRules) {
Preferences.getInstance().setValue(MODULE, OPTIONAL_STRENGTH_RULES_KEY, mUseOptionalStrengthRules.isSelected());
} else if (source == mIncludeUnspentPointsInTotal) {
Preferences.getInstance().setValue(MODULE, TOTAL_POINTS_DISPLAY_KEY, mIncludeUnspentPointsInTotal.isSelected());
} else if (source == mUseGurpsMetricRules) {
Preferences.getInstance().setValue(MODULE, GURPS_METRIC_RULES_KEY, mUseGurpsMetricRules.isSelected());
} else if (source == mAutoName) {
Preferences.getInstance().setValue(MODULE, AUTO_NAME_KEY, mAutoName.isSelected());
}
adjustResetButton();
}
}