From b3d77db4d87fc313d4c50ec6577c33c5e2a9a5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 29 Sep 2023 21:11:50 +0200 Subject: [PATCH] ABC Explorer - Context menu on ABCContainer, ScriptPack --- src/com/jpexs/decompiler/flash/gui/Main.java | 6 +- .../decompiler/flash/gui/MainFrameMenu.java | 3 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 19 +++++++ .../flash/gui/abc/ABCExplorerDialog.java | 33 +++++++++++ .../flash/gui/locales/MainFrame.properties | 4 +- .../flash/gui/tagtree/TagTreeContextMenu.java | 55 ++++++++++++++++++- 6 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index c6b8e9fac..8d7745948 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -47,6 +47,7 @@ import com.jpexs.decompiler.flash.console.CommandLineArgumentParser; import com.jpexs.decompiler.flash.console.ContextMenuTools; import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode; import com.jpexs.decompiler.flash.gfx.GfxConvertor; +import com.jpexs.decompiler.flash.gui.abc.ABCExplorerDialog; import com.jpexs.decompiler.flash.gui.abc.LinkDialog; import com.jpexs.decompiler.flash.gui.debugger.DebugListener; import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools; @@ -130,6 +131,7 @@ import java.util.Objects; import java.util.Set; import java.util.Timer; import java.util.TimerTask; +import java.util.WeakHashMap; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.ConsoleHandler; @@ -217,7 +219,7 @@ public class Main { public static CancellableWorker importWorker = null; public static CancellableWorker deobfuscatePCodeWorker = null; - public static CancellableWorker swfPrepareWorker = null; + public static CancellableWorker swfPrepareWorker = null; public static boolean isSwfAir(Openable openable) { SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(openable.getShortPathTitle()); @@ -3192,5 +3194,5 @@ public class Main { } catch (Exception ex) { throw new RuntimeException("Problems with creating the log files"); } - } + } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java index 2668e996f..d735f6d31 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -1688,8 +1688,7 @@ public abstract class MainFrameMenu implements MenuBuilder { return; } - ABCExplorerDialog aed = new ABCExplorerDialog(Main.getMainFrame().getWindow(), swf, null); - aed.setVisible(true); + mainFrame.getPanel().showAbcExplorer(swf, null); } public boolean stackActionPerformed(ActionEvent evt) { diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index cae874e09..f6cc8ada7 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -94,6 +94,7 @@ import com.jpexs.decompiler.flash.flexsdk.MxmlcAs3ScriptReplacer; import com.jpexs.decompiler.flash.flv.FLVInputStream; import com.jpexs.decompiler.flash.flv.FLVTAG; import com.jpexs.decompiler.flash.flv.VIDEODATA; +import com.jpexs.decompiler.flash.gui.abc.ABCExplorerDialog; import com.jpexs.decompiler.flash.gui.abc.ABCPanel; import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane; @@ -452,6 +453,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private List> unfilteredTagListExpandedNodes = new ArrayList<>(); public ScrollPosStorage scrollPosStorage; + + private Map abcExplorerDialogs = new WeakHashMap<>(); public void savePins() { pinsPanel.save(); @@ -5920,4 +5923,20 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return statusPanel; } + public ABCExplorerDialog showAbcExplorer(SWF swf, ABC abc) { + ABCExplorerDialog dialog = abcExplorerDialogs.get(swf); + if (dialog != null) { + dialog.selectAbc(abc); + if (!dialog.isVisible()) { + dialog.setVisible(true); + } else { + dialog.toFront(); + } + } else { + dialog = new ABCExplorerDialog(mainFrame.getWindow(), swf, abc); + abcExplorerDialogs.put(swf, dialog); + dialog.setVisible(true); + } + return dialog; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java index ca18f9b0f..3e76b40d8 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java @@ -142,6 +142,19 @@ public class ABCExplorerDialog extends AppDialog { View.setWindowIcon(this); View.centerScreen(this); } + + public void selectAbc(ABC abc) { + if (abc == null && !abcContainers.isEmpty()) { + abcComboBox.setSelectedIndex(0); + return; + } + for (int i = 0; i < abcContainers.size(); i++) { + if (abcContainers.get(i).getABC() == abc) { + abcComboBox.setSelectedIndex(i); + break; + } + } + } private ABC getSelectedAbc() { return abcContainers.get(abcComboBox.getSelectedIndex()).getABC(); @@ -202,6 +215,26 @@ public class ABCExplorerDialog extends AppDialog { mainTabbedPane.addTab("si (" + abc.script_info.size() + ")", makeTreePanel(abc, TreeType.SCRIPT_INFO)); mainTabbedPane.addTab("mb (" + abc.bodies.size() + ")", makeTreePanel(abc, TreeType.METHOD_BODY)); } + + public void selectScriptInfo(int scriptIndex) { + if (mainTabbedPane.getTabCount() > 0) { + mainTabbedPane.setSelectedIndex(5); + JPanel pan = (JPanel) mainTabbedPane.getComponentAt(5); + FasterScrollPane fasterScrollPane = (FasterScrollPane) pan.getComponent(0); + JTree tree = (JTree)fasterScrollPane.getViewport().getView(); + TreeModel model = tree.getModel(); + if (scriptIndex >= model.getChildCount(model.getRoot())) { + return; + } + Object scriptInfoNode = model.getChild(model.getRoot(), scriptIndex); + TreePath path = new TreePath(new Object[]{ + model.getRoot(), + scriptInfoNode + }); + tree.setSelectionPath(path); + tree.scrollPathToVisible(path); + } + } private JPanel makeTreePanel(ABC abc, TreeType type) { JTree tree = new JTree(new ExplorerTreeModel(abc, type)); diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 54721ee77..c405b0138 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1153,4 +1153,6 @@ error.font.cannotaddcharacter = ERROR: Cannot add more characters to the font.\r info.noteditable.compound = The script is compound - has multiple externally visible definitions. The direct editing is not available. -menu.tools.abcexplorer = ABC Explorer \ No newline at end of file +menu.tools.abcexplorer = ABC Explorer + +contextmenu.abcexplorer = Open in ABC Explorer \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 715562cf3..5291741c6 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.gui.SelectTagPositionDialog; import com.jpexs.decompiler.flash.gui.TreeNodeType; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.ViewMessages; +import com.jpexs.decompiler.flash.gui.abc.ABCExplorerDialog; import com.jpexs.decompiler.flash.gui.abc.AddClassDialog; import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.action.AddScriptDialog; @@ -250,6 +251,8 @@ public class TagTreeContextMenu extends JPopupMenu { private JMenuItem unpinAllMenuItem; private JMenuItem unpinOthersMenuItem; + + private JMenuItem abcExplorerMenuItem; private List items = new ArrayList<>(); @@ -358,11 +361,16 @@ public class TagTreeContextMenu extends JPopupMenu { replaceRefsWithTagMenuItem.setIcon(View.getIcon("replacewithtag16")); add(replaceRefsWithTagMenuItem); + abcExplorerMenuItem = new JMenuItem(mainPanel.translate("contextmenu.abcexplorer")); + abcExplorerMenuItem.addActionListener(this::abcExplorerActionPerformed); + abcExplorerMenuItem.setIcon(View.getIcon("abc16")); + add(abcExplorerMenuItem); + rawEditMenuItem = new JMenuItem(mainPanel.translate("contextmenu.rawEdit")); rawEditMenuItem.addActionListener(this::rawEditActionPerformed); rawEditMenuItem.setIcon(View.getIcon("rawedit16")); - add(rawEditMenuItem); - + add(rawEditMenuItem); + jumpToCharacterMenuItem = new JMenuItem(mainPanel.translate("contextmenu.jumpToCharacter")); jumpToCharacterMenuItem.addActionListener(this::jumpToCharacterActionPerformed); jumpToCharacterMenuItem.setIcon(View.getIcon("jumpto16")); @@ -931,6 +939,7 @@ public class TagTreeContextMenu extends JPopupMenu { replaceNoFillMenuItem.setVisible(false); replaceWithTagMenuItem.setVisible(false); replaceRefsWithTagMenuItem.setVisible(false); + abcExplorerMenuItem.setVisible(false); rawEditMenuItem.setVisible(false); jumpToCharacterMenuItem.setVisible(false); exportJavaSourceMenuItem.setVisible(allSelectedIsSwf); @@ -1141,6 +1150,21 @@ public class TagTreeContextMenu extends JPopupMenu { jumpToCharacterMenuItem.setVisible(true); } + if (firstItem instanceof ScriptPack) { + abcExplorerMenuItem.setVisible(true); + } + + if (firstItem instanceof AS3Package) { + AS3Package pkg = (AS3Package) firstItem; + if (pkg.isCompoundScript()) { + abcExplorerMenuItem.setVisible(true); + } + } + + if (firstItem instanceof ABCContainerTag) { + abcExplorerMenuItem.setVisible(true); + } + if (firstItem instanceof Tag) { rawEditMenuItem.setVisible(true); } @@ -1799,6 +1823,33 @@ public class TagTreeContextMenu extends JPopupMenu { tag.replaceCharacter(characterId, newCharacterId); } + private void abcExplorerActionPerformed(ActionEvent evt) { + TreeItem item = getCurrentItem(); + if (item == null) { + return; + } + if (item instanceof ABCContainerTag) { + ABCContainerTag cnt = (ABCContainerTag)item; + mainPanel.showAbcExplorer(cnt.getSwf(), cnt.getABC()); + return; + } + + if (item instanceof ScriptPack) { + ScriptPack pack = (ScriptPack)item; + ABCExplorerDialog dialog = mainPanel.showAbcExplorer(pack.abc.getSwf(), pack.abc); + dialog.selectScriptInfo(pack.scriptIndex); + } + + if (item instanceof AS3Package) { + AS3Package pkg = (AS3Package) item; + if (pkg.isCompoundScript()) { + ScriptPack pack = pkg.getCompoundInitializerPack(); + ABCExplorerDialog dialog = mainPanel.showAbcExplorer(pack.abc.getSwf(), pack.abc); + dialog.selectScriptInfo(pack.scriptIndex); + } + } + } + private void rawEditActionPerformed(ActionEvent evt) { TreeItem itemr = getCurrentItem(); if (itemr == null) {