diff --git a/jadx-gui/src/main/java/jadx/gui/settings/TabStateViewAdapter.java b/jadx-gui/src/main/java/jadx/gui/settings/TabStateViewAdapter.java index 27fd56931..96f6a391a 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/TabStateViewAdapter.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/TabStateViewAdapter.java @@ -32,6 +32,7 @@ public class TabStateViewAdapter { tvs.setPinned(viewState.isPinned()); tvs.setBookmarked(viewState.isBookmarked()); tvs.setHidden(viewState.isHidden()); + tvs.setPreviewTab(viewState.isPreviewTab()); return tvs; } @@ -47,6 +48,7 @@ public class TabStateViewAdapter { viewState.setPinned(tvs.isPinned()); viewState.setBookmarked(tvs.isBookmarked()); viewState.setHidden(tvs.isHidden()); + viewState.setPreviewTab(tvs.isPreviewTab()); return viewState; } catch (Exception e) { LOG.error("Failed to load tab state: " + tvs, e); diff --git a/jadx-gui/src/main/java/jadx/gui/settings/data/TabViewState.java b/jadx-gui/src/main/java/jadx/gui/settings/data/TabViewState.java index 7854b86d6..69f10b628 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/data/TabViewState.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/data/TabViewState.java @@ -10,6 +10,7 @@ public class TabViewState { boolean pinned; boolean bookmarked; boolean hidden; + boolean previewTab; public String getType() { return type; @@ -82,4 +83,12 @@ public class TabViewState { public void setHidden(boolean hidden) { this.hidden = hidden; } + + public boolean isPreviewTab() { + return previewTab; + } + + public void setPreviewTab(boolean previewTab) { + this.previewTab = previewTab; + } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index f6e644481..ce7ea3c80 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -115,11 +115,15 @@ import jadx.gui.settings.ui.JadxSettingsWindow; import jadx.gui.settings.ui.plugins.PluginSettings; import jadx.gui.tree.TreeExpansionService; import jadx.gui.treemodel.ApkSignature; +import jadx.gui.treemodel.JInputFiles; +import jadx.gui.treemodel.JInputScripts; +import jadx.gui.treemodel.JInputs; import jadx.gui.treemodel.JLoadableNode; import jadx.gui.treemodel.JNode; import jadx.gui.treemodel.JPackage; import jadx.gui.treemodel.JResource; import jadx.gui.treemodel.JRoot; +import jadx.gui.treemodel.JSources; import jadx.gui.ui.action.ActionModel; import jadx.gui.ui.action.JadxGuiAction; import jadx.gui.ui.codearea.AbstractCodeArea; @@ -882,8 +886,15 @@ public class MainWindow extends JFrame { return true; } } else if (obj instanceof JNode) { - tabsController.codeJump((JNode) obj, true); - return true; + JNode treeNode = (JNode) obj; + if (!(treeNode instanceof JPackage) + && !(treeNode instanceof JSources) + && !(treeNode instanceof JInputs) + && !(treeNode instanceof JInputFiles) + && !(treeNode instanceof JInputScripts)) { + tabsController.codeJump(treeNode, true); + return true; + } } } catch (Exception e) { LOG.error("Content loading error", e); @@ -1062,11 +1073,10 @@ public class MainWindow extends JFrame { flatPkgMenuItem = new JCheckBoxMenuItem(NLS.str("menu.flatten"), Icons.FLAT_PKG); flatPkgMenuItem.setState(isFlattenPackage); - JCheckBoxMenuItem enablePreviewTabMenuItem = new JCheckBoxMenuItem(NLS.str("menu.enable_preview_tab")); - enablePreviewTabMenuItem.setState(settings.isEnablePreviewTab()); - enablePreviewTabMenuItem.addActionListener(event -> { + JadxGuiAction enablePreviewTabAction = new JadxGuiAction(ActionModel.PREVIEW_TAB, () -> { settings.setEnablePreviewTab(!settings.isEnablePreviewTab()); }); + enablePreviewTabAction.setSelected(settings.isEnablePreviewTab()); JCheckBoxMenuItem heapUsageBarMenuItem = new JCheckBoxMenuItem(NLS.str("menu.heapUsageBar")); heapUsageBarMenuItem.setState(settings.isShowHeapUsageBar()); @@ -1159,7 +1169,7 @@ public class MainWindow extends JFrame { view.add(quickTabsAction.makeCheckBoxMenuItem()); view.add(flatPkgMenuItem); view.addSeparator(); - view.add(enablePreviewTabMenuItem); + view.add(enablePreviewTabAction.makeCheckBoxMenuItem()); view.add(syncAction); view.add(alwaysSelectOpened); view.addSeparator(); @@ -1241,6 +1251,7 @@ public class MainWindow extends JFrame { toolbar.addSeparator(); toolbar.add(syncAction); toolbar.add(flatPkgButton); + toolbar.add(enablePreviewTabAction.makeToggleButton()); toolbar.add(quickTabsAction.makeToggleButton()); toolbar.addSeparator(); toolbar.add(textSearchAction); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/action/ActionModel.java b/jadx-gui/src/main/java/jadx/gui/ui/action/ActionModel.java index 8097a38fb..94abe3038 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/action/ActionModel.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/action/ActionModel.java @@ -57,6 +57,8 @@ public enum ActionModel { Shortcut.keyboard(KeyEvent.VK_A, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)), GO_TO_ANDROID_MANIFEST(MENU_TOOLBAR, "menu.go_to_android_manifest", "menu.go_to_android_manifest", "ui/androidManifest", Shortcut.none()), + PREVIEW_TAB(MENU_TOOLBAR, "menu.enable_preview_tab", "menu.enable_preview_tab", "ui/editorPreview", + Shortcut.none()), DECOMPILE_ALL(MENU_TOOLBAR, "menu.decompile_all", "menu.decompile_all", "ui/runAll", Shortcut.none()), RESET_CACHE(MENU_TOOLBAR, "menu.reset_cache", "menu.reset_cache", "ui/reset", diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorViewState.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorViewState.java index 62d44b3a5..610024a16 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorViewState.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/EditorViewState.java @@ -17,6 +17,7 @@ public class EditorViewState { private boolean pinned; private boolean bookmarked; private boolean hidden; + private boolean previewTab; public EditorViewState(JNode node) { this(node, "", 0, EditorViewState.ZERO); @@ -85,6 +86,14 @@ public class EditorViewState { return hidden; } + public boolean isPreviewTab() { + return previewTab; + } + + public void setPreviewTab(boolean previewTab) { + this.previewTab = previewTab; + } + public void setHidden(boolean hidden) { this.hidden = hidden; } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/tab/TabsController.java b/jadx-gui/src/main/java/jadx/gui/ui/tab/TabsController.java index ba579cad0..482d60c2c 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/tab/TabsController.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/tab/TabsController.java @@ -83,7 +83,7 @@ public class TabsController { public TabBlueprint previewTab(JNode node) { TabBlueprint blueprint = getPreviewTab(); if (blueprint != null) { - closeTabForce(blueprint); + closeTab(blueprint.getNode()); } blueprint = openTab(node, false, true); @@ -244,6 +244,7 @@ public class TabsController { public void setTabPinnedInternal(TabBlueprint blueprint, boolean pinned) { if (blueprint.isPinned() != pinned) { + blueprint.setPreviewTab(false); blueprint.setPinned(pinned); listeners.forEach(l -> l.onTabPinChange(blueprint)); } @@ -256,6 +257,7 @@ public class TabsController { private void setTabBookmarkedInternal(TabBlueprint blueprint, boolean bookmarked) { if (blueprint.isBookmarked() != bookmarked) { + blueprint.setPreviewTab(false); blueprint.setBookmarked(bookmarked); listeners.forEach(l -> l.onTabBookmarkChange(blueprint)); removeTabIfNotReferenced(blueprint); @@ -269,6 +271,7 @@ public class TabsController { private void setTabHiddenInternal(TabBlueprint blueprint, boolean hidden) { if (blueprint != null && blueprint.isHidden() != hidden) { + blueprint.setPreviewTab(false); blueprint.setHidden(hidden); listeners.forEach(l -> l.onTabVisibilityChange(blueprint)); } @@ -338,7 +341,7 @@ public class TabsController { public void restoreEditorViewState(EditorViewState viewState) { JNode node = viewState.getNode(); - TabBlueprint blueprint = openTab(node, viewState.isHidden()); + TabBlueprint blueprint = openTab(node, viewState.isHidden(), viewState.isPreviewTab()); setTabPinnedInternal(blueprint, viewState.isPinned()); setTabBookmarkedInternal(blueprint, viewState.isBookmarked()); listeners.forEach(l -> l.onTabRestore(blueprint, viewState)); @@ -373,6 +376,7 @@ public class TabsController { viewState.setPinned(blueprint.isPinned()); viewState.setBookmarked(blueprint.isBookmarked()); viewState.setHidden(blueprint.isHidden()); + viewState.setPreviewTab(blueprint.isPreviewTab()); return viewState; } } diff --git a/jadx-gui/src/main/resources/icons/ui/editorPreview.svg b/jadx-gui/src/main/resources/icons/ui/editorPreview.svg new file mode 100644 index 000000000..4ae77edcc --- /dev/null +++ b/jadx-gui/src/main/resources/icons/ui/editorPreview.svg @@ -0,0 +1,8 @@ + + + + + + + +