feat(gui): show start page on jadx open
This commit is contained in:
@@ -135,6 +135,9 @@ public class JadxProject {
|
||||
.map(TabStateViewAdapter::build)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
if (tabStateList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean dataChanged;
|
||||
dataChanged = data.setOpenTabs(tabStateList);
|
||||
dataChanged |= data.setActiveTab(activeTab);
|
||||
|
||||
@@ -210,6 +210,11 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
partialSync(settings -> settings.recentProjects = recentProjects);
|
||||
}
|
||||
|
||||
public void removeRecentProject(Path projectPath) {
|
||||
recentProjects.remove(projectPath);
|
||||
partialSync(settings -> settings.recentProjects = recentProjects);
|
||||
}
|
||||
|
||||
public void saveWindowPos(Window window) {
|
||||
WindowLocation pos = new WindowLocation(window.getClass().getSimpleName(), window.getBounds());
|
||||
windowPos.put(pos.getWindowId(), pos);
|
||||
|
||||
@@ -14,6 +14,7 @@ import jadx.api.JavaNode;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.gui.utils.Icons;
|
||||
import jadx.gui.utils.OverlayIcon;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
@@ -84,10 +85,10 @@ public class JMethod extends JNode {
|
||||
|
||||
OverlayIcon overIcon = new OverlayIcon(icon);
|
||||
if (accessFlags.isFinal()) {
|
||||
overIcon.add(UiUtils.ICON_FINAL);
|
||||
overIcon.add(Icons.FINAL);
|
||||
}
|
||||
if (accessFlags.isStatic()) {
|
||||
overIcon.add(UiUtils.ICON_STATIC);
|
||||
overIcon.add(Icons.STATIC);
|
||||
}
|
||||
|
||||
return overIcon;
|
||||
|
||||
@@ -125,12 +125,14 @@ import jadx.gui.ui.panel.IssuesPanel;
|
||||
import jadx.gui.ui.panel.JDebuggerPanel;
|
||||
import jadx.gui.ui.panel.ProgressPanel;
|
||||
import jadx.gui.ui.popupmenu.JPackagePopupMenu;
|
||||
import jadx.gui.ui.treenodes.StartPageNode;
|
||||
import jadx.gui.ui.treenodes.SummaryNode;
|
||||
import jadx.gui.update.JadxUpdate;
|
||||
import jadx.gui.update.JadxUpdate.IUpdateCallback;
|
||||
import jadx.gui.update.data.Release;
|
||||
import jadx.gui.utils.CacheObject;
|
||||
import jadx.gui.utils.FontUtils;
|
||||
import jadx.gui.utils.Icons;
|
||||
import jadx.gui.utils.LafManager;
|
||||
import jadx.gui.utils.Link;
|
||||
import jadx.gui.utils.NLS;
|
||||
@@ -152,7 +154,6 @@ public class MainWindow extends JFrame {
|
||||
private static final double WINDOW_RATIO = 1 - BORDER_RATIO * 2;
|
||||
public static final double SPLIT_PANE_RESIZE_WEIGHT = 0.15;
|
||||
|
||||
private static final ImageIcon ICON_OPEN = UiUtils.openSvgIcon("ui/openDisk");
|
||||
private static final ImageIcon ICON_ADD_FILES = UiUtils.openSvgIcon("ui/addFile");
|
||||
private static final ImageIcon ICON_SAVE_ALL = UiUtils.openSvgIcon("ui/menu-saveall");
|
||||
private static final ImageIcon ICON_RELOAD = UiUtils.openSvgIcon("ui/refresh");
|
||||
@@ -249,7 +250,7 @@ public class MainWindow extends JFrame {
|
||||
|
||||
private void processCommandLineArgs() {
|
||||
if (settings.getFiles().isEmpty()) {
|
||||
openFileOrProject();
|
||||
tabbedPane.showNode(new StartPageNode());
|
||||
} else {
|
||||
open(FileUtils.fileNamesToPaths(settings.getFiles()), this::handleSelectClassOption);
|
||||
}
|
||||
@@ -286,12 +287,20 @@ public class MainWindow extends JFrame {
|
||||
});
|
||||
}
|
||||
|
||||
public void openFileOrProject() {
|
||||
public void openFileDialog() {
|
||||
showOpenDialog(FileDialog.OpenMode.OPEN);
|
||||
}
|
||||
|
||||
public void openProjectDialog() {
|
||||
showOpenDialog(FileDialog.OpenMode.OPEN_PROJECT);
|
||||
}
|
||||
|
||||
private void showOpenDialog(FileDialog.OpenMode mode) {
|
||||
saveAll();
|
||||
if (!ensureProjectIsSaved()) {
|
||||
return;
|
||||
}
|
||||
FileDialog fileDialog = new FileDialog(this, FileDialog.OpenMode.OPEN);
|
||||
FileDialog fileDialog = new FileDialog(this, mode);
|
||||
List<Path> openPaths = fileDialog.show();
|
||||
if (!openPaths.isEmpty()) {
|
||||
settings.setLastOpenFilePath(fileDialog.getCurrentDir());
|
||||
@@ -313,6 +322,7 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void newProject() {
|
||||
saveAll();
|
||||
if (!ensureProjectIsSaved()) {
|
||||
return;
|
||||
}
|
||||
@@ -386,7 +396,11 @@ public class MainWindow extends JFrame {
|
||||
s -> update());
|
||||
}
|
||||
|
||||
void open(List<Path> paths) {
|
||||
public void open(Path path) {
|
||||
open(Collections.singletonList(path), EMPTY_RUNNABLE);
|
||||
}
|
||||
|
||||
public void open(List<Path> paths) {
|
||||
open(paths, EMPTY_RUNNABLE);
|
||||
}
|
||||
|
||||
@@ -825,14 +839,15 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void initMenuAndToolbar() {
|
||||
Action openAction = new AbstractAction(NLS.str("file.open_action"), ICON_OPEN) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
openFileOrProject();
|
||||
}
|
||||
};
|
||||
openAction.putValue(Action.SHORT_DESCRIPTION, NLS.str("file.open_action"));
|
||||
openAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_O, UiUtils.ctrlButton()));
|
||||
ActionHandler openAction = new ActionHandler(this::openFileDialog);
|
||||
openAction.setNameAndDesc(NLS.str("file.open_action"));
|
||||
openAction.setIcon(Icons.OPEN);
|
||||
openAction.setKeyBinding(getKeyStroke(KeyEvent.VK_O, UiUtils.ctrlButton()));
|
||||
|
||||
ActionHandler openProject = new ActionHandler(this::openProjectDialog);
|
||||
openProject.setNameAndDesc(NLS.str("file.open_project"));
|
||||
openProject.setIcon(Icons.OPEN_PROJECT);
|
||||
openProject.setKeyBinding(getKeyStroke(KeyEvent.VK_O, InputEvent.SHIFT_DOWN_MASK | UiUtils.ctrlButton()));
|
||||
|
||||
Action addFilesAction = new AbstractAction(NLS.str("file.add_files_action"), ICON_ADD_FILES) {
|
||||
@Override
|
||||
@@ -842,7 +857,7 @@ public class MainWindow extends JFrame {
|
||||
};
|
||||
addFilesAction.putValue(Action.SHORT_DESCRIPTION, NLS.str("file.add_files_action"));
|
||||
|
||||
newProjectAction = new AbstractAction(NLS.str("file.new_project")) {
|
||||
newProjectAction = new AbstractAction(NLS.str("file.new_project"), Icons.NEW_PROJECT) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
newProject();
|
||||
@@ -1089,6 +1104,7 @@ public class MainWindow extends JFrame {
|
||||
JMenu file = new JMenu(NLS.str("menu.file"));
|
||||
file.setMnemonic(KeyEvent.VK_F);
|
||||
file.add(openAction);
|
||||
file.add(openProject);
|
||||
file.add(addFilesAction);
|
||||
file.addSeparator();
|
||||
file.add(newProjectAction);
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
@@ -21,15 +20,13 @@ import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import jadx.gui.treemodel.JClass;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.ui.panel.ContentPanel;
|
||||
import jadx.gui.utils.Icons;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
public class TabComponent extends JPanel {
|
||||
private static final long serialVersionUID = -8147035487543610321L;
|
||||
|
||||
private static final ImageIcon ICON_CLOSE = UiUtils.openSvgIcon("ui/closeHovered");
|
||||
private static final ImageIcon ICON_CLOSE_INACTIVE = UiUtils.openSvgIcon("ui/close");
|
||||
|
||||
private final TabbedPane tabbedPane;
|
||||
private final ContentPanel contentPanel;
|
||||
|
||||
@@ -71,8 +68,8 @@ public class TabComponent extends JPanel {
|
||||
label.setIcon(node.getIcon());
|
||||
|
||||
final JButton closeBtn = new JButton();
|
||||
closeBtn.setIcon(ICON_CLOSE_INACTIVE);
|
||||
closeBtn.setRolloverIcon(ICON_CLOSE);
|
||||
closeBtn.setIcon(Icons.CLOSE_INACTIVE);
|
||||
closeBtn.setRolloverIcon(Icons.CLOSE);
|
||||
closeBtn.setRolloverEnabled(true);
|
||||
closeBtn.setOpaque(false);
|
||||
closeBtn.setUI(new BasicButtonUI());
|
||||
|
||||
@@ -29,6 +29,7 @@ public class FileDialog {
|
||||
|
||||
public enum OpenMode {
|
||||
OPEN,
|
||||
OPEN_PROJECT,
|
||||
ADD,
|
||||
SAVE_PROJECT,
|
||||
EXPORT,
|
||||
@@ -95,13 +96,19 @@ public class FileDialog {
|
||||
private void initForMode(OpenMode mode) {
|
||||
switch (mode) {
|
||||
case OPEN:
|
||||
case OPEN_PROJECT:
|
||||
case ADD:
|
||||
fileExtList = new ArrayList<>(Arrays.asList("apk", "dex", "jar", "class", "smali", "zip", "aar", "arsc"));
|
||||
if (mode == OpenMode.OPEN) {
|
||||
fileExtList.addAll(Arrays.asList(JadxProject.PROJECT_EXTENSION, "aab"));
|
||||
if (mode == OpenMode.OPEN_PROJECT) {
|
||||
fileExtList = Collections.singletonList(JadxProject.PROJECT_EXTENSION);
|
||||
title = NLS.str("file.open_title");
|
||||
} else {
|
||||
title = NLS.str("file.add_files_action");
|
||||
fileExtList = new ArrayList<>(Arrays.asList("apk", "dex", "jar", "class", "smali", "zip", "xapk", "aar", "arsc"));
|
||||
if (mode == OpenMode.OPEN) {
|
||||
fileExtList.addAll(Arrays.asList(JadxProject.PROJECT_EXTENSION, "aab"));
|
||||
title = NLS.str("file.open_title");
|
||||
} else {
|
||||
title = NLS.str("file.add_files_action");
|
||||
}
|
||||
}
|
||||
selectionMode = JFileChooser.FILES_AND_DIRECTORIES;
|
||||
currentDir = mainWindow.getSettings().getLastOpenFilePath();
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
package jadx.gui.ui.panel;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import jadx.gui.settings.JadxSettings;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.TabbedPane;
|
||||
import jadx.gui.ui.treenodes.StartPageNode;
|
||||
import jadx.gui.utils.Icons;
|
||||
import jadx.gui.utils.NLS;
|
||||
|
||||
public class StartPagePanel extends ContentPanel {
|
||||
|
||||
public StartPagePanel(TabbedPane tabbedPane, StartPageNode node) {
|
||||
super(tabbedPane, node);
|
||||
MainWindow mainWindow = tabbedPane.getMainWindow();
|
||||
Font baseFont = mainWindow.getSettings().getFont();
|
||||
|
||||
JButton openFile = new JButton(NLS.str("file.open_title"), Icons.OPEN);
|
||||
openFile.addActionListener(ev -> mainWindow.openFileDialog());
|
||||
|
||||
JButton openProject = new JButton(NLS.str("file.open_project"), Icons.OPEN_PROJECT);
|
||||
openProject.addActionListener(ev -> mainWindow.openProjectDialog());
|
||||
|
||||
JPanel start = new JPanel();
|
||||
start.setBorder(sectionFrame(NLS.str("start_page.start"), baseFont));
|
||||
start.setLayout(new BoxLayout(start, BoxLayout.LINE_AXIS));
|
||||
start.add(openFile);
|
||||
start.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
start.add(openProject);
|
||||
start.add(Box.createHorizontalGlue());
|
||||
|
||||
JPanel recentPanel = new JPanel();
|
||||
JScrollPane scrollPane = new JScrollPane(recentPanel);
|
||||
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
scrollPane.setPreferredSize(new Dimension(400, 200));
|
||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
fillRecentPanel(recentPanel, scrollPane, mainWindow);
|
||||
|
||||
JPanel recent = new JPanel();
|
||||
recent.setBorder(sectionFrame(NLS.str("start_page.recent"), baseFont));
|
||||
recent.setLayout(new BoxLayout(recent, BoxLayout.PAGE_AXIS));
|
||||
recent.add(scrollPane);
|
||||
|
||||
JPanel center = new JPanel();
|
||||
center.setLayout(new BorderLayout(10, 10));
|
||||
center.add(start, BorderLayout.PAGE_START);
|
||||
center.add(recent, BorderLayout.CENTER);
|
||||
center.setMaximumSize(new Dimension(700, 600));
|
||||
center.setAlignmentX(CENTER_ALIGNMENT);
|
||||
|
||||
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
|
||||
setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
|
||||
add(Box.createVerticalGlue());
|
||||
add(center);
|
||||
add(Box.createVerticalGlue());
|
||||
}
|
||||
|
||||
private void fillRecentPanel(JPanel panel, JScrollPane scrollPane, MainWindow mainWindow) {
|
||||
JadxSettings settings = mainWindow.getSettings();
|
||||
List<Path> recentProjects = settings.getRecentProjects();
|
||||
panel.removeAll();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
|
||||
Font baseFont = settings.getFont();
|
||||
Font font = baseFont.deriveFont(baseFont.getSize() - 1f);
|
||||
for (Path path : recentProjects) {
|
||||
JButton openBtn = new JButton(path.getFileName().toString());
|
||||
openBtn.setToolTipText(path.toAbsolutePath().toString());
|
||||
openBtn.setFont(font);
|
||||
openBtn.setBorderPainted(false);
|
||||
openBtn.addActionListener(ev -> mainWindow.open(path));
|
||||
|
||||
JButton removeBtn = new JButton();
|
||||
removeBtn.setIcon(Icons.CLOSE_INACTIVE);
|
||||
removeBtn.setRolloverIcon(Icons.CLOSE);
|
||||
removeBtn.setRolloverEnabled(true);
|
||||
removeBtn.setFocusable(false);
|
||||
removeBtn.setBorder(null);
|
||||
removeBtn.setBorderPainted(false);
|
||||
removeBtn.setContentAreaFilled(false);
|
||||
removeBtn.setOpaque(true);
|
||||
removeBtn.addActionListener(e -> {
|
||||
mainWindow.getSettings().removeRecentProject(path);
|
||||
fillRecentPanel(panel, scrollPane, mainWindow);
|
||||
panel.revalidate();
|
||||
scrollPane.repaint();
|
||||
});
|
||||
JPanel linePanel = new JPanel();
|
||||
linePanel.setLayout(new BoxLayout(linePanel, BoxLayout.LINE_AXIS));
|
||||
linePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
linePanel.add(openBtn);
|
||||
linePanel.add(Box.createHorizontalGlue());
|
||||
linePanel.add(removeBtn);
|
||||
|
||||
panel.add(linePanel);
|
||||
}
|
||||
panel.add(Box.createVerticalGlue());
|
||||
}
|
||||
|
||||
private static Border sectionFrame(String title, Font font) {
|
||||
TitledBorder titledBorder = BorderFactory.createTitledBorder(title);
|
||||
titledBorder.setTitleFont(font.deriveFont(Font.BOLD, font.getSize() + 1));
|
||||
Border spacing = BorderFactory.createEmptyBorder(10, 10, 10, 10);
|
||||
return BorderFactory.createCompoundBorder(titledBorder, spacing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package jadx.gui.ui.treenodes;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import jadx.gui.treemodel.JClass;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.ui.TabbedPane;
|
||||
import jadx.gui.ui.panel.ContentPanel;
|
||||
import jadx.gui.ui.panel.StartPagePanel;
|
||||
import jadx.gui.utils.Icons;
|
||||
import jadx.gui.utils.NLS;
|
||||
|
||||
public class StartPageNode extends JNode {
|
||||
private static final long serialVersionUID = 8983134608645736174L;
|
||||
|
||||
@Override
|
||||
public ContentPanel getContentPanel(TabbedPane tabbedPane) {
|
||||
return new StartPagePanel(tabbedPane, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String makeString() {
|
||||
return NLS.str("start_page.title");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return Icons.START_PAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass getJParent() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package jadx.gui.utils;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import static jadx.gui.utils.UiUtils.openSvgIcon;
|
||||
|
||||
public class Icons {
|
||||
|
||||
public static final ImageIcon OPEN = openSvgIcon("ui/openDisk");
|
||||
public static final ImageIcon OPEN_PROJECT = openSvgIcon("ui/projectDirectory");
|
||||
public static final ImageIcon NEW_PROJECT = openSvgIcon("ui/newFolder");
|
||||
|
||||
public static final ImageIcon CLOSE = openSvgIcon("ui/closeHovered");
|
||||
public static final ImageIcon CLOSE_INACTIVE = openSvgIcon("ui/close");
|
||||
|
||||
public static final ImageIcon STATIC = openSvgIcon("nodes/staticMark");
|
||||
public static final ImageIcon FINAL = openSvgIcon("nodes/finalMark");
|
||||
|
||||
public static final ImageIcon START_PAGE = openSvgIcon("nodes/newWindow");
|
||||
}
|
||||
@@ -46,9 +46,6 @@ import jadx.gui.ui.codearea.AbstractCodeArea;
|
||||
public class UiUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UiUtils.class);
|
||||
|
||||
public static final ImageIcon ICON_STATIC = openSvgIcon("nodes/staticMark");
|
||||
public static final ImageIcon ICON_FINAL = openSvgIcon("nodes/finalMark");
|
||||
|
||||
/**
|
||||
* The minimum about of memory in bytes we are trying to keep free, otherwise the application may
|
||||
* run out of heap
|
||||
@@ -190,10 +187,10 @@ public class UiUtils {
|
||||
}
|
||||
OverlayIcon overIcon = new OverlayIcon(icon);
|
||||
if (af.isFinal()) {
|
||||
overIcon.add(ICON_FINAL);
|
||||
overIcon.add(Icons.FINAL);
|
||||
}
|
||||
if (af.isStatic()) {
|
||||
overIcon.add(ICON_STATIC);
|
||||
overIcon.add(Icons.STATIC);
|
||||
}
|
||||
return overIcon;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ public class ActionHandler extends AbstractAction {
|
||||
|
||||
private final Consumer<ActionEvent> consumer;
|
||||
|
||||
public ActionHandler(Runnable action) {
|
||||
this.consumer = ev -> action.run();
|
||||
}
|
||||
|
||||
public ActionHandler(Consumer<ActionEvent> consumer) {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=Neue Version %s verfügbar!
|
||||
file.open_action=Datei öffnen…
|
||||
file.add_files_action=Dateien hinzufügen…
|
||||
file.open_title=Datei öffnen
|
||||
#file.open_project=Open project
|
||||
file.new_project=Neues Projekt
|
||||
file.save_project=Projekt speichern
|
||||
file.save_project_as=Projekt speichern als…
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=Als Gradle-Projekt speichern
|
||||
file.save_all_msg=Verzeichnis für das Speichern dekompilierter Ressourcen auswählen
|
||||
file.exit=Beenden
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=Quelltexte
|
||||
tree.resources_title=Ressourcen
|
||||
tree.loading=Laden…
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=New version %s available!
|
||||
file.open_action=Open files ...
|
||||
file.add_files_action=Add files
|
||||
file.open_title=Open file
|
||||
file.open_project=Open project
|
||||
file.new_project=New project
|
||||
file.save_project=Save project
|
||||
file.save_project_as=Save project as...
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=Save as gradle project
|
||||
file.save_all_msg=Select directory for save decompiled sources
|
||||
file.exit=Exit
|
||||
|
||||
start_page.title=Start page
|
||||
start_page.start=Start
|
||||
start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=Source code
|
||||
tree.resources_title=Resources
|
||||
tree.loading=Loading...
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=¡Nueva versión %s disponible!
|
||||
file.open_action=Abrir archivo...
|
||||
#file.add_files_action=Add files ...
|
||||
file.open_title=Abrir archivo
|
||||
#file.open_project=Open project
|
||||
#file.new_project=
|
||||
#file.save_project=
|
||||
#file.save_project_as=
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=Guardar como proyecto Gradle
|
||||
file.save_all_msg=Seleccionar carpeta para guardar fuentes descompiladas
|
||||
file.exit=Salir
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=Código fuente
|
||||
tree.resources_title=Recursos
|
||||
tree.loading=Cargando...
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=새 버전 %s 이(가) 존재합니다!
|
||||
file.open_action=파일 열기 ...
|
||||
file.add_files_action=파일 추가
|
||||
file.open_title=파일 열기
|
||||
#file.open_project=Open project
|
||||
file.new_project=새 프로젝트
|
||||
file.save_project=프로젝트 저장
|
||||
file.save_project_as=다른 이름으로 프로젝트 저장...
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=Gradle 프로젝트로 저장
|
||||
file.save_all_msg=디컴파일된 소스를 저장할 디렉토리 선택
|
||||
file.exit=나가기
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=소스코드
|
||||
tree.resources_title=리소스
|
||||
tree.loading=로딩중...
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=Nova versão %s disponível!
|
||||
file.open_action=Abrir arquivos...
|
||||
file.add_files_action=Adicionar arquivos
|
||||
file.open_title=Abrir arquivo
|
||||
#file.open_project=Open project
|
||||
file.new_project=Novo projeto
|
||||
file.save_project=Salvar projeto
|
||||
file.save_project_as=Salvar projeto como...
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=Salvar como um projeto gradle
|
||||
file.save_all_msg=Selecionar diretório para salvar arquivos descompilados
|
||||
file.exit=Sair
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=Código fonte
|
||||
tree.resources_title=Recursos
|
||||
tree.loading=Carregando...
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=发现新版本 %s!
|
||||
file.open_action=打开文件...
|
||||
file.add_files_action=添加文件
|
||||
file.open_title=打开文件
|
||||
#file.open_project=Open project
|
||||
file.new_project=新建项目
|
||||
file.save_project=保存项目
|
||||
file.save_project_as=另存项目为...
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=另存为 Gradle 项目
|
||||
file.save_all_msg=请选择保存反编译资源的目录
|
||||
file.exit=退出
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=源代码
|
||||
tree.resources_title=资源文件
|
||||
tree.loading=加载中...
|
||||
|
||||
@@ -23,6 +23,7 @@ menu.update_label=新版本 %s 可供下載!
|
||||
file.open_action=開啟檔案...
|
||||
file.add_files_action=新增檔案
|
||||
file.open_title=開啟檔案
|
||||
#file.open_project=Open project
|
||||
file.new_project=新建專案
|
||||
file.save_project=儲存專案
|
||||
file.save_project_as=另存專案...
|
||||
@@ -35,6 +36,10 @@ file.export_gradle=另存為 gradle 專案
|
||||
file.save_all_msg=選擇儲存反編譯原始碼的路徑
|
||||
file.exit=離開
|
||||
|
||||
#start_page.title=Start page
|
||||
#start_page.start=Start
|
||||
#start_page.recent=Recent projects
|
||||
|
||||
tree.sources_title=原始碼
|
||||
tree.resources_title=資源
|
||||
tree.loading=載入中...
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2H13V4V5H11V4H4V11H5V13H2V12V11V4V2Z" fill="#6E6E6E"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 6H6V14H14V6ZM12 8H8V12H12V8Z" fill="#6E6E6E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 310 B |
@@ -0,0 +1,8 @@
|
||||
<!-- Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#6E6E6E" d="M9,13 L2,13 L2,5 L2,3 L6.60006714,3 L7.75640322,5 L14,5 L14,8 L11,8 L11,10 L9,10 L9,13 Z"/>
|
||||
<rect width="2" height="6" x="12" y="9" fill="#6E6E6E"/>
|
||||
<rect width="6" height="2" x="10" y="11" fill="#6E6E6E"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 544 B |
@@ -0,0 +1,7 @@
|
||||
<!-- Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#6E6E6E" d="M10,15 L10,10 L15,10 L15,15 L10,15 Z M11,14 L13,14 L13,13 L11,13 L11,14 Z"/>
|
||||
<path fill="#6E6E6E" d="M14,9 L9,9 L9,13 L2,13 L2,5 L2,3 L6.60006714,3 L7.75640322,5 L14,5 L14,9 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 512 B |
Reference in New Issue
Block a user