From 863d40a1c1f6591ef1ee8594b12ae4b0942fe810 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Thu, 5 Mar 2020 22:17:08 +0000 Subject: Made Enigma gui translatable (#193) * made enigma gui translatable * key renamings * missed strings * string.format() & another missed string * cached content (thanks @liach) * added a dialog when changing language * better sentence * more %s * liach's requests * empty map * the last (?) missed strings * IT WORKS * French translation * Update fr_fr.json --- src/main/java/cuchaz/enigma/Constants.java | 2 +- src/main/java/cuchaz/enigma/EnigmaProject.java | 12 +-- src/main/java/cuchaz/enigma/Main.java | 1 + .../cuchaz/enigma/analysis/index/JarIndex.java | 12 ++- src/main/java/cuchaz/enigma/config/Config.java | 5 + src/main/java/cuchaz/enigma/gui/Gui.java | 49 +++++----- src/main/java/cuchaz/enigma/gui/GuiController.java | 5 +- .../java/cuchaz/enigma/gui/dialog/AboutDialog.java | 5 +- .../java/cuchaz/enigma/gui/dialog/CrashDialog.java | 11 ++- .../cuchaz/enigma/gui/dialog/JavadocDialog.java | 9 +- .../cuchaz/enigma/gui/dialog/ProgressDialog.java | 3 +- .../cuchaz/enigma/gui/dialog/SearchDialog.java | 3 +- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 81 ++++++++++------ .../cuchaz/enigma/gui/elements/PopupMenuBar.java | 21 +++-- .../java/cuchaz/enigma/gui/panels/PanelDeobf.java | 3 +- .../cuchaz/enigma/gui/panels/PanelIdentifier.java | 5 +- .../java/cuchaz/enigma/gui/panels/PanelObf.java | 3 +- .../cuchaz/enigma/gui/stats/StatsGenerator.java | 11 ++- .../mapping/serde/EnigmaMappingsReader.java | 7 +- .../mapping/serde/EnigmaMappingsWriter.java | 5 +- .../mapping/serde/SrgMappingsWriter.java | 11 ++- .../mapping/serde/TinyMappingsReader.java | 3 +- .../translation/mapping/serde/TinyV2Reader.java | 3 +- src/main/java/cuchaz/enigma/utils/I18n.java | 102 +++++++++++++++++++++ 24 files changed, 264 insertions(+), 108 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/utils/I18n.java (limited to 'src/main/java/cuchaz/enigma') diff --git a/src/main/java/cuchaz/enigma/Constants.java b/src/main/java/cuchaz/enigma/Constants.java index afffb5d..577315f 100644 --- a/src/main/java/cuchaz/enigma/Constants.java +++ b/src/main/java/cuchaz/enigma/Constants.java @@ -14,7 +14,7 @@ package cuchaz.enigma; public class Constants { public static final String NAME = "Enigma"; public static final String VERSION = "@VERSION@/Fabric"; - public static final String URL = "https://fabric.asie.pl"; + public static final String URL = "https://fabricmc.net"; public static final int MiB = 1024 * 1024; // 1 mebibyte public static final int KiB = 1024; // 1 kebibyte } diff --git a/src/main/java/cuchaz/enigma/EnigmaProject.java b/src/main/java/cuchaz/enigma/EnigmaProject.java index 2a7ca98..fddaccc 100644 --- a/src/main/java/cuchaz/enigma/EnigmaProject.java +++ b/src/main/java/cuchaz/enigma/EnigmaProject.java @@ -19,6 +19,8 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; + import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; @@ -32,12 +34,10 @@ import java.nio.file.Path; import java.util.Collection; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.stream.Collectors; -import java.util.stream.Stream; public class EnigmaProject { private final Enigma enigma; @@ -148,7 +148,7 @@ public class EnigmaProject { Translator deobfuscator = nameProposalServices.length == 0 ? mapper.getDeobfuscator() : new ProposingTranslator(mapper, nameProposalServices); AtomicInteger count = new AtomicInteger(); - progress.init(classEntries.size(), "Deobfuscating classes..."); + progress.init(classEntries.size(), I18n.translate("progress.classes.deobfuscating")); Map compiled = classEntries.parallelStream() .map(entry -> { @@ -180,7 +180,7 @@ public class EnigmaProject { } public void write(Path path, ProgressListener progress) throws IOException { - progress.init(this.compiled.size(), "Writing jar..."); + progress.init(this.compiled.size(), I18n.translate("progress.jar.writing")); try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(path))) { AtomicInteger count = new AtomicInteger(); @@ -205,7 +205,7 @@ public class EnigmaProject { .filter(classNode -> classNode.name.indexOf('$') == -1) .collect(Collectors.toList()); - progress.init(classes.size(), "Decompiling classes..."); + progress.init(classes.size(), I18n.translate("progress.classes.decompiling")); //create a common instance outside the loop as mappings shouldn't be changing while this is happening CompiledSourceTypeLoader typeLoader = new CompiledSourceTypeLoader(this.compiled::get); @@ -256,7 +256,7 @@ public class EnigmaProject { } public void write(Path path, ProgressListener progress) throws IOException { - progress.init(decompiled.size(), "Writing sources..."); + progress.init(decompiled.size(), I18n.translate("progress.sources.writing")); int count = 0; for (ClassSource source : decompiled) { diff --git a/src/main/java/cuchaz/enigma/Main.java b/src/main/java/cuchaz/enigma/Main.java index dbbcee4..ceb5554 100644 --- a/src/main/java/cuchaz/enigma/Main.java +++ b/src/main/java/cuchaz/enigma/Main.java @@ -14,6 +14,7 @@ package cuchaz.enigma; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.gui.GuiController; import cuchaz.enigma.translation.mapping.serde.MappingFormat; + import joptsimple.*; import java.io.BufferedReader; diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index 8e92dd8..c96e774 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java @@ -20,6 +20,8 @@ import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.mapping.IndexEntryResolver; import cuchaz.enigma.translation.representation.Lambda; import cuchaz.enigma.translation.representation.entry.*; +import cuchaz.enigma.utils.I18n; + import org.objectweb.asm.ClassReader; import org.objectweb.asm.Opcodes; @@ -58,18 +60,18 @@ public class JarIndex implements JarIndexer { } public void indexJar(ClassCache classCache, ProgressListener progress) { - progress.init(4, "Indexing jar"); + progress.init(4, I18n.translate("progress.jar.indexing")); - progress.step(1, "Entries..."); + progress.step(1, I18n.translate("progress.jar.indexing.entries")); classCache.visit(() -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE); - progress.step(2, "Entry references..."); + progress.step(2, I18n.translate("progress.jar.indexing.references")); classCache.visit(() -> new IndexReferenceVisitor(this, entryIndex, inheritanceIndex, Opcodes.ASM5), 0); - progress.step(3, "Bridge methods..."); + progress.step(3, I18n.translate("progress.jar.indexing.methods")); bridgeMethodIndex.findBridgeMethods(); - progress.step(4, "Processing..."); + progress.step(4, I18n.translate("progress.jar.indexing.process")); processIndex(this); } diff --git a/src/main/java/cuchaz/enigma/config/Config.java b/src/main/java/cuchaz/enigma/config/Config.java index e2afb01..a00fe2d 100644 --- a/src/main/java/cuchaz/enigma/config/Config.java +++ b/src/main/java/cuchaz/enigma/config/Config.java @@ -4,6 +4,8 @@ import com.bulenkov.darcula.DarculaLaf; import com.google.common.io.Files; import com.google.gson.*; +import cuchaz.enigma.utils.I18n; + import javax.swing.*; import javax.swing.plaf.metal.MetalLookAndFeel; import java.awt.*; @@ -165,6 +167,8 @@ public class Config { public Integer lineNumbersBackground; public Integer lineNumbersSelected; public Integer lineNumbersForeground; + + public String language = I18n.DEFAULT_LANGUAGE; public LookAndFeel lookAndFeel = LookAndFeel.DEFAULT; @@ -213,6 +217,7 @@ public class Config { public void reset() throws IOException { this.lookAndFeel = LookAndFeel.DEFAULT; this.lookAndFeel.apply(this); + this.language = I18n.DEFAULT_LANGUAGE; this.saveConfig(); } diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 1ea3e44..5eeb07d 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java @@ -36,6 +36,7 @@ import cuchaz.enigma.gui.util.History; import cuchaz.enigma.throwables.IllegalNameException; import cuchaz.enigma.translation.mapping.*; import cuchaz.enigma.translation.representation.entry.*; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import de.sciss.syntaxpane.DefaultSyntaxKit; @@ -120,12 +121,12 @@ public class Gui { this.controller = new GuiController(this, profile); // init file choosers - this.jarFileChooser = new FileDialog(getFrame(), "Open Jar", FileDialog.LOAD); + this.jarFileChooser = new FileDialog(getFrame(), I18n.translate("menu.file.jar.open"), FileDialog.LOAD); this.tinyMappingsFileChooser = new FileDialog(getFrame(), "Open tiny Mappings", FileDialog.LOAD); this.enigmaMappingsFileChooser = new FileChooserAny(); this.exportSourceFileChooser = new FileChooserFolder(); - this.exportJarFileChooser = new FileDialog(getFrame(), "Export jar", FileDialog.SAVE); + this.exportJarFileChooser = new FileDialog(getFrame(), I18n.translate("menu.file.export.jar"), FileDialog.SAVE); this.obfPanel = new PanelObf(this); this.deobfPanel = new PanelDeobf(this); @@ -275,9 +276,9 @@ public class Gui { centerPanel.add(sourceScroller, BorderLayout.CENTER); tabs = new JTabbedPane(); tabs.setPreferredSize(new Dimension(250, 0)); - tabs.addTab("Inheritance", inheritancePanel); - tabs.addTab("Implementations", implementationsPanel); - tabs.addTab("Call Graph", callPanel); + tabs.addTab(I18n.translate("info_panel.tree.inheritance"), inheritancePanel); + tabs.addTab(I18n.translate("info_panel.tree.implementations"), implementationsPanel); + tabs.addTab(I18n.translate("info_panel.tree.calls"), callPanel); JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, tabs); splitRight.setResizeWeight(1); // let the left side take all the slack splitRight.resetToPreferredSizes(); @@ -458,33 +459,33 @@ public class Gui { } private void showLocalVariableEntry(LocalVariableEntry entry) { - addNameValue(infoPanel, "Variable", entry.getName()); - addNameValue(infoPanel, "Class", entry.getContainingClass().getFullName()); - addNameValue(infoPanel, "Method", entry.getParent().getName()); - addNameValue(infoPanel, "Index", Integer.toString(entry.getIndex())); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.variable"), entry.getName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.class"), entry.getContainingClass().getFullName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.method"), entry.getParent().getName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.index"), Integer.toString(entry.getIndex())); } private void showClassEntry(ClassEntry entry) { - addNameValue(infoPanel, "Class", entry.getFullName()); - addModifierComboBox(infoPanel, "Modifier", entry); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.class"), entry.getFullName()); + addModifierComboBox(infoPanel, I18n.translate("info_panel.identifier.modifier"), entry); } private void showFieldEntry(FieldEntry entry) { - addNameValue(infoPanel, "Field", entry.getName()); - addNameValue(infoPanel, "Class", entry.getParent().getFullName()); - addNameValue(infoPanel, "TypeDescriptor", entry.getDesc().toString()); - addModifierComboBox(infoPanel, "Modifier", entry); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.field"), entry.getName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.class"), entry.getParent().getFullName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.type_descriptor"), entry.getDesc().toString()); + addModifierComboBox(infoPanel, I18n.translate("info_panel.identifier.modifier"), entry); } private void showMethodEntry(MethodEntry entry) { if (entry.isConstructor()) { - addNameValue(infoPanel, "Constructor", entry.getParent().getFullName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.constructor"), entry.getParent().getFullName()); } else { - addNameValue(infoPanel, "Method", entry.getName()); - addNameValue(infoPanel, "Class", entry.getParent().getFullName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.method"), entry.getName()); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.class"), entry.getParent().getFullName()); } - addNameValue(infoPanel, "MethodDescriptor", entry.getDesc().toString()); - addModifierComboBox(infoPanel, "Modifier", entry); + addNameValue(infoPanel, I18n.translate("info_panel.identifier.method_descriptor"), entry.getDesc().toString()); + addModifierComboBox(infoPanel, I18n.translate("info_panel.identifier.modifier"), entry); } private void addNameValue(JPanel container, String name, String value) { @@ -573,9 +574,9 @@ public class Gui { this.popupMenu.toggleMappingMenu.setEnabled(isRenamable); if (isToken && !Objects.equals(referenceEntry, mapper.deobfuscate(referenceEntry))) { - this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated"); + this.popupMenu.toggleMappingMenu.setText(I18n.translate("popup_menu.reset_obfuscated")); } else { - this.popupMenu.toggleMappingMenu.setText("Mark as deobfuscated"); + this.popupMenu.toggleMappingMenu.setText(I18n.translate("popup_menu.mark_deobfuscated")); } } @@ -794,7 +795,7 @@ public class Gui { } public void showDiscardDiag(Function callback, String... options) { - int response = JOptionPane.showOptionDialog(this.frame, "Your mappings have not been saved yet. Do you want to save?", "Save your changes?", JOptionPane.YES_NO_CANCEL_OPTION, + int response = JOptionPane.showOptionDialog(this.frame, I18n.translate("prompt.close.summary"), I18n.translate("prompt.close.title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); callback.apply(response); } @@ -820,7 +821,7 @@ public class Gui { } return null; - }, "Save and exit", "Discard changes", "Cancel"); + }, I18n.translate("prompt.close.save"), I18n.translate("prompt.close.discard"), I18n.translate("prompt.close.cancel")); } } diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 0b2fe27..dc5010c 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -32,6 +32,7 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.ReadableToken; import cuchaz.enigma.utils.Utils; import org.objectweb.asm.Opcodes; @@ -391,7 +392,7 @@ public class GuiController { boolean requiresDecompile = forceDecomp || currentSource == null || !currentSource.getEntry().equals(targetClass); if (requiresDecompile) { currentSource = null; // Or the GUI may try to find a nonexistent token - gui.setEditorText("(decompiling...)"); + gui.setEditorText(I18n.translate("info_panel.editor.class.decompiling")); } DECOMPILER_SERVICE.submit(() -> { @@ -413,7 +414,7 @@ public class GuiController { try { CompilationUnit sourceTree = (CompilationUnit) sourceProvider.getSources(targetClass.getFullName()).clone(); if (sourceTree == null) { - gui.setEditorText("Unable to find class: " + targetClass); + gui.setEditorText(I18n.translate("info_panel.editor.class.not_found") + " " + targetClass); return DecompiledClassSource.text(targetClass, "Unable to find class"); } diff --git a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java index 7b3234d..82fd6a5 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java @@ -12,6 +12,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -22,7 +23,7 @@ public class AboutDialog { public static void show(JFrame parent) { // init frame - final JFrame frame = new JFrame(Constants.NAME + " - About"); + final JFrame frame = new JFrame(String.format(I18n.translate("menu.help.about.title"), Constants.NAME)); final Container pane = frame.getContentPane(); pane.setLayout(new FlowLayout()); @@ -52,7 +53,7 @@ public class AboutDialog { pane.add(linkPanel); // show ok button - JButton okButton = new JButton("Ok"); + JButton okButton = new JButton(I18n.translate("menu.help.about.ok")); pane.add(okButton); okButton.addActionListener(arg0 -> frame.dispose()); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java index 04dd5d7..7e66ecd 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java @@ -12,6 +12,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -28,11 +29,11 @@ public class CrashDialog { private CrashDialog(JFrame parent) { // init frame - frame = new JFrame(Constants.NAME + " - Crash Report"); + frame = new JFrame(String.format(I18n.translate("crash.title"), Constants.NAME)); final Container pane = frame.getContentPane(); pane.setLayout(new BorderLayout()); - JLabel label = new JLabel(Constants.NAME + " has crashed! =("); + JLabel label = new JLabel(String.format(I18n.translate("crash.summary"), Constants.NAME)); label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); pane.add(label, BorderLayout.NORTH); @@ -46,14 +47,14 @@ public class CrashDialog { FlowLayout buttonsLayout = new FlowLayout(); buttonsLayout.setAlignment(FlowLayout.RIGHT); buttonsPanel.setLayout(buttonsLayout); - buttonsPanel.add(Utils.unboldLabel(new JLabel("If you choose exit, you will lose any unsaved work."))); - JButton ignoreButton = new JButton("Ignore"); + buttonsPanel.add(Utils.unboldLabel(new JLabel(I18n.translate("crash.exit.warning")))); + JButton ignoreButton = new JButton(I18n.translate("crash.ignore")); ignoreButton.addActionListener(event -> { // close (hide) the dialog frame.setVisible(false); }); buttonsPanel.add(ignoreButton); - JButton exitButton = new JButton("Exit"); + JButton exitButton = new JButton(I18n.translate("crash.exit")); exitButton.addActionListener(event -> { // exit enigma System.exit(1); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java index 84e4d8f..57811ee 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java @@ -11,6 +11,7 @@ package cuchaz.enigma.gui.dialog; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -26,7 +27,7 @@ public class JavadocDialog { private JavadocDialog(JFrame parent, JTextArea text, Callback callback) { // init frame - frame = new JFrame("Edit Javadocs"); + frame = new JFrame(I18n.translate("javadocs.edit")); final Container pane = frame.getContentPane(); pane.setLayout(new BorderLayout()); @@ -55,14 +56,14 @@ public class JavadocDialog { FlowLayout buttonsLayout = new FlowLayout(); buttonsLayout.setAlignment(FlowLayout.RIGHT); buttonsPanel.setLayout(buttonsLayout); - buttonsPanel.add(Utils.unboldLabel(new JLabel("Edit javadocs here."))); - JButton cancelButton = new JButton("Cancel"); + buttonsPanel.add(Utils.unboldLabel(new JLabel(I18n.translate("javadocs.instruction")))); + JButton cancelButton = new JButton(I18n.translate("javadocs.cancel")); cancelButton.addActionListener(event -> { // close (hide) the dialog callback.closeUi(frame, false); }); buttonsPanel.add(cancelButton); - JButton saveButton = new JButton("Save"); + JButton saveButton = new JButton(I18n.translate("javadocs.save")); saveButton.addActionListener(event -> { // exit enigma callback.closeUi(frame, true); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index ae30667..6d9a419 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java @@ -13,6 +13,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -29,7 +30,7 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { public ProgressDialog(JFrame parent) { // init frame - this.frame = new JFrame(Constants.NAME + " - Operation in progress"); + this.frame = new JFrame(String.format(I18n.translate("progress.operation"), Constants.NAME)); final Container pane = this.frame.getContentPane(); FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.LEFT); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java index 1657d7b..47f9149 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java @@ -14,6 +14,7 @@ package cuchaz.enigma.gui.dialog; import com.google.common.collect.Lists; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.utils.I18n; import me.xdrop.fuzzywuzzy.FuzzySearch; import me.xdrop.fuzzywuzzy.model.ExtractedResult; @@ -45,7 +46,7 @@ public class SearchDialog { } public void show() { - frame = new JFrame("Search"); + frame = new JFrame(I18n.translate("menu.view.search")); frame.setVisible(false); JPanel pane = new JPanel(); pane.setBorder(new EmptyBorder(5, 10, 5, 10)); diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index cdcad05..50f0849 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -7,7 +7,7 @@ import cuchaz.enigma.gui.dialog.AboutDialog; import cuchaz.enigma.gui.dialog.SearchDialog; import cuchaz.enigma.gui.stats.StatsMember; import cuchaz.enigma.translation.mapping.serde.MappingFormat; -import cuchaz.enigma.utils.Utils; +import cuchaz.enigma.utils.I18n; import javax.swing.*; import java.awt.*; @@ -40,10 +40,10 @@ public class MenuBar extends JMenuBar { this.gui = gui; { - JMenu menu = new JMenu("File"); + JMenu menu = new JMenu(I18n.translate("menu.file")); this.add(menu); { - JMenuItem item = new JMenuItem("Open Jar..."); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.jar.open")); menu.add(item); item.addActionListener(event -> { this.gui.jarFileChooser.setVisible(true); @@ -54,19 +54,19 @@ public class MenuBar extends JMenuBar { }); } { - JMenuItem item = new JMenuItem("Close Jar"); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.jar.close")); menu.add(item); item.addActionListener(event -> this.gui.getController().closeJar()); this.closeJarMenu = item; } menu.addSeparator(); - JMenu openMenu = new JMenu("Open Mappings..."); + JMenu openMenu = new JMenu(I18n.translate("menu.file.mappings.open")); menu.add(openMenu); { openMappingsMenus = new ArrayList<>(); for (MappingFormat format : MappingFormat.values()) { if (format.getReader() != null) { - JMenuItem item = new JMenuItem(Utils.caplisiseCamelCase(format.name())); + JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); openMenu.add(item); item.addActionListener(event -> { if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { @@ -79,7 +79,7 @@ public class MenuBar extends JMenuBar { } } { - JMenuItem item = new JMenuItem("Save Mappings"); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.mappings.save")); menu.add(item); item.addActionListener(event -> { this.gui.getController().saveMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath()); @@ -87,13 +87,13 @@ public class MenuBar extends JMenuBar { item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); this.saveMappingsMenu = item; } - JMenu saveMenu = new JMenu("Save Mappings As..."); + JMenu saveMenu = new JMenu(I18n.translate("menu.file.mappings.save_as")); menu.add(saveMenu); { saveMappingsMenus = new ArrayList<>(); for (MappingFormat format : MappingFormat.values()) { if (format.getWriter() != null) { - JMenuItem item = new JMenuItem(Utils.caplisiseCamelCase(format.name())); + JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); saveMenu.add(item); item.addActionListener(event -> { // TODO: Use a specific file chooser for it @@ -107,7 +107,7 @@ public class MenuBar extends JMenuBar { } } { - JMenuItem item = new JMenuItem("Close Mappings"); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.mappings.close")); menu.add(item); item.addActionListener(event -> { if (this.gui.getController().isDirty()) { @@ -118,7 +118,7 @@ public class MenuBar extends JMenuBar { } else if (response == JOptionPane.NO_OPTION) this.gui.getController().closeMappings(); return null; - }), "Save and close", "Discard changes", "Cancel"); + }), I18n.translate("prompt.close.save"), I18n.translate("prompt.close.discard"), I18n.translate("prompt.close.cancel")); } else this.gui.getController().closeMappings(); @@ -126,14 +126,14 @@ public class MenuBar extends JMenuBar { this.closeMappingsMenu = item; } { - JMenuItem item = new JMenuItem("Drop Invalid Mappings"); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.mappings.drop")); menu.add(item); item.addActionListener(event -> this.gui.getController().dropMappings()); this.dropMappingsMenu = item; } menu.addSeparator(); { - JMenuItem item = new JMenuItem("Export Source..."); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.export.source")); menu.add(item); item.addActionListener(event -> { if (this.gui.exportSourceFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { @@ -143,7 +143,7 @@ public class MenuBar extends JMenuBar { this.exportSourceMenu = item; } { - JMenuItem item = new JMenuItem("Export Jar..."); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.export.jar")); menu.add(item); item.addActionListener(event -> { this.gui.exportJarFileChooser.setVisible(true); @@ -156,22 +156,22 @@ public class MenuBar extends JMenuBar { } menu.addSeparator(); { - JMenuItem stats = new JMenuItem("Mapping Stats..."); + JMenuItem stats = new JMenuItem(I18n.translate("menu.file.stats")); stats.addActionListener(event -> { - JFrame frame = new JFrame("Choose Included Members"); + JFrame frame = new JFrame(I18n.translate("menu.file.stats.title")); Container pane = frame.getContentPane(); pane.setLayout(new FlowLayout()); Map checkboxes = Arrays .stream(StatsMember.values()) .collect(Collectors.toMap(m -> m, m -> { - JCheckBox checkbox = new JCheckBox(Utils.caplisiseCamelCase(m.name())); + JCheckBox checkbox = new JCheckBox(I18n.translate("type." + m.name().toLowerCase(Locale.ROOT))); pane.add(checkbox); return checkbox; })); - JButton button = new JButton("Generate Stats"); + JButton button = new JButton(I18n.translate("menu.file.stats.generate")); button.addActionListener(e -> { Set includedMembers = checkboxes @@ -195,24 +195,53 @@ public class MenuBar extends JMenuBar { } menu.addSeparator(); { - JMenuItem item = new JMenuItem("Exit"); + JMenuItem item = new JMenuItem(I18n.translate("menu.file.exit")); menu.add(item); item.addActionListener(event -> this.gui.close()); } } { - JMenu menu = new JMenu("View"); + JMenu menu = new JMenu(I18n.translate("menu.view")); this.add(menu); { - JMenu themes = new JMenu("Themes"); + JMenu themes = new JMenu(I18n.translate("menu.view.themes")); menu.add(themes); for (Config.LookAndFeel lookAndFeel : Config.LookAndFeel.values()) { - JMenuItem theme = new JMenuItem(lookAndFeel.getName()); + JMenuItem theme = new JMenuItem(I18n.translate("menu.view.themes." + lookAndFeel.name().toLowerCase(Locale.ROOT))); themes.add(theme); theme.addActionListener(event -> Themes.setLookAndFeel(gui, lookAndFeel)); } + + JMenu languages = new JMenu(I18n.translate("menu.view.languages")); + menu.add(languages); + for (String lang : I18n.getAvailableLanguages()) { + JMenuItem language = new JMenuItem(I18n.getLanguageName(lang)); + languages.add(language); + language.addActionListener(event -> I18n.setLanguage(lang)); + language.addActionListener(event -> { + JFrame frame = new JFrame(I18n.translate("menu.view.languages.title")); + Container pane = frame.getContentPane(); + pane.setLayout(new FlowLayout()); + + JLabel text = new JLabel((I18n.translate("menu.view.languages.summary"))); + text.setHorizontalAlignment(JLabel.CENTER); + pane.add(text); + + JButton okButton = new JButton(I18n.translate("menu.view.languages.ok")); + okButton.setAlignmentX(JButton.CENTER_ALIGNMENT); + okButton.setHorizontalAlignment(JButton.CENTER); + pane.add(okButton); + okButton.addActionListener(arg0 -> frame.dispose()); + + frame.setSize(350, 110); + frame.setResizable(false); + frame.setLocationRelativeTo(this.gui.getFrame()); + frame.setVisible(true); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + }); + } - JMenuItem search = new JMenuItem("Search"); + JMenuItem search = new JMenuItem(I18n.translate("menu.view.search")); search.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_MASK)); menu.add(search); search.addActionListener(event -> { @@ -224,15 +253,15 @@ public class MenuBar extends JMenuBar { } } { - JMenu menu = new JMenu("Help"); + JMenu menu = new JMenu(I18n.translate("menu.help")); this.add(menu); { - JMenuItem item = new JMenuItem("About"); + JMenuItem item = new JMenuItem(I18n.translate("menu.help.about")); menu.add(item); item.addActionListener(event -> AboutDialog.show(this.gui.getFrame())); } { - JMenuItem item = new JMenuItem("GitHub Page"); + JMenuItem item = new JMenuItem(I18n.translate("menu.help.github")); menu.add(item); item.addActionListener(event -> { try { diff --git a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java index b9d459f..b0fb2b0 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java @@ -1,6 +1,7 @@ package cuchaz.enigma.gui.elements; import cuchaz.enigma.gui.Gui; +import cuchaz.enigma.utils.I18n; import javax.swing.*; import java.awt.event.InputEvent; @@ -21,7 +22,7 @@ public class PopupMenuBar extends JPopupMenu { public PopupMenuBar(Gui gui) { { - JMenuItem menu = new JMenuItem("Rename"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.rename")); menu.addActionListener(event -> gui.startRename()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0)); menu.setEnabled(false); @@ -29,7 +30,7 @@ public class PopupMenuBar extends JPopupMenu { this.renameMenu = menu; } { - JMenuItem menu = new JMenuItem("Edit Javadoc"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.javadoc")); menu.addActionListener(event -> gui.startDocChange()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0)); menu.setEnabled(false); @@ -37,7 +38,7 @@ public class PopupMenuBar extends JPopupMenu { this.editJavadocMenu = menu; } { - JMenuItem menu = new JMenuItem("Show Inheritance"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.inheritance")); menu.addActionListener(event -> gui.showInheritance()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, 0)); menu.setEnabled(false); @@ -45,7 +46,7 @@ public class PopupMenuBar extends JPopupMenu { this.showInheritanceMenu = menu; } { - JMenuItem menu = new JMenuItem("Show Implementations"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.implementations")); menu.addActionListener(event -> gui.showImplementations()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, 0)); menu.setEnabled(false); @@ -53,7 +54,7 @@ public class PopupMenuBar extends JPopupMenu { this.showImplementationsMenu = menu; } { - JMenuItem menu = new JMenuItem("Show Calls"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.calls")); menu.addActionListener(event -> gui.showCalls(true)); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0)); menu.setEnabled(false); @@ -61,7 +62,7 @@ public class PopupMenuBar extends JPopupMenu { this.showCallsMenu = menu; } { - JMenuItem menu = new JMenuItem("Show Calls (Specific)"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.calls.specific")); menu.addActionListener(event -> gui.showCalls(false)); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.SHIFT_DOWN_MASK)); menu.setEnabled(false); @@ -69,7 +70,7 @@ public class PopupMenuBar extends JPopupMenu { this.showCallsSpecificMenu = menu; } { - JMenuItem menu = new JMenuItem("Go to Declaration"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.declaration")); menu.addActionListener(event -> gui.getController().navigateTo(gui.cursorReference.entry)); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); menu.setEnabled(false); @@ -77,7 +78,7 @@ public class PopupMenuBar extends JPopupMenu { this.openEntryMenu = menu; } { - JMenuItem menu = new JMenuItem("Go back"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.back")); menu.addActionListener(event -> gui.getController().openPreviousReference()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)); menu.setEnabled(false); @@ -85,7 +86,7 @@ public class PopupMenuBar extends JPopupMenu { this.openPreviousMenu = menu; } { - JMenuItem menu = new JMenuItem("Go forward"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.forward")); menu.addActionListener(event -> gui.getController().openNextReference()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0)); menu.setEnabled(false); @@ -93,7 +94,7 @@ public class PopupMenuBar extends JPopupMenu { this.openNextMenu = menu; } { - JMenuItem menu = new JMenuItem("Mark as deobfuscated"); + JMenuItem menu = new JMenuItem(I18n.translate("popup_menu.mark_deobfuscated")); menu.addActionListener(event -> gui.toggleMapping()); menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)); menu.setEnabled(false); diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java index 2a4e2d7..c24226b 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelDeobf.java @@ -2,6 +2,7 @@ package cuchaz.enigma.gui.panels; import cuchaz.enigma.gui.ClassSelector; import cuchaz.enigma.gui.Gui; +import cuchaz.enigma.utils.I18n; import javax.swing.*; import java.awt.*; @@ -19,7 +20,7 @@ public class PanelDeobf extends JPanel { this.deobfClasses.setRenameSelectionListener(gui::onPanelRename); this.setLayout(new BorderLayout()); - this.add(new JLabel("De-obfuscated Classes"), BorderLayout.NORTH); + this.add(new JLabel(I18n.translate("info_panel.classes.deobfuscated")), BorderLayout.NORTH); this.add(new JScrollPane(this.deobfClasses), BorderLayout.CENTER); } } diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java index 1bf6887..0cca40d 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java @@ -1,6 +1,7 @@ package cuchaz.enigma.gui.panels; import cuchaz.enigma.gui.Gui; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -15,12 +16,12 @@ public class PanelIdentifier extends JPanel { this.setLayout(new GridLayout(4, 1, 0, 0)); this.setPreferredSize(new Dimension(0, 100)); - this.setBorder(BorderFactory.createTitledBorder("Identifier Info")); + this.setBorder(BorderFactory.createTitledBorder(I18n.translate("info_panel.identifier"))); } public void clearReference() { this.removeAll(); - JLabel label = new JLabel("No identifier selected"); + JLabel label = new JLabel(I18n.translate("info_panel.identifier.none")); Utils.unboldLabel(label); label.setHorizontalAlignment(JLabel.CENTER); this.add(label); diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java index 8ee564b..dd7f9f9 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java @@ -3,6 +3,7 @@ package cuchaz.enigma.gui.panels; import cuchaz.enigma.gui.ClassSelector; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.utils.I18n; import javax.swing.*; import java.awt.*; @@ -30,7 +31,7 @@ public class PanelObf extends JPanel { this.obfClasses.setRenameSelectionListener(gui::onPanelRename); this.setLayout(new BorderLayout()); - this.add(new JLabel("Obfuscated Classes"), BorderLayout.NORTH); + this.add(new JLabel(I18n.translate("info_panel.classes.obfuscated")), BorderLayout.NORTH); this.add(new JScrollPane(this.obfClasses), BorderLayout.CENTER); } } diff --git a/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index a6e465d..e783530 100644 --- a/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -11,6 +11,7 @@ import cuchaz.enigma.translation.mapping.EntryResolver; import cuchaz.enigma.translation.mapping.ResolutionStrategy; import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.*; +import cuchaz.enigma.utils.I18n; import java.util.*; @@ -45,14 +46,14 @@ public class StatsGenerator { totalWork += entryIndex.getClasses().size(); } - progress.init(totalWork, "Generating stats"); + progress.init(totalWork, I18n.translate("progress.stats")); Map counts = new HashMap<>(); int numDone = 0; if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { for (MethodEntry method : entryIndex.getMethods()) { - progress.step(numDone++, "Methods"); + progress.step(numDone++, I18n.translate("type.methods")); MethodEntry root = entryResolver .resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT) .stream() @@ -77,19 +78,19 @@ public class StatsGenerator { if (includedMembers.contains(StatsMember.FIELDS)) { for (FieldEntry field : entryIndex.getFields()) { - progress.step(numDone++, "Fields"); + progress.step(numDone++, I18n.translate("type.fields")); update(counts, field); } } if (includedMembers.contains(StatsMember.CLASSES)) { for (ClassEntry clazz : entryIndex.getClasses()) { - progress.step(numDone++, "Classes"); + progress.step(numDone++, I18n.translate("type.classes")); update(counts, clazz); } } - progress.step(-1, "Generating data"); + progress.step(-1, I18n.translate("progress.stats.data")); Tree tree = new Tree<>(); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java index 5e49a2a..60ce587 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java @@ -12,6 +12,7 @@ import cuchaz.enigma.translation.mapping.tree.HashEntryTree; import cuchaz.enigma.translation.representation.MethodDescriptor; import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.*; +import cuchaz.enigma.utils.I18n; import javax.annotation.Nullable; import java.io.IOException; @@ -28,12 +29,12 @@ public enum EnigmaMappingsReader implements MappingsReader { FILE { @Override public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - progress.init(1, "Loading mapping file"); + progress.init(1, I18n.translate("progress.mappings.enigma_file.loading")); EntryTree mappings = new HashEntryTree<>(); readFile(path, mappings); - progress.step(1, "Done!"); + progress.step(1, I18n.translate("progress.mappings.enigma_file.done")); return mappings; } @@ -48,7 +49,7 @@ public enum EnigmaMappingsReader implements MappingsReader { .filter(f -> f.toString().endsWith(".mapping")) .collect(Collectors.toList()); - progress.init(files.size(), "Loading mapping files"); + progress.init(files.size(), I18n.translate("progress.mappings.enigma_directory.loading")); int step = 0; for (Path file : files) { diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java index f490b1d..2ce1234 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java @@ -40,6 +40,7 @@ import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.LFPrintWriter; public enum EnigmaMappingsWriter implements MappingsWriter { @@ -51,7 +52,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter { .map(entry -> (ClassEntry) entry) .collect(Collectors.toList()); - progress.init(classes.size(), "Writing classes"); + progress.init(classes.size(), I18n.translate("progress.mappings.enigma_file.writing")); int steps = 0; try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) { @@ -74,7 +75,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter { applyDeletions(path, changedClasses, mappings, delta.getBaseMappings(), saveParameters.getFileNameFormat()); - progress.init(changedClasses.size(), "Writing classes"); + progress.init(changedClasses.size(), I18n.translate("progress.mappings.enigma_directory.writing")); AtomicInteger steps = new AtomicInteger(); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java index 1270d51..f67f8fc 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java @@ -14,6 +14,7 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; import cuchaz.enigma.utils.LFPrintWriter; import java.io.IOException; @@ -45,7 +46,7 @@ public enum SrgMappingsWriter implements MappingsWriter { Collection> rootEntries = Lists.newArrayList(mappings).stream() .map(EntryTreeNode::getEntry) .collect(Collectors.toList()); - progress.init(rootEntries.size(), "Generating mappings"); + progress.init(rootEntries.size(), I18n.translate("progress.mappings.srg_file.generating")); int steps = 0; for (Entry entry : sorted(rootEntries)) { @@ -53,13 +54,13 @@ public enum SrgMappingsWriter implements MappingsWriter { writeEntry(classLines, fieldLines, methodLines, mappings, entry); } - progress.init(3, "Writing mappings"); + progress.init(3, I18n.translate("progress.mappings.srg_file.writing")); try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) { - progress.step(0, "Classes"); + progress.step(0, I18n.translate("type.classes")); classLines.forEach(writer::println); - progress.step(1, "Fields"); + progress.step(1, I18n.translate("type.fields")); fieldLines.forEach(writer::println); - progress.step(2, "Methods"); + progress.step(2, I18n.translate("type.methods")); methodLines.forEach(writer::println); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java index aceb02f..773c95e 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyMappingsReader.java @@ -14,6 +14,7 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; import java.io.IOException; import java.nio.file.Files; @@ -32,7 +33,7 @@ public enum TinyMappingsReader implements MappingsReader { EntryTree mappings = new HashEntryTree<>(); lines.remove(0); - progress.init(lines.size(), "Loading mapping file"); + progress.init(lines.size(), I18n.translate("progress.mappings.tiny_file.loading")); for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { progress.step(lineNumber, ""); diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java index c0488e9..a47143a 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/TinyV2Reader.java @@ -14,6 +14,7 @@ import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -45,7 +46,7 @@ final class TinyV2Reader implements MappingsReader { private EntryTree read(Path path, List lines, ProgressListener progress) throws MappingParseException { EntryTree mappings = new HashEntryTree<>(); - progress.init(lines.size(), "Loading mapping file"); + progress.init(lines.size(), I18n.translate("progress.mappings.tiny_v2.loading")); BitSet state = new BitSet(STATE_SIZE); @SuppressWarnings({"unchecked", "rawtypes"}) diff --git a/src/main/java/cuchaz/enigma/utils/I18n.java b/src/main/java/cuchaz/enigma/utils/I18n.java new file mode 100644 index 0000000..f91c916 --- /dev/null +++ b/src/main/java/cuchaz/enigma/utils/I18n.java @@ -0,0 +1,102 @@ +package cuchaz.enigma.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Stream; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ResourceInfo; +import com.google.gson.Gson; + +import cuchaz.enigma.config.Config; + +public class I18n { + public static final String DEFAULT_LANGUAGE = "en_us"; + private static final Gson GSON = new Gson(); + private static Map translations = Maps.newHashMap(); + private static Map defaultTranslations = Maps.newHashMap(); + private static Map languageNames = Maps.newHashMap(); + + static { + translations = load(Config.getInstance().language); + defaultTranslations = load(DEFAULT_LANGUAGE); + } + + @SuppressWarnings("unchecked") + public static Map load(String language) { + try (InputStream inputStream = I18n.class.getResourceAsStream("/lang/" + language + ".json")) { + if (inputStream != null) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { + return GSON.fromJson(reader, Map.class); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return Collections.emptyMap(); + } + + public static String translate(String key) { + String value = translations.get(key); + if (value != null) { + return value; + } + value = defaultTranslations.get(key); + if (value != null) { + return value; + } + return key; + } + + public static String getLanguageName(String language) { + return languageNames.get(language); + } + + public static void setLanguage(String language) { + Config.getInstance().language = language; + try { + Config.getInstance().saveConfig(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static ArrayList getAvailableLanguages() { + ArrayList list = new ArrayList(); + + try { + ImmutableList resources = ClassPath.from(Thread.currentThread().getContextClassLoader()).getResources().asList(); + Stream dirStream = resources.stream(); + dirStream.forEach(context -> { + String file = context.getResourceName(); + if (file.startsWith("lang/") && file.endsWith(".json")) { + String fileName = file.substring(5, file.length() - 5); + list.add(fileName); + loadLanguageName(fileName); + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + return list; + } + + private static void loadLanguageName(String fileName) { + try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("lang/" + fileName + ".json")) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + Map map = GSON.fromJson(reader, Map.class); + languageNames.put(fileName, map.get("language").toString()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} -- cgit v1.2.3