diff options
author | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2025-02-21 23:51:13 -0500 |
---|---|---|
committer | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2025-02-23 20:31:46 -0500 |
commit | 9a25a05d1b376dc20a14696afa280ff4940b1f8a (patch) | |
tree | ffc8b19b8262556b28f39ce691e2ec2fe90b0ed8 | |
parent | a9485b187844cad900bc43c0651406c51a7295c1 (diff) |
Add internationalization API to GUI
This commit intentionally fails one test, since that is for
functionality I intend to add later.
-rw-r--r-- | .classpath | 2 | ||||
-rw-r--r-- | src/main/java/sevenUnitsGUI/Presenter.java | 58 | ||||
-rw-r--r-- | src/main/java/sevenUnitsGUI/TabbedView.java | 5 | ||||
-rw-r--r-- | src/main/java/sevenUnitsGUI/View.java | 7 | ||||
-rw-r--r-- | src/main/java/sevenUnitsGUI/ViewBot.java | 5 | ||||
-rw-r--r-- | src/test/java/sevenUnitsGUI/I18nTest.java | 21 |
6 files changed, 97 insertions, 1 deletions
@@ -25,6 +25,6 @@ <attribute name="module" value="true"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/> <classpathentry kind="output" path="bin/default"/> </classpath> diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java index c46ee53..21f2951 100644 --- a/src/main/java/sevenUnitsGUI/Presenter.java +++ b/src/main/java/sevenUnitsGUI/Presenter.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -77,6 +78,15 @@ public final class Presenter { /** A Predicate that returns true iff the argument is a full base unit */ private static final Predicate<Unit> IS_FULL_BASE = unit -> unit instanceof LinearUnit && ((LinearUnit) unit).isBase(); + /** + * The default locale, used in two situations: + * <ul> + * <li> If no text is available in your locale, + * uses text from this locale. + * <li> Users are initialized with this locale. + * </ul> + */ + static final String DEFAULT_LOCALE = "en"; /** * Adds default units and dimensions to a database. @@ -317,6 +327,12 @@ public final class Presenter { */ private final Set<String> metricExceptions; + /** maps locale names (e.g. 'en') to key-text maps */ + final Map<String, Map<String, String>> locales; + + /** name of locale in locales to use */ + String userLocale; + /** * If this is true, views that show units as a list will have metric units * removed from the From unit list and imperial/USC units removed from the To @@ -375,6 +391,9 @@ public final class Presenter { e); } + // TODO load locales + this.locales = new HashMap<>(); + // set default settings temporarily if (Files.exists(CONFIG_FILE)) { this.loadSettings(CONFIG_FILE); @@ -736,6 +755,14 @@ public final class Presenter { } /** + * @return set of all locales available to select + * @since 2025-02-21 + */ + public final Set<String> getAvailableLocales() { + return this.locales.keySet(); + } + + /** * Gets a name for this dimension using the database * * @param dimension dimension to name @@ -751,6 +778,20 @@ public final class Presenter { } /** + * Gets the correct text for a provided ID. + * If this text is available in the user's locale, that text is provided. + * Otherwise, text is taken from the system default locale {@link #DEFAULT_LOCALE}. + * + * @param textID ID of text to get (used in locale files) + * @return text to be displayed + */ + public String getLocalizedText(String textID) { + final Map<String, String> userLocale = this.locales.get(this.userLocale); + final Map<String, String> defaultLocale = this.locales.get(DEFAULT_LOCALE); + return userLocale.getOrDefault(textID, defaultLocale.get(textID)); + } + + /** * @return the rule that is used by this presenter to convert numbers into * strings * @since 2022-04-10 @@ -786,6 +827,14 @@ public final class Presenter { } /** + * @return user's selected locale + * @since 2025-02-21 + */ + public String getUserLocale() { + return userLocale; + } + + /** * @return a search rule that shows all single prefixes * @since 2022-07-08 */ @@ -1100,6 +1149,15 @@ public final class Presenter { this.updateView(); } + /** + * Sets the user's locale, updating the view. + * @param userLocale locale to use + */ + public void setUserLocale(String userLocale) { + this.userLocale = userLocale; + this.view.updateText(); + } + private List<Map.Entry<String, String>> settingsFromFile(Path settingsFile) { try (Stream<String> lines = Files.lines(settingsFile)) { return lines.map(Presenter::withoutComments) diff --git a/src/main/java/sevenUnitsGUI/TabbedView.java b/src/main/java/sevenUnitsGUI/TabbedView.java index 6542541..493fc10 100644 --- a/src/main/java/sevenUnitsGUI/TabbedView.java +++ b/src/main/java/sevenUnitsGUI/TabbedView.java @@ -827,4 +827,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView { this.presenter.setNumberDisplayRule(roundingRule); this.presenter.saveSettings(); } + + @Override + public void updateText() { + // TODO Auto-generated method stub + } } diff --git a/src/main/java/sevenUnitsGUI/View.java b/src/main/java/sevenUnitsGUI/View.java index 7dd0c44..4140992 100644 --- a/src/main/java/sevenUnitsGUI/View.java +++ b/src/main/java/sevenUnitsGUI/View.java @@ -112,4 +112,11 @@ public interface View { */ void showUnit(NameSymbol name, String definition, String dimensionName, UnitType type); + + /** + * Updates the view's text to reflect the presenter's locale. + * + * This method <b>must not</b> call {@link Presenter#setUserLocale(String)}. + */ + void updateText(); } diff --git a/src/main/java/sevenUnitsGUI/ViewBot.java b/src/main/java/sevenUnitsGUI/ViewBot.java index e6593fb..8fff46d 100644 --- a/src/main/java/sevenUnitsGUI/ViewBot.java +++ b/src/main/java/sevenUnitsGUI/ViewBot.java @@ -505,4 +505,9 @@ public final class ViewBot public List<UnitViewingRecord> unitViewList() { return Collections.unmodifiableList(this.unitViewingRecords); } + + @Override + public void updateText() { + // do nothing, since ViewBot is not localized + } } 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."); + } + +} |