i18n for the setup wizard

This commit is contained in:
Zlatin Balevsky
2020-09-28 17:35:02 +01:00
parent 8293a5128d
commit b12172eef1
10 changed files with 126 additions and 48 deletions

View File

@ -1,2 +1,59 @@
# System tray
EXIT=Exit
OPEN_MUWIRE=Open MuWire
# Wizard general
CANCEL=Cancel
PREVIOUS=Previous
NEXT=Next
FINISH=Finish
# Wizard nickname step
SELECT_A_NICKNAME=Select a nickname
PLEASE_SELECT_A_NICKNAME=Please select a nickname
NICKNAME_CANNOT_BE_BLANK=Nickname cannot be blank
NICKNAME_CANNOT_CONTAIN=Nickname cannot contain any of {0} and must be no longer than {1} characters. Choose another.
# Wizard directories step
SELECT_DOWNLOAD_AND_INCOMPLETE_DIRECTORIES=Select directories for saving downloaded and incomplete files.
DIRECTORIES_WILL_BE_CREATED=They will be created if they do not already exist.
DIRECTORY_FOR_DOWNLOADED_FILES=Directory for saving downloaded files
DIRECTORY_FOR_INCOMPLETE_FILES=Directory for storing incomplete files
CHOOSE=Choose
DOWNLOAD_LOCATION_NOT_WRITEABLE=Download location not writeable
INCOMPLETE_LOCATION_NOT_WRITEABLE=Incomplete location not writeable
SELECT_DIRECTORY_DOWNLOAD_FILES=Select directory for downloaded files
SELECT_DIRECTORY_INCOMPLETE_FILES=Select directory for incomplete files
# Wizard embedded router step
PORT_SETTINGS=Port Settings
TCP_PORT=TCP port
UDP_PORT=UDP port
BANDWIDTH_SETTINGS=Bandwidth Settings
INBOUND_BANDWIDTH=Inbound Bandwidth (KB)
OUTBOUND_BANDWIDTH=Outbound Bandwidth (KB)
INVALID_UDP_PORT=Invalid UDP Port
INVALID_TCP_PORT=Invalid TCP Port
INVALID_PORT=Invalid Port
OUT_CANNOT_BE_NEGATIVE=Out bandwidth cannot be negative
IN_CANNOT_BE_NEGATIVE=In bandwidth cannot be negative
INVALID_BANDWIDTH=Invalid bandwidth
# Wizard external router step
EXTERNAL_ROUTER_I2CP_SETTINGS=External Router I2CP Settings
HOST=Host
PORT=Port
INVALID_ADDRESS=Invalid Address
# Wizard tunnel step
SPEED_VS_ANONYMITY=Speed vs. Anonymity
MAX_SPEED=Max Speed
MAX_ANONYMITY=Max Anonymity
RELIABILITY_VS_RESOURCES=Reliability vs. Resource Usage
MIN_RESOURCES=Min Resources
MAX_RELIABILITY=Max Reliability
# Wizard last step
WIZARD_COMPLETE=The wizard is complete. Press "Finish" to launch MuWire.
LAUNCH_EMBEDDED_ROUTER=MuWire will launch an embedded I2P router. This can take a few minutes.

View File

@ -144,7 +144,7 @@ class Initialize extends AbstractLifecycleHandler {
def trayIcon = new TrayIcon(image, "MuWire", popupMenu)
def exit = new MenuItem(Translator.getString("EXIT"))
def exit = new MenuItem(Translator.trans("EXIT"))
exit.addActionListener({
application.getWindowManager().findWindow("main-frame").setVisible(false)
application.getWindowManager().findWindow("shutdown-window").setVisible(true)
@ -169,7 +169,7 @@ class Initialize extends AbstractLifecycleHandler {
}
}
def show = new MenuItem(Translator.getString("OPEN_MUWIRE"))
def show = new MenuItem(Translator.trans("OPEN_MUWIRE"))
show.addActionListener(showMW)
popupMenu.add(show)
popupMenu.add(exit)

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import griffon.core.artifact.GriffonView
import static com.muwire.gui.Translator.trans
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
@ -37,12 +38,12 @@ class WizardView {
panel (constraints : BorderLayout.SOUTH) {
gridLayout(rows:1, cols:2)
panel {
button(text : "Cancel", cancelAction)
button(text : trans("CANCEL"), cancelAction)
}
panel {
button(text : "Previous", enabled : bind {model.previousButtonEnabled}, previousAction)
button(text : "Next", enabled : bind {model.nextButtonEnabled}, nextAction)
button(text : "Finish", enabled : bind {model.finishButtonEnabled}, finishAction)
button(text : trans("PREVIOUS"), enabled : bind {model.previousButtonEnabled}, previousAction)
button(text : trans("NEXT"), enabled : bind {model.nextButtonEnabled}, nextAction)
button(text : trans("FINISH"), enabled : bind {model.finishButtonEnabled}, finishAction)
}
}
}

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import java.awt.GridBagConstraints
import static com.muwire.gui.Translator.trans
import javax.swing.JFileChooser
@ -22,19 +23,19 @@ class DirectoriesStep extends WizardStep {
builder.panel(constraints : getConstraint()) {
gridBagLayout()
label(text : "Select directories for saving downloaded and incomplete files.",
label(text : trans("SELECT_DOWNLOAD_AND_INCOMPLETE_DIRECTORIES"),
constraints : gbc(gridx: 0, gridy: 0, gridwidth : 2, insets: [10,0,0,0]))
label(text : "They will be created if they do not already exist.",
label(text : trans("DIRECTORIES_WILL_BE_CREATED"),
constraints : gbc(gridx:0, gridy: 1, gridwidth: 2, insets: [0,0,10,0]))
label(text : "Directory for saving downloaded files", constraints : gbc(gridx:0, gridy: 2))
label(text : trans("DIRECTORY_FOR_DOWNLOADED_FILES"), constraints : gbc(gridx:0, gridy: 2))
downloadLocationField = textField(text : defaults.downloadLocation,
constraints : gbc(gridx : 0, gridy : 3, fill : GridBagConstraints.HORIZONTAL, weightx: 100))
downloadLocationButton = button(text : "Choose", constraints : gbc(gridx: 1, gridy: 3), actionPerformed : showDownloadChooser)
label(text : "Directory for storing incomplete files", constraints : gbc(gridx:0, gridy: 4))
downloadLocationButton = button(text : trans("CHOOSE"), constraints : gbc(gridx: 1, gridy: 3), actionPerformed : showDownloadChooser)
label(text : trans("DIRECTORY_FOR_INCOMPLETE_FILES"), constraints : gbc(gridx:0, gridy: 4))
incompleteLocationField = textField(text : defaults.incompleteLocation,
constraints : gbc(gridx:0, gridy:5, fill : GridBagConstraints.HORIZONTAL, weightx: 100))
incompleteLocationButton = button(text : "Choose", constraints : gbc(gridx: 1, gridy: 5), actionPerformed : showIncompleteChooser)
incompleteLocationButton = button(text : trans("CHOOSE"), constraints : gbc(gridx: 1, gridy: 5), actionPerformed : showIncompleteChooser)
}
}
@ -42,9 +43,9 @@ class DirectoriesStep extends WizardStep {
protected List<String> validate() {
def rv = []
if (!canWrite(downloadLocationField.text))
rv << "Download location not writeable"
rv << trans("DOWNLOAD_LOCATION_NOT_WRITEABLE")
if (!canWrite(incompleteLocationField.text))
rv << "Incomplete location not writeable"
rv << trans("INCOMPLETE_LOCATION_NOT_WRITEABLE")
rv
}
@ -65,13 +66,13 @@ class DirectoriesStep extends WizardStep {
}
def showDownloadChooser = {
String text = chooseFile("Select directory for downloaded files")
String text = chooseFile("SELECT_DIRECTORY_DOWNLOAD_FILES")
if (text != null)
downloadLocationField.text = text
}
def showIncompleteChooser = {
String text = chooseFile("Select directory for incomplete files")
String text = chooseFile("SELECT_DIRECTORY_INCOMPLETE_FILES")
if (text != null)
incompleteLocationField.text = text
}
@ -79,7 +80,7 @@ class DirectoriesStep extends WizardStep {
private String chooseFile(String title) {
def chooser = new JFileChooser()
chooser.setFileHidingEnabled(false)
chooser.setDialogTitle(title)
chooser.setDialogTitle(trans(title))
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
int rv = chooser.showOpenDialog(null)
if (rv == JFileChooser.APPROVE_OPTION)

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import java.awt.GridBagConstraints
import static com.muwire.gui.Translator.trans
import javax.swing.border.TitledBorder
@ -23,20 +24,20 @@ class EmbeddedRouterStep extends WizardStep {
protected void buildUI(FactoryBuilderSupport builder) {
builder.panel(constraints : getConstraint()) {
gridBagLayout()
panel(border : titledBorder(title : "Port Settings", border : etchedBorder(), titlePosition : TitledBorder.TOP,
panel(border : titledBorder(title : trans("PORT_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP,
constraints : gbc(gridx: 0, gridy : 0, fill : GridBagConstraints.HORIZONTAL, weightx: 100))) {
gridBagLayout()
label(text : "TCP port", constraints : gbc(gridx :0, gridy: 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("TCP_PORT"), constraints : gbc(gridx :0, gridy: 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
tcpPortField = textField(text : String.valueOf(defaults.i2npTcpPort), columns : 4, constraints : gbc(gridx:1, gridy:0, anchor : GridBagConstraints.LINE_END))
label(text : "UDP port", constraints : gbc(gridx :0, gridy: 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("UDP_PORT"), constraints : gbc(gridx :0, gridy: 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
udpPortField = textField(text : String.valueOf(defaults.i2npUdpPort), columns : 4, constraints : gbc(gridx:1, gridy:1, anchor : GridBagConstraints.LINE_END))
}
panel( border : titledBorder(title : "Bandwidth Settings", border : etchedBorder(), titlePosition : TitledBorder.TOP),
panel( border : titledBorder(title : trans("BANDWIDTH_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP),
constraints : gbc(gridx : 0, gridy : 1, fill : GridBagConstraints.HORIZONTAL, weightx : 100)) {
gridBagLayout()
label(text : "Inbound bandwidth (KB)", constraints : gbc(gridx: 0, gridy : 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("INBOUND_BANDWIDTH"), constraints : gbc(gridx: 0, gridy : 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
inBwField = textField(text : String.valueOf(defaults.inBw), columns : 3, constraints : gbc(gridx : 1, gridy : 0, anchor : GridBagConstraints.LINE_END))
label(text : "Outbound bandwidth (KB)", constraints : gbc(gridx: 0, gridy : 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("OUTBOUND_BANDWIDTH"), constraints : gbc(gridx: 0, gridy : 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
outBwField = textField(text : String.valueOf(defaults.outBw), columns : 3, constraints : gbc(gridx : 1, gridy : 1, anchor : GridBagConstraints.LINE_END))
}
panel (constraints : gbc(gridx: 0, gridy : 2, weighty: 100))
@ -50,21 +51,21 @@ class EmbeddedRouterStep extends WizardStep {
int udpPort = Integer.parseInt(udpPortField.text)
int tcpPort = Integer.parseInt(tcpPortField.text)
if (udpPort <= 0 || udpPort > 0xFFFF)
rv << "Invalid UDP Port"
rv << trans("INVALID_UDP_PORT")
if (tcpPort <= 0 || tcpPort > 0xFFFF)
rv << "Invalid TCP Port"
rv << trans("INVALID_TCP_PORT")
} catch (NumberFormatException e) {
rv << "Invalid port"
rv << trans("INVALID_PORT")
}
try {
int outBw = Integer.parseInt(outBwField.text)
int inBw = Integer.parseInt(inBwField.text)
if (outBw <= 0)
rv << "Out bandwidth cannot be negative"
rv << trans("OUT_CANNOT_BE_NEGATIVE")
if (inBw <= 0)
rv << "In bandwidth cannot be ngative"
rv << trans("IN_CANNOT_BE_NEGATIVE")
} catch (NumberFormatException e) {
rv << "Invalid bandwidth"
rv << trans("INVALID_BANDWIDTH")
}
rv

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import java.awt.GridBagConstraints
import static com.muwire.gui.Translator.trans
import javax.swing.border.TitledBorder
@ -19,14 +20,14 @@ class ExternalRouterStep extends WizardStep {
protected void buildUI(FactoryBuilderSupport builder) {
builder.panel(constraints : getConstraint()) {
gridBagLayout()
panel(border : titledBorder(title : "External Router I2CP Settings", border : etchedBorder(), titlePosition : TitledBorder.TOP,
panel(border : titledBorder(title : trans("EXTERNAL_ROUTER_I2CP_SETTINGS"), border : etchedBorder(), titlePosition : TitledBorder.TOP,
constraints : gbc(gridx: 0, gridy : 0, fill : GridBagConstraints.HORIZONTAL, weightx: 100))) {
gridBagLayout()
label(text : "Host", constraints : gbc(gridx: 0, gridy : 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("HOST"), constraints : gbc(gridx: 0, gridy : 0, anchor : GridBagConstraints.LINE_START, weightx : 100))
addressField = textField(text : defaults.i2cpHost, constraints : gbc(gridx:1, gridy:0, anchor: GridBagConstraints.LINE_END))
label(text : "Port", constraints : gbc(gridx: 0, gridy : 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
label(text : trans("PORT"), constraints : gbc(gridx: 0, gridy : 1, anchor : GridBagConstraints.LINE_START, weightx : 100))
portField = textField(text : String.valueOf(defaults.i2cpPort), constraints : gbc(gridx:1, gridy:1, anchor: GridBagConstraints.LINE_END))
}
panel(constraints : gbc(gridx:0, gridy:1, weighty: 100))
@ -39,14 +40,14 @@ class ExternalRouterStep extends WizardStep {
try {
InetAddress.getAllByName(addressField.text)
} catch (UnknownHostException iox) {
rv << "Not a valid InetAddress"
rv << trans("INVALID_ADDRESS")
}
try {
int port = Integer.parseInt(portField.text)
if (port <= 0 && port > 0xFFFF)
rv << "Not a valid port"
rv << trans("INVALID_PORT")
} catch (NumberFormatException e) {
rv << "Not a valid port"
rv << trans("INVALID_PORT")
}
rv
}

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import com.muwire.core.MuWireSettings
import static com.muwire.gui.Translator.trans
class LastStep extends WizardStep {
@ -15,9 +16,9 @@ class LastStep extends WizardStep {
protected void buildUI(FactoryBuilderSupport builder) {
builder.panel(constraints: getConstraint()) {
gridBagLayout()
label(text: "The wizard is complete. Press \"Finish\" to launch MuWire.", constraints : gbc(gridx: 0, gridy: 0))
label(text: trans("WIZARD_COMPLETE"), constraints : gbc(gridx: 0, gridy: 0))
if (embeddedRouterAvailable)
label(text : "MuWire will launch an embedded I2P router. This can take a few minutes.", constraints: gbc(gridx:0, gridy:1))
label(text : trans("LAUNCH_EMBEDDED_ROUTER"), constraints: gbc(gridx:0, gridy:1))
}
}

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import com.muwire.core.Constants
import static com.muwire.gui.Translator.trans
import com.muwire.core.MuWireSettings
import com.muwire.core.util.DataUtil
@ -15,7 +16,7 @@ class NicknameStep extends WizardStep {
@Override
protected void buildUI(FactoryBuilderSupport builder) {
builder.panel(constraints : getConstraint()) {
label(text: "Select a nickname")
label(text: trans("SELECT_A_NICKNAME"))
nickField = textField(columns: 30)
}
}
@ -24,12 +25,12 @@ class NicknameStep extends WizardStep {
protected List<String> validate() {
String nickname = nickField.text
if (nickname == null)
return ['Please select a nickname']
return [trans('PLEASE_SELECT_A_NICKNAME')]
nickname = nickname.trim()
if (nickname.length() == 0)
return ['Nickname cannot be blank']
return [trans('NICKNAME_CANNOT_BE_BLANK')]
if (!DataUtil.isValidName(nickname))
return ["Nickname cannot contain any of ${Constants.INVALID_NICKNAME_CHARS} and must be no longer than ${Constants.MAX_NICKNAME_LENGTH} characters. Choose another."]
return [trans('NICKNAME_CANNOT_CONTAIN', Constants.INVALID_NICKNAME_CHARS, Constants.MAX_NICKNAME_LENGTH)]
null
}

View File

@ -1,6 +1,7 @@
package com.muwire.gui.wizard
import java.awt.GridBagConstraints
import static com.muwire.gui.Translator.trans
import javax.swing.JLabel
import javax.swing.border.TitledBorder
@ -21,20 +22,20 @@ class TunnelStep extends WizardStep {
protected void buildUI(FactoryBuilderSupport builder) {
builder.panel (constraints : getConstraint()) {
gridBagLayout()
panel (border : titledBorder(title : "Speed vs. Anonymity", border : etchedBorder(), titlePosition: TitledBorder.TOP,
panel (border : titledBorder(title : trans("SPEED_VS_ANONYMITY"), border : etchedBorder(), titlePosition: TitledBorder.TOP,
constraints : gbc(gridx: 0, gridy: 0, fill : GridBagConstraints.HORIZONTAL, weightx : 100))) {
def lengthTable = new Hashtable()
lengthTable.put(1, new JLabel("Max Speed"))
lengthTable.put(3, new JLabel("Max Anonymity"))
lengthTable.put(1, new JLabel(trans("MAX_SPEED")))
lengthTable.put(3, new JLabel(trans("MAX_ANONYMITY")))
tunnelLengthSlider = slider(minimum : 1, maximum : 3, value : defaults.tunnelLength,
majorTickSpacing : 1, snapToTicks: true, paintTicks: true, labelTable : lengthTable,
paintLabels : true)
}
panel (border : titledBorder(title : "Reliability vs. Resource Usage", border : etchedBorder(), titlePosition: TitledBorder.TOP,
panel (border : titledBorder(title : trans("RELIABILITY_VS_RESOURCES"), border : etchedBorder(), titlePosition: TitledBorder.TOP,
constraints : gbc(gridx: 0, gridy: 1, fill : GridBagConstraints.HORIZONTAL, weightx : 100))) {
def quantityTable = new Hashtable()
quantityTable.put(1, new JLabel("Min Resources"))
quantityTable.put(6, new JLabel("Max Reliability"))
quantityTable.put(1, new JLabel(trans("MIN_RESOURCES")))
quantityTable.put(6, new JLabel(trans("MAX_RELIABILITY")))
tunnelQuantitySlider = slider(minimum : 1, maximum : 6, value : defaults.tunnelQuantity,
majorTickSpacing : 1, snapToTicks : true, paintTicks: true, labelTable : quantityTable,
paintLabels : true)

View File

@ -1,5 +1,7 @@
package com.muwire.gui;
import java.text.ChoiceFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
@ -33,7 +35,7 @@ public class Translator {
localeBundle = ResourceBundle.getBundle("messages", locale);
}
public synchronized static String getString(String key) {
public synchronized static String trans(String key) {
if (localeBundle == null)
throw new IllegalStateException("locale not initialized");
try {
@ -43,6 +45,18 @@ public class Translator {
}
}
public synchronized static String trans(String key, Object... values) {
if (localeBundle == null)
throw new IllegalStateException("locale not initialized");
String pattern;
try {
pattern = localeBundle.getString(key);
} catch (MissingResourceException notTranslated) {
pattern = usBundle.getString(key);
}
return MessageFormat.format(pattern, values);
}
public static class LocaleWrapper {
private final Locale locale;
LocaleWrapper(Locale locale) {