From 9a25a05d1b376dc20a14696afa280ff4940b1f8a Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Fri, 21 Feb 2025 23:51:13 -0500 Subject: Add internationalization API to GUI This commit intentionally fails one test, since that is for functionality I intend to add later. --- src/test/java/sevenUnitsGUI/I18nTest.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/java/sevenUnitsGUI/I18nTest.java (limited to 'src/test') diff --git a/src/test/java/sevenUnitsGUI/I18nTest.java b/src/test/java/sevenUnitsGUI/I18nTest.java new file mode 100644 index 0000000..73bd727 --- /dev/null +++ b/src/test/java/sevenUnitsGUI/I18nTest.java @@ -0,0 +1,21 @@ +package sevenUnitsGUI; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +class I18nTest { + + /** + * Tests that the default locale exists. + * + * Currently this test fails. + */ + @Test + void testDefaultLocale() { + Presenter p = new Presenter(new ViewBot()); + assertNotNull(p.locales.get(Presenter.DEFAULT_LOCALE), + "Default locale does not exist."); + } + +} -- cgit v1.2.3 From 4436b29053a0b757562ecc1d0a78e22902e6e5ae Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Sun, 23 Feb 2025 19:20:30 -0500 Subject: Allow default datafile to be disabled If this option is deselected, the default unit, prefix, dimension and metric exception data will not be loaded, and only custom data and the few units that are not provided by files will be available. The main rationale for this change is so that the data can be localized by custom unit files. --- src/main/java/sevenUnitsGUI/Presenter.java | 93 +++++++++++++++++++++----- src/main/java/sevenUnitsGUI/TabbedView.java | 18 ++++- src/main/resources/locales/en.txt | 1 + src/main/resources/locales/fr.txt | 1 + src/test/java/sevenUnitsGUI/PresenterTest.java | 18 +++++ 5 files changed, 110 insertions(+), 21 deletions(-) (limited to 'src/test') diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java index 6467f03..ba600e3 100644 --- a/src/main/java/sevenUnitsGUI/Presenter.java +++ b/src/main/java/sevenUnitsGUI/Presenter.java @@ -347,6 +347,19 @@ public final class Presenter { * unit view in views that show units as a list to choose from. */ private boolean showDuplicates = false; + + /** + * The default unit, prefix, dimension and exception data will only be loaded + * if this variable is true. + */ + private boolean useDefaultDatafiles = true; + + /** Custom unit datafiles that will be loaded by {@link #reloadData} */ + private final Set customUnitFiles = new HashSet<>(); + /** Custom dimension datafiles that will be loaded by {@link #reloadData} */ + private final Set customDimensionFiles = new HashSet<>(); + /** Custom exception datafiles that will be loaded by {@link #reloadData} */ + private final Set customExceptionFiles = new HashSet<>(); /** * Creates a Presenter @@ -357,8 +370,45 @@ public final class Presenter { public Presenter(View view) { this.view = view; this.database = new UnitDatabase(); - addDefaults(this.database); + this.metricExceptions = new HashSet<>(); + + this.locales = this.loadLocales(); + this.userLocale = DEFAULT_LOCALE; + + // set default settings temporarily + if (Files.exists(CONFIG_FILE)) { + this.loadSettings(CONFIG_FILE); + } + this.reloadData(); + + // print out unit counts + System.out.println(this.loadStatMsg()); + } + + /** + * Clears then reloads all unit, prefix, dimension and exception data. + */ + public void reloadData() { + this.database.clear(); + this.metricExceptions.clear(); + addDefaults(this.database); + + if (this.useDefaultDatafiles) { + this.loadDefaultData(); + } + + this.customUnitFiles.forEach( + path -> this.handleLoadErrors(this.database.loadUnitsFile(path))); + this.customDimensionFiles.forEach( + path -> this.handleLoadErrors(this.database.loadDimensionFile(path))); + this.customExceptionFiles.forEach(this::loadExceptionFile); + } + + /** + * Load units, prefixes and dimensions from the default files. + */ + private void loadDefaultData() { // load units and prefixes try (final var units = inputStream(DEFAULT_UNITS_FILEPATH)) { this.handleLoadErrors(this.database.loadUnitsFromStream(units)); @@ -377,7 +427,6 @@ public final class Presenter { // load metric exceptions try { - this.metricExceptions = new HashSet<>(); try (var exceptions = inputStream(DEFAULT_EXCEPTIONS_FILEPATH); var scanner = new Scanner(exceptions)) { while (scanner.hasNextLine()) { @@ -392,17 +441,6 @@ public final class Presenter { throw new AssertionError("Loading of metric_exceptions.txt failed.", e); } - - this.locales = this.loadLocales(); - this.userLocale = DEFAULT_LOCALE; - - // set default settings temporarily - if (Files.exists(CONFIG_FILE)) { - this.loadSettings(CONFIG_FILE); - } - - // print out unit counts - System.out.println(this.loadStatMsg()); } /** @@ -962,6 +1000,10 @@ public final class Presenter { * @since 2021-12-15 */ void loadSettings(Path settingsFile) { + this.customDimensionFiles.clear(); + this.customExceptionFiles.clear(); + this.customUnitFiles.clear(); + for (final Map.Entry setting : this .settingsFromFile(settingsFile)) { final var value = setting.getValue(); @@ -970,15 +1012,13 @@ public final class Presenter { // set manually to avoid the unnecessary saving of the non-manual // methods case "custom_dimension_file": - this.handleLoadErrors( - this.database.loadDimensionFile(pathFromConfig(value))); + this.customDimensionFiles.add(pathFromConfig(value)); break; case "custom_exception_file": - this.loadExceptionFile(pathFromConfig(value)); + this.customExceptionFiles.add(pathFromConfig(value)); break; case "custom_unit_file": - this.handleLoadErrors( - this.database.loadUnitsFile(pathFromConfig(value))); + this.customUnitFiles.add(pathFromConfig(value)); break; case "number_display_rule": this.setDisplayRuleFromString(value); @@ -1204,6 +1244,16 @@ public final class Presenter { return null; } } + + /** + * Sets whether or not the default datafiles will be loaded. + * This method automatically updates the view's units. + */ + public void setUseDefaultDatafiles(boolean useDefaultDatafiles) { + this.useDefaultDatafiles = useDefaultDatafiles; + this.reloadData(); + this.updateView(); + } /** * Sets the user's locale, updating the view. @@ -1304,6 +1354,13 @@ public final class Presenter { ucview.setToUnitNames(toNames); } } + + /** + * @return true iff the default datafiles are being used + */ + public boolean usingDefaultDatafiles() { + return this.useDefaultDatafiles; + } /** * @param message message to add diff --git a/src/main/java/sevenUnitsGUI/TabbedView.java b/src/main/java/sevenUnitsGUI/TabbedView.java index ca9f23c..40ed0a7 100644 --- a/src/main/java/sevenUnitsGUI/TabbedView.java +++ b/src/main/java/sevenUnitsGUI/TabbedView.java @@ -662,10 +662,22 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { miscPanel.add(showAllVariations, new GridBagBuilder(0, 1, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); + final JCheckBox useDefaultFiles = new JCheckBox(); + this.localizedTextSetters.put("tv.settings.use_default_files", + useDefaultFiles::setText); + useDefaultFiles.setSelected(this.presenter.usingDefaultDatafiles()); + useDefaultFiles.addItemListener(e -> { + this.presenter + .setUseDefaultDatafiles(e.getStateChange() == ItemEvent.SELECTED); + this.presenter.saveSettings(); + }); + miscPanel.add(useDefaultFiles, new GridBagBuilder(0, 2, 2, 1) + .setAnchor(GridBagConstraints.LINE_START).build()); + final JLabel localeLabel = new JLabel(); this.localizedTextSetters.put("tv.settings.locale", localeLabel::setText); - miscPanel.add(localeLabel, new GridBagBuilder(0, 2, 1, 1) + miscPanel.add(localeLabel, new GridBagBuilder(0, 3, 1, 1) .setAnchor(GridBagConstraints.LINE_START).build()); this.presenter.getAvailableLocales().stream().sorted() @@ -675,14 +687,14 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { this.presenter.setUserLocale((String) e.getItem()); this.presenter.saveSettings(); }); - miscPanel.add(localeSelector, new GridBagBuilder(1, 2, 1, 1) + miscPanel.add(localeSelector, new GridBagBuilder(1, 3, 1, 1) .setAnchor(GridBagConstraints.LINE_END).build()); final JButton unitFileButton = new JButton(); this.localizedTextSetters.put("tv.settings.unitfiles.button", unitFileButton::setText); unitFileButton.setEnabled(false); - miscPanel.add(unitFileButton, new GridBagBuilder(0, 3, 2, 1) + miscPanel.add(unitFileButton, new GridBagBuilder(0, 4, 2, 1) .setAnchor(GridBagConstraints.LINE_START).build()); } diff --git a/src/main/resources/locales/en.txt b/src/main/resources/locales/en.txt index 19ed781..5173cf3 100644 --- a/src/main/resources/locales/en.txt +++ b/src/main/resources/locales/en.txt @@ -25,5 +25,6 @@ tv.settings.search.common_prefixes=Include Common Prefixes tv.settings.search.all_prefixes=Include All Single Prefixes tv.settings.oneway=Convert One Way Only tv.settings.show_duplicate=Show Duplicate Units & Prefixes +tv.settings.use_default_files=Use Default Datafiles tv.settings.locale=🌐 Locale: tv.settings.unitfiles.button=Manage Unit Data Files diff --git a/src/main/resources/locales/fr.txt b/src/main/resources/locales/fr.txt index d25e2b0..e8b7138 100644 --- a/src/main/resources/locales/fr.txt +++ b/src/main/resources/locales/fr.txt @@ -25,5 +25,6 @@ tv.settings.search.common_prefixes=Inclure prĂ©fixes frĂ©quents tv.settings.search.all_prefixes=Inclure tous prĂ©fixes seuls tv.settings.oneway=Convertir Seulement en un Direction tv.settings.show_duplicate=Montrer unitĂ©s et prĂ©fixes doubles +tv.settings.use_default_files=Utilise donĂ©es par dĂ©faut tv.settings.locale=🌐 Locale: tv.settings.unitfiles.button=GĂ©rer donĂ©es d’unitĂ©s diff --git a/src/test/java/sevenUnitsGUI/PresenterTest.java b/src/test/java/sevenUnitsGUI/PresenterTest.java index 9e25a08..8b16365 100644 --- a/src/test/java/sevenUnitsGUI/PresenterTest.java +++ b/src/test/java/sevenUnitsGUI/PresenterTest.java @@ -17,6 +17,7 @@ package sevenUnitsGUI; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -154,6 +155,23 @@ public final class PresenterTest { expectedOutput.getValue().toString(false, RoundingMode.HALF_EVEN)); assertEquals(List.of(expectedUC), viewBot.unitConversionList()); } + + /** + * Ensures that the default unitfile can be disabled. + * + * @since v1.0.0 + * @since 2025-02-23 + */ + @Test + void testDisableDefault() { + final var viewBot = new ViewBot(); + final var presenter = new Presenter(viewBot); + assumeTrue(presenter.database.containsUnitName("joule"), + "Attempted to test disabling default on unit not in default file."); + presenter.setUseDefaultDatafiles(false); + assertFalse(presenter.database.containsUnitName("joule"), + "Presenter disabled default datafiles, but still contains the joule."); + } /** * Tests that duplicate units are successfully removed, if that is asked for -- cgit v1.2.3