@@ -1,16 +1,23 @@
|
||||
package jadx.cli;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.beust.jcommander.IStringConverter;
|
||||
import com.beust.jcommander.Parameter;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.api.JadxArgs.RENAME;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
@@ -83,6 +90,10 @@ public class JadxCLIArgs {
|
||||
@Parameter(names = {"-f", "--fallback"}, description = "make simple dump (using goto instead of 'if', 'for', etc)")
|
||||
protected boolean fallbackMode = false;
|
||||
|
||||
@Parameter(names = {"--rename-flags"}, description = "what to rename, comma-separated, 'case' for system case sensitivity, 'valid' for java identifiers, 'printable' characters, 'none' or 'all'",
|
||||
converter = RenameConverter.class)
|
||||
protected Set<RENAME> renameFlags = EnumSet.allOf(RENAME.class);
|
||||
|
||||
@Parameter(names = {"-v", "--verbose"}, description = "verbose output")
|
||||
protected boolean verbose = false;
|
||||
|
||||
@@ -164,6 +175,9 @@ public class JadxCLIArgs {
|
||||
args.setExportAsGradleProject(exportAsGradleProject);
|
||||
args.setUseImports(useImports);
|
||||
args.setDebugInfo(debugInfo);
|
||||
args.setRenameCaseSensitive(isRenameCaseSensitive());
|
||||
args.setRenameValid(isRenameValid());
|
||||
args.setRenamePrintable(isRenamePrintable());
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -254,4 +268,73 @@ public class JadxCLIArgs {
|
||||
public boolean isExportAsGradleProject() {
|
||||
return exportAsGradleProject;
|
||||
}
|
||||
|
||||
public boolean isRenameCaseSensitive() {
|
||||
return renameFlags.contains(RENAME.CASE);
|
||||
}
|
||||
|
||||
public void setRenameCaseSensitive(boolean renameCase) {
|
||||
if (renameCase && !isRenameCaseSensitive()) {
|
||||
renameFlags.add(RENAME.CASE);
|
||||
} else if (!renameCase && isRenameCaseSensitive()) {
|
||||
renameFlags.remove(RENAME.CASE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRenameValid() {
|
||||
return renameFlags.contains(RENAME.VALID);
|
||||
}
|
||||
|
||||
public void setRenameValid(boolean renameValid) {
|
||||
if (renameValid && !isRenameValid()) {
|
||||
renameFlags.add(RENAME.VALID);
|
||||
} else if (!renameValid && isRenameValid()) {
|
||||
renameFlags.remove(RENAME.VALID);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRenamePrintable() {
|
||||
return renameFlags.contains(RENAME.PRINTABLE);
|
||||
}
|
||||
|
||||
public void setRenamePrintable(boolean renamePrintable) {
|
||||
if (renamePrintable && !isRenamePrintable()) {
|
||||
renameFlags.add(RENAME.PRINTABLE);
|
||||
} else if (!renamePrintable && isRenamePrintable()) {
|
||||
renameFlags.remove(RENAME.PRINTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static class RenameConverter implements IStringConverter<Set<RENAME>> {
|
||||
|
||||
private final String paramName;
|
||||
|
||||
RenameConverter(String paramName) {
|
||||
this.paramName = paramName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RENAME> convert(String value) {
|
||||
Set<RENAME> set = new HashSet<>();
|
||||
if (value.equalsIgnoreCase("ALL")) {
|
||||
set.add(RENAME.CASE);
|
||||
set.add(RENAME.VALID);
|
||||
set.add(RENAME.PRINTABLE);
|
||||
} else if (!value.equalsIgnoreCase("NONE")) {
|
||||
for (String s : value.split(",")) {
|
||||
try {
|
||||
set.add(RENAME.valueOf(s.toUpperCase(Locale.ROOT)));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String values = "'" + RENAME.CASE
|
||||
+ "', '" + RENAME.VALID
|
||||
+ "' and '" + RENAME.PRINTABLE + '\'';
|
||||
throw new IllegalArgumentException(
|
||||
s + " is unknown for parameter " + paramName
|
||||
+ ", possible values are " + values.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package jadx.cli;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.api.JadxArgs.RENAME;
|
||||
import jadx.cli.JadxCLIArgs.RenameConverter;
|
||||
|
||||
public class RenameConverterTest {
|
||||
|
||||
private RenameConverter converter;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
converter = new RenameConverter("someParam");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void all() {
|
||||
Set<RENAME> set = converter.convert("all");
|
||||
assertEquals(3, set.size());
|
||||
assertTrue(set.contains(RENAME.CASE));
|
||||
assertTrue(set.contains(RENAME.VALID));
|
||||
assertTrue(set.contains(RENAME.PRINTABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void none() {
|
||||
Set<RENAME> set = converter.convert("none");
|
||||
assertTrue(set.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrong() {
|
||||
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
|
||||
() -> converter.convert("wrong"),
|
||||
"Expected convert() to throw, but it didn't");
|
||||
|
||||
assertEquals("wrong is unknown for parameter someParam, "
|
||||
+ "possible values are 'case', 'valid' and 'printable'",
|
||||
thrown.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ package jadx.api;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JadxArgs {
|
||||
|
||||
@@ -30,11 +32,11 @@ public class JadxArgs {
|
||||
private boolean useImports = true;
|
||||
private boolean debugInfo = true;
|
||||
|
||||
private boolean isSkipResources = false;
|
||||
private boolean isSkipSources = false;
|
||||
private boolean skipResources = false;
|
||||
private boolean skipSources = false;
|
||||
|
||||
private boolean isDeobfuscationOn = false;
|
||||
private boolean isDeobfuscationForceSave = false;
|
||||
private boolean deobfuscationOn = false;
|
||||
private boolean deobfuscationForceSave = false;
|
||||
private boolean useSourceNameAsClassAlias = false;
|
||||
|
||||
private int deobfuscationMinLength = 0;
|
||||
@@ -45,7 +47,11 @@ public class JadxArgs {
|
||||
private boolean respectBytecodeAccModifiers = false;
|
||||
private boolean exportAsGradleProject = false;
|
||||
|
||||
private boolean isFsCaseSensitive;
|
||||
private boolean fsCaseSensitive;
|
||||
|
||||
public enum RENAME {CASE, VALID, PRINTABLE}
|
||||
|
||||
private Set<RENAME> renameFlags = EnumSet.allOf(RENAME.class);
|
||||
|
||||
public JadxArgs() {
|
||||
// use default options
|
||||
@@ -150,35 +156,35 @@ public class JadxArgs {
|
||||
}
|
||||
|
||||
public boolean isSkipResources() {
|
||||
return isSkipResources;
|
||||
return skipResources;
|
||||
}
|
||||
|
||||
public void setSkipResources(boolean skipResources) {
|
||||
isSkipResources = skipResources;
|
||||
this.skipResources = skipResources;
|
||||
}
|
||||
|
||||
public boolean isSkipSources() {
|
||||
return isSkipSources;
|
||||
return skipSources;
|
||||
}
|
||||
|
||||
public void setSkipSources(boolean skipSources) {
|
||||
isSkipSources = skipSources;
|
||||
this.skipSources = skipSources;
|
||||
}
|
||||
|
||||
public boolean isDeobfuscationOn() {
|
||||
return isDeobfuscationOn;
|
||||
return deobfuscationOn;
|
||||
}
|
||||
|
||||
public void setDeobfuscationOn(boolean deobfuscationOn) {
|
||||
isDeobfuscationOn = deobfuscationOn;
|
||||
this.deobfuscationOn = deobfuscationOn;
|
||||
}
|
||||
|
||||
public boolean isDeobfuscationForceSave() {
|
||||
return isDeobfuscationForceSave;
|
||||
return deobfuscationForceSave;
|
||||
}
|
||||
|
||||
public void setDeobfuscationForceSave(boolean deobfuscationForceSave) {
|
||||
isDeobfuscationForceSave = deobfuscationForceSave;
|
||||
this.deobfuscationForceSave = deobfuscationForceSave;
|
||||
}
|
||||
|
||||
public boolean isUseSourceNameAsClassAlias() {
|
||||
@@ -238,11 +244,47 @@ public class JadxArgs {
|
||||
}
|
||||
|
||||
public boolean isFsCaseSensitive() {
|
||||
return isFsCaseSensitive;
|
||||
return fsCaseSensitive;
|
||||
}
|
||||
|
||||
public void setFsCaseSensitive(boolean fsCaseSensitive) {
|
||||
isFsCaseSensitive = fsCaseSensitive;
|
||||
this.fsCaseSensitive = fsCaseSensitive;
|
||||
}
|
||||
|
||||
public boolean isRenameCaseSensitive() {
|
||||
return renameFlags.contains(RENAME.CASE);
|
||||
}
|
||||
|
||||
public void setRenameCaseSensitive(boolean renameCaseSensitive) {
|
||||
if (renameCaseSensitive && !isRenameCaseSensitive()) {
|
||||
renameFlags.add(RENAME.CASE);
|
||||
} else if (!renameCaseSensitive && isRenameCaseSensitive()) {
|
||||
renameFlags.remove(RENAME.CASE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRenameValid() {
|
||||
return renameFlags.contains(RENAME.VALID);
|
||||
}
|
||||
|
||||
public void setRenameValid(boolean renameValid) {
|
||||
if (renameValid && !isRenameValid()) {
|
||||
renameFlags.add(RENAME.VALID);
|
||||
} else if (!renameValid && isRenameValid()) {
|
||||
renameFlags.remove(RENAME.VALID);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRenamePrintable() {
|
||||
return renameFlags.contains(RENAME.PRINTABLE);
|
||||
}
|
||||
|
||||
public void setRenamePrintable(boolean renamePrintable) {
|
||||
if (renamePrintable && !isRenamePrintable()) {
|
||||
renameFlags.add(RENAME.PRINTABLE);
|
||||
} else if (!renamePrintable && isRenamePrintable()) {
|
||||
renameFlags.remove(RENAME.PRINTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -257,10 +299,10 @@ public class JadxArgs {
|
||||
", fallbackMode=" + fallbackMode +
|
||||
", showInconsistentCode=" + showInconsistentCode +
|
||||
", useImports=" + useImports +
|
||||
", isSkipResources=" + isSkipResources +
|
||||
", isSkipSources=" + isSkipSources +
|
||||
", isDeobfuscationOn=" + isDeobfuscationOn +
|
||||
", isDeobfuscationForceSave=" + isDeobfuscationForceSave +
|
||||
", skipResources=" + skipResources +
|
||||
", skipSources=" + skipSources +
|
||||
", deobfuscationOn=" + deobfuscationOn +
|
||||
", deobfuscationForceSave=" + deobfuscationForceSave +
|
||||
", useSourceNameAsClassAlias=" + useSourceNameAsClassAlias +
|
||||
", deobfuscationMinLength=" + deobfuscationMinLength +
|
||||
", deobfuscationMaxLength=" + deobfuscationMaxLength +
|
||||
@@ -268,6 +310,8 @@ public class JadxArgs {
|
||||
", replaceConsts=" + replaceConsts +
|
||||
", respectBytecodeAccModifiers=" + respectBytecodeAccModifiers +
|
||||
", exportAsGradleProject=" + exportAsGradleProject +
|
||||
", fsCaseSensitive=" + fsCaseSensitive +
|
||||
", renameFlags=" + renameFlags +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,15 +80,13 @@ public class NameMapper {
|
||||
public static boolean isValidIdentifier(String str) {
|
||||
return notEmpty(str)
|
||||
&& !isReserved(str)
|
||||
&& VALID_JAVA_IDENTIFIER.matcher(str).matches()
|
||||
&& isAllCharsPrintable(str);
|
||||
&& VALID_JAVA_IDENTIFIER.matcher(str).matches();
|
||||
}
|
||||
|
||||
public static boolean isValidFullIdentifier(String str) {
|
||||
return notEmpty(str)
|
||||
&& !isReserved(str)
|
||||
&& VALID_JAVA_FULL_IDENTIFIER.matcher(str).matches()
|
||||
&& isAllCharsPrintable(str);
|
||||
&& VALID_JAVA_FULL_IDENTIFIER.matcher(str).matches();
|
||||
}
|
||||
|
||||
public static boolean isValidIdentifierStart(int codePoint) {
|
||||
|
||||
@@ -43,17 +43,17 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
if (deobfuscationOn) {
|
||||
deobfuscator.execute();
|
||||
}
|
||||
checkClasses(root, args.isFsCaseSensitive());
|
||||
checkClasses(root, args);
|
||||
}
|
||||
|
||||
private void checkClasses(RootNode root, boolean caseSensitive) {
|
||||
private void checkClasses(RootNode root, JadxArgs args) {
|
||||
List<ClassNode> classes = root.getClasses(true);
|
||||
for (ClassNode cls : classes) {
|
||||
checkClassName(cls);
|
||||
checkFields(cls);
|
||||
checkMethods(cls);
|
||||
checkClassName(cls, args);
|
||||
checkFields(cls, args);
|
||||
checkMethods(cls, args);
|
||||
}
|
||||
if (!caseSensitive) {
|
||||
if (!args.isFsCaseSensitive() && args.isRenameCaseSensitive()) {
|
||||
Set<String> clsFullPaths = new HashSet<>(classes.size());
|
||||
for (ClassNode cls : classes) {
|
||||
ClassInfo clsInfo = cls.getClassInfo();
|
||||
@@ -69,12 +69,12 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkClassName(ClassNode cls) {
|
||||
private void checkClassName(ClassNode cls, JadxArgs args) {
|
||||
ClassInfo classInfo = cls.getClassInfo();
|
||||
ClassInfo alias = classInfo.getAlias();
|
||||
String clsName = alias.getShortName();
|
||||
|
||||
String newShortName = fixClsShortName(clsName);
|
||||
String newShortName = fixClsShortName(args, clsName);
|
||||
if (!newShortName.equals(clsName)) {
|
||||
classInfo.rename(cls.root(), alias.makeFullClsName(newShortName, true));
|
||||
alias = classInfo.getAlias();
|
||||
@@ -86,35 +86,42 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private String fixClsShortName(String clsName) {
|
||||
private String fixClsShortName(JadxArgs args, String clsName) {
|
||||
char firstChar = clsName.charAt(0);
|
||||
if (Character.isDigit(firstChar)) {
|
||||
boolean renameValid = args.isRenameValid();
|
||||
if (Character.isDigit(firstChar) && renameValid) {
|
||||
return Consts.ANONYMOUS_CLASS_PREFIX + NameMapper.removeInvalidCharsMiddle(clsName);
|
||||
}
|
||||
if (firstChar == '$') {
|
||||
if (firstChar == '$' && renameValid) {
|
||||
return 'C' + NameMapper.removeInvalidCharsMiddle(clsName);
|
||||
}
|
||||
String cleanClsName = NameMapper.removeInvalidChars(clsName, "C");
|
||||
if (!NameMapper.isValidIdentifier(cleanClsName)) {
|
||||
String cleanClsName = args.isRenamePrintable()
|
||||
? NameMapper.removeInvalidChars(clsName, "C")
|
||||
: clsName;
|
||||
if (renameValid && !NameMapper.isValidIdentifier(cleanClsName)) {
|
||||
return 'C' + cleanClsName;
|
||||
}
|
||||
return cleanClsName;
|
||||
}
|
||||
|
||||
private void checkFields(ClassNode cls) {
|
||||
private void checkFields(ClassNode cls, JadxArgs args) {
|
||||
Set<String> names = new HashSet<>();
|
||||
for (FieldNode field : cls.getFields()) {
|
||||
FieldInfo fieldInfo = field.getFieldInfo();
|
||||
String fieldName = fieldInfo.getAlias();
|
||||
if (!names.add(fieldName) || !NameMapper.isValidIdentifier(fieldName)) {
|
||||
if (!names.add(fieldName)
|
||||
|| (args.isRenameValid() && !NameMapper.isValidIdentifier(fieldName))
|
||||
|| (args.isRenamePrintable() && !NameMapper.isAllCharsPrintable(fieldName))) {
|
||||
deobfuscator.forceRenameField(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkMethods(ClassNode cls) {
|
||||
private void checkMethods(ClassNode cls, JadxArgs args) {
|
||||
for (MethodNode mth : cls.getMethods()) {
|
||||
if (!NameMapper.isValidIdentifier(mth.getAlias())) {
|
||||
String alias = mth.getAlias();
|
||||
if (args.isRenameValid() && !NameMapper.isValidIdentifier(alias)
|
||||
|| (args.isRenamePrintable() && !NameMapper.isAllCharsPrintable(alias))) {
|
||||
deobfuscator.forceRenameMethod(mth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,45 @@
|
||||
package jadx.gui.settings;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import say.swing.JFontChooser;
|
||||
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.codearea.EditorTheme;
|
||||
import jadx.gui.utils.LangLocale;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.Utils;
|
||||
import say.swing.JFontChooser;
|
||||
|
||||
public class JadxSettingsWindow extends JDialog {
|
||||
private static final long serialVersionUID = -1804570470377354148L;
|
||||
@@ -51,6 +74,7 @@ public class JadxSettingsWindow extends JDialog {
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
panel.add(makeDeobfuscationGroup());
|
||||
panel.add(makeRenameGroup());
|
||||
panel.add(makeDecompilationGroup());
|
||||
panel.add(makeProjectGroup());
|
||||
panel.add(makeEditorGroup());
|
||||
@@ -165,6 +189,35 @@ public class JadxSettingsWindow extends JDialog {
|
||||
return deobfGroup;
|
||||
}
|
||||
|
||||
private SettingsGroup makeRenameGroup() {
|
||||
JCheckBox renameCaseSensitive = new JCheckBox();
|
||||
renameCaseSensitive.setSelected(settings.isRenameCaseSensitive());
|
||||
renameCaseSensitive.addItemListener(e -> {
|
||||
settings.setRenameCaseSensitive(e.getStateChange() == ItemEvent.SELECTED);
|
||||
needReload();
|
||||
});
|
||||
|
||||
JCheckBox renameValid = new JCheckBox();
|
||||
renameValid.setSelected(settings.isRenameValid());
|
||||
renameValid.addItemListener(e -> {
|
||||
settings.setRenameValid(e.getStateChange() == ItemEvent.SELECTED);
|
||||
needReload();
|
||||
});
|
||||
|
||||
JCheckBox renamePrintable = new JCheckBox();
|
||||
renamePrintable.setSelected(settings.isRenamePrintable());
|
||||
renamePrintable.addItemListener(e -> {
|
||||
settings.setRenamePrintable(e.getStateChange() == ItemEvent.SELECTED);
|
||||
needReload();
|
||||
});
|
||||
|
||||
SettingsGroup group = new SettingsGroup(NLS.str("preferences.rename"));
|
||||
group.addRow(NLS.str("preferences.rename_case"), renameCaseSensitive);
|
||||
group.addRow(NLS.str("preferences.rename_valid"), renameValid);
|
||||
group.addRow(NLS.str("preferences.rename_printable"), renamePrintable);
|
||||
return group;
|
||||
}
|
||||
|
||||
private void enableComponentList(Collection<JComponent> connectedComponents, boolean enabled) {
|
||||
connectedComponents.forEach(comp -> comp.setEnabled(enabled));
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ public class MainWindow extends JFrame {
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
closeWindow();
|
||||
}
|
||||
@@ -386,6 +387,16 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void saveAll(boolean export) {
|
||||
JadxArgs decompilerArgs = wrapper.getArgs();
|
||||
if ((!decompilerArgs.isFsCaseSensitive() && !decompilerArgs.isRenameCaseSensitive())
|
||||
|| !decompilerArgs.isRenameValid() || !decompilerArgs.isRenamePrintable()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this,
|
||||
NLS.str("msg.rename_disabled", settings.getLangLocale()),
|
||||
NLS.str("msg.rename_disabled_title", settings.getLangLocale()),
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
}
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
fileChooser.setToolTipText(NLS.str("file.save_all_msg"));
|
||||
@@ -397,7 +408,6 @@ public class MainWindow extends JFrame {
|
||||
|
||||
int ret = fileChooser.showSaveDialog(mainPanel);
|
||||
if (ret == JFileChooser.APPROVE_OPTION) {
|
||||
JadxArgs decompilerArgs = wrapper.getArgs();
|
||||
decompilerArgs.setExportAsGradleProject(export);
|
||||
if (export) {
|
||||
decompilerArgs.setSkipSources(false);
|
||||
|
||||
@@ -113,6 +113,10 @@ preferences.cancel=Cancel
|
||||
preferences.reset=Reset
|
||||
preferences.reset_message=Reset settings to default values?
|
||||
preferences.reset_title=Reset settings
|
||||
preferences.rename=Rename
|
||||
preferences.rename_case=System case sensitivity
|
||||
preferences.rename_valid=To be valid identifier
|
||||
preferences.rename_printable=To be printable
|
||||
|
||||
msg.open_file=Please open file
|
||||
msg.saving_sources=Saving sources...
|
||||
@@ -121,6 +125,8 @@ msg.language_changed=New language will be displayed the next time application st
|
||||
msg.index_not_initialized=Index not initialized, search will be disabled!
|
||||
msg.project_error_title=Error
|
||||
msg.project_error=Project could not be loaded
|
||||
msg.rename_disabled_title=Rename disabled
|
||||
msg.rename_disabled=Some of rename settings are disabled, please take this into consideration
|
||||
|
||||
popup.undo=Undo
|
||||
popup.redo=Redo
|
||||
|
||||
@@ -113,6 +113,10 @@ preferences.cancel=Cancelar
|
||||
preferences.reset=Reestablecer
|
||||
preferences.reset_message=¿Reestablecer preferencias a valores por defecto?
|
||||
preferences.reset_title=Reestablecer preferencias
|
||||
#preferences.rename=
|
||||
#preferences.rename_case=
|
||||
#preferences.rename_valid=
|
||||
#preferences.rename_printable=
|
||||
|
||||
msg.open_file=Por favor, abra un archivo
|
||||
msg.saving_sources=Guardando fuente...
|
||||
@@ -121,6 +125,8 @@ msg.language_changed=El nuevo idioma se mostrará la próxima vez que la aplicac
|
||||
msg.index_not_initialized=Índice no inicializado, ¡la bósqueda se desactivará!
|
||||
#msg.project_error_title=
|
||||
#msg.project_error=
|
||||
#msg.rename_disabled_title=
|
||||
#msg.rename_disabled=
|
||||
|
||||
popup.undo=Deshacer
|
||||
popup.redo=Rehacer
|
||||
|
||||
@@ -113,6 +113,10 @@ preferences.cancel=取消
|
||||
preferences.reset=重置
|
||||
preferences.reset_message=要恢复默认设置吗?
|
||||
preferences.reset_title=重置设置
|
||||
#preferences.rename=
|
||||
#preferences.rename_case=
|
||||
#preferences.rename_valid=
|
||||
#preferences.rename_printable=
|
||||
|
||||
msg.open_file=请打开文件
|
||||
msg.saving_sources=正在导出源代码...
|
||||
@@ -121,6 +125,8 @@ msg.language_changed=在下次启动时将会显示新的语言。
|
||||
msg.index_not_initialized=索引尚未初始化,无法进行搜索!
|
||||
#msg.project_error_title=
|
||||
#msg.project_error=
|
||||
#msg.rename_disabled_title=
|
||||
#msg.rename_disabled=
|
||||
|
||||
popup.undo=撤销
|
||||
popup.redo=重做
|
||||
|
||||
Reference in New Issue
Block a user