Added Translation Support
This still needs a lot more work but most of the menu bar has been mapped out, all that's left are the settings for the decompilers. Titlebars, buttons and other dialogues still need to be mapped out, more of a proof of concept than anything.
This commit is contained in:
parent
812f4ea3cd
commit
9438079ac1
13 changed files with 534 additions and 64 deletions
|
@ -2,6 +2,7 @@ package the.bytecode.club.bytecodeviewer;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
|
import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.theme.RSTATheme;
|
import the.bytecode.club.bytecodeviewer.gui.theme.RSTATheme;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Language;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ public class Configuration
|
||||||
|
|
||||||
public static long lastHotKeyExecuted = System.currentTimeMillis();
|
public static long lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
|
||||||
|
public static Language language = Language.ENGLISH;
|
||||||
|
|
||||||
public static LAFTheme lafTheme = LAFTheme.SYSTEM; //lightmode by default since it uses the system theme
|
public static LAFTheme lafTheme = LAFTheme.SYSTEM; //lightmode by default since it uses the system theme
|
||||||
public static RSTATheme rstaTheme = lafTheme.getRSTATheme();
|
public static RSTATheme rstaTheme = lafTheme.getRSTATheme();
|
||||||
}
|
}
|
|
@ -26,8 +26,13 @@ import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameMethods;
|
||||||
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
||||||
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.*;
|
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.*;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.exporting.Export;
|
import the.bytecode.club.bytecodeviewer.resources.exporting.Export;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBoxMenuItem;
|
||||||
import the.bytecode.club.bytecodeviewer.util.*;
|
import the.bytecode.club.bytecodeviewer.util.*;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.ResourceDecompiling;
|
import the.bytecode.club.bytecodeviewer.resources.ResourceDecompiling;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Language;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenu;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenuItem;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
|
|
||||||
|
@ -72,78 +77,80 @@ public class MainViewerGUI extends JFrame
|
||||||
public final JMenuBar rootMenu = new JMenuBar();
|
public final JMenuBar rootMenu = new JMenuBar();
|
||||||
|
|
||||||
//all of the files main menu components
|
//all of the files main menu components
|
||||||
public final JMenu fileMainMenu = new JMenu("File");
|
public final JMenu fileMainMenu = new TranslatedJMenu("File", Translation.FILE);
|
||||||
public final JMenuItem newWorkSpace = new JMenuItem("New Workspace");
|
public final JMenuItem addResource = new TranslatedJMenuItem("Add...", Translation.ADD);
|
||||||
public final JMenuItem addResource = new JMenuItem("Add...");
|
public final JMenuItem newWorkSpace = new TranslatedJMenuItem("New Workspace", Translation.NEW_WORKSPACE);
|
||||||
public final JMenuItem reloadResources = new JMenuItem("Reload Resources");
|
public final JMenuItem reloadResources = new TranslatedJMenuItem("Reload Resources", Translation.RELOAD_RESOURCES);
|
||||||
public final JMenuItem runButton = new JMenuItem("Run");
|
public final JMenuItem runButton = new TranslatedJMenuItem("Run", Translation.RUN);
|
||||||
public final JMenuItem compileButton = new JMenuItem("Compile");
|
public final JMenuItem compileButton = new TranslatedJMenuItem("Compile", Translation.COMPILE);
|
||||||
public final JMenuItem saveAsRunnableJar = new JMenuItem("Save As Runnable Jar..");
|
public final JMenuItem saveAsRunnableJar = new TranslatedJMenuItem("Save As Runnable Jar..", Translation.SAVE_AS_RUNNABLE_JAR);
|
||||||
public final JMenuItem saveAsDex = new JMenuItem("Save As DEX..");
|
public final JMenuItem saveAsDex = new TranslatedJMenuItem("Save As DEX..", Translation.SAVE_AS_DEX);
|
||||||
public final JMenuItem saveAsAPK = new JMenuItem("Save As APK..");
|
public final JMenuItem saveAsAPK = new TranslatedJMenuItem("Save As APK..", Translation.SAVE_AS_APK);
|
||||||
public final JMenuItem saveAsZip = new JMenuItem("Save As Zip..");
|
public final JMenuItem saveAsZip = new TranslatedJMenuItem("Save As Zip..", Translation.SAVE_AS_ZIP);
|
||||||
public final JMenuItem decompileSaveOpened = new JMenuItem("Decompile & Save Opened Class..");
|
public final JMenuItem decompileSaveOpened = new TranslatedJMenuItem("Decompile & Save Opened Class..", Translation.DECOMPILE_SAVE_OPENED_CLASSES);
|
||||||
public final JMenuItem decompileSaveAll = new JMenuItem("Decompile & Save All Classes..");
|
public final JMenuItem decompileSaveAll = new TranslatedJMenuItem("Decompile & Save All Classes..", Translation.DECOMPILE_SAVE_ALL_CLASSES);
|
||||||
public final JMenu recentFilesSecondaryMenu = new JMenu("Recent Files");
|
public final JMenu recentFilesSecondaryMenu = new TranslatedJMenu("Recent Files", Translation.RECENT_FILES);
|
||||||
public final JMenuItem about = new JMenuItem("About");
|
public final JMenuItem about = new TranslatedJMenuItem("About", Translation.ABOUT);
|
||||||
public final JMenuItem exit = new JMenuItem("Exit");
|
public final JMenuItem exit = new TranslatedJMenuItem("Exit", Translation.EXIT);
|
||||||
|
|
||||||
//all of the view main menu components
|
//all of the view main menu components
|
||||||
public final JMenu viewMainMenu = new JMenu("View");
|
public final JMenu viewMainMenu = new TranslatedJMenu("View", Translation.VIEW);
|
||||||
public final DecompilerSelectionPane viewPane1 = new DecompilerSelectionPane(1);
|
public final DecompilerSelectionPane viewPane1 = new DecompilerSelectionPane(1);
|
||||||
public final DecompilerSelectionPane viewPane2 = new DecompilerSelectionPane(2);
|
public final DecompilerSelectionPane viewPane2 = new DecompilerSelectionPane(2);
|
||||||
public final DecompilerSelectionPane viewPane3 = new DecompilerSelectionPane(3);
|
public final DecompilerSelectionPane viewPane3 = new DecompilerSelectionPane(3);
|
||||||
|
|
||||||
//all of the plugins main menu components
|
//all of the plugins main menu components
|
||||||
public final JMenu pluginsMainMenu = new JMenu("Plugins");
|
public final JMenu pluginsMainMenu = new TranslatedJMenu("Plugins", Translation.PLUGINS);
|
||||||
public final JMenuItem openExternalPlugin = new JMenuItem("Open Plugin...");
|
public final JMenuItem openExternalPlugin = new TranslatedJMenuItem("Open Plugin...", Translation.OPEN_PLUGIN);
|
||||||
public final JMenu recentPluginsSecondaryMenu = new JMenu("Recent Plugins");
|
public final JMenu recentPluginsSecondaryMenu = new TranslatedJMenu("Recent Plugins", Translation.RECENT_PLUGINS);
|
||||||
public final JMenuItem ZKMStringDecrypter = new JMenuItem("ZKM String Decrypter");
|
public final JMenuItem codeSequenceDiagram = new TranslatedJMenuItem("Code Sequence Diagram", Translation.CODE_SEQUENCE_DIAGRAM);
|
||||||
public final JMenuItem allatoriStringDecrypter = new JMenuItem("Allatori String Decrypter");
|
public final JMenuItem maliciousCodeScanner = new TranslatedJMenuItem("Malicious Code Scanner", Translation.MALICIOUS_CODE_SCANNER);
|
||||||
public final JMenuItem codeSequenceDiagram = new JMenuItem("Code Sequence Diagram");
|
public final JMenuItem showAllStrings = new TranslatedJMenuItem("Show All Strings", Translation.SHOW_ALL_STRINGS);
|
||||||
public final JMenuItem maliciousCodeScanner = new JMenuItem("Malicious Code Scanner");
|
public final JMenuItem showMainMethods = new TranslatedJMenuItem("Show Main Methods", Translation.SHOW_MAIN_METHODS);
|
||||||
public final JMenuItem showAllStrings = new JMenuItem("Show All Strings");
|
public final JMenuItem replaceStrings = new TranslatedJMenuItem("Replace Strings", Translation.REPLACE_STRINGS);
|
||||||
public final JMenuItem showMainMethods = new JMenuItem("Show Main Methods");
|
public final JMenuItem stackFramesRemover = new TranslatedJMenuItem("StackFrames Remover", Translation.STACK_FRAMES_REMOVER);
|
||||||
public final JMenuItem replaceStrings = new JMenuItem("Replace Strings");
|
public final JMenuItem ZKMStringDecrypter = new TranslatedJMenuItem("ZKM String Decrypter", Translation.ZKM_STRING_DECRYPTER);
|
||||||
public final JMenuItem stackFramesRemover = new JMenuItem("StackFrames Remover");
|
public final JMenuItem allatoriStringDecrypter = new TranslatedJMenuItem("Allatori String Decrypter", Translation.ALLATORI_STRING_DECRYPTER);
|
||||||
public final JMenuItem zStringArrayDecrypter = new JMenuItem("ZStringArray Decrypter");
|
public final JMenuItem zStringArrayDecrypter = new TranslatedJMenuItem("ZStringArray Decrypter", Translation.ZSTRINGARRAY_DECRYPTER);
|
||||||
|
|
||||||
//all of the settings main menu components
|
//all of the settings main menu components
|
||||||
public final ButtonGroup apkConversionGroup = new ButtonGroup();
|
public final ButtonGroup apkConversionGroup = new ButtonGroup();
|
||||||
public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar");
|
public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar");
|
||||||
public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify");
|
public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify");
|
||||||
public final JMenu fontSize = new JMenu("Font Size");
|
public final JMenu rstaTheme = new TranslatedJMenu("Text Area Theme", Translation.TEXT_AREA_THEME);
|
||||||
|
public final JMenu lafTheme = new TranslatedJMenu("Window Theme", Translation.WINDOW_THEME);
|
||||||
|
public final JMenu language = new TranslatedJMenu("Language", Translation.LANGUAGE);
|
||||||
|
public final JMenu fontSize = new TranslatedJMenu("Font Size", Translation.FONT_SIZE);
|
||||||
public final JSpinner fontSpinner = new JSpinner();
|
public final JSpinner fontSpinner = new JSpinner();
|
||||||
public final JMenu rstaTheme = new JMenu("Text Area Theme");
|
|
||||||
public final JMenu lafTheme = new JMenu("Window Theme");
|
|
||||||
|
|
||||||
//BCV settings
|
|
||||||
public final JCheckBoxMenuItem refreshOnChange = new JCheckBoxMenuItem("Refresh On View Change");
|
|
||||||
private final JCheckBoxMenuItem deleteForeignOutdatedLibs = new JCheckBoxMenuItem("Delete Foreign/Outdated Libs");
|
|
||||||
public final JMenu settingsMainMenu = new JMenu("Settings");
|
|
||||||
public final JMenu visualSettings = new JMenu("Visual Settings");
|
|
||||||
public final JMenu apkConversion = new JMenu("APK Conversion");
|
|
||||||
public final JMenu bytecodeDecompilerSettingsSecondaryMenu = new JMenu("Bytecode Decompiler");
|
|
||||||
public final JCheckBoxMenuItem updateCheck = new JCheckBoxMenuItem("Update Check");
|
|
||||||
public final JMenuItem setPython2 = new JMenuItem("Set Python 2.7 Executable");
|
|
||||||
public final JMenuItem setPython3 = new JMenuItem("Set Python 3.X Executable");
|
|
||||||
public final JMenuItem setJRERT = new JMenuItem("Set JRE RT Library");
|
|
||||||
public final JMenuItem setJavac = new JMenuItem("Set Javac Executable");
|
|
||||||
public final JMenuItem setOptionalLibrary = new JMenuItem("Set Optional Library Folder");
|
|
||||||
public final JCheckBoxMenuItem compileOnSave = new JCheckBoxMenuItem("Compile On Save");
|
|
||||||
public final JCheckBoxMenuItem showFileInTabTitle = new JCheckBoxMenuItem("Show File In Tab Title");
|
|
||||||
public final JCheckBoxMenuItem simplifyNameInTabTitle = new JCheckBoxMenuItem("Simplify Name In Tab Title");
|
|
||||||
public final JCheckBoxMenuItem forcePureAsciiAsText = new JCheckBoxMenuItem("Force Pure Ascii As Text");
|
|
||||||
public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile On Refresh");
|
|
||||||
public final JCheckBoxMenuItem decodeAPKResources = new JCheckBoxMenuItem("Decode APK Resources");
|
|
||||||
public final JCheckBoxMenuItem synchronizedViewing = new JCheckBoxMenuItem("Synchronized Viewing");
|
|
||||||
public final JCheckBoxMenuItem showClassMethods = new JCheckBoxMenuItem("Show Class Methods");
|
|
||||||
public final Map<RSTATheme, JRadioButtonMenuItem> rstaThemes = new HashMap<>();
|
public final Map<RSTATheme, JRadioButtonMenuItem> rstaThemes = new HashMap<>();
|
||||||
public final Map<LAFTheme, JRadioButtonMenuItem> lafThemes = new HashMap<>();
|
public final Map<LAFTheme, JRadioButtonMenuItem> lafThemes = new HashMap<>();
|
||||||
|
public final Map<Language, JRadioButtonMenuItem> languages = new HashMap<>();
|
||||||
|
|
||||||
|
//BCV settings
|
||||||
|
public final JCheckBoxMenuItem refreshOnChange = new TranslatedJCheckBoxMenuItem("Refresh On View Change", Translation.REFRESH_ON_VIEW_CHANGE);
|
||||||
|
private final JCheckBoxMenuItem deleteForeignOutdatedLibs = new TranslatedJCheckBoxMenuItem("Delete Foreign/Outdated Libs", Translation.DELETE_UNKNOWN_LIBS);
|
||||||
|
public final JMenu settingsMainMenu = new TranslatedJMenu("Settings", Translation.SETTINGS);
|
||||||
|
public final JMenu visualSettings = new TranslatedJMenu("Visual Settings", Translation.VISUAL_SETTINGS);
|
||||||
|
public final JMenu apkConversion = new TranslatedJMenu("APK Conversion", Translation.APK_CONVERSION);
|
||||||
|
public final JMenu bytecodeDecompilerSettingsSecondaryMenu = new TranslatedJMenu("Bytecode Decompiler", Translation.BYTECODE_DECOMPILER);
|
||||||
|
public final JCheckBoxMenuItem updateCheck = new TranslatedJCheckBoxMenuItem("Update Check", Translation.UPDATE_CHECK);
|
||||||
|
public final JMenuItem setPython2 = new TranslatedJMenuItem("Set Python 2.7 Executable", Translation.SET_PYTHON_27_EXECUTABLE);
|
||||||
|
public final JMenuItem setPython3 = new TranslatedJMenuItem("Set Python 3.X Executable", Translation.SET_PYTHON_30_EXECUTABLE);
|
||||||
|
public final JMenuItem setJRERT = new TranslatedJMenuItem("Set JRE RT Library", Translation.SET_JRE_RT_LIBRARY);
|
||||||
|
public final JMenuItem setJavac = new TranslatedJMenuItem("Set Javac Executable", Translation.SET_JAVAC_EXECUTABLE);
|
||||||
|
public final JMenuItem setOptionalLibrary = new TranslatedJMenuItem("Set Optional Library Folder", Translation.SET_OPTIONAL_LIBRARY_FOLDER);
|
||||||
|
public final JCheckBoxMenuItem compileOnSave = new TranslatedJCheckBoxMenuItem("Compile On Save", Translation.COMPILE_ON_SAVE);
|
||||||
|
public final JCheckBoxMenuItem showFileInTabTitle = new TranslatedJCheckBoxMenuItem("Show File In Tab Title", Translation.SHOW_TAB_FILE_IN_TAB_TITLE);
|
||||||
|
public final JCheckBoxMenuItem simplifyNameInTabTitle = new TranslatedJCheckBoxMenuItem("Simplify Name In Tab Title", Translation.SIMPLIFY_NAME_IN_TAB_TITLE);
|
||||||
|
public final JCheckBoxMenuItem forcePureAsciiAsText = new TranslatedJCheckBoxMenuItem("Force Pure Ascii As Text", Translation.FORCE_PURE_ASCII_AS_TEXT);
|
||||||
|
public final JCheckBoxMenuItem autoCompileOnRefresh = new TranslatedJCheckBoxMenuItem("Compile On Refresh", Translation.COMPILE_ON_REFRESH);
|
||||||
|
public final JCheckBoxMenuItem decodeAPKResources = new TranslatedJCheckBoxMenuItem("Decode APK Resources", Translation.DECODE_APK_RESOURCES);
|
||||||
|
public final JCheckBoxMenuItem synchronizedViewing = new TranslatedJCheckBoxMenuItem("Synchronized Viewing", Translation.SYNCHRONIZED_VIEWING);
|
||||||
|
public final JCheckBoxMenuItem showClassMethods = new TranslatedJCheckBoxMenuItem("Show Class Methods", Translation.SHOW_CLASS_METHODS);
|
||||||
|
|
||||||
//CFIDE settings
|
//CFIDE settings
|
||||||
public final JCheckBoxMenuItem appendBracketsToLabels = new JCheckBoxMenuItem("Append Brackets To Labels");
|
public final JCheckBoxMenuItem appendBracketsToLabels = new TranslatedJCheckBoxMenuItem("Append Brackets To Labels", Translation.APPEND_BRACKETS_TO_LABEL);
|
||||||
public JCheckBoxMenuItem debugHelpers = new JCheckBoxMenuItem("Debug Helpers");
|
public JCheckBoxMenuItem debugHelpers = new TranslatedJCheckBoxMenuItem("Debug Helpers", Translation.DEBUG_HELPERS);
|
||||||
|
|
||||||
//FernFlower settings
|
//FernFlower settings
|
||||||
public final JMenu fernFlowerSettingsSecondaryMenu = new JMenu("FernFlower");
|
public final JMenu fernFlowerSettingsSecondaryMenu = new JMenu("FernFlower");
|
||||||
|
@ -399,7 +406,7 @@ public class MainViewerGUI extends JFrame
|
||||||
{
|
{
|
||||||
Configuration.rstaTheme = t;
|
Configuration.rstaTheme = t;
|
||||||
item.setSelected(true);
|
item.setSelected(true);
|
||||||
Settings.saveSettings();
|
SettingsSerializer.saveSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
rstaThemes.put(t, item);
|
rstaThemes.put(t, item);
|
||||||
|
@ -421,7 +428,7 @@ public class MainViewerGUI extends JFrame
|
||||||
Configuration.rstaTheme = theme.getRSTATheme();
|
Configuration.rstaTheme = theme.getRSTATheme();
|
||||||
rstaThemes.get(Configuration.rstaTheme).setSelected(true);
|
rstaThemes.get(Configuration.rstaTheme).setSelected(true);
|
||||||
item.setSelected(true);
|
item.setSelected(true);
|
||||||
Settings.saveSettings();
|
SettingsSerializer.saveSettings();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -437,9 +444,29 @@ public class MainViewerGUI extends JFrame
|
||||||
lafThemes.put(theme, item);
|
lafThemes.put(theme, item);
|
||||||
lafTheme.add(item);
|
lafTheme.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ButtonGroup languageGroup = new ButtonGroup();
|
||||||
|
for (Language l : Language.values())
|
||||||
|
{
|
||||||
|
JRadioButtonMenuItem item = new JRadioButtonMenuItem(l.getReadableName());
|
||||||
|
if (Configuration.language.equals(l))
|
||||||
|
item.setSelected(true);
|
||||||
|
|
||||||
|
languageGroup.add(item);
|
||||||
|
|
||||||
|
item.addActionListener(e ->
|
||||||
|
{
|
||||||
|
SettingsSerializer.saveSettings();
|
||||||
|
MiscUtils.setLanguage(l);
|
||||||
|
});
|
||||||
|
|
||||||
|
languages.put(l, item);
|
||||||
|
language.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
visualSettings.add(lafTheme);
|
visualSettings.add(lafTheme);
|
||||||
visualSettings.add(rstaTheme);
|
visualSettings.add(rstaTheme);
|
||||||
|
visualSettings.add(language);
|
||||||
visualSettings.add(fontSize);
|
visualSettings.add(fontSize);
|
||||||
visualSettings.add(showFileInTabTitle);
|
visualSettings.add(showFileInTabTitle);
|
||||||
visualSettings.add(simplifyNameInTabTitle);
|
visualSettings.add(simplifyNameInTabTitle);
|
||||||
|
@ -538,7 +565,7 @@ public class MainViewerGUI extends JFrame
|
||||||
bytecodeDecompilerSettingsSecondaryMenu.add(appendBracketsToLabels);
|
bytecodeDecompilerSettingsSecondaryMenu.add(appendBracketsToLabels);
|
||||||
|
|
||||||
deleteForeignOutdatedLibs.addActionListener(arg0 -> showForeignLibraryWarning());
|
deleteForeignOutdatedLibs.addActionListener(arg0 -> showForeignLibraryWarning());
|
||||||
forcePureAsciiAsText.addActionListener(arg0 -> Settings.saveSettings());
|
forcePureAsciiAsText.addActionListener(arg0 -> SettingsSerializer.saveSettings());
|
||||||
setPython2.addActionListener(arg0 -> selectPythonC());
|
setPython2.addActionListener(arg0 -> selectPythonC());
|
||||||
setJRERT.addActionListener(arg0 -> selectJRERTLibrary());
|
setJRERT.addActionListener(arg0 -> selectJRERTLibrary());
|
||||||
setPython3.addActionListener(arg0 -> selectPythonC3());
|
setPython3.addActionListener(arg0 -> selectPythonC3());
|
||||||
|
@ -546,12 +573,12 @@ public class MainViewerGUI extends JFrame
|
||||||
setJavac.addActionListener(arg0 -> selectJavac());
|
setJavac.addActionListener(arg0 -> selectJavac());
|
||||||
showFileInTabTitle.addActionListener(arg0 -> {
|
showFileInTabTitle.addActionListener(arg0 -> {
|
||||||
Configuration.displayParentInTab = BytecodeViewer.viewer.showFileInTabTitle.isSelected();
|
Configuration.displayParentInTab = BytecodeViewer.viewer.showFileInTabTitle.isSelected();
|
||||||
Settings.saveSettings();
|
SettingsSerializer.saveSettings();
|
||||||
BytecodeViewer.refreshAllTabTitles();
|
BytecodeViewer.refreshAllTabTitles();
|
||||||
});
|
});
|
||||||
simplifyNameInTabTitle.addActionListener(arg0 -> {
|
simplifyNameInTabTitle.addActionListener(arg0 -> {
|
||||||
Configuration.simplifiedTabNames = BytecodeViewer.viewer.simplifyNameInTabTitle.isSelected();
|
Configuration.simplifiedTabNames = BytecodeViewer.viewer.simplifyNameInTabTitle.isSelected();
|
||||||
Settings.saveSettings();
|
SettingsSerializer.saveSettings();
|
||||||
BytecodeViewer.refreshAllTabTitles();
|
BytecodeViewer.refreshAllTabTitles();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package the.bytecode.club.bytecodeviewer.gui.components;
|
package the.bytecode.club.bytecodeviewer.gui.components;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBoxMenuItem;
|
||||||
import the.bytecode.club.bytecodeviewer.util.RefreshWorkPane;
|
import the.bytecode.club.bytecodeviewer.util.RefreshWorkPane;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -33,7 +35,7 @@ public class DecompilerViewComponent
|
||||||
private final JMenu menu;
|
private final JMenu menu;
|
||||||
private final JRadioButtonMenuItem java = new JRadioButtonMenuItem("Java");
|
private final JRadioButtonMenuItem java = new JRadioButtonMenuItem("Java");
|
||||||
private final JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode");
|
private final JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode");
|
||||||
private final JCheckBoxMenuItem editable = new JCheckBoxMenuItem("Editable");
|
private final JCheckBoxMenuItem editable = new TranslatedJCheckBoxMenuItem("Editable", Translation.EDITABLE);
|
||||||
|
|
||||||
public DecompilerViewComponent(String name) {
|
public DecompilerViewComponent(String name) {
|
||||||
this(name, false);
|
this(name, false);
|
||||||
|
|
|
@ -2,6 +2,9 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent;
|
import the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenu;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
@ -14,7 +17,7 @@ public class DecompilerSelectionPane
|
||||||
public final int paneID;
|
public final int paneID;
|
||||||
public final JMenu menu;
|
public final JMenu menu;
|
||||||
public final ButtonGroup group = new ButtonGroup();
|
public final ButtonGroup group = new ButtonGroup();
|
||||||
public final JRadioButtonMenuItem none = new JRadioButtonMenuItem("None");
|
public final JRadioButtonMenuItem none = new TranslatedJRadioButtonMenuItem("None", Translation.NONE);
|
||||||
public final DecompilerViewComponent procyon = new DecompilerViewComponent("Procyon");
|
public final DecompilerViewComponent procyon = new DecompilerViewComponent("Procyon");
|
||||||
public final DecompilerViewComponent CFR = new DecompilerViewComponent("CFR");
|
public final DecompilerViewComponent CFR = new DecompilerViewComponent("CFR");
|
||||||
public final DecompilerViewComponent JADX = new DecompilerViewComponent("JADX");
|
public final DecompilerViewComponent JADX = new DecompilerViewComponent("JADX");
|
||||||
|
@ -28,7 +31,12 @@ public class DecompilerSelectionPane
|
||||||
|
|
||||||
public DecompilerSelectionPane(int paneID) {
|
public DecompilerSelectionPane(int paneID) {
|
||||||
this.paneID = paneID;
|
this.paneID = paneID;
|
||||||
this.menu = new JMenu("Pane " + paneID);
|
if(paneID == 1)
|
||||||
|
this.menu = new TranslatedJMenu("Pane " + paneID, Translation.PANE_1);
|
||||||
|
else if(paneID == 2)
|
||||||
|
this.menu = new TranslatedJMenu("Pane " + paneID, Translation.PANE_2);
|
||||||
|
else
|
||||||
|
this.menu = new TranslatedJMenu("Pane " + paneID, Translation.PANE_3);
|
||||||
buildMenu();
|
buildMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.collections4.map.HashedMap;
|
||||||
|
import org.apache.commons.collections4.map.LinkedMap;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Resources;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the supported languages
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public enum Language
|
||||||
|
{
|
||||||
|
ENGLISH("/translations/english.json", "English", "en"),
|
||||||
|
MANDARIN("/translations/mandarin.json", "普通话", "zh_cn", "zh"),
|
||||||
|
//HINDI("/translations/hindi.json", "hi"),
|
||||||
|
/*SPANISH("/translations/spanish.json", "es"),
|
||||||
|
FRENCH("/translations/french.json", "fr"),
|
||||||
|
ARABIC("/translations/arabic.json", "ab"),
|
||||||
|
RUSSIAN("/translations/russian.json", "ru"),*/
|
||||||
|
GERMAN("/translations/german.json", "Deutsche", "de"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private static final HashedMap<String, Language> languageCodeLookup;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
languageCodeLookup = new HashedMap<>();
|
||||||
|
for(Language l : values())
|
||||||
|
l.languageCode.forEach((langCode)->
|
||||||
|
languageCodeLookup.put(langCode, l));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String resourcePath;
|
||||||
|
private final String readableName;
|
||||||
|
private final HashSet<String> languageCode;
|
||||||
|
|
||||||
|
Language(String resourcePath, String readableName, String... languageCodes)
|
||||||
|
{
|
||||||
|
this.resourcePath = resourcePath;
|
||||||
|
this.languageCode = new HashSet<>(Arrays.asList(languageCodes));
|
||||||
|
this.readableName = readableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadLanguage() throws IOException
|
||||||
|
{
|
||||||
|
HashMap<String, String> translationMap = BytecodeViewer.gson.fromJson(
|
||||||
|
IOUtils.toString(Resources.class.getResourceAsStream(resourcePath), StandardCharsets.UTF_8),
|
||||||
|
new TypeToken<HashMap<String, String>>(){}.getType());
|
||||||
|
|
||||||
|
for(Translation translation : Translation.values())
|
||||||
|
{
|
||||||
|
TranslatedComponent text = translation.getTranslatedComponent();
|
||||||
|
|
||||||
|
//skip translating if the language config is missing the translation key
|
||||||
|
if(!translationMap.containsKey(text.key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//update translation text value
|
||||||
|
text.value = translationMap.get(text.key);
|
||||||
|
|
||||||
|
//check if translation key has been assigned to a component,
|
||||||
|
//on fail print an error alerting the devs
|
||||||
|
if(translation.getTranslatedComponent().runOnUpdate.isEmpty())
|
||||||
|
{
|
||||||
|
System.err.println("Translation Reference " + translation.name() + " is missing component attachment, skipping...");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//trigger translation event
|
||||||
|
translation.getTranslatedComponent().runOnUpdate.forEach(Runnable::run);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
// When adding new Translation Components:
|
||||||
|
// 1) start by adding the strings into the english.json
|
||||||
|
// 2) run this function to get the keys and add them into Translation.java
|
||||||
|
// 3) replace the swing component (MainViewerGUI) with a translated component
|
||||||
|
// and reference the correct translation key
|
||||||
|
// 4) add the translation key to the rest of the translation files
|
||||||
|
public void printLanguageKeys() throws IOException
|
||||||
|
{
|
||||||
|
if(this != ENGLISH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LinkedMap<String, String> translationMap = BytecodeViewer.gson.fromJson(
|
||||||
|
IOUtils.toString(Resources.class.getResourceAsStream(resourcePath), StandardCharsets.UTF_8),
|
||||||
|
new TypeToken<LinkedMap<String, String>>(){}.getType());
|
||||||
|
|
||||||
|
for(String key : translationMap.keySet())
|
||||||
|
System.out.println(key + ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourcePath()
|
||||||
|
{
|
||||||
|
return resourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet<String> getLanguageCode()
|
||||||
|
{
|
||||||
|
return languageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReadableName()
|
||||||
|
{
|
||||||
|
return readableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashedMap<String, Language> getLanguageCodeLookup()
|
||||||
|
{
|
||||||
|
return languageCodeLookup;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public class TranslatedComponent
|
||||||
|
{
|
||||||
|
public String key;
|
||||||
|
public String value;
|
||||||
|
public List<Runnable> runOnUpdate = new ArrayList<>();
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the specific translations strings needed for BCV
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public enum Translation
|
||||||
|
{
|
||||||
|
FILE,
|
||||||
|
ADD,
|
||||||
|
NEW_WORKSPACE,
|
||||||
|
RELOAD_RESOURCES,
|
||||||
|
RUN,
|
||||||
|
COMPILE,
|
||||||
|
SAVE_AS_RUNNABLE_JAR,
|
||||||
|
SAVE_AS_ZIP,
|
||||||
|
SAVE_AS_DEX,
|
||||||
|
SAVE_AS_APK,
|
||||||
|
DECOMPILE_SAVE_OPENED_CLASSES,
|
||||||
|
DECOMPILE_SAVE_ALL_CLASSES,
|
||||||
|
RECENT_FILES,
|
||||||
|
ABOUT,
|
||||||
|
EXIT,
|
||||||
|
|
||||||
|
VIEW,
|
||||||
|
VISUAL_SETTINGS,
|
||||||
|
LANGUAGE,
|
||||||
|
WINDOW_THEME,
|
||||||
|
TEXT_AREA_THEME,
|
||||||
|
FONT_SIZE,
|
||||||
|
SHOW_TAB_FILE_IN_TAB_TITLE,
|
||||||
|
SIMPLIFY_NAME_IN_TAB_TITLE,
|
||||||
|
SYNCHRONIZED_VIEWING,
|
||||||
|
SHOW_CLASS_METHODS,
|
||||||
|
|
||||||
|
PANE_1,
|
||||||
|
PANE_2,
|
||||||
|
PANE_3,
|
||||||
|
NONE,
|
||||||
|
EDITABLE,
|
||||||
|
|
||||||
|
SETTINGS,
|
||||||
|
COMPILE_ON_SAVE,
|
||||||
|
COMPILE_ON_REFRESH,
|
||||||
|
REFRESH_ON_VIEW_CHANGE,
|
||||||
|
DECODE_APK_RESOURCES,
|
||||||
|
APK_CONVERSION,
|
||||||
|
UPDATE_CHECK,
|
||||||
|
DELETE_UNKNOWN_LIBS,
|
||||||
|
FORCE_PURE_ASCII_AS_TEXT,
|
||||||
|
SET_PYTHON_27_EXECUTABLE,
|
||||||
|
SET_PYTHON_30_EXECUTABLE,
|
||||||
|
SET_JRE_RT_LIBRARY,
|
||||||
|
SET_OPTIONAL_LIBRARY_FOLDER,
|
||||||
|
SET_JAVAC_EXECUTABLE,
|
||||||
|
BYTECODE_DECOMPILER,
|
||||||
|
DEBUG_HELPERS,
|
||||||
|
APPEND_BRACKETS_TO_LABEL,
|
||||||
|
|
||||||
|
PLUGINS,
|
||||||
|
OPEN_PLUGIN,
|
||||||
|
RECENT_PLUGINS,
|
||||||
|
CODE_SEQUENCE_DIAGRAM,
|
||||||
|
MALICIOUS_CODE_SCANNER,
|
||||||
|
SHOW_MAIN_METHODS,
|
||||||
|
SHOW_ALL_STRINGS,
|
||||||
|
REPLACE_STRINGS,
|
||||||
|
STACK_FRAMES_REMOVER,
|
||||||
|
ZKM_STRING_DECRYPTER,
|
||||||
|
ALLATORI_STRING_DECRYPTER,
|
||||||
|
ZSTRINGARRAY_DECRYPTER,
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private final TranslatedComponent component;
|
||||||
|
|
||||||
|
Translation()
|
||||||
|
{
|
||||||
|
this.component = new TranslatedComponent();
|
||||||
|
this.component.key = name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslatedComponent getTranslatedComponent()
|
||||||
|
{
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation.components;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponent;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public class TranslatedJCheckBoxMenuItem extends JCheckBoxMenuItem
|
||||||
|
{
|
||||||
|
private final TranslatedComponent component;
|
||||||
|
|
||||||
|
public TranslatedJCheckBoxMenuItem(String text, Translation translation)
|
||||||
|
{
|
||||||
|
super(text);
|
||||||
|
this.component = translation.getTranslatedComponent();
|
||||||
|
this.component.runOnUpdate.add(this::updateText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateText()
|
||||||
|
{
|
||||||
|
setText(component.value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation.components;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponent;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public class TranslatedJMenu extends JMenu
|
||||||
|
{
|
||||||
|
private final TranslatedComponent component;
|
||||||
|
|
||||||
|
public TranslatedJMenu(String text, Translation translation)
|
||||||
|
{
|
||||||
|
super(text);
|
||||||
|
this.component = translation.getTranslatedComponent();
|
||||||
|
this.component.runOnUpdate.add(this::updateText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateText()
|
||||||
|
{
|
||||||
|
setText(component.value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation.components;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponent;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public class TranslatedJMenuItem extends JMenuItem
|
||||||
|
{
|
||||||
|
private final TranslatedComponent component;
|
||||||
|
|
||||||
|
public TranslatedJMenuItem(String text, Translation translation)
|
||||||
|
{
|
||||||
|
super(text);
|
||||||
|
this.component = translation.getTranslatedComponent();
|
||||||
|
this.component.runOnUpdate.add(this::updateText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateText()
|
||||||
|
{
|
||||||
|
setText(component.value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.translation.components;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponent;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Translation;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Konloch
|
||||||
|
* @since 6/28/2021
|
||||||
|
*/
|
||||||
|
public class TranslatedJRadioButtonMenuItem extends JRadioButtonMenuItem
|
||||||
|
{
|
||||||
|
private final TranslatedComponent component;
|
||||||
|
|
||||||
|
public TranslatedJRadioButtonMenuItem(String text, Translation translation)
|
||||||
|
{
|
||||||
|
super(text);
|
||||||
|
this.component = translation.getTranslatedComponent();
|
||||||
|
this.component.runOnUpdate.add(this::updateText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateText()
|
||||||
|
{
|
||||||
|
setText(component.value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,12 @@ package the.bytecode.club.bytecodeviewer.util;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.Language;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -13,7 +17,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.gson;
|
import static the.bytecode.club.bytecodeviewer.BytecodeViewer.gson;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
|
@ -235,6 +239,30 @@ public class MiscUtils
|
||||||
return asciiEncoder.canEncode(v);
|
return asciiEncoder.canEncode(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Language guessLanguage()
|
||||||
|
{
|
||||||
|
String userLanguage = System.getProperty("user.language");
|
||||||
|
String systemLanguageCode = userLanguage != null ? userLanguage.toLowerCase() : "";
|
||||||
|
|
||||||
|
return Language.getLanguageCodeLookup().getOrDefault(systemLanguageCode, Language.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLanguage(Language language)
|
||||||
|
{
|
||||||
|
Configuration.language = language;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Language.ENGLISH.loadLanguage(); //load english first incase the translation file is missing anything
|
||||||
|
language.loadLanguage(); //load translation file and swap text around as needed
|
||||||
|
SwingUtilities.updateComponentTreeUI(BytecodeViewer.viewer);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String getChildFromPath(String path)
|
public static String getChildFromPath(String path)
|
||||||
{
|
{
|
||||||
if (path != null && path.contains("/"))
|
if (path != null && path.contains("/"))
|
||||||
|
|
65
src/main/resources/translations/english.json
Normal file
65
src/main/resources/translations/english.json
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"FILE": "File",
|
||||||
|
"ADD": "Add...",
|
||||||
|
"NEW_WORKSPACE": "New Workspace",
|
||||||
|
"RELOAD_RESOURCES": "Reload Resources",
|
||||||
|
"RUN": "Run",
|
||||||
|
"COMPILE": "Compile",
|
||||||
|
"SAVE_AS_RUNNABLE_JAR": "Save As Runnable Jar...",
|
||||||
|
"SAVE_AS_ZIP": "Save As Zip...",
|
||||||
|
"SAVE_AS_DEX": "Save As DEX...",
|
||||||
|
"SAVE_AS_APK": "Save As APK...",
|
||||||
|
"DECOMPILE_SAVE_OPENED_CLASSES": "Decompile & Save Opened Classes",
|
||||||
|
"DECOMPILE_SAVE_ALL_CLASSES": "Decompile & Save All Classes",
|
||||||
|
"RECENT_FILES": "Recent Files",
|
||||||
|
"ABOUT": "About",
|
||||||
|
"EXIT": "Exit",
|
||||||
|
|
||||||
|
"VIEW": "View",
|
||||||
|
"VISUAL_SETTINGS": "Visual Settings",
|
||||||
|
"LANGUAGE": "Language",
|
||||||
|
"WINDOW_THEME": "Window Theme",
|
||||||
|
"TEXT_AREA_THEME": "Text Area Theme",
|
||||||
|
"FONT_SIZE": "Font Size",
|
||||||
|
"SHOW_TAB_FILE_IN_TAB_TITLE": "Show File In Tab Title",
|
||||||
|
"SIMPLIFY_NAME_IN_TAB_TITLE": "Simplify Name In Tab Title",
|
||||||
|
"SYNCHRONIZED_VIEWING": "Synchronized Viewing",
|
||||||
|
"SHOW_CLASS_METHODS": "Show Class Methods",
|
||||||
|
|
||||||
|
"PANE_1": "Pane 1",
|
||||||
|
"PANE_2": "Pane 2",
|
||||||
|
"PANE_3": "Pane 3",
|
||||||
|
"NONE": "None",
|
||||||
|
"EDITABLE": "Editable",
|
||||||
|
|
||||||
|
"SETTINGS": "Settings",
|
||||||
|
"COMPILE_ON_SAVE": "Compile On Save",
|
||||||
|
"COMPILE_ON_REFRESH": "Compile On Refresh",
|
||||||
|
"REFRESH_ON_VIEW_CHANGE": "Refresh On View Change",
|
||||||
|
"DECODE_APK_RESOURCES": "Decode APK Resources",
|
||||||
|
"APK_CONVERSION": "APK Conversion",
|
||||||
|
"UPDATE_CHECK": "Update Check",
|
||||||
|
"DELETE_UNKNOWN_LIBS": "Delete Foreign/Outdated Libs",
|
||||||
|
"FORCE_PURE_ASCII_AS_TEXT": "Force Pure Ascii As Text",
|
||||||
|
"SET_PYTHON_27_EXECUTABLE": "Set Python 2.7 Executable",
|
||||||
|
"SET_PYTHON_30_EXECUTABLE": "Set Python 3.X Executable",
|
||||||
|
"SET_JRE_RT_LIBRARY": "Set JRE RT Library",
|
||||||
|
"SET_OPTIONAL_LIBRARY_FOLDER": "Set Optional Library Folder",
|
||||||
|
"SET_JAVAC_EXECUTABLE": "Set Javac Executable",
|
||||||
|
"BYTECODE_DECOMPILER": "Bytecode Decompiler",
|
||||||
|
"DEBUG_HELPERS": "Debug Helpers",
|
||||||
|
"APPEND_BRACKETS_TO_LABEL": "Append Brackets To Label",
|
||||||
|
|
||||||
|
"PLUGINS": "Plugins",
|
||||||
|
"OPEN_PLUGIN": "Open Plugin...",
|
||||||
|
"RECENT_PLUGINS": "Recent Plugins",
|
||||||
|
"CODE_SEQUENCE_DIAGRAM": "Code Sequence Diagram",
|
||||||
|
"MALICIOUS_CODE_SCANNER": "Malicious Code Scanner",
|
||||||
|
"SHOW_MAIN_METHODS": "Show Main Methods",
|
||||||
|
"SHOW_ALL_STRINGS": "Show All Strings",
|
||||||
|
"REPLACE_STRINGS": "Replace Strings",
|
||||||
|
"STACK_FRAMES_REMOVER": "Stack Frames Remover",
|
||||||
|
"ZKM_STRING_DECRYPTER": "ZKM String Decrypter",
|
||||||
|
"ALLATORI_STRING_DECRYPTER": "Allatori String Decrypter",
|
||||||
|
"ZSTRINGARRAY_DECRYPTER": "ZStringArray Decrypter"
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue