■ ■ ■ ■ ■ ■
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
| skipped 86 lines |
87 | 87 | | import jadx.api.ResourceFile; |
88 | 88 | | import jadx.api.plugins.utils.CommonFileUtils; |
89 | 89 | | import jadx.core.Jadx; |
| 90 | + | import jadx.core.export.TemplateFile; |
90 | 91 | | import jadx.core.utils.ListUtils; |
91 | 92 | | import jadx.core.utils.StringUtils; |
92 | 93 | | import jadx.core.utils.files.FileUtils; |
| skipped 11 lines |
104 | 105 | | import jadx.gui.settings.JadxSettingsWindow; |
105 | 106 | | import jadx.gui.treemodel.ApkSignature; |
106 | 107 | | import jadx.gui.treemodel.JClass; |
107 | | - | import jadx.gui.treemodel.JField; |
108 | 108 | | import jadx.gui.treemodel.JLoadableNode; |
109 | | - | import jadx.gui.treemodel.JMethod; |
110 | 109 | | import jadx.gui.treemodel.JNode; |
111 | 110 | | import jadx.gui.treemodel.JPackage; |
112 | 111 | | import jadx.gui.treemodel.JResource; |
| skipped 5 lines |
118 | 117 | | import jadx.gui.ui.dialog.ADBDialog; |
119 | 118 | | import jadx.gui.ui.dialog.AboutDialog; |
120 | 119 | | import jadx.gui.ui.dialog.LogViewerDialog; |
121 | | - | import jadx.gui.ui.dialog.RenameDialog; |
122 | 120 | | import jadx.gui.ui.dialog.SearchDialog; |
123 | 121 | | import jadx.gui.ui.filedialog.FileDialogWrapper; |
124 | 122 | | import jadx.gui.ui.filedialog.FileOpenMode; |
| skipped 1 lines |
126 | 124 | | import jadx.gui.ui.panel.IssuesPanel; |
127 | 125 | | import jadx.gui.ui.panel.JDebuggerPanel; |
128 | 126 | | import jadx.gui.ui.panel.ProgressPanel; |
129 | | - | import jadx.gui.ui.popupmenu.JPackagePopupMenu; |
130 | 127 | | import jadx.gui.ui.treenodes.StartPageNode; |
131 | 128 | | import jadx.gui.ui.treenodes.SummaryNode; |
132 | 129 | | import jadx.gui.update.JadxUpdate; |
| skipped 82 lines |
215 | 212 | | private JDebuggerPanel debuggerPanel; |
216 | 213 | | private JSplitPane verticalSplitter; |
217 | 214 | | |
218 | | - | private List<ILoadListener> loadListeners = new ArrayList<>(); |
| 215 | + | private final List<ILoadListener> loadListeners = new ArrayList<>(); |
219 | 216 | | private boolean loaded; |
| 217 | + | |
| 218 | + | private JMenu pluginsMenu; |
220 | 219 | | |
221 | 220 | | public MainWindow(JadxSettings settings) { |
222 | 221 | | this.settings = settings; |
| skipped 180 lines |
403 | 402 | | s -> update()); |
404 | 403 | | } |
405 | 404 | | |
| 405 | + | public void addNewScript() { |
| 406 | + | FileDialogWrapper fileDialog = new FileDialogWrapper(this, FileOpenMode.CUSTOM_SAVE); |
| 407 | + | fileDialog.setTitle(NLS.str("file.save")); |
| 408 | + | Path workingDir = project.getWorkingDir(); |
| 409 | + | Path baseDir = workingDir != null ? workingDir : settings.getLastSaveFilePath(); |
| 410 | + | fileDialog.setSelectedFile(baseDir.resolve("script.jadx.kts")); |
| 411 | + | fileDialog.setFileExtList(Collections.singletonList("jadx.kts")); |
| 412 | + | fileDialog.setSelectionMode(JFileChooser.FILES_ONLY); |
| 413 | + | List<Path> paths = fileDialog.show(); |
| 414 | + | if (paths.size() != 1) { |
| 415 | + | return; |
| 416 | + | } |
| 417 | + | Path scriptFile = paths.get(0); |
| 418 | + | try { |
| 419 | + | TemplateFile tmpl = TemplateFile.fromResources("/files/script.jadx.kts.tmpl"); |
| 420 | + | FileUtils.writeFile(scriptFile, tmpl.build()); |
| 421 | + | } catch (Exception e) { |
| 422 | + | LOG.error("Failed to save new script file: {}", scriptFile, e); |
| 423 | + | } |
| 424 | + | List<Path> inputs = project.getFilePaths(); |
| 425 | + | inputs.add(scriptFile); |
| 426 | + | project.setFilePaths(inputs); |
| 427 | + | project.save(); |
| 428 | + | reopen(); |
| 429 | + | } |
| 430 | + | |
| 431 | + | public void removeInput(Path file) { |
| 432 | + | List<Path> inputs = project.getFilePaths(); |
| 433 | + | inputs.remove(file); |
| 434 | + | project.setFilePaths(inputs); |
| 435 | + | project.save(); |
| 436 | + | reopen(); |
| 437 | + | } |
| 438 | + | |
406 | 439 | | public void open(Path path) { |
407 | 440 | | open(Collections.singletonList(path), EMPTY_RUNNABLE); |
408 | 441 | | } |
| skipped 372 lines |
781 | 814 | | } |
782 | 815 | | |
783 | 816 | | private void treeRightClickAction(MouseEvent e) { |
784 | | - | JNode obj = getJNodeUnderMouse(e); |
785 | | - | if (obj instanceof JPackage) { |
786 | | - | JPackagePopupMenu menu = new JPackagePopupMenu(this, (JPackage) obj); |
787 | | - | menu.show(e.getComponent(), e.getX(), e.getY()); |
788 | | - | } else if (obj instanceof JClass || obj instanceof JField || obj instanceof JMethod) { |
789 | | - | JMenuItem jmi = new JMenuItem(NLS.str("popup.rename")); |
790 | | - | jmi.addActionListener(action -> RenameDialog.rename(this, obj)); |
791 | | - | JPopupMenu menu = new JPopupMenu(); |
792 | | - | menu.add(jmi); |
| 817 | + | JNode node = getJNodeUnderMouse(e); |
| 818 | + | if (node == null) { |
| 819 | + | return; |
| 820 | + | } |
| 821 | + | JPopupMenu menu = node.onTreePopupMenu(this); |
| 822 | + | if (menu != null) { |
793 | 823 | | menu.show(e.getComponent(), e.getX(), e.getY()); |
794 | 824 | | } |
795 | 825 | | } |
| skipped 142 lines |
938 | 968 | | } |
939 | 969 | | }; |
940 | 970 | | saveAllAction.putValue(Action.SHORT_DESCRIPTION, NLS.str("file.save_all")); |
941 | | - | saveAllAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_S, UiUtils.ctrlButton())); |
| 971 | + | saveAllAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_E, UiUtils.ctrlButton())); |
942 | 972 | | |
943 | 973 | | Action exportAction = new AbstractAction(NLS.str("file.export_gradle"), ICON_EXPORT) { |
944 | 974 | | @Override |
| skipped 2 lines |
947 | 977 | | } |
948 | 978 | | }; |
949 | 979 | | exportAction.putValue(Action.SHORT_DESCRIPTION, NLS.str("file.export_gradle")); |
950 | | - | exportAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_E, UiUtils.ctrlButton())); |
| 980 | + | exportAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_E, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)); |
951 | 981 | | |
952 | 982 | | JMenu recentProjects = new JMenu(NLS.str("menu.recent_projects")); |
953 | 983 | | recentProjects.addMenuListener(new RecentProjectsMenuListener(recentProjects)); |
| skipped 194 lines |
1148 | 1178 | | nav.add(backAction); |
1149 | 1179 | | nav.add(forwardAction); |
1150 | 1180 | | |
| 1181 | + | pluginsMenu = new JMenu(NLS.str("menu.plugins")); |
| 1182 | + | pluginsMenu.setMnemonic(KeyEvent.VK_P); |
| 1183 | + | pluginsMenu.setVisible(false); |
| 1184 | + | |
1151 | 1185 | | JMenu tools = new JMenu(NLS.str("menu.tools")); |
1152 | 1186 | | tools.setMnemonic(KeyEvent.VK_T); |
1153 | 1187 | | tools.add(deobfMenuItem); |
| skipped 18 lines |
1172 | 1206 | | menuBar.add(view); |
1173 | 1207 | | menuBar.add(nav); |
1174 | 1208 | | menuBar.add(tools); |
| 1209 | + | menuBar.add(pluginsMenu); |
1175 | 1210 | | menuBar.add(help); |
1176 | 1211 | | setJMenuBar(menuBar); |
1177 | 1212 | | |
| skipped 452 lines |
1630 | 1665 | | @Override |
1631 | 1666 | | public void menuCanceled(MenuEvent e) { |
1632 | 1667 | | } |
| 1668 | + | } |
| 1669 | + | |
| 1670 | + | public JMenu getPluginsMenu() { |
| 1671 | + | return pluginsMenu; |
1633 | 1672 | | } |
1634 | 1673 | | } |
1635 | 1674 | | |