feat(gui): add export dialog with options (PR #2378)
fix(gui):add export dialog with options (#1983)
This commit is contained in:
@@ -12,8 +12,8 @@ import jadx.core.utils.files.FileUtils;
|
||||
import jadx.gui.logs.LogCollector;
|
||||
import jadx.gui.settings.JadxSettings;
|
||||
import jadx.gui.settings.JadxSettingsAdapter;
|
||||
import jadx.gui.ui.ExceptionDialog;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.dialog.ExceptionDialog;
|
||||
import jadx.gui.utils.LafManager;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.SystemInfo;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package jadx.gui.settings;
|
||||
|
||||
public class ExportProjectProperties {
|
||||
private boolean skipSources;
|
||||
private boolean skipResources;
|
||||
private boolean asGradleMode;
|
||||
private boolean useGradleKts;
|
||||
private String exportPath;
|
||||
|
||||
public ExportProjectProperties() {
|
||||
|
||||
}
|
||||
|
||||
public boolean isSkipSources() {
|
||||
return skipSources;
|
||||
}
|
||||
|
||||
public void setSkipSources(boolean skipSources) {
|
||||
this.skipSources = skipSources;
|
||||
}
|
||||
|
||||
public boolean isSkipResources() {
|
||||
return skipResources;
|
||||
}
|
||||
|
||||
public void setSkipResources(boolean skipResources) {
|
||||
this.skipResources = skipResources;
|
||||
}
|
||||
|
||||
public boolean isAsGradleMode() {
|
||||
return asGradleMode;
|
||||
}
|
||||
|
||||
public void setAsGradleMode(boolean asGradleMode) {
|
||||
this.asGradleMode = asGradleMode;
|
||||
}
|
||||
|
||||
public boolean isUseGradleKts() {
|
||||
return useGradleKts;
|
||||
}
|
||||
|
||||
public void setUseGradleKts(boolean useGradleKts) {
|
||||
this.useGradleKts = useGradleKts;
|
||||
}
|
||||
|
||||
public String getExportPath() {
|
||||
return exportPath;
|
||||
}
|
||||
|
||||
public void setExportPath(String exportPath) {
|
||||
this.exportPath = exportPath;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
@@ -107,6 +108,7 @@ import jadx.gui.logs.LogOptions;
|
||||
import jadx.gui.logs.LogPanel;
|
||||
import jadx.gui.plugins.mappings.RenameMappingsGui;
|
||||
import jadx.gui.plugins.quark.QuarkDialog;
|
||||
import jadx.gui.settings.ExportProjectProperties;
|
||||
import jadx.gui.settings.JadxProject;
|
||||
import jadx.gui.settings.JadxSettings;
|
||||
import jadx.gui.settings.ui.JadxSettingsWindow;
|
||||
@@ -126,6 +128,8 @@ import jadx.gui.ui.codearea.EditorTheme;
|
||||
import jadx.gui.ui.codearea.EditorViewState;
|
||||
import jadx.gui.ui.dialog.ADBDialog;
|
||||
import jadx.gui.ui.dialog.AboutDialog;
|
||||
import jadx.gui.ui.dialog.ExceptionDialog;
|
||||
import jadx.gui.ui.dialog.ExportProjectDialog;
|
||||
import jadx.gui.ui.dialog.LogViewerDialog;
|
||||
import jadx.gui.ui.dialog.SearchDialog;
|
||||
import jadx.gui.ui.filedialog.FileDialogWrapper;
|
||||
@@ -160,7 +164,7 @@ import jadx.gui.utils.shortcut.ShortcutsController;
|
||||
import jadx.gui.utils.ui.ActionHandler;
|
||||
import jadx.gui.utils.ui.NodeLabel;
|
||||
|
||||
public class MainWindow extends JFrame {
|
||||
public class MainWindow extends JFrame implements ExportProjectDialog.ExportProjectDialogListener {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainWindow.class);
|
||||
|
||||
private static final String DEFAULT_TITLE = "jadx-gui";
|
||||
@@ -798,23 +802,23 @@ public class MainWindow extends JFrame {
|
||||
backgroundExecutor.cancelAll();
|
||||
}
|
||||
|
||||
private void saveAll(boolean export) {
|
||||
FileDialogWrapper fileDialog = new FileDialogWrapper(this, FileOpenMode.EXPORT);
|
||||
List<Path> saveDirs = fileDialog.show();
|
||||
if (saveDirs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
private void exportProject() {
|
||||
ExportProjectDialog dialog = new ExportProjectDialog(this, this);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
private void saveAll(ExportProjectProperties exportProjectProperties) {
|
||||
JadxArgs decompilerArgs = wrapper.getArgs();
|
||||
decompilerArgs.setExportAsGradleProject(export);
|
||||
if (export) {
|
||||
decompilerArgs.setExportAsGradleProject(exportProjectProperties.isAsGradleMode());
|
||||
if (exportProjectProperties.isAsGradleMode()) {
|
||||
decompilerArgs.setSkipSources(false);
|
||||
decompilerArgs.setSkipResources(false);
|
||||
} else {
|
||||
decompilerArgs.setSkipSources(settings.isSkipSources());
|
||||
decompilerArgs.setSkipResources(settings.isSkipResources());
|
||||
decompilerArgs.setSkipSources(exportProjectProperties.isSkipSources());
|
||||
decompilerArgs.setSkipResources(exportProjectProperties.isSkipResources());
|
||||
}
|
||||
settings.setLastSaveFilePath(fileDialog.getCurrentDir());
|
||||
backgroundExecutor.execute(new ExportTask(this, wrapper, saveDirs.get(0).toFile()));
|
||||
|
||||
backgroundExecutor.execute(new ExportTask(this, wrapper, new File(exportProjectProperties.getExportPath())));
|
||||
}
|
||||
|
||||
public void initTree() {
|
||||
@@ -1069,8 +1073,7 @@ public class MainWindow extends JFrame {
|
||||
liveReloadMenuItem = new JCheckBoxMenuItem(liveReloadAction);
|
||||
liveReloadMenuItem.setState(project.isEnableLiveReload());
|
||||
|
||||
JadxGuiAction saveAllAction = new JadxGuiAction(ActionModel.SAVE_ALL, () -> saveAll(false));
|
||||
JadxGuiAction exportAction = new JadxGuiAction(ActionModel.EXPORT, () -> saveAll(true));
|
||||
JadxGuiAction exportAction = new JadxGuiAction(ActionModel.EXPORT, this::exportProject);
|
||||
|
||||
JMenu recentProjects = new JadxMenu(NLS.str("menu.recent_projects"), shortcutsController);
|
||||
recentProjects.addMenuListener(new RecentProjectsMenuListener(this, recentProjects));
|
||||
@@ -1161,7 +1164,6 @@ public class MainWindow extends JFrame {
|
||||
file.add(liveReloadMenuItem);
|
||||
renameMappings.addMenuActions(file);
|
||||
file.addSeparator();
|
||||
file.add(saveAllAction);
|
||||
file.add(exportAction);
|
||||
file.addSeparator();
|
||||
file.add(recentProjects);
|
||||
@@ -1245,7 +1247,6 @@ public class MainWindow extends JFrame {
|
||||
toolbar.addSeparator();
|
||||
toolbar.add(reloadAction);
|
||||
toolbar.addSeparator();
|
||||
toolbar.add(saveAllAction);
|
||||
toolbar.add(exportAction);
|
||||
toolbar.addSeparator();
|
||||
toolbar.add(syncAction);
|
||||
@@ -1292,7 +1293,6 @@ public class MainWindow extends JFrame {
|
||||
forwardAction.setEnabled(loaded);
|
||||
forwardVariantAction.setEnabled(loaded);
|
||||
syncAction.setEnabled(loaded);
|
||||
saveAllAction.setEnabled(loaded);
|
||||
exportAction.setEnabled(loaded);
|
||||
saveProjectAsAction.setEnabled(loaded);
|
||||
reloadAction.setEnabled(loaded);
|
||||
@@ -1790,4 +1790,9 @@ public class MainWindow extends JFrame {
|
||||
public JadxGuiEventsImpl events() {
|
||||
return events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProjectExportCalled(ExportProjectProperties exportProjectProperties) {
|
||||
saveAll(exportProjectProperties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public enum ActionModel {
|
||||
Shortcut.keyboard(KeyEvent.VK_F5, InputEvent.SHIFT_DOWN_MASK)),
|
||||
SAVE_ALL(MENU_TOOLBAR, "file.save_all", "file.save_all", "ui/menu-saveall",
|
||||
Shortcut.keyboard(KeyEvent.VK_E, UiUtils.ctrlButton())),
|
||||
EXPORT(MENU_TOOLBAR, "file.export_gradle", "file.export_gradle", "ui/export",
|
||||
EXPORT(MENU_TOOLBAR, "file.export", "file.export", "ui/export",
|
||||
Shortcut.keyboard(KeyEvent.VK_E, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)),
|
||||
PREFS(MENU_TOOLBAR, "menu.preferences", "menu.preferences", "ui/settings",
|
||||
Shortcut.keyboard(KeyEvent.VK_P, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)),
|
||||
|
||||
+6
-7
@@ -1,4 +1,4 @@
|
||||
package jadx.gui.ui;
|
||||
package jadx.gui.ui.dialog;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
@@ -18,7 +18,6 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
@@ -46,7 +45,7 @@ public class ExceptionDialog extends JDialog {
|
||||
private static final String FMT_DETAIL_LENGTH = "-13";
|
||||
|
||||
public static void registerUncaughtExceptionHandler() {
|
||||
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> showExceptionDialog(thread, ex));
|
||||
Thread.setDefaultUncaughtExceptionHandler(ExceptionDialog::showExceptionDialog);
|
||||
}
|
||||
|
||||
public static void showExceptionDialog(Thread thread, Throwable ex) {
|
||||
@@ -78,7 +77,7 @@ public class ExceptionDialog extends JDialog {
|
||||
try {
|
||||
// TODO: Use ProcessHandle.current().info().commandLine() once min Java is 9+
|
||||
List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
|
||||
details.put("Program args", args.stream().collect(Collectors.joining(" ")));
|
||||
details.put("Program args", String.join(" ", args));
|
||||
} catch (Throwable t) {
|
||||
LOG.error("failed to get program arguments", t);
|
||||
}
|
||||
@@ -89,7 +88,7 @@ public class ExceptionDialog extends JDialog {
|
||||
|
||||
String issueTitle;
|
||||
try {
|
||||
issueTitle = URLEncoder.encode(ex.toString(), StandardCharsets.UTF_8.toString());
|
||||
issueTitle = URLEncoder.encode(ex.toString(), StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
LOG.error("URL encoding of title failed", e);
|
||||
issueTitle = ex.getClass().getSimpleName();
|
||||
@@ -105,7 +104,7 @@ public class ExceptionDialog extends JDialog {
|
||||
|
||||
String issueBody;
|
||||
try {
|
||||
issueBody = URLEncoder.encode(body, StandardCharsets.UTF_8.toString());
|
||||
issueBody = URLEncoder.encode(body, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
LOG.error("URL encoding of body failed", e);
|
||||
issueBody = "Please copy the displayed text in the Jadx error dialog and paste it here";
|
||||
@@ -126,7 +125,7 @@ public class ExceptionDialog extends JDialog {
|
||||
StringBuilder detailsTextBuilder = new StringBuilder();
|
||||
details.forEach((key, value) -> detailsTextBuilder.append(String.format("%" + FMT_DETAIL_LENGTH + "s: %s\n", key, value)));
|
||||
|
||||
messageArea.setText(detailsTextBuilder.toString() + "\n" + stackTrace);
|
||||
messageArea.setText(detailsTextBuilder + "\n" + stackTrace);
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
JButton exitButton = new JButton("Terminate Jadx");
|
||||
@@ -0,0 +1,207 @@
|
||||
package jadx.gui.ui.dialog;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.gui.settings.ExportProjectProperties;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.filedialog.FileDialogWrapper;
|
||||
import jadx.gui.ui.filedialog.FileOpenMode;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.TextStandardActions;
|
||||
import jadx.gui.utils.ui.DocumentUpdateListener;
|
||||
|
||||
public class ExportProjectDialog extends JDialog {
|
||||
|
||||
public interface ExportProjectDialogListener {
|
||||
void onProjectExportCalled(ExportProjectProperties exportProjectProperties);
|
||||
}
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExportProjectDialog.class);
|
||||
private final ExportProjectDialogListener exportProjectDialogListener;
|
||||
private final ExportProjectProperties exportProjectProperties = new ExportProjectProperties();
|
||||
private final MainWindow mainWindow;
|
||||
private JTextField pathField;
|
||||
|
||||
public ExportProjectDialog(MainWindow mainWindow, ExportProjectDialogListener exportProjectDialogListener) {
|
||||
super(mainWindow);
|
||||
this.mainWindow = mainWindow;
|
||||
this.exportProjectDialogListener = exportProjectDialogListener;
|
||||
initUI();
|
||||
}
|
||||
|
||||
private void initUI() {
|
||||
|
||||
JPanel contentPane = makeContentPane();
|
||||
|
||||
JPanel buttonPane = initButtonsPanel();
|
||||
|
||||
Container container = getContentPane();
|
||||
// contentPane.add(topPanel, BorderLayout.NORTH);
|
||||
container.add(contentPane, BorderLayout.CENTER);
|
||||
container.add(buttonPane, BorderLayout.PAGE_END);
|
||||
|
||||
setTitle(NLS.str("export_dialog.title"));
|
||||
|
||||
pack();
|
||||
setSize(400, 250);
|
||||
setLocationRelativeTo(mainWindow);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setModalityType(ModalityType.MODELESS);
|
||||
}
|
||||
|
||||
private JPanel makeContentPane() {
|
||||
|
||||
JPanel mainPanel = new JPanel();
|
||||
|
||||
// top layout
|
||||
JLabel label = new JLabel(NLS.str("export_dialog.save_path"));
|
||||
JTextField pathField = new JTextField();
|
||||
pathField.setText(mainWindow.getSettings().getLastSaveFilePath().toString());
|
||||
pathField.getDocument().addDocumentListener(new DocumentUpdateListener(ev -> setExportProjectPath(pathField)));
|
||||
new TextStandardActions(pathField);
|
||||
|
||||
JButton browseButton = makeEditorBrowseButton(pathField);
|
||||
|
||||
// check box layout
|
||||
JPanel exportOptionsPanel = new JPanel();
|
||||
exportOptionsPanel.setBorder(BorderFactory.createTitledBorder(NLS.str("export_dialog.export_options")));
|
||||
exportOptionsPanel.setLayout(new BoxLayout(exportOptionsPanel, BoxLayout.PAGE_AXIS));
|
||||
|
||||
JCheckBox resourceDecode = new JCheckBox(NLS.str("preferences.skipResourcesDecode"));
|
||||
resourceDecode.setSelected(mainWindow.getSettings().isSkipResources());
|
||||
resourceDecode.addItemListener(e -> {
|
||||
exportProjectProperties.setSkipResources(e.getStateChange() == ItemEvent.SELECTED);
|
||||
});
|
||||
|
||||
JCheckBox skipSources = new JCheckBox(NLS.str("preferences.skipSourcesDecode"));
|
||||
skipSources.setSelected(mainWindow.getSettings().isSkipSources());
|
||||
skipSources.addItemListener(e -> {
|
||||
exportProjectProperties.setSkipSources(e.getStateChange() == ItemEvent.SELECTED);
|
||||
});
|
||||
|
||||
JCheckBox exportAsGradleProject = new JCheckBox(NLS.str("export_dialog.export_gradle"));
|
||||
exportAsGradleProject.addItemListener(e -> {
|
||||
boolean isSelected = e.getStateChange() == ItemEvent.SELECTED;
|
||||
|
||||
exportProjectProperties.setAsGradleMode(isSelected);
|
||||
resourceDecode.setEnabled(!isSelected);
|
||||
skipSources.setEnabled(!isSelected);
|
||||
});
|
||||
|
||||
exportOptionsPanel.add(resourceDecode);
|
||||
exportOptionsPanel.add(skipSources);
|
||||
exportOptionsPanel.add(exportAsGradleProject);
|
||||
|
||||
// build group box layout
|
||||
JPanel groupBoxPanel = new JPanel();
|
||||
GroupLayout groupBoxLayout = new GroupLayout(groupBoxPanel);
|
||||
groupBoxLayout.setAutoCreateGaps(true);
|
||||
groupBoxLayout.setAutoCreateContainerGaps(true);
|
||||
groupBoxPanel.setLayout(groupBoxLayout);
|
||||
|
||||
groupBoxLayout.setHorizontalGroup(groupBoxLayout.createParallelGroup()
|
||||
.addComponent(exportOptionsPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Integer.MAX_VALUE));
|
||||
groupBoxLayout.setVerticalGroup(groupBoxLayout.createSequentialGroup()
|
||||
.addComponent(exportOptionsPanel));
|
||||
|
||||
// main layout
|
||||
GroupLayout layout = new GroupLayout(mainPanel);
|
||||
mainPanel.setLayout(layout);
|
||||
layout.setAutoCreateGaps(true);
|
||||
layout.setAutoCreateContainerGaps(true);
|
||||
|
||||
// arrange components using GroupLayout
|
||||
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(label)
|
||||
.addComponent(pathField)
|
||||
.addComponent(browseButton))
|
||||
.addComponent(groupBoxPanel));
|
||||
|
||||
layout.setVerticalGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(label)
|
||||
.addComponent(pathField)
|
||||
.addComponent(browseButton))
|
||||
.addComponent(groupBoxPanel));
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private void setExportProjectPath(JTextField field) {
|
||||
String path = field.getText();
|
||||
if (!path.isEmpty()) {
|
||||
exportProjectProperties.setExportPath(field.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected JPanel initButtonsPanel() {
|
||||
|
||||
JButton cancelButton = new JButton(NLS.str("common_dialog.cancel"));
|
||||
cancelButton.addActionListener(event -> dispose());
|
||||
|
||||
JButton exportProjectButton = new JButton(NLS.str("common_dialog.ok"));
|
||||
exportProjectButton.addActionListener(event -> exportProject());
|
||||
getRootPane().setDefaultButton(exportProjectButton);
|
||||
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
|
||||
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
buttonPane.add(Box.createHorizontalGlue());
|
||||
buttonPane.add(exportProjectButton);
|
||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
buttonPane.add(cancelButton);
|
||||
return buttonPane;
|
||||
}
|
||||
|
||||
private JButton makeEditorBrowseButton(final JTextField textField) {
|
||||
JButton button = new JButton(NLS.str("export_dialog.browse"));
|
||||
button.addActionListener(e -> {
|
||||
FileDialogWrapper fileDialog = new FileDialogWrapper(mainWindow, FileOpenMode.EXPORT);
|
||||
mainWindow.getSettings().setLastSaveFilePath(fileDialog.getCurrentDir());
|
||||
List<Path> saveDirs = fileDialog.show();
|
||||
if (saveDirs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String path = saveDirs.get(0).toString();
|
||||
textField.setText(path);
|
||||
});
|
||||
return button;
|
||||
}
|
||||
|
||||
private void exportProject() {
|
||||
if (!new File(exportProjectProperties.getExportPath()).exists()) {
|
||||
JOptionPane.showMessageDialog(this, NLS.str("message.enter_valid_path"),
|
||||
NLS.str("message.errorTitle"), JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
exportProjectDialogListener.onProjectExportCalled(exportProjectProperties);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@ file.live_reload_desc=Dateien bei Änderungen autom. neuladen
|
||||
#file.close_mappings=Zuordnungen exportieren als…
|
||||
file.save_all=Alles speichern
|
||||
#file.save=Save
|
||||
file.export_gradle=Als Gradle-Projekt speichern
|
||||
#file.export=Export project
|
||||
file.save_all_msg=Verzeichnis für das Speichern dekompilierter Ressourcen auswählen
|
||||
file.exit=Beenden
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=Die Aufgabe ist durch Fehler fehlgeschlagen (siehe Protokoll f
|
||||
message.errorTitle=Fehler
|
||||
message.load_errors=Laden fehlgeschlagen.\nAnzahl der Fehler: %d\nKlicke auf OK, um die Log-Ansicht zu öffnen.
|
||||
message.no_classes=Keine Klassen geladen, nichts zu dekompilieren!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>Speichern unvollständig.<br> %s<br> %d Klassen oder Ressourcen wurden nicht gespeichert!</html>
|
||||
message.indexIncomplete=<html>Index einiger Klassen übersprungen.<br> %s<br> %d Klassen wurden nicht indiziert und werden nicht in den Suchergebnissen erscheinen!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Shift + Enter verwenden, um eine neue Zeile zu beginnen
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Log-Anzeige
|
||||
log_viewer.log_level=Log-Level:
|
||||
#log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.inlineMethods=Inline-Methoden
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=Dateisystem unterscheidet zwischen Groß/Kleinschreibung
|
||||
preferences.skipResourcesDecode=Keine Ressourcen dekodieren
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=Kotlin-Methoden für die Umbenennung von Variablen verwenden
|
||||
preferences.commentsLevel=Level der Code Kommentierungen
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings_as=Save mappings as...
|
||||
file.close_mappings=Close mappings
|
||||
file.save_all=Save all
|
||||
file.save=Save
|
||||
file.export_gradle=Save as gradle project
|
||||
file.export=Export project
|
||||
file.save_all_msg=Select directory for save decompiled sources
|
||||
file.exit=Exit
|
||||
file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=Task failed with error (check log for details).
|
||||
message.errorTitle=Error
|
||||
message.load_errors=Load failed.\nErrors count: %d\nClick OK to open log viewer.
|
||||
message.no_classes=No classes loaded, nothing to decompile!
|
||||
message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>Save incomplete.<br> %s<br> %d classes or resources were not saved!</html>
|
||||
message.indexIncomplete=<html>Index of some classes skipped.<br> %s<br> %d classes were not indexed and will not appear in search results!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Use 'Shift + Enter' to start a new line
|
||||
|
||||
rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
export_dialog.title=Export to source code
|
||||
export_dialog.save_path=Save path:
|
||||
export_dialog.browse=Browse
|
||||
export_dialog.export_options=Export options
|
||||
export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Log Viewer
|
||||
log_viewer.log_level=Log level:
|
||||
log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=Extract finally block
|
||||
preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=File system is case-sensitive
|
||||
preferences.skipResourcesDecode=Don't decode resources
|
||||
preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=Use kotlin methods for variables rename
|
||||
preferences.commentsLevel=Code comments level
|
||||
preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.open_title=Abrir archivo
|
||||
#file.close_mappings=Close mappings
|
||||
file.save_all=Guardar todo
|
||||
#file.save=Save
|
||||
file.export_gradle=Guardar como proyecto Gradle
|
||||
#file.export=Export project
|
||||
file.save_all_msg=Seleccionar carpeta para guardar fuentes descompiladas
|
||||
file.exit=Salir
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ nav.forward=Adelante
|
||||
#message.errorTitle=Error
|
||||
#message.load_errors=Load failed.\nErrors count: %d\nClick OK to open log viewer.
|
||||
#message.no_classes=No classes loaded, nothing to decompile!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
#message.saveIncomplete=<html>Save incomplete.<br> %s<br> %d classes or resources were not saved!</html>
|
||||
#message.indexIncomplete=<html>Index of some classes skipped.<br> %s<br> %d classes were not indexed and will not appear in search results!</html>
|
||||
@@ -170,6 +171,12 @@ usage_dialog.label=Usage for:
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Visor log
|
||||
log_viewer.log_level=Nivel log:
|
||||
#log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.replaceConsts=Reemplazar constantes
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
#preferences.fsCaseSensitive=File system is case-sensitive
|
||||
preferences.skipResourcesDecode=No descodificar recursos
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
#preferences.useKotlinMethodsForVarNames=Use kotlin methods for variables rename
|
||||
#preferences.commentsLevel=Code comments level
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings_as=Simpan pemetaan sebagai...
|
||||
file.close_mappings=Tutup pemetaan
|
||||
file.save_all=Simpan semua
|
||||
file.save=Simpan
|
||||
file.export_gradle=Simpan sebagai proyek gradle
|
||||
#file.export=Export project
|
||||
file.save_all_msg=Pilih direktori untuk menyimpan sumber yang telah didekompilasi
|
||||
file.exit=Keluar
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=Tugas gagal dengan kesalahan (periksa log untuk detailnya).
|
||||
message.errorTitle=Kesalahan
|
||||
message.load_errors=Pemuatan gagal.\nJumlah kesalahan: %d\nKlik OK untuk membuka penampil log.
|
||||
message.no_classes=Tidak ada kelas yang dimuat, tidak ada yang dapat didekompilasi!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>Simpan tidak lengkap.<br> %s<br> %d kelas atau sumber daya tidak disimpan!</html>
|
||||
message.indexIncomplete=<html>Indeks beberapa kelas dilewati.<br> %s<br> %d kelas tidak diindeks dan tidak akan muncul dalam hasil pencarian!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Gunakan Shift + Enter untuk memulai baris baru
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Pemantau Log
|
||||
log_viewer.log_level=Tingkat log:
|
||||
log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=Ekstrak blok finally
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=File sistem bersifat sensitif huruf besar-kecil
|
||||
preferences.skipResourcesDecode=Jangan dekode sumber daya
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=Gunakan metode Kotlin untuk mengganti nama variabel
|
||||
preferences.commentsLevel=Tingkat komentar kode
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings=다른 이름으로 매핑 내보내기...
|
||||
#file.close_mappings=다른 이름으로 매핑 내보내기...
|
||||
file.save_all=모두 저장
|
||||
#file.save=Save
|
||||
file.export_gradle=Gradle 프로젝트로 저장
|
||||
#file.export=Export project
|
||||
file.save_all_msg=디컴파일된 소스를 저장할 디렉토리 선택
|
||||
file.exit=나가기
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=작업이 오류로 실패했습니다. (자세한 내용은
|
||||
message.errorTitle=오류
|
||||
message.load_errors=로드하지 못했습니다.\n오류 수: %d\n로그 뷰어를 열려면 확인을 클릭하십시오.
|
||||
message.no_classes=로드된 클래스 없음, 디컴파일 대상 존재하지 않음
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>저장이 완료되지 않았습니다.<br> %s<br> %d개의 클래스 또는 리소스가 저장되지 않았습니다!</html>
|
||||
message.indexIncomplete=<html>일부 클래스의 색인을 건너뛰었습니다.<br> %s<br> %d개의 클래스는 색인이 생성되지 않았으며 검색 결과에 나타나지 않습니다.</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Shift + Enter 를 입력해 새 라인에 입력
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=로그 뷰어
|
||||
log_viewer.log_level=로그 레벨:
|
||||
#log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=finally 블록 추출
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=파일 시스템 대소문자 구별
|
||||
preferences.skipResourcesDecode=리소스 디코딩 하지 않기
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=변수 이름 바꾸기에 kotlin 메서드 사용
|
||||
preferences.commentsLevel=코드 주석 수준
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.live_reload_desc=Recarregar arquivos automaticamente ao serem alterados
|
||||
#file.close_mappings=Close mappings
|
||||
file.save_all=Salvar tudo
|
||||
#file.save=Save
|
||||
file.export_gradle=Salvar como um projeto gradle
|
||||
#file.export=Export project
|
||||
file.save_all_msg=Selecionar diretório para salvar arquivos descompilados
|
||||
file.exit=Sair
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=Tarefa falhou com erro (cheque o log para detalhes).
|
||||
message.errorTitle=Erro
|
||||
message.load_errors=Carregamento falhou.\nNúmero de erros: %d\nClique em ok para abrir o visualizador de log.
|
||||
message.no_classes=Nenhuma classe carregada, nada para ser descompilado!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>Operação não foi completa.<br> %s<br> %d classes ou recursos não foram salvos!</html>
|
||||
message.indexIncomplete=<html>Indexação de algumas classes foram ignoradas.<br> %s<br> %d classes não foram indexadas não vão aparecer nos resultados de busca!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Use Shift + Enter para pular uma linha
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Visualizador de log
|
||||
log_viewer.log_level=Nível do log:
|
||||
#log_viewer.mode=Mode:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=Extrair blocos finally
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=Sistema de arquivo diferencia maiúsculas de minúsculas
|
||||
preferences.skipResourcesDecode=Não decodificar recursos
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=Usar métodos do kotlin para renomear variáveis
|
||||
preferences.commentsLevel=Nível de comentários do código
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings_as=Сохранить маппинги как...
|
||||
file.close_mappings=Закрыть маппинги
|
||||
file.save_all=Сохранить все
|
||||
file.save=Сохранить
|
||||
file.export_gradle=Сохранить как Gradle проект
|
||||
#file.export=Export project
|
||||
file.save_all_msg=Выбрать папку для декомпилированных проектов
|
||||
file.exit=Выход
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=Выполнение задачи закончено с оши
|
||||
message.errorTitle=Ошибка
|
||||
message.load_errors=Ошибка прогрузки.\nКоличество ошибок: %d\nНажмите OK, чтобы открыть лог.
|
||||
message.no_classes=Классы не найдены, нечего декомпилировать!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>Сохранение не завершено.<br> %s<br> %d классов или ресурсов не сохранено!</html>
|
||||
message.indexIncomplete=<html>Индексирование некоторых классов пропущено.<br> %s<br> %d классов не индексировано, и не будет отображаться в результатах поиска!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=Используйте Shift + Enter для перенос
|
||||
|
||||
rename_dialog.class_help=Введите полный путь к пакету, в который вы хотите переместить этот класс. Введите '.' для перемещения в пакет по умолчанию (пустой) пакет
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=Просмотр логов
|
||||
log_viewer.log_level=Уровень лога:
|
||||
log_viewer.mode=Режим:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=Вычленять finally блоки
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=Учитывать регистр в файловой системе
|
||||
preferences.skipResourcesDecode=Не декодировать ресурсы
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=Kotlin методы как имена полей
|
||||
preferences.commentsLevel=Уровень лога операций
|
||||
preferences.saveOption=Автосохранение настроек
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings_as=映射另存为…
|
||||
file.close_mappings=关闭映射
|
||||
file.save_all=全部保存(伪代码)
|
||||
file.save=保存
|
||||
file.export_gradle=另存为 Gradle 项目
|
||||
#file.export=Export project
|
||||
file.save_all_msg=请选择保存反编译资源的目录
|
||||
file.exit=退出
|
||||
file.export_node=导出文件
|
||||
@@ -105,6 +105,7 @@ message.taskError=任务失败,出现错误(详情请查看日志)。
|
||||
message.errorTitle=错误
|
||||
message.load_errors=加载失败。\n错误数:%d\n点击确定查看日志
|
||||
message.no_classes=无类被加载,没什么可反编译!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>保存未完成。<br> %s<br> %d 类或资源未被保存!</html>
|
||||
message.indexIncomplete=<html>已跳过某些类索引。<br> %s<br> %d 类未被索引,不会出现在搜索结果中!</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=使用 Shift + Enter 换行
|
||||
|
||||
rename_dialog.class_help=输入包名全路径,将类移动到另一个包。以'.'开始则移到默认(空)包下。
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=日志查看器
|
||||
log_viewer.log_level=日志等级:
|
||||
log_viewer.mode=模式:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=提取finally块
|
||||
preferences.restoreSwitchOverString=恢复switch字符串
|
||||
preferences.fsCaseSensitive=文件系统区分大小写
|
||||
preferences.skipResourcesDecode=不反编译资源文件
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=使用Kotlin方法来重命名变量
|
||||
preferences.commentsLevel=代码注释等级
|
||||
preferences.saveOption=自动保存设置
|
||||
|
||||
@@ -45,7 +45,7 @@ file.save_mappings_as=儲存對映檔為...
|
||||
file.close_mappings=關閉對映檔
|
||||
file.save_all=全部儲存
|
||||
file.save=儲存
|
||||
file.export_gradle=另存為 gradle 專案
|
||||
#file.export=Export project
|
||||
file.save_all_msg=選擇儲存反編譯原始碼的路徑
|
||||
file.exit=離開
|
||||
#file.export_node=Export file
|
||||
@@ -105,6 +105,7 @@ message.taskError=工作發生錯誤 (查看記錄檔以了解詳情)。
|
||||
message.errorTitle=錯誤
|
||||
message.load_errors=載入失敗。\n錯誤數:%d\n點擊 OK 以開啟記錄檔檢視器
|
||||
message.no_classes=未載入任何類別,沒有東西可以反編譯!
|
||||
#message.enter_valid_path=Enter valid path to save!
|
||||
|
||||
message.saveIncomplete=<html>儲存未完成。<br> %s<br> %d 個類別或資源尚未儲存!</html>
|
||||
message.indexIncomplete=<html>某些類別的索引被略過。<br> %s<br> %d 個類別未被索引,故不會出現在搜尋結果中。</html>
|
||||
@@ -170,6 +171,12 @@ comment_dialog.usage=按下 Shift + Enter 來換行
|
||||
|
||||
#rename_dialog.class_help=Enter full name to move class to another package. Start with '.' to move to default (empty) package
|
||||
|
||||
#export_dialog.title=Export to source code
|
||||
#export_dialog.save_path=Save path:
|
||||
#export_dialog.browse=Browse
|
||||
#export_dialog.export_options=Export options
|
||||
#export_dialog.export_gradle=Export as gradle project
|
||||
|
||||
log_viewer.title=記錄檔檢視器
|
||||
log_viewer.log_level=記錄層級:
|
||||
log_viewer.mode=模式:
|
||||
@@ -213,6 +220,7 @@ preferences.extractFinally=擷取 finally 區塊
|
||||
#preferences.restoreSwitchOverString=Restore switch over string
|
||||
preferences.fsCaseSensitive=檔案系統區分大小寫
|
||||
preferences.skipResourcesDecode=不要為資源解碼
|
||||
#preferences.skipSourcesDecode=Don't decompile source code
|
||||
preferences.useKotlinMethodsForVarNames=使用 Kotlin 方法來為變數重新命名
|
||||
preferences.commentsLevel=程式碼註解層級
|
||||
#preferences.saveOption=Auto-save settings
|
||||
|
||||
Reference in New Issue
Block a user