summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Hopkins <adrien.p.hopkins@gmail.com>2025-02-21 23:51:13 -0500
committerAdrien Hopkins <adrien.p.hopkins@gmail.com>2025-02-23 20:31:46 -0500
commit9a25a05d1b376dc20a14696afa280ff4940b1f8a (patch)
treeffc8b19b8262556b28f39ce691e2ec2fe90b0ed8
parenta9485b187844cad900bc43c0651406c51a7295c1 (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--.classpath2
-rw-r--r--src/main/java/sevenUnitsGUI/Presenter.java58
-rw-r--r--src/main/java/sevenUnitsGUI/TabbedView.java5
-rw-r--r--src/main/java/sevenUnitsGUI/View.java7
-rw-r--r--src/main/java/sevenUnitsGUI/ViewBot.java5
-rw-r--r--src/test/java/sevenUnitsGUI/I18nTest.java21
6 files changed, 97 insertions, 1 deletions
diff --git a/.classpath b/.classpath
index d4e759d..02a1f84 100644
--- a/.classpath
+++ b/.classpath
@@ -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.");
+ }
+
+}