diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index 8f09a092d..f06a72827 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -52,7 +52,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; import com.jpexs.decompiler.flash.action.swf5.ActionSetMember; import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.exporters.BinaryDataExporter; import com.jpexs.decompiler.flash.exporters.FontExporter; @@ -271,7 +271,7 @@ public final class SWF implements TreeItem, Timelined { private Timeline timeline; - public DumpInfo dumpInfo; + public DumpInfoSwfNode dumpInfo; public void updateCharacters() { characters.clear(); @@ -512,7 +512,7 @@ public final class SWF implements TreeItem, Timelined { uncompressedData = baos.toByteArray(); SWFInputStream sis = new SWFInputStream(this, uncompressedData); - dumpInfo = new DumpInfo("rootswf", "", null, 0, 0); + dumpInfo = new DumpInfoSwfNode(this, "rootswf", "", null, 0, 0); sis.dumpInfo = dumpInfo; sis.readBytesEx(3, "signature"); // skip siganture version = sis.readUI8("version"); diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java index eababc219..3313db2d2 100644 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java +++ b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java @@ -42,7 +42,7 @@ public class DumpInfo { public List childInfos = new ArrayList<>(); - public DumpInfo(String name, String type, Object value, long startByte, int lengthBytes) { + public DumpInfo(String name, String type, Object value, long startByte, long lengthBytes) { this.name = name; this.type = type; diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java b/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java new file mode 100644 index 000000000..6a9eefe8f --- /dev/null +++ b/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.dumpview; + +import com.jpexs.decompiler.flash.SWF; + +/** + * + * @author JPEXS + */ +public class DumpInfoSwfNode extends DumpInfo { + + private SWF swf; + + public DumpInfoSwfNode(SWF swf, String name, String type, Object value, long startByte, long lengthBytes) { + super(name, type, value, startByte, lengthBytes); + this.swf = swf; + } + + public SWF getSwf() { + return swf; + } + + public static DumpInfoSwfNode getSwfNode(DumpInfo dumpInfo) { + while (!(dumpInfo instanceof DumpInfoSwfNode)) { + dumpInfo = dumpInfo.parent; + } + return (DumpInfoSwfNode) dumpInfo; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/DumpTree.java b/src/com/jpexs/decompiler/flash/gui/DumpTree.java deleted file mode 100644 index 21e335ca5..000000000 --- a/src/com/jpexs/decompiler/flash/gui/DumpTree.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import javax.swing.JComponent; -import javax.swing.JTree; -import javax.swing.plaf.basic.BasicLabelUI; -import javax.swing.plaf.basic.BasicTreeUI; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeModel; - -/** - * - * @author JPEXS - */ -public class DumpTree extends JTree { - - public class DumpTreeCellRenderer extends DefaultTreeCellRenderer { - - @Override - public Component getTreeCellRendererComponent( - JTree tree, - Object value, - boolean sel, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - - super.getTreeCellRendererComponent( - tree, value, sel, - expanded, leaf, row, - hasFocus); - - //DumpInfo dumpInfo = (DumpInfo) value; - setUI(new BasicLabelUI()); - setOpaque(false); - setBackgroundNonSelectionColor(Color.white); - - return this; - } - } - - DumpTree(DumpTreeModel treeModel) { - super(treeModel); - setCellRenderer(new DumpTreeCellRenderer()); - setRootVisible(false); - setBackground(Color.white); - setUI(new BasicTreeUI() { - @Override - public void paint(Graphics g, JComponent c) { - setHashColor(Color.gray); - super.paint(g, c); - } - }); - } - - @Override - public void setModel(TreeModel tm) { - super.setModel(tm); - if (tm != null) { - int rowCount = tm.getChildCount(tm.getRoot()); - for (int i = rowCount - 1; i >= 0; i--) { - expandRow(i); - } - } - } - -} diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 8e2c631b3..c16bf6d3d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -16,6 +16,9 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.gui.dumpview.DumpTreeModel; +import com.jpexs.decompiler.flash.gui.dumpview.DumpViewPanel; +import com.jpexs.decompiler.flash.gui.dumpview.DumpTree; import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.ApplicationInfo; @@ -59,6 +62,7 @@ import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog; import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; import com.jpexs.decompiler.flash.gui.action.ActionPanel; +import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import com.jpexs.decompiler.flash.gui.timeline.TimelineFrame; import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode; @@ -247,6 +251,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private final PreviewPanel previewPanel; private DumpViewPanel dumpViewPanel; private final JPanel treePanel; + private TreePanelMode treePanelMode; private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); private CancellableWorker setSourceWorker; public TreeNode oldNode; @@ -255,12 +260,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public static final String ACTION_SELECT_BKCOLOR = "SELECTCOLOR"; public static final String ACTION_REPLACE = "REPLACE"; - private static final String ACTION_RAW_EDIT = "RAWEDIT"; - private static final String ACTION_JUMP_TO_CHARACTER = "JUMPTOCHARACTER"; - private static final String ACTION_REMOVE_ITEM = "REMOVEITEM"; - private static final String ACTION_REMOVE_ITEM_WITH_DEPENDENCIES = "REMOVEITEMWITHDEPENDENCIES"; - private static final String ACTION_CLOSE_SWF = "CLOSESWF"; - private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE"; // play morph shape in 2 second(s) public static final int MORPH_SHAPE_ANIMATION_LENGTH = 2; @@ -311,146 +310,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec statusPanel.setWorkStatus(s, worker); } - private void createContextMenu() { - final JPopupMenu contextPopupMenu = new JPopupMenu(); - - final JMenuItem expandRecursiveMenuItem = new JMenuItem(translate("contextmenu.expandAll")); - expandRecursiveMenuItem.addActionListener(this); - expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE); - contextPopupMenu.add(expandRecursiveMenuItem); - - final JMenuItem removeMenuItem = new JMenuItem(translate("contextmenu.remove")); - removeMenuItem.addActionListener(this); - removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM); - contextPopupMenu.add(removeMenuItem); - - final JMenuItem removeWithDependenciesMenuItem = new JMenuItem(translate("contextmenu.removeWithDependencies")); - removeWithDependenciesMenuItem.addActionListener(this); - removeWithDependenciesMenuItem.setActionCommand(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES); - contextPopupMenu.add(removeWithDependenciesMenuItem); - - final JMenuItem exportSelectionMenuItem = new JMenuItem(translate("menu.file.export.selection")); - exportSelectionMenuItem.setActionCommand(MainFrameRibbonMenu.ACTION_EXPORT_SEL); - exportSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(exportSelectionMenuItem); - - final JMenuItem replaceSelectionMenuItem = new JMenuItem(translate("button.replace")); - replaceSelectionMenuItem.setActionCommand(ACTION_REPLACE); - replaceSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(replaceSelectionMenuItem); - - final JMenuItem rawEditMenuItem = new JMenuItem(translate("contextmenu.rawEdit")); - rawEditMenuItem.setActionCommand(ACTION_RAW_EDIT); - rawEditMenuItem.addActionListener(this); - rawEditMenuItem.setVisible(false); - contextPopupMenu.add(rawEditMenuItem); - - final JMenuItem jumpToCharacterMenuItem = new JMenuItem(translate("contextmenu.jumpToCharacter")); - jumpToCharacterMenuItem.setActionCommand(ACTION_JUMP_TO_CHARACTER); - jumpToCharacterMenuItem.addActionListener(this); - jumpToCharacterMenuItem.setVisible(false); - contextPopupMenu.add(jumpToCharacterMenuItem); - - final JMenuItem closeSelectionMenuItem = new JMenuItem(translate("contextmenu.closeSwf")); - closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF); - closeSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(closeSelectionMenuItem); - - final JMenu moveTagMenu = new JMenu(translate("contextmenu.moveTag")); - contextPopupMenu.add(moveTagMenu); - - tagTree.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (SwingUtilities.isRightMouseButton(e)) { - - int row = tagTree.getClosestRowForLocation(e.getX(), e.getY()); - int[] selectionRows = tagTree.getSelectionRows(); - if (!Helper.contains(selectionRows, row)) { - tagTree.setSelectionRow(row); - } - - TreePath[] paths = tagTree.getSelectionPaths(); - if (paths == null || paths.length == 0) { - return; - } - boolean allSelectedIsTagOrFrame = true; - for (TreePath treePath : paths) { - TreeNode treeNode = (TreeNode) treePath.getLastPathComponent(); - - TreeItem tag = treeNode.getItem(); - if (!(tag instanceof Tag) && !(tag instanceof FrameNodeItem)) { - allSelectedIsTagOrFrame = false; - break; - } - } - - replaceSelectionMenuItem.setVisible(false); - closeSelectionMenuItem.setVisible(false); - moveTagMenu.setVisible(false); - expandRecursiveMenuItem.setVisible(false); - - if (paths.length == 1) { - TreeNode treeNode = (TreeNode) paths[0].getLastPathComponent(); - - TreeItem item = ((TreeNode) treeNode).getItem(); - - if (item instanceof ImageTag && ((ImageTag) item).importSupported()) { - replaceSelectionMenuItem.setVisible(true); - } - - if (item instanceof DefineBinaryDataTag) { - replaceSelectionMenuItem.setVisible(true); - } - - if (item instanceof DefineSoundTag) { - replaceSelectionMenuItem.setVisible(true); - } - - if (treeNode instanceof SWFNode) { - closeSelectionMenuItem.setVisible(true); - } - - if (item instanceof Tag && swfs.size() > 1) { - final Tag tag = (Tag) item; - moveTagMenu.removeAll(); - for (SWFList targetSwfList : swfs) { - for (final SWF targetSwf : targetSwfList) { - if (targetSwf != tag.getSwf()) { - JMenuItem swfItem = new JMenuItem(targetSwf.getShortFileName()); - swfItem.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent ae) { - tag.getSwf().tags.remove(tag); - tag.setSwf(targetSwf); - targetSwf.tags.add(tag); - refreshTree(); - } - }); - moveTagMenu.add(swfItem); - } - } - } - moveTagMenu.setVisible(true); - } - - TreeModel model = tagTree.getModel(); - expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0); - - jumpToCharacterMenuItem.setVisible(item instanceof CharacterIdTag && !(item instanceof CharacterTag)); - - rawEditMenuItem.setVisible(item instanceof Tag); - } - - removeMenuItem.setVisible(allSelectedIsTagOrFrame); - exportSelectionMenuItem.setEnabled(hasExportableNodes()); - contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); - } - } - }); - } - private JPanel createWelcomePanel() { JPanel welcomePanel = new JPanel(); welcomePanel.setLayout(new BoxLayout(welcomePanel, BoxLayout.Y_AXIS)); @@ -530,7 +389,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec cl2.show(detailPanel, DETAILCARDEMPTYPANEL); UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName()); - tagTree = new TagTree((TagTreeModel) null); + tagTree = new TagTree((TagTreeModel) null, this); tagTree.addTreeSelectionListener(this); DragSource dragSource = DragSource.getDefaultDragSource(); @@ -612,10 +471,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } }); - createContextMenu(); + tagTree.createContextMenu(swfs); - dumpTree = new DumpTree((DumpTreeModel) null); + dumpTree = new DumpTree((DumpTreeModel) null, this); dumpTree.addTreeSelectionListener(this); + dumpTree.createContextMenu(); statusPanel = new MainFrameStatusPanel(this); add(statusPanel, BorderLayout.SOUTH); @@ -1034,19 +894,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } - public List getSelectedNodes() { - List ret = new ArrayList<>(); - TreePath[] tps = tagTree.getSelectionPaths(); - if (tps == null) { - return ret; - } - for (TreePath tp : tps) { - TagNode te = (TagNode) tp.getLastPathComponent(); - ret.add(te); - } - return ret; - } - public void renameIdentifier(SWF swf, String identifier) throws InterruptedException { String oldName = identifier; String newName = View.showInputDialog(translate("rename.enternew"), oldName); @@ -1094,48 +941,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } - public List getSelected(JTree tree) { - TreeSelectionModel tsm = tree.getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); - ret.add(treeNode); - } - return ret; - } - - public List getAllSubs(JTree tree, TreeNode o) { - TagTreeModel tm = (TagTreeModel) tree.getModel(); - List ret = new ArrayList<>(); - for (int i = 0; i < tm.getChildCount(o); i++) { - TreeNode c = tm.getChild(o, i); - ret.add(c); - ret.addAll(getAllSubs(tree, c)); - } - return ret; - } - - public List getAllSelected(TagTree tree) { - TreeSelectionModel tsm = tree.getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); - ret.add(treeNode); - ret.addAll(getAllSubs(tree, treeNode)); - } - return ret; - } - public List getASTreeNodes(TagTree tree) { List result = new ArrayList<>(); TagTreeModel tm = (TagTreeModel) tree.getModel(); @@ -1165,68 +970,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } private SearchDialog searchDialog; - public boolean hasExportableNodes() { - return !getSelection(getCurrentSwf()).isEmpty(); - } - - private List getSelection(SWF swf) { - List ret = new ArrayList<>(); - List sel = getAllSelected(tagTree); - for (TreeNode d : sel) { - if (d.getItem().getSwf() != swf) { - continue; - } - if (d instanceof ContainerNode) { - ContainerNode n = (ContainerNode) d; - TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem()); - if (nodeType == TreeNodeType.IMAGE) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.SHAPE) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.MORPH_SHAPE) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.AS) { - ret.add(n); - } - if (nodeType == TreeNodeType.MOVIE) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.SOUND) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.BINARY_DATA) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.TEXT) { - ret.add((Tag) n.getItem()); - } - if (nodeType == TreeNodeType.FONT) { - ret.add((Tag) n.getItem()); - } - } - if (d instanceof FrameNode) { - FrameNode fn = (FrameNode) d; - if (!fn.scriptsNode) { - ret.add(d.getItem()); - } - } - if (d instanceof TreeElement) { - if (((TreeElement) d).isLeaf()) { - TreeElement treeElement = (TreeElement) d; - ret.add((ScriptPack) treeElement.getItem()); - } - } - } - return ret; - } - public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException { List ret = new ArrayList<>(); - List sel = getAllSelected(tagTree); + List sel = tagTree.getAllSelected(tagTree); for (SWFList swfList : swfs) { for (SWF swf : swfList) { @@ -1371,16 +1118,24 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return null; } - TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); - if (treeNode == null) { - return swfs.get(0).get(0); - } + if (treePanelMode == TreePanelMode.TAG_TREE) { + TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); + if (treeNode == null) { + return swfs.get(0).get(0); + } - if (treeNode instanceof SWFBundleNode) { - return null; - } + if (treeNode instanceof SWFBundleNode) { + return null; + } - return treeNode.getItem().getSwf(); + return treeNode.getItem().getSwf(); + } else if (treePanelMode == TreePanelMode.DUMP_TREE) { + DumpInfo dumpInfo = (DumpInfo) dumpTree.getLastSelectedPathComponent(); + + return DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf(); + } + + return null; } private void clearCache() { @@ -1849,7 +1604,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public void export(final boolean onlySel) { final SWF swf = getCurrentSwf(); - List sel = getSelection(swf); + List sel = tagTree.getSelection(swf); if (!onlySel) { sel = null; } else { @@ -2085,6 +1840,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec showCard(CARDEMPTYPANEL); TreeItem treeItem = tagTree.getCurrentTreeItem(); View.refreshTree(tagTree, new TagTreeModel(mainFrame, swfs)); + View.refreshTree(dumpTree, new DumpTreeModel(swfs)); if (treeItem != null) { setTreeItem(treeItem); } @@ -2274,74 +2030,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } break; - case ACTION_RAW_EDIT: { - TreeItem item = tagTree.getCurrentTreeItem(); - if (item == null) { - return; - } - - showCard(CARDPREVIEWPANEL); - previewPanel.showGenericTagPanel((Tag) item); - } - break; - case ACTION_JUMP_TO_CHARACTER: { - TreeItem item = tagTree.getCurrentTreeItem(); - if (item == null || !(item instanceof CharacterIdTag)) { - return; - } - - CharacterIdTag characterIdTag = (CharacterIdTag) item; - setTreeItem(item.getSwf().characters.get(characterIdTag.getCharacterId())); - } - break; - case ACTION_EXPAND_RECURSIVE: { - TreePath path = tagTree.getSelectionPath(); - if (path == null) { - return; - } - View.expandTreeNodesRecursive(tagTree, path, true); - } - break; - case ACTION_REMOVE_ITEM: - case ACTION_REMOVE_ITEM_WITH_DEPENDENCIES: - List sel = getSelected(tagTree); - - List tagsToRemove = new ArrayList<>(); - for (TreeNode o : sel) { - TreeItem tag = o.getItem(); - if (tag instanceof Tag) { - tagsToRemove.add((Tag) tag); - } else if (tag instanceof FrameNodeItem) { - FrameNodeItem frameNode = (FrameNodeItem) tag; - Frame frame = frameNode.getParent().getTimeline().frames.get(frameNode.getFrame() - 1); - if (frame.showFrameTag != null) { - tagsToRemove.add(frame.showFrameTag); - } else { - // this should be the last frame, so remove the inner tags - tagsToRemove.addAll(frame.innerTags); - } - } - } - - boolean removeDependencies = e.getActionCommand().equals(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES); - if (tagsToRemove.size() == 1) { - Tag tag = tagsToRemove.get(0); - if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tag.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { - tag.getSwf().removeTag(tag, removeDependencies); - refreshTree(); - } - } else if (tagsToRemove.size() > 1) { - if (View.showConfirmDialog(this, translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { - for (Tag tag : tagsToRemove) { - tag.getSwf().removeTag(tag, removeDependencies); - } - refreshTree(); - } - } - break; - case ACTION_CLOSE_SWF: { - Main.closeFile(getCurrentSwfList()); - } } if (Main.isWorking()) { return; @@ -2382,8 +2070,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private void dumpTreeValueChanged(TreeSelectionEvent e) { DumpInfo dumpInfo = (DumpInfo) e.getPath().getLastPathComponent(); - // todo honfika: support multiple swf - dumpViewPanel.setData(swfs.get(0).swfs.get(0).uncompressedData, dumpInfo); + + dumpViewPanel.setData(DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().uncompressedData, dumpInfo); dumpViewPanel.revalidate(); showCard(CARDDUMPVIEW); } @@ -2438,8 +2126,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec treePanel.removeAll(); if (show) { treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER); + treePanelMode = TreePanelMode.DUMP_TREE; } else { treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER); + treePanelMode = TreePanelMode.TAG_TREE; } treePanel.revalidate(); } @@ -2619,13 +2309,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.setParametersPanelVisible(false); } } else if (tagObj instanceof Tag) { - showCard(CARDPREVIEWPANEL); - previewPanel.showGenericTagPanel((Tag) tagObj); + showGenericTag((Tag) tagObj); } else { showCard(CARDEMPTYPANEL); } } + public void showGenericTag(Tag tag) { + + showCard(CARDPREVIEWPANEL); + previewPanel.showGenericTagPanel(tag); + } + private void showFontTag(FontTag ft) { previewPanel.showFontPanel(ft); diff --git a/src/com/jpexs/decompiler/flash/gui/TagTree.java b/src/com/jpexs/decompiler/flash/gui/TagTree.java index 6bf46f303..f430af2ac 100644 --- a/src/com/jpexs/decompiler/flash/gui/TagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/TagTree.java @@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; +import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.gui.treenodes.TagTreeRoot; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; @@ -49,7 +51,11 @@ import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; +import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem; import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; @@ -57,24 +63,48 @@ import com.jpexs.decompiler.flash.treeitems.SWFList; import com.jpexs.decompiler.flash.treeitems.StringItem; import com.jpexs.decompiler.flash.treeitems.TreeElementItem; import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.flash.treenodes.ContainerNode; +import com.jpexs.decompiler.flash.treenodes.FrameNode; import com.jpexs.decompiler.flash.treenodes.TreeNode; +import com.jpexs.helpers.Helper; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; import javax.swing.JTree; +import javax.swing.SwingUtilities; import javax.swing.plaf.basic.BasicLabelUI; import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; /** * * @author JPEXS */ -public class TagTree extends JTree { +public class TagTree extends JTree implements ActionListener { + + private static final String ACTION_RAW_EDIT = "RAWEDIT"; + private static final String ACTION_JUMP_TO_CHARACTER = "JUMPTOCHARACTER"; + private static final String ACTION_REMOVE_ITEM = "REMOVEITEM"; + private static final String ACTION_REMOVE_ITEM_WITH_DEPENDENCIES = "REMOVEITEMWITHDEPENDENCIES"; + private static final String ACTION_CLOSE_SWF = "CLOSESWF"; + private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE"; + + private final MainPanel mainPanel; public class TagTreeCellRenderer extends DefaultTreeCellRenderer { @@ -140,8 +170,9 @@ public class TagTree extends JTree { } } - TagTree(TagTreeModel treeModel) { + TagTree(TagTreeModel treeModel, MainPanel mainPanel) { super(treeModel); + this.mainPanel = mainPanel; setCellRenderer(new TagTreeCellRenderer()); setRootVisible(false); setBackground(Color.white); @@ -246,43 +277,322 @@ public class TagTree extends JTree { return TreeNodeType.OTHER_TAG; } - /*if(t instanceof StringNode){ - StringNode sn=(StringNode)t; - String name = sn.getItem().getName(); - if(name!=null){ - switch(name){ - case TagTreeModel.FOLDER_BINARY_DATA: - break; - case TagTreeModel.FOLDER_BUTTONS: - break; - case TagTreeModel.FOLDER_FONTS: - break; - case TagTreeModel.FOLDER_FRAMES: - break; - case TagTreeModel.FOLDER_IMAGES: - break; - case TagTreeModel.FOLDER_MORPHSHAPES: - break; - case TagTreeModel.FOLDER_MOVIES: - break; - case TagTreeModel.FOLDER_OTHERS: - break; - case TagTreeModel.FOLDER_SCRIPTS: - break; - case TagTreeModel.FOLDER_SHAPES: - break; - case TagTreeModel.FOLDER_SOUNDS: - break; - case TagTreeModel.FOLDER_SPRITES: - break; - case TagTreeModel.FOLDER_TEXTS: - break; - } - } - }*/ return TreeNodeType.FOLDER; } + public void createContextMenu(final List swfs) { + final JPopupMenu contextPopupMenu = new JPopupMenu(); + + final JMenuItem expandRecursiveMenuItem = new JMenuItem(mainPanel.translate("contextmenu.expandAll")); + expandRecursiveMenuItem.addActionListener(this); + expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE); + contextPopupMenu.add(expandRecursiveMenuItem); + + final JMenuItem removeMenuItem = new JMenuItem(mainPanel.translate("contextmenu.remove")); + removeMenuItem.addActionListener(this); + removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM); + contextPopupMenu.add(removeMenuItem); + + final JMenuItem removeWithDependenciesMenuItem = new JMenuItem(mainPanel.translate("contextmenu.removeWithDependencies")); + removeWithDependenciesMenuItem.addActionListener(this); + removeWithDependenciesMenuItem.setActionCommand(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES); + contextPopupMenu.add(removeWithDependenciesMenuItem); + + final JMenuItem exportSelectionMenuItem = new JMenuItem(mainPanel.translate("menu.file.export.selection")); + exportSelectionMenuItem.setActionCommand(MainFrameRibbonMenu.ACTION_EXPORT_SEL); + exportSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(exportSelectionMenuItem); + + final JMenuItem replaceSelectionMenuItem = new JMenuItem(mainPanel.translate("button.replace")); + replaceSelectionMenuItem.setActionCommand(MainPanel.ACTION_REPLACE); + replaceSelectionMenuItem.addActionListener(mainPanel); + contextPopupMenu.add(replaceSelectionMenuItem); + + final JMenuItem rawEditMenuItem = new JMenuItem(mainPanel.translate("contextmenu.rawEdit")); + rawEditMenuItem.setActionCommand(ACTION_RAW_EDIT); + rawEditMenuItem.addActionListener(this); + rawEditMenuItem.setVisible(false); + contextPopupMenu.add(rawEditMenuItem); + + final JMenuItem jumpToCharacterMenuItem = new JMenuItem(mainPanel.translate("contextmenu.jumpToCharacter")); + jumpToCharacterMenuItem.setActionCommand(ACTION_JUMP_TO_CHARACTER); + jumpToCharacterMenuItem.addActionListener(this); + jumpToCharacterMenuItem.setVisible(false); + contextPopupMenu.add(jumpToCharacterMenuItem); + + final JMenuItem closeSelectionMenuItem = new JMenuItem(mainPanel.translate("contextmenu.closeSwf")); + closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF); + closeSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(closeSelectionMenuItem); + + final JMenu moveTagMenu = new JMenu(mainPanel.translate("contextmenu.moveTag")); + contextPopupMenu.add(moveTagMenu); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + + int row = getClosestRowForLocation(e.getX(), e.getY()); + int[] selectionRows = getSelectionRows(); + if (!Helper.contains(selectionRows, row)) { + setSelectionRow(row); + } + + TreePath[] paths = getSelectionPaths(); + if (paths == null || paths.length == 0) { + return; + } + boolean allSelectedIsTagOrFrame = true; + for (TreePath treePath : paths) { + TreeNode treeNode = (TreeNode) treePath.getLastPathComponent(); + + TreeItem tag = treeNode.getItem(); + if (!(tag instanceof Tag) && !(tag instanceof FrameNodeItem)) { + allSelectedIsTagOrFrame = false; + break; + } + } + + replaceSelectionMenuItem.setVisible(false); + closeSelectionMenuItem.setVisible(false); + moveTagMenu.setVisible(false); + expandRecursiveMenuItem.setVisible(false); + + if (paths.length == 1) { + TreeNode treeNode = (TreeNode) paths[0].getLastPathComponent(); + + TreeItem item = ((TreeNode) treeNode).getItem(); + + if (item instanceof ImageTag && ((ImageTag) item).importSupported()) { + replaceSelectionMenuItem.setVisible(true); + } + + if (item instanceof DefineBinaryDataTag) { + replaceSelectionMenuItem.setVisible(true); + } + + if (item instanceof DefineSoundTag) { + replaceSelectionMenuItem.setVisible(true); + } + + if (treeNode instanceof SWFNode) { + closeSelectionMenuItem.setVisible(true); + } + + if (item instanceof Tag && swfs.size() > 1) { + final Tag tag = (Tag) item; + moveTagMenu.removeAll(); + for (SWFList targetSwfList : swfs) { + for (final SWF targetSwf : targetSwfList) { + if (targetSwf != tag.getSwf()) { + JMenuItem swfItem = new JMenuItem(targetSwf.getShortFileName()); + swfItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent ae) { + tag.getSwf().tags.remove(tag); + tag.setSwf(targetSwf); + targetSwf.tags.add(tag); + mainPanel.refreshTree(); + } + }); + moveTagMenu.add(swfItem); + } + } + } + moveTagMenu.setVisible(true); + } + + TreeModel model = getModel(); + expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0); + + jumpToCharacterMenuItem.setVisible(item instanceof CharacterIdTag && !(item instanceof CharacterTag)); + + rawEditMenuItem.setVisible(item instanceof Tag); + } + + removeMenuItem.setVisible(allSelectedIsTagOrFrame); + exportSelectionMenuItem.setEnabled(hasExportableNodes()); + contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand()) { + case ACTION_RAW_EDIT: { + TreeItem item = getCurrentTreeItem(); + if (item == null) { + return; + } + + mainPanel.showGenericTag((Tag) item); + } + break; + case ACTION_JUMP_TO_CHARACTER: { + TreeItem item = getCurrentTreeItem(); + if (item == null || !(item instanceof CharacterIdTag)) { + return; + } + + CharacterIdTag characterIdTag = (CharacterIdTag) item; + mainPanel.setTreeItem(item.getSwf().characters.get(characterIdTag.getCharacterId())); + } + break; + case ACTION_EXPAND_RECURSIVE: { + TreePath path = getSelectionPath(); + if (path == null) { + return; + } + View.expandTreeNodesRecursive(this, path, true); + } + break; + case ACTION_REMOVE_ITEM: + case ACTION_REMOVE_ITEM_WITH_DEPENDENCIES: + List sel = getSelected(this); + + List tagsToRemove = new ArrayList<>(); + for (TreeNode o : sel) { + TreeItem tag = o.getItem(); + if (tag instanceof Tag) { + tagsToRemove.add((Tag) tag); + } else if (tag instanceof FrameNodeItem) { + FrameNodeItem frameNode = (FrameNodeItem) tag; + Frame frame = frameNode.getParent().getTimeline().frames.get(frameNode.getFrame() - 1); + if (frame.showFrameTag != null) { + tagsToRemove.add(frame.showFrameTag); + } else { + // this should be the last frame, so remove the inner tags + tagsToRemove.addAll(frame.innerTags); + } + } + } + + boolean removeDependencies = e.getActionCommand().equals(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES); + if (tagsToRemove.size() == 1) { + Tag tag = tagsToRemove.get(0); + if (View.showConfirmDialog(this, mainPanel.translate("message.confirm.remove").replace("%item%", tag.toString()), mainPanel.translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + tag.getSwf().removeTag(tag, removeDependencies); + mainPanel.refreshTree(); + } + } else if (tagsToRemove.size() > 1) { + if (View.showConfirmDialog(this, mainPanel.translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), mainPanel.translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + for (Tag tag : tagsToRemove) { + tag.getSwf().removeTag(tag, removeDependencies); + } + mainPanel.refreshTree(); + } + } + break; + case ACTION_CLOSE_SWF: { + Main.closeFile(mainPanel.getCurrentSwfList()); + } + } + } + + public boolean hasExportableNodes() { + return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); + } + + public List getAllSubs(JTree tree, TreeNode o) { + TagTreeModel tm = (TagTreeModel) tree.getModel(); + List ret = new ArrayList<>(); + for (int i = 0; i < tm.getChildCount(o); i++) { + TreeNode c = tm.getChild(o, i); + ret.add(c); + ret.addAll(getAllSubs(tree, c)); + } + return ret; + } + + public List getAllSelected(TagTree tree) { + TreeSelectionModel tsm = tree.getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); + ret.add(treeNode); + ret.addAll(getAllSubs(tree, treeNode)); + } + return ret; + } + + public List getSelected(JTree tree) { + TreeSelectionModel tsm = tree.getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); + ret.add(treeNode); + } + return ret; + } + + public List getSelection(SWF swf) { + List ret = new ArrayList<>(); + List sel = getAllSelected(this); + for (TreeNode d : sel) { + if (d.getItem().getSwf() != swf) { + continue; + } + if (d instanceof ContainerNode) { + ContainerNode n = (ContainerNode) d; + TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem()); + if (nodeType == TreeNodeType.IMAGE) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.SHAPE) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.MORPH_SHAPE) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.AS) { + ret.add(n); + } + if (nodeType == TreeNodeType.MOVIE) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.SOUND) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.BINARY_DATA) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.TEXT) { + ret.add((Tag) n.getItem()); + } + if (nodeType == TreeNodeType.FONT) { + ret.add((Tag) n.getItem()); + } + } + if (d instanceof FrameNode) { + FrameNode fn = (FrameNode) d; + if (!fn.scriptsNode) { + ret.add(d.getItem()); + } + } + if (d instanceof TreeElement) { + if (((TreeElement) d).isLeaf()) { + TreeElement treeElement = (TreeElement) d; + ret.add((ScriptPack) treeElement.getItem()); + } + } + } + return ret; + } + public List getTagsWithType(List list, TreeNodeType type) { List ret = new ArrayList<>(); for (TreeElementItem item : list) { diff --git a/src/com/jpexs/decompiler/flash/gui/TreePanelMode.java b/src/com/jpexs/decompiler/flash/gui/TreePanelMode.java new file mode 100644 index 000000000..8e7ec2ecc --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/TreePanelMode.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +/** + * + * @author JPEXS + */ +public enum TreePanelMode { + + TAG_TREE, DUMP_TREE +} diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java new file mode 100644 index 000000000..067fa9aee --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.dumpview; + +import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; +import com.jpexs.decompiler.flash.gui.Main; +import com.jpexs.decompiler.flash.gui.MainPanel; +import com.jpexs.decompiler.flash.gui.View; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.helpers.Helper; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicLabelUI; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +/** + * + * @author JPEXS + */ +public class DumpTree extends JTree implements ActionListener { + + private static final String ACTION_CLOSE_SWF = "CLOSESWF"; + private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE"; + + private final MainPanel mainPanel; + + public class DumpTreeCellRenderer extends DefaultTreeCellRenderer { + + @Override + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + super.getTreeCellRendererComponent( + tree, value, sel, + expanded, leaf, row, + hasFocus); + + //DumpInfo dumpInfo = (DumpInfo) value; + setUI(new BasicLabelUI()); + setOpaque(false); + setBackgroundNonSelectionColor(Color.white); + + return this; + } + } + + public DumpTree(DumpTreeModel treeModel, MainPanel mainPanel) { + super(treeModel); + this.mainPanel = mainPanel; + setCellRenderer(new DumpTreeCellRenderer()); + setRootVisible(false); + setBackground(Color.white); + setUI(new BasicTreeUI() { + @Override + public void paint(Graphics g, JComponent c) { + setHashColor(Color.gray); + super.paint(g, c); + } + }); + } + + public void createContextMenu() { + final JPopupMenu contextPopupMenu = new JPopupMenu(); + + final JMenuItem expandRecursiveMenuItem = new JMenuItem(mainPanel.translate("contextmenu.expandAll")); + expandRecursiveMenuItem.addActionListener(this); + expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE); + contextPopupMenu.add(expandRecursiveMenuItem); + + final JMenuItem closeSelectionMenuItem = new JMenuItem(mainPanel.translate("contextmenu.closeSwf")); + closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF); + closeSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(closeSelectionMenuItem); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + + int row = getClosestRowForLocation(e.getX(), e.getY()); + int[] selectionRows = getSelectionRows(); + if (!Helper.contains(selectionRows, row)) { + setSelectionRow(row); + } + + TreePath[] paths = getSelectionPaths(); + if (paths == null || paths.length == 0) { + return; + } + closeSelectionMenuItem.setVisible(false); + expandRecursiveMenuItem.setVisible(false); + + if (paths.length == 1) { + DumpInfo treeNode = (DumpInfo) paths[0].getLastPathComponent(); + + if (treeNode instanceof DumpInfoSwfNode) { + closeSelectionMenuItem.setVisible(true); + } + + TreeModel model = getModel(); + expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0); + } + + contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand()) { + case ACTION_EXPAND_RECURSIVE: { + TreePath path = getSelectionPath(); + if (path == null) { + return; + } + View.expandTreeNodesRecursive(this, path, true); + } + break; + case ACTION_CLOSE_SWF: { + Main.closeFile(mainPanel.getCurrentSwfList()); + } + } + } + + @Override + public void setModel(TreeModel tm) { + super.setModel(tm); + if (tm != null) { + int rowCount = tm.getChildCount(tm.getRoot()); + for (int i = rowCount - 1; i >= 0; i--) { + expandRow(i); + } + } + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTreeModel.java similarity index 97% rename from src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java rename to src/com/jpexs/decompiler/flash/gui/dumpview/DumpTreeModel.java index 877998a98..93957a3db 100644 --- a/src/com/jpexs/decompiler/flash/gui/DumpTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTreeModel.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.gui; +package com.jpexs.decompiler.flash.gui.dumpview; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.dumpview.DumpInfo; diff --git a/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java similarity index 97% rename from src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java rename to src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java index 8ebf563a7..a9d0a96c9 100644 --- a/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java @@ -14,9 +14,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.gui; +package com.jpexs.decompiler.flash.gui.dumpview; import com.jpexs.decompiler.flash.dumpview.DumpInfo; +import com.jpexs.decompiler.flash.gui.HexView; import java.awt.BorderLayout; import java.awt.Dimension; import java.util.ArrayList;