From 9e771ae9ede0f47973f55112d696bd907392de22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 30 Oct 2022 09:00:49 +0100 Subject: [PATCH] Tag list view - model refactored - does not use DefaultTreeModel now --- .../flash/gui/FolderPreviewPanel.java | 2 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 424 ++++++--------- .../flash/gui/taglistview/TagListTree.java | 264 ++------- .../taglistview/TagListTreeCellRenderer.java | 12 +- .../gui/taglistview/TagListTreeModel.java | 301 +++++++++++ .../gui/taglistview/TagListTreeNode.java | 103 ---- .../gui/taglistview/TagListTreeRoot.java | 38 ++ .../flash/gui/tagtree/AbstractTagTree.java | 505 ++++++++++++++++++ .../gui/tagtree/AbstractTagTreeModel.java | 134 +++++ .../decompiler/flash/gui/tagtree/TagTree.java | 228 +------- .../flash/gui/tagtree/TagTreeContextMenu.java | 205 ++----- .../flash/gui/tagtree/TagTreeModel.java | 95 +--- 12 files changed, 1279 insertions(+), 1032 deletions(-) create mode 100644 src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeModel.java delete mode 100644 src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeNode.java create mode 100644 src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeRoot.java create mode 100644 src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java create mode 100644 src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTreeModel.java diff --git a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java index 3efd7a506..f7eb7c034 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java @@ -149,7 +149,7 @@ public class FolderPreviewPanel extends JPanel { } if (e.getButton() == MouseEvent.BUTTON3) { - mainPanel.getContextPopupMenu().update(new ArrayList<>(selectedItems.values()), mainPanel.getCurrentView()); + mainPanel.getContextPopupMenu().update(new ArrayList<>(selectedItems.values())); mainPanel.getContextPopupMenu().show(FolderPreviewPanel.this, e.getX(), e.getY()); } repaint(); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 9702ec8eb..0692e674e 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -92,7 +92,9 @@ import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane; import com.jpexs.decompiler.flash.gui.helpers.ObservableList; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import com.jpexs.decompiler.flash.gui.taglistview.TagListTree; -import com.jpexs.decompiler.flash.gui.taglistview.TagListTreeNode; +import com.jpexs.decompiler.flash.gui.taglistview.TagListTreeModel; +import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; +import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel; import com.jpexs.decompiler.flash.gui.tagtree.TagTree; import com.jpexs.decompiler.flash.gui.tagtree.TagTreeContextMenu; import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel; @@ -256,6 +258,7 @@ import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.tree.DefaultTreeSelectionModel; import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; import jsyntaxpane.DefaultSyntaxKit; /** @@ -365,17 +368,111 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private int currentView = VIEW_RESOURCES; public List searchResultsDialogs = new ArrayList<>(); - + private TagTreeContextMenu contextPopupMenu; private static final Logger logger = Logger.getLogger(MainPanel.class.getName()); + private class MyTreeSelectionModel extends DefaultTreeSelectionModel { + + private boolean isModified() { + if (abcPanel != null && abcPanel.isEditing()) { + abcPanel.tryAutoSave(); + } + + if (actionPanel != null && actionPanel.isEditing()) { + actionPanel.tryAutoSave(); + } + + if (previewPanel.isEditing()) { + previewPanel.tryAutoSave(); + } + + if (headerPanel.isEditing()) { + headerPanel.tryAutoSave(); + } + + return (abcPanel != null && abcPanel.isEditing()) + || (actionPanel != null && actionPanel.isEditing()) + || previewPanel.isEditing() || headerPanel.isEditing(); + } + + @Override + public void addSelectionPath(TreePath path) { + if (isModified()) { + return; + } + + super.addSelectionPath(path); + } + + @Override + public void addSelectionPaths(TreePath[] paths) { + if (isModified()) { + return; + } + + super.addSelectionPaths(paths); + } + + @Override + public void setSelectionPath(TreePath path) { + if (isModified()) { + return; + } + + super.setSelectionPath(path); + } + + @Override + public void setSelectionPaths(TreePath[] pPaths) { + if (isModified()) { + return; + } + + super.setSelectionPaths(pPaths); + } + + @Override + public void clearSelection() { + if (isModified()) { + return; + } + + super.clearSelection(); + } + + public void setSelection(TreePath[] selection) { + if (isModified()) { + return; + } + + this.selection = selection; + } + + @Override + public void removeSelectionPath(TreePath path) { + if (isModified()) { + return; + } + + super.removeSelectionPath(path); + } + + @Override + public void removeSelectionPaths(TreePath[] paths) { + if (isModified()) { + return; + } + + super.removeSelectionPaths(paths); + } + } + public TagTreeContextMenu getContextPopupMenu() { return contextPopupMenu; } - - public void setPercent(int percent) { View.checkAccess(); @@ -513,103 +610,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName()); tagTree = new TagTree(null, this); tagTree.addTreeSelectionListener(this); - tagTree.setSelectionModel(new DefaultTreeSelectionModel() { - private boolean isModified() { - if (abcPanel != null && abcPanel.isEditing()) { - abcPanel.tryAutoSave(); - } + tagTree.setSelectionModel(new MyTreeSelectionModel()); - if (actionPanel != null && actionPanel.isEditing()) { - actionPanel.tryAutoSave(); - } - - if (previewPanel.isEditing()) { - previewPanel.tryAutoSave(); - } - - if (headerPanel.isEditing()) { - headerPanel.tryAutoSave(); - } - - return (abcPanel != null && abcPanel.isEditing()) - || (actionPanel != null && actionPanel.isEditing()) - || previewPanel.isEditing() || headerPanel.isEditing(); - } - - @Override - public void addSelectionPath(TreePath path) { - if (isModified()) { - return; - } - - super.addSelectionPath(path); - } - - @Override - public void addSelectionPaths(TreePath[] paths) { - if (isModified()) { - return; - } - - super.addSelectionPaths(paths); - } - - @Override - public void setSelectionPath(TreePath path) { - if (isModified()) { - return; - } - - super.setSelectionPath(path); - } - - @Override - public void setSelectionPaths(TreePath[] pPaths) { - if (isModified()) { - return; - } - - super.setSelectionPaths(pPaths); - } - - @Override - public void clearSelection() { - if (isModified()) { - return; - } - - super.clearSelection(); - } - - public void setSelection(TreePath[] selection) { - if (isModified()) { - return; - } - - this.selection = selection; - } - - @Override - public void removeSelectionPath(TreePath path) { - if (isModified()) { - return; - } - - super.removeSelectionPath(path); - } - - @Override - public void removeSelectionPaths(TreePath[] paths) { - if (isModified()) { - return; - } - - super.removeSelectionPaths(paths); - } - }); - - tagListTree = new TagListTree(this); + tagListTree = new TagListTree(null, this); tagListTree.addTreeSelectionListener(this); + tagListTree.setSelectionModel(new MyTreeSelectionModel()); DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(tagTree, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() { @@ -690,7 +695,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } }); - contextPopupMenu = new TagTreeContextMenu(tagTree, tagListTree, this); + List trees = new ArrayList<>(); + trees.add(tagTree); + trees.add(tagListTree); + + contextPopupMenu = new TagTreeContextMenu(trees, this); dumpTree = new DumpTree(null, this); dumpTree.addTreeSelectionListener(this); @@ -825,7 +834,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se updateUi(); this.swfs.addCollectionChangedListener((e) -> { - TagTreeModel ttm = tagTree.getModel(); + AbstractTagTreeModel ttm = tagTree.getModel(); if (ttm != null) { if (getCurrentSwf() == null) { tagTree.setSelectionPath(ttm.getTreePath(ttm.getRoot())); @@ -834,6 +843,15 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se tagTree.expandRoot(); tagTree.expandFirstLevelNodes(); } + ttm = tagListTree.getModel(); + if (ttm != null) { + if (getCurrentSwf() == null) { + tagListTree.setSelectionPath(ttm.getTreePath(ttm.getRoot())); + } + ttm.updateSwfs(e); + tagListTree.expandRoot(); + tagListTree.expandFirstLevelNodes(); + } DumpTreeModel dtm = dumpTree.getModel(); if (dtm != null) { @@ -844,12 +862,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se dumpTree.expandFirstLevelNodes(); } - if (tagListTree.isInitialized()) { - tagListTree.updateSwfs(); - tagListTree.expandRoot(); - tagListTree.expandFirstLevelNodes(); - } - if (swfs.isEmpty()) { tagTree.setUI(new BasicTreeUI() { { @@ -1274,10 +1286,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return tagTree.getSelection(getCurrentSwf()); } else if (currentView == MainPanel.VIEW_TAGLIST) { return tagListTree.getSelection(getCurrentSwf()); - } + } return new ArrayList<>(); } - + public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException, InterruptedException { List ret = new ArrayList<>(); @@ -1756,38 +1768,31 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf(); } else if (treePanelMode == TreePanelMode.TAGLIST_TREE) { - TagListTreeNode node = (TagListTreeNode) tagListTree.getLastSelectedPathComponent(); - if (node == null) { - return null; - } - TreeItem treeNode = (TreeItem) node.getData(); + TreeItem treeNode = (TreeItem) tagListTree.getLastSelectedPathComponent(); if (treeNode == null || treeNode instanceof SWFList) { return null; } + return treeNode.getSwf(); } return null; } - - private TreeItem getLastSelectedPathComponent() { + + public AbstractTagTree getCurrentTree() { if (currentView == VIEW_RESOURCES) { - return (TreeItem)tagTree.getLastSelectedPathComponent(); + return tagTree; } if (currentView == VIEW_TAGLIST) { - TagListTreeNode node = (TagListTreeNode)tagListTree.getLastSelectedPathComponent(); - if (node == null) { - return null; - } - return (TreeItem) node.getData(); + return tagListTree; } - return null; + return tagTree; //??? } public void gotoFrame(int frame) { View.checkAccess(); - TreeItem treeItem = (TreeItem) getLastSelectedPathComponent(); + TreeItem treeItem = (TreeItem) getCurrentTree().getLastSelectedPathComponent(); if (treeItem == null) { return; } @@ -1939,7 +1944,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } return new LinkedHashSet<>(allSwfs); } - + private List getAllSelected() { if (currentView == VIEW_RESOURCES) { return tagTree.getAllSelected(); @@ -1959,7 +1964,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } return new ArrayList<>(); } - + public void searchInActionScriptOrText(Boolean searchInText, SWF swf, boolean useSelection) { View.checkAccess(); @@ -2276,24 +2281,17 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } public void setTagTreeSelectedNode(TreeItem treeItem) { - if (currentView == VIEW_RESOURCES) { - TagTreeModel ttm = tagTree.getModel(); - TreePath tp = ttm.getTreePath(treeItem); - if (tp != null) { - tagTree.setSelectionPath(tp); - tagTree.scrollPathToVisible(tp); - } else { - showCard(CARDEMPTYPANEL); - } + if (currentView != VIEW_RESOURCES && currentView != VIEW_TAGLIST) { + return; } - if (currentView == VIEW_TAGLIST) { - TreePath tp = tagListTree.getPathForData(treeItem); - if (tp != null) { - tagListTree.setSelectionPath(tp); - tagListTree.scrollPathToVisible(tp); - } else { - showCard(CARDEMPTYPANEL); - } + AbstractTagTree tree = getCurrentTree(); + AbstractTagTreeModel ttm = tree.getModel(); + TreePath tp = ttm.getTreePath(treeItem); + if (tp != null) { + tree.setSelectionPath(tp); + tree.scrollPathToVisible(tp); + } else { + showCard(CARDEMPTYPANEL); } } @@ -3005,7 +3003,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } public void treeOperation(Runnable runnable) { - TreeItem treeItem = getCurrentTreeItem(); + TreeItem treeItem = getCurrentTree().getCurrentTreeItem(); tagTree.clearSelection(); tagListTree.clearSelection(); runnable.run(); @@ -3013,7 +3011,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se showCard(CARDEMPTYPANEL); tagTree.updateSwfs(new SWF[0]); - tagListTree.updateSwfs(); + tagListTree.updateSwfs(new SWF[0]); if (treeItem != null) { SWF swf = treeItem.getSwf(); @@ -3036,17 +3034,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se clear(); showCard(CARDEMPTYPANEL); TreeItem treeItem = null; - if (currentView == VIEW_RESOURCES) { - treeItem = tagTree.getCurrentTreeItem(); - } else if (currentView == VIEW_TAGLIST) { - TagListTreeNode node = (TagListTreeNode) tagListTree.getLastSelectedPathComponent(); - if (node != null) { - treeItem = (TreeItem) node.getData(); - } + if (currentView == VIEW_RESOURCES || currentView == VIEW_TAGLIST) { + treeItem = getCurrentTree().getCurrentTreeItem(); } tagTree.updateSwfs(swfs); - tagListTree.updateSwfs(); + tagListTree.updateSwfs(swfs); if (treeItem != null) { SWF swf = treeItem.getSwf(); @@ -3127,11 +3120,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se public boolean previousTag() { JTree tree = null; if (getCurrentView() == VIEW_RESOURCES) { - tree = tagTree; + tree = tagTree; } else if (getCurrentView() == VIEW_TAGLIST) { - tree = tagTree; + tree = tagTree; } - + if (tree != null) { if (tree.getSelectionRows().length > 0) { int row = tree.getSelectionRows()[0]; @@ -3143,16 +3136,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } return true; } - + return false; } public boolean nextTag() { JTree tree = null; if (getCurrentView() == VIEW_RESOURCES) { - tree = tagTree; + tree = tagTree; } else if (getCurrentView() == VIEW_TAGLIST) { - tree = tagTree; + tree = tagTree; } if (tree != null) { if (tree.getSelectionRows().length > 0) { @@ -3297,22 +3290,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } - - private TreeItem getCurrentTreeItem() { - if (currentView == MainPanel.VIEW_RESOURCES) { - return tagTree.getCurrentTreeItem(); - } - if (currentView == MainPanel.VIEW_TAGLIST) { - TagListTreeNode node = (TagListTreeNode) tagListTree.getLastSelectedPathComponent(); - if (node != null) { - return (TreeItem) node.getData(); - } - } - return null; - } - public void replaceNoFillButtonActionPerformed(ActionEvent evt) { - TreeItem item = getCurrentTreeItem(); + TreeItem item = getCurrentTree().getCurrentTreeItem(); if (item == null) { return; } @@ -3354,7 +3333,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } public void replaceAlphaButtonActionPerformed(ActionEvent evt) { - TreeItem item = getCurrentTreeItem(); + TreeItem item = getCurrentTree().getCurrentTreeItem(); if (item == null) { return; } @@ -3500,17 +3479,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } private void valueChanged(Object source, TreePath selectedPath) { - TreeItem treeItem = null; - if (selectedPath != null) { - if (source == tagListTree) { - TagListTreeNode node = (TagListTreeNode) selectedPath.getLastPathComponent(); - if (node != null) { - treeItem = (TreeItem) node.getData(); - } - } else { - treeItem = (TreeItem) selectedPath.getLastPathComponent(); - } - } + TreeItem treeItem = (TreeItem) selectedPath.getLastPathComponent(); if (treeItem == null) { return; @@ -3553,35 +3522,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se valueChanged(source, e.getPath()); } - public TreePath convertViewPath(TreePath path) { - if (currentView == VIEW_RESOURCES) { - return path; - } - if (currentView == VIEW_TAGLIST) { - Object newPath[] = new Object[path.getPathCount()]; - for (int i = 0; i < path.getPathCount(); i++) { - TagListTreeNode node = (TagListTreeNode) path.getPathComponent(i); - newPath[i] = node.getData(); - } - return new TreePath(newPath); - } - return null; - } - private int getFrameForTreeItem(TreeItem treeItem) { if (treeItem == null) { return -1; } - TreePath path = null; - if (currentView == VIEW_RESOURCES) { - path = tagTree.getModel().getTreePath(treeItem); - } else if (currentView == VIEW_TAGLIST) { - path = tagListTree.getPathForData(treeItem); - } + TreePath path = getCurrentTree().getModel().getTreePath(treeItem); if (path == null) { return -1; } - path = convertViewPath(path); for (int i = path.getPathCount() - 1; i >= 0; i--) { if (path.getPathComponent(i) instanceof Frame) { Frame frame = (Frame) path.getPathComponent(i); @@ -3596,16 +3544,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return null; } - TreePath path = null; - if (currentView == VIEW_RESOURCES) { - path = tagTree.getModel().getTreePath(treeItem); - } else if (currentView == VIEW_TAGLIST) { - path = tagListTree.getPathForData(treeItem); - } + TreePath path = getCurrentTree().getModel().getTreePath(treeItem); if (path == null) { return null; } - path = convertViewPath(path); for (int i = path.getPathCount() - 1; i >= 0; i--) { if (path.getPathComponent(i) instanceof Timelined) { return (Timelined) path.getPathComponent(i); @@ -3688,8 +3630,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } break; case VIEW_TAGLIST: - if (!tagListTree.isInitialized()) { - tagListTree.setSwfs(swfs); + if (tagListTree.getModel() == null) { + TagListTreeModel ttm = new TagListTreeModel(swfs); + tagListTree.setModel(ttm); tagListTree.expandFirstLevelNodes(); } break; @@ -3728,8 +3671,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se public boolean showView(int view) { View.checkAccess(); - int prevView = currentView; - boolean okay = false; setTreeModel(view); switch (view) { case VIEW_DUMP: @@ -3741,8 +3682,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se treePanelMode = TreePanelMode.DUMP_TREE; showDetail(DETAILCARDEMPTYPANEL); reload(true); - okay = true; - break; + return true; case VIEW_RESOURCES: currentView = view; if (!isWelcomeScreen) { @@ -3760,13 +3700,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se }); reload(true); - okay = true; - break; + return true; case VIEW_TIMELINE: currentView = view; final SWF swf = getCurrentSwf(); if (swf != null) { - TreeItem item = getCurrentTreeItem(); + TreeItem item = getCurrentTree().getCurrentTreeItem(); if (item instanceof TagScript) { item = ((TagScript) item).getTag(); } @@ -3778,11 +3717,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se timelineViewPanel.setTimelined(swf); } showContentPanelCard(TIMELINE_PANEL); - okay = true; - break; + return true; } - okay = false; - break; + return false; case VIEW_TAGLIST: currentView = view; if (!isWelcomeScreen) { @@ -3791,23 +3728,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se showTreePanelCard(TAGLIST_VIEW); treePanelMode = TreePanelMode.TAGLIST_TREE; reload(true); - okay = true; + return true; } - if (prevView != currentView) { - viewChanged(); - } - - return okay; - } - - private void viewChanged() { - if (currentView == VIEW_RESOURCES) { - valueChanged(tagTree, tagTree.getSelectionPath()); - } - if (currentView == VIEW_TAGLIST) { - valueChanged(tagListTree, tagListTree.getSelectionPath()); - } + return false; } private void dumpViewReload(boolean forceReload) { @@ -3985,17 +3909,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return; }*/ + AbstractTagTree tree = getCurrentTree(); TreeItem treeItem = null; - if (currentView == VIEW_RESOURCES) { - TreePath treePath = tagTree.getSelectionPath(); - if (treePath != null && tagTree.getModel().treePathExists(treePath)) { - treeItem = (TreeItem) treePath.getLastPathComponent(); - } - } else if (currentView == VIEW_TAGLIST) { - TagListTreeNode node = (TagListTreeNode) tagListTree.getLastSelectedPathComponent(); - if (node != null) { - treeItem = (TreeItem) node.getData(); - } + TreePath treePath = tree.getSelectionPath(); + if (treePath != null && tree.getModel().treePathExists(treePath)) { + treeItem = (TreeItem) treePath.getLastPathComponent(); } // save last selected node to config diff --git a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTree.java b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTree.java index c22a12b97..9f0fd0355 100644 --- a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTree.java +++ b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTree.java @@ -18,240 +18,72 @@ package com.jpexs.decompiler.flash.gui.taglistview; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.gui.MainPanel; -import com.jpexs.decompiler.flash.gui.View; -import com.jpexs.decompiler.flash.gui.tagtree.TagTree; +import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; +import static com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree.getSelection; +import com.jpexs.decompiler.flash.tags.DefineScalingGridTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.FrameLabelTag; +import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject3Tag; +import com.jpexs.decompiler.flash.tags.PlaceObject4Tag; +import com.jpexs.decompiler.flash.tags.PlaceObjectTag; +import com.jpexs.decompiler.flash.tags.RemoveObject2Tag; +import com.jpexs.decompiler.flash.tags.RemoveObjectTag; import com.jpexs.decompiler.flash.tags.ShowFrameTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; +import com.jpexs.decompiler.flash.tags.StartSound2Tag; +import com.jpexs.decompiler.flash.tags.StartSoundTag; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.timeline.Frame; -import com.jpexs.decompiler.flash.timeline.Timeline; -import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; import com.jpexs.decompiler.flash.treeitems.TreeItem; -import java.awt.Color; import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashSet; +import java.util.Arrays; import java.util.List; -import java.util.Set; -import javax.swing.JTree; -import javax.swing.plaf.basic.BasicTreeUI; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; /** * * @author JPEXS */ -public class TagListTree extends JTree { - - private List swfs; +public class TagListTree extends AbstractTagTree { - private TagListTreeNode root; - - private boolean initialized = false; - - private MainPanel mainPanel; - - public TagListTree(MainPanel mainPanel) { - this.mainPanel = mainPanel; - - setCellRenderer(new TagListTreeCellRenderer()); - setRootVisible(false); - setShowsRootHandles(true); - setRowHeight(Math.max(getFont().getSize() + 5, 16)); - - if (View.isOceanic()) { - setBackground(Color.white); - setUI(new BasicTreeUI() { - { - setHashColor(Color.gray); - } - }); - } - } - - public boolean isInitialized() { - return initialized; - } - - public void setSwfs(List swfs) { - this.swfs = swfs; - if (updateSwfs()) { - initialized = true; - } - } - - public boolean updateSwfs() { - if (swfs == null) { - return false; - } - TagListTreeNode newRoot = new TagListTreeNode(); - newRoot.setData("root"); - for (SWFList swfList : swfs) { - populateNodes(newRoot, swfList); - } - - List> expandedNodes = View.getExpandedNodes(this); - setModel(new DefaultTreeModel(newRoot)); - - View.expandTreeNodes(this, expandedNodes); - - root = newRoot; - return true; - } - - private void populateNodes(TagListTreeNode parent, Object obj) { - if (obj instanceof SWFList) { - SWFList list = (SWFList) obj; - TagListTreeNode node = new TagListTreeNode(); - node.setData(list); - node.setParent(parent); - parent.addChild(node); - - if (!list.isBundle()) { - node.setData(list.get(0)); - populateTimelineNodes(list.get(0), node, list.get(0)); - } else { - for (SWF swf : list) { - TagListTreeNode subNode = new TagListTreeNode(); - subNode.setData(swf); - subNode.setParent(node); - node.addChild(subNode); - parent.addChild(node); - populateTimelineNodes(swf, node, swf); - } - } - } - } - - private void populateTimelineNodes(SWF swf, TagListTreeNode root, Timelined timelined) { - int f = 0; - - Timeline timeline = timelined.getTimeline(); - - TagListTreeNode frameNode = new TagListTreeNode(); - Frame fr = timeline.getFrame(0); - if (fr == null) { - return; - } - frameNode.setData(fr); - frameNode.setParent(root); - root.addChild(frameNode); - - for (Tag t : timelined.getTags()) { - TagListTreeNode node = new TagListTreeNode(); - node.setData(t); - node.setParent(frameNode); - frameNode.addChild(node); - - if (t instanceof DefineSpriteTag) { - populateTimelineNodes(swf, node, (DefineSpriteTag) t); - } - if (t instanceof ShowFrameTag) { - f++; - fr = timeline.getFrame(f); - if (fr != null) { - frameNode = new TagListTreeNode(); - frameNode.setData(timeline.getFrame(f)); - frameNode.setParent(root); - root.addChild(frameNode); - } - } - } - } - - public void expandRoot() { - expandPath(new TreePath(new Object[]{root})); - } - - public void expandFirstLevelNodes() { - int childCount = root.getChildCount(); - for (int i = 0; i < childCount; i++) { - expandPath(new TreePath(new Object[]{root, root.getChildAt(i)})); - } - } - - - public TreePath getPathForData(Object data) { - TagListTreeNode node = getNodeForData(data); - if (node == null) { - return new TreePath(new Object[0]); - } - return getPathForNode(node); - } - - public TreePath getPathForNode(TagListTreeNode node) { - List path = new ArrayList<>(); - while (node.getParent() != null) { - path.add(0, node); - node = (TagListTreeNode)node.getParent(); - } - path.add(0, node); - Object[] pathArr = path.toArray(new Object[path.size()]); - return new TreePath(pathArr); - } - - public TagListTreeNode getNodeForData(Object data) { - return getNodeForData(root, data); - } - - private TagListTreeNode getNodeForData(TagListTreeNode startNode, Object data) { - if (startNode.getData() == data) { - return startNode; - } - for (int i = 0; i < startNode.getChildCount(); i++) { - TagListTreeNode foundNode = getNodeForData((TagListTreeNode)startNode.getChildAt(i), data); - if (foundNode != null) { - return foundNode; - } - } - return null; - } - - public List getSelected() { - TreePath[] paths = getSelectionPaths(); - Set selected = new LinkedHashSet<>(); - for (TreePath path : paths) { - selected.add((TreeItem)((TagListTreeNode)path.getLastPathComponent()).getData()); - } - List ret = new ArrayList<>(selected); - return ret; - } - - public List getAllSelected() { - TreePath[] paths = getSelectionPaths(); - Set selected = new LinkedHashSet<>(); - for (TreePath path : paths) { - populateSelected((TagListTreeNode)path.getLastPathComponent(), selected); - } - List ret = new ArrayList<>(selected); - return ret; - } + public TagListTree(TagListTreeModel model, MainPanel mainPanel) { + super(model, mainPanel); + setCellRenderer(new TagListTreeCellRenderer()); + } + @Override public List getSelection(SWF swf) { - return TagTree.getSelection(swf, getAllSelected()); + List sel; + sel = new ArrayList<>(); + + for (TreeItem treeItem : mainPanel.folderPreviewPanel.selectedItems.values()) { + sel.add(treeItem); + getAllSubs(treeItem, sel); + } + return getSelection(swf, sel); } - public void populateSelectedSwf(SWF swf, TagListTreeNode node, Set selected){ - TreeItem item = (TreeItem) node.getData(); - if (item.getSwf() == swf) { - selected.add(item); - } - - for (int i = 0; i < node.getChildCount(); i++) { - populateSelected((TagListTreeNode)node.getChildAt(i), selected); - } + @Override + public TagListTreeModel getModel() { + return (TagListTreeModel) super.getModel(); } - - public void populateSelected(TagListTreeNode node, Set selected){ - selected.add((TreeItem)node.getData()); - for (int i = 0; i < node.getChildCount(); i++) { - populateSelected((TagListTreeNode)node.getChildAt(i), selected); + + @Override + public List getNestedTagIds(Tag obj) { + if (obj instanceof DefineSpriteTag) { + return Arrays.asList(PlaceObjectTag.ID, PlaceObject2Tag.ID, PlaceObject3Tag.ID, PlaceObject4Tag.ID, + RemoveObjectTag.ID, RemoveObject2Tag.ID, ShowFrameTag.ID, FrameLabelTag.ID, + StartSoundTag.ID, StartSound2Tag.ID, VideoFrameTag.ID, + SoundStreamBlockTag.ID, SoundStreamHeadTag.ID, SoundStreamHead2Tag.ID, + DefineScalingGridTag.ID); //scaling grid? FIXME? } + return new ArrayList<>(); //FIXME: it should be actually all tags } - - public boolean hasExportableNodes() { - return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); + + @Override + public List getFrameNestedTagIds() { + return new ArrayList<>(); //FIXME: it should be alltags for swf timeline, limited for sprite timeline } } diff --git a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeCellRenderer.java b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeCellRenderer.java index d20f5ddbc..130fa5bad 100644 --- a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeCellRenderer.java +++ b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeCellRenderer.java @@ -51,13 +51,9 @@ public class TagListTreeCellRenderer extends DefaultTreeCellRenderer { @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { - Object subValue = value; - if (value instanceof TagListTreeNode) { - subValue = ((TagListTreeNode) value).getData(); - } TreeItem val = null; - if (subValue instanceof TreeItem) { - val = (TreeItem) subValue; + if (value instanceof TreeItem) { + val = (TreeItem) value; } if (val != null && !(val instanceof SWFList) && val.getSwf() == null) { @@ -69,8 +65,8 @@ public class TagListTreeCellRenderer extends DefaultTreeCellRenderer { if (renderer instanceof JLabel) { JLabel lab = (JLabel) renderer; - if (subValue instanceof TreeItem) { - lab.setIcon(TagTree.getIconForType(TagTree.getTreeNodeType((TreeItem) subValue))); + if (value instanceof TreeItem) { + lab.setIcon(TagTree.getIconForType(TagTree.getTreeNodeType((TreeItem) value))); boolean isReadOnly = false; if (val instanceof Tag) { diff --git a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeModel.java b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeModel.java new file mode 100644 index 000000000..4d6cda5c2 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeModel.java @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2022 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.taglistview; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedAction; +import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedEvent; +import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.treeitems.HeaderItem; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; + +/** + * + * @author JPEXS + */ +public class TagListTreeModel extends AbstractTagTreeModel { + + private final TagListTreeRoot root = new TagListTreeRoot(); + + private List swfs; + + private Map swfHeaders = new HashMap<>(); + + public TagListTreeModel(List swfs) { + this.swfs = swfs; + } + + @Override + public TreeItem getRoot() { + return root; + } + + private HeaderItem getSwfHeader(SWF swf) { + if (swfHeaders.containsKey(swf)) { + return swfHeaders.get(swf); + } + HeaderItem header = new HeaderItem(swf, translate("node.header")); + swfHeaders.put(swf, header); + return header; + } + + private String translate(String key) { + return AppStrings.translate(key); + } + + @Override + public TreeItem getChild(Object parent, int index) { + if(getChildCount(parent) == 0) { + return null; + } + TreeItem parentNode = (TreeItem) parent; + + if (parentNode == root) { + SWFList swfList = swfs.get(index); + if (!swfList.isBundle()) { + return swfList.get(0); + } + return swfList; + } else if (parentNode instanceof SWFList) { + return ((SWFList) parentNode).swfs.get(index); + } else if (parentNode instanceof SWF) { + if (index == 0) { + return getSwfHeader((SWF) parentNode); + } + return ((SWF) parentNode).getTimeline().getFrame(index - 1); + } else if (parentNode instanceof DefineSpriteTag) { + return ((DefineSpriteTag) parentNode).getTimeline().getFrame(index); + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).allInnerTags.get(index); + } else if (parentNode instanceof DefineBinaryDataTag) { + return ((DefineBinaryDataTag) parentNode).innerSwf; + } + throw new Error("Unsupported parent type: " + parentNode.getClass().getName()); + } + + @Override + public int getChildCount(Object parent) { + TreeItem parentNode = (TreeItem) parent; + if (parentNode == root) { + return swfs.size(); + } else if (parentNode instanceof SWFList) { + return ((SWFList) parentNode).swfs.size(); + } else if (parentNode instanceof SWF) { + return ((SWF) parentNode).getTimeline().getFrameCount() + 1; + } else if (parentNode instanceof HeaderItem) { + return 0; + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).allInnerTags.size(); + } else if (parentNode instanceof DefineSpriteTag) { + return ((DefineSpriteTag) parentNode).getTimeline().getFrameCount(); + } else if (parentNode instanceof DefineBinaryDataTag) { + return (((DefineBinaryDataTag) parentNode).innerSwf == null ? 0 : 1); + } + + return 0; + } + + @Override + public boolean isLeaf(Object node) { + return (getChildCount(node) == 0); + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + if(getChildCount(parent) == 0) { + return -1; + } + TreeItem parentNode = (TreeItem) parent; + + if (parentNode == root) { + SWFList swfList = child instanceof SWFList + ? (SWFList) child + : ((SWF) child).swfList; + return swfs.indexOf(swfList); + } else if (parentNode instanceof SWFList) { + return ((SWFList) parentNode).swfs.indexOf(child); + } else if (parentNode instanceof SWF) { + + HeaderItem header = getSwfHeader((SWF) parentNode); + if (header == child) { + return 0; + } + return ((Frame)child).frame + 1; + } else if (parentNode instanceof DefineSpriteTag) { + if (((Frame)child).timeline != ((DefineSpriteTag)parentNode).getTimeline()) { + return -1; + } + return ((Frame)child).frame; + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).allInnerTags.indexOf(child); + } else if (parentNode instanceof DefineBinaryDataTag) { + return ((DefineBinaryDataTag) parentNode).innerSwf == child ? 0 : -1; + } + return -1; + } + + + + @Override + public void updateSwfs(CollectionChangedEvent e) { + if (e.getAction() != CollectionChangedAction.ADD) { + List toRemove = new ArrayList<>(); + for (SWF swf : swfHeaders.keySet()) { + SWF swf2 = swf.getRootSwf(); + if (swf2 != null && !swfs.contains(swf2.swfList)) { + toRemove.add(swf); + } + } + + for (SWF swf : toRemove) { + swfHeaders.remove(swf); + } + } + + switch (e.getAction()) { + case ADD: { + TreePath rootPath = new TreePath(new Object[]{root}); + fireTreeNodesInserted(new TreeModelEvent(this, rootPath, new int[]{e.getNewIndex()}, new Object[]{e.getNewItem()})); + break; + } + case REMOVE: { + TreePath rootPath = new TreePath(new Object[]{root}); + fireTreeNodesRemoved(new TreeModelEvent(this, rootPath, new int[]{e.getOldIndex()}, new Object[]{e.getOldItem()})); + break; + } + default: + fireTreeStructureChanged(new TreeModelEvent(this, new TreePath(root))); + } + } + + private Frame searchForFrame(Object parent, SWF swf, Timelined t, int frame) { + int childCount = getChildCount(parent); + Frame lastVisibleFrame = null; + for (int i = 0; i < childCount; i++) { + TreeItem child = getChild(parent, i); + if ((child instanceof DefineSpriteTag) && child == t) { + Frame si = searchForFrame(child, swf, t, frame); + if (si != null) { + return si; + } + } + if (child instanceof Frame) { + Frame f = (Frame) child; + if (f.frame <= frame) { + lastVisibleFrame = f; + } + } + } + return lastVisibleFrame; + } + + @Override + public Frame getFrame(SWF swf, Timelined t, int frame) { + return searchForFrame(swf, swf, t, frame); + } + + @Override + public List getAllChildren(Object parent) { + TreeItem parentNode = (TreeItem) parent; + if (parentNode == root) { + List result = new ArrayList<>(swfs.size()); + for (SWFList swfList : swfs) { + if (!swfList.isBundle()) { + result.add(swfList.get(0)); + } + result.add(swfList); + } + return result; + } else if (parentNode instanceof SWFList) { + return ((SWFList) parentNode).swfs; + } else if (parentNode instanceof SWF) { + List ret = new ArrayList<>(); + ret.add(getSwfHeader((SWF)parentNode)); + ret.addAll(((SWF)parentNode).getTimeline().getFrames()); + return ret; + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).allInnerTags; + } else if (parentNode instanceof DefineSpriteTag) { + return ((DefineSpriteTag) parentNode).getTimeline().getFrames(); + } else if (parentNode instanceof DefineBinaryDataTag) { + DefineBinaryDataTag binaryDataTag = (DefineBinaryDataTag) parentNode; + if (binaryDataTag.innerSwf != null) { + List result = new ArrayList<>(1); + result.add(((DefineBinaryDataTag) parentNode).innerSwf); + return result; + } else { + return new ArrayList<>(0); + } + } + + return new ArrayList<>(); + } + + @Override + protected List searchTreeItem(TreeItem obj, TreeItem parent, List path) { + List ret = null; + for (TreeItem n : getAllChildren(parent)) { + List newPath = new ArrayList<>(); + newPath.addAll(path); + newPath.add(n); + + if (obj.equals(n)) { + return newPath; + } + + ret = searchTreeItem(obj, n, newPath); + if (ret != null) { + return ret; + } + } + return ret; + } + + @Override + public TreePath getTreePath(TreeItem obj) { + List path = new ArrayList<>(); + path.add(root); + if (obj != root) { + path = searchTreeItem(obj, root, path); + } + if (path == null) { + return null; + } + + TreePath tp = new TreePath(path.toArray(new Object[path.size()])); + return tp; + } + + @Override + public void updateSwf(SWF swf) { + swfHeaders.clear(); + TreePath changedPath = getTreePath(swf == null ? root : swf); + fireTreeStructureChanged(new TreeModelEvent(this, changedPath)); + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeNode.java b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeNode.java deleted file mode 100644 index 663ab30f8..000000000 --- a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeNode.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2022 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.taglistview; - -import com.jpexs.decompiler.flash.tags.DoInitActionTag; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import javax.swing.tree.TreeNode; - -/** - * - * @author JPEXS - */ -public class TagListTreeNode implements TreeNode { - - private final List children = new ArrayList<>(); - private TreeNode parent; - private Object data; - - @Override - public String toString() { - //hack - if (data instanceof DoInitActionTag) { - DoInitActionTag doinit = (DoInitActionTag) data; - String exportName = doinit.getSwf().getExportName(doinit.spriteId); - if (exportName != null && !exportName.isEmpty()) { - return DoInitActionTag.NAME + " (" + doinit.spriteId + ") : " + exportName; - } - } - return data.toString(); - } - - public void setData(Object data) { - this.data = data; - } - - public Object getData() { - return data; - } - - public void addChild(TreeNode node) { - children.add(node); - } - - public void setParent(TreeNode parent) { - this.parent = parent; - } - - @Override - public TreeNode getChildAt(int childIndex) { - return children.get(childIndex); - } - - @Override - public int getChildCount() { - return children.size(); - } - - @Override - public TreeNode getParent() { - return parent; - } - - @Override - public int getIndex(TreeNode node) { - return children.indexOf(node); - } - - @Override - public boolean getAllowsChildren() { - return true; - } - - @Override - public boolean isLeaf() { - return children.isEmpty(); - } - - @Override - public Enumeration children() { - return Collections.enumeration(children); - } - - public void removeChild(int index) { - children.remove(index); - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeRoot.java b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeRoot.java new file mode 100644 index 000000000..8d3eeb843 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/taglistview/TagListTreeRoot.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 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.taglistview; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class TagListTreeRoot implements TreeItem { + + @Override + public SWF getSwf() { + return null; + } + + @Override + public boolean isModified() { + return false; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java new file mode 100644 index 000000000..6f271f4be --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java @@ -0,0 +1,505 @@ +/* + * Copyright (C) 2022 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.tagtree; + +import com.jpexs.decompiler.flash.SWC; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.ZippedSWFBundle; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.gui.MainPanel; +import com.jpexs.decompiler.flash.gui.TreeNodeType; +import com.jpexs.decompiler.flash.gui.View; +import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedEvent; +import com.jpexs.decompiler.flash.iggy.conversion.IggySwfBundle; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.DefineFont3Tag; +import com.jpexs.decompiler.flash.tags.DefineFont4Tag; +import com.jpexs.decompiler.flash.tags.DefineFontTag; +import com.jpexs.decompiler.flash.tags.DefineSoundTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; +import com.jpexs.decompiler.flash.tags.DoActionTag; +import com.jpexs.decompiler.flash.tags.DoInitActionTag; +import com.jpexs.decompiler.flash.tags.EndTag; +import com.jpexs.decompiler.flash.tags.FileAttributesTag; +import com.jpexs.decompiler.flash.tags.MetadataTag; +import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; +import com.jpexs.decompiler.flash.tags.ShowFrameTag; +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.ButtonTag; +import com.jpexs.decompiler.flash.tags.base.ImageTag; +import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.decompiler.flash.tags.base.RemoveTag; +import com.jpexs.decompiler.flash.tags.base.ShapeTag; +import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; +import com.jpexs.decompiler.flash.tags.base.TextTag; +import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.timeline.AS2Package; +import com.jpexs.decompiler.flash.timeline.AS3Package; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.FrameScript; +import com.jpexs.decompiler.flash.timeline.TagScript; +import com.jpexs.decompiler.flash.treeitems.FolderItem; +import com.jpexs.decompiler.flash.treeitems.HeaderItem; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; +import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; +import java.awt.Color; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.swing.Icon; +import javax.swing.JTree; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +/** + * + * @author JPEXS + */ +public abstract class AbstractTagTree extends JTree { + public TagTreeContextMenu contextPopupMenu; + + protected final MainPanel mainPanel; + + private static final Map ICONS; + + static { + ICONS = new HashMap<>(); + for (TreeNodeType treeNodeType : TreeNodeType.values()) { + if (treeNodeType != TreeNodeType.UNKNOWN) { + String tagTypeStr = treeNodeType.toString().toLowerCase(Locale.ENGLISH).replace("_", ""); + ICONS.put(treeNodeType, View.getIcon(tagTypeStr + "16")); + } + } + } + + public static Icon getIconForType(TreeNodeType t) { + return ICONS.get(t); + } + + public AbstractTagTree(AbstractTagTreeModel treeModel, MainPanel mainPanel) { + super(treeModel); + this.mainPanel = mainPanel; + setRootVisible(false); + if (View.isOceanic()) { + setBackground(Color.white); + } + setRowHeight(Math.max(getFont().getSize() + 5, 16)); + setLargeModel(true); + setUI(new BasicTreeUI() { + { + if (View.isOceanic()) { + setHashColor(Color.gray); + } + } + }); + } + + public static TreeNodeType getTreeNodeType(TreeItem t) { + + if (t instanceof TagScript) { + t = ((TagScript) t).getTag(); + } + + if (t instanceof HeaderItem) { + return TreeNodeType.HEADER; + } + + if ((t instanceof DefineFontTag) + || (t instanceof DefineFont2Tag) + || (t instanceof DefineFont3Tag) + || (t instanceof DefineFont4Tag) + || (t instanceof DefineCompactedFont)) { + return TreeNodeType.FONT; + } + + // DefineText, DefineText2, DefineEditTextTag + if (t instanceof TextTag) { + return TreeNodeType.TEXT; + } + + // DefineBits, DefineBitsJPEG2, DefineBitsJPEG3, DefineBitsJPEG4, DefineBitsLossless, DefineBitsLossless2 + if (t instanceof ImageTag) { + return TreeNodeType.IMAGE; + } + + // DefineShape, DefineShape2, DefineShape3, DefineShape4 + if (t instanceof ShapeTag) { + return TreeNodeType.SHAPE; + } + + // DefineMorphShape, DefineMorphShape2 + if (t instanceof MorphShapeTag) { + return TreeNodeType.MORPH_SHAPE; + } + + if (t instanceof DefineSpriteTag) { + return TreeNodeType.SPRITE; + } + + // DefineButton, DefineButton2 + if (t instanceof ButtonTag) { + return TreeNodeType.BUTTON; + } + + if (t instanceof DefineVideoStreamTag) { + return TreeNodeType.MOVIE; + } + + if ((t instanceof DefineSoundTag) || (t instanceof SoundStreamHeadTag) || (t instanceof SoundStreamHead2Tag)) { + return TreeNodeType.SOUND; + } + + if (t instanceof DefineBinaryDataTag) { + return TreeNodeType.BINARY_DATA; + } + + if (Configuration.useAsTypeIcons.get()) { + if (t instanceof DoInitActionTag) { + DoInitActionTag doInit = (DoInitActionTag) t; + if (doInit.getSwf().getExportName(doInit.spriteId) != null) { + return TreeNodeType.AS_CLASS; + } + return TreeNodeType.AS_INIT; + } + + if (t instanceof CLIPACTIONRECORD) { + return TreeNodeType.AS_CLIP; + } + + if (t instanceof BUTTONCONDACTION) { + return TreeNodeType.AS_BUTTON; + } + + if (t instanceof DoActionTag) { + return TreeNodeType.AS_FRAME; + } + } + + if (t instanceof ASMSource) { + return TreeNodeType.AS; + } + + if (t instanceof ScriptPack) { + if (Configuration.useAsTypeIcons.get()) { + ScriptPack pack = (ScriptPack) t; + Trait trait = pack.getPublicTrait(); + if (trait == null) { + return TreeNodeType.AS; + } + if (trait instanceof TraitFunction) { + return TreeNodeType.AS_FUNCTION; + } + if (trait instanceof TraitMethodGetterSetter) { + return TreeNodeType.AS_FUNCTION; + } + if (trait instanceof TraitSlotConst) { + TraitSlotConst traitSlotConst = (TraitSlotConst) trait; + if (traitSlotConst.isConst()) { + return TreeNodeType.AS_CONST; + } else { + return TreeNodeType.AS_VAR; + } + } + if (trait instanceof TraitClass) { + TraitClass traitClass = (TraitClass) trait; + if (pack.abc.instance_info.get(traitClass.class_info).isInterface()) { + return TreeNodeType.AS_INTERFACE; + } + return TreeNodeType.AS_CLASS; + } + } + return TreeNodeType.AS; + } + + if (t instanceof AS2Package) { + return TreeNodeType.PACKAGE; + } + + if (t instanceof AS3Package) { + return TreeNodeType.PACKAGE; + } + + if ((t instanceof Frame) + || (t instanceof FrameScript)) { + return TreeNodeType.FRAME; + } + + if (t instanceof ShowFrameTag) { + return TreeNodeType.SHOW_FRAME; + } + + if (t instanceof SWF) { + return TreeNodeType.FLASH; + } + + if (t instanceof SWFList) { + SWFList slist = (SWFList) t; + if (slist.isBundle()) { + if (slist.bundle.getClass() == ZippedSWFBundle.class) { + return TreeNodeType.BUNDLE_ZIP; + } else if (slist.bundle.getClass() == SWC.class) { + return TreeNodeType.BUNDLE_SWC; + } else if (slist.bundle.getClass() == IggySwfBundle.class) { + return TreeNodeType.BUNDLE_IGGY; + } else { + return TreeNodeType.BUNDLE_BINARY; + } + } + } + + if (t instanceof SetBackgroundColorTag) { + return TreeNodeType.SET_BACKGROUNDCOLOR; + } + if (t instanceof FileAttributesTag) { + return TreeNodeType.FILE_ATTRIBUTES; + } + if (t instanceof MetadataTag) { + return TreeNodeType.METADATA; + } + if (t instanceof PlaceObjectTypeTag) { + return TreeNodeType.PLACE_OBJECT; + } + if (t instanceof RemoveTag) { + return TreeNodeType.REMOVE_OBJECT; + } + + if (t instanceof EndTag) { + return TreeNodeType.END; + } + + if (t instanceof Tag) { + return TreeNodeType.OTHER_TAG; + } + + if (t instanceof FolderItem) { + return TreeNodeType.FOLDER; + } + + return TreeNodeType.FOLDER; + } + + @Override + public AbstractTagTreeModel getModel() { + return (AbstractTagTreeModel) super.getModel(); + } + + public void expandRoot() { + AbstractTagTreeModel ttm = getModel(); + TreeItem root = ttm.getRoot(); + expandPath(new TreePath(new Object[]{root})); + } + + public void expandFirstLevelNodes() { + AbstractTagTreeModel ttm = getModel(); + TreeItem root = ttm.getRoot(); + int childCount = ttm.getChildCount(root); + for (int i = 0; i < childCount; i++) { + expandPath(new TreePath(new Object[]{root, ttm.getChild(root, i)})); + } + } + + public void setExpandPathString(String pathStr) { + if (pathStr != null && pathStr.length() > 0) { + String[] path = pathStr.split("\\|"); + + TreePath tp = View.getTreePathByPathStrings(this, Arrays.asList(path)); + if (tp != null) { + // the current view is the Resources view, otherwise tp is null + if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { + mainPanel.tagTree.expandPath(tp.getParentPath()); + } + if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { + mainPanel.tagListTree.expandPath(tp.getParentPath()); + } + } + } + } + + public void setSelectionPathString(String pathStr) { + if (pathStr != null && pathStr.length() > 0) { + String[] path = pathStr.split("\\|"); + + TreePath tp = View.getTreePathByPathStrings(this, Arrays.asList(path)); + if (tp != null) { + // the current view is the Resources view, otherwise tp is null + mainPanel.setTagTreeSelectedNode((TreeItem) tp.getLastPathComponent()); + } + } + } + + public void getAllSubs(TreeItem o, List ret) { + AbstractTagTreeModel tm = getModel(); + for (TreeItem c : tm.getAllChildren(o)) { + ret.add(c); + getAllSubs(c, ret); + } + } + + public List getAllSelected() { + TreeSelectionModel tsm = getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); + ret.add(treeNode); + getAllSubs(treeNode, ret); + } + return ret; + } + + public List getSelected() { + if (!mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { + return new ArrayList<>(mainPanel.folderPreviewPanel.selectedItems.values()); + } + TreeSelectionModel tsm = getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); + ret.add(treeNode); + } + return ret; + } + + public boolean hasExportableNodes() { + return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); + } + + public abstract List getSelection(SWF swf); + + public static List getSelection(SWF swf, List sel) { + List ret = new ArrayList<>(); + for (TreeItem d : sel) { + if (d instanceof SWFList) { + continue; + } + if (d.getSwf() != swf) { + continue; + } + + if (d instanceof TagScript) { + Tag tag = ((TagScript) d).getTag(); + if (tag instanceof DoActionTag || tag instanceof DoInitActionTag) { + d = tag; + } + } + + if (d instanceof Tag || d instanceof ASMSource) { + TreeNodeType nodeType = TagTree.getTreeNodeType(d); + if (nodeType == TreeNodeType.IMAGE) { + ret.add(d); + } + if (nodeType == TreeNodeType.SHAPE) { + ret.add(d); + } + if (nodeType == TreeNodeType.MORPH_SHAPE) { + ret.add(d); + } + if (nodeType == TreeNodeType.SPRITE) { + ret.add(d); + } + if (nodeType == TreeNodeType.BUTTON) { + ret.add(d); + } + if (nodeType == TreeNodeType.AS + || nodeType == TreeNodeType.AS_BUTTON + || nodeType == TreeNodeType.AS_CLASS + || nodeType == TreeNodeType.AS_CLIP + || nodeType == TreeNodeType.AS_CONST + || nodeType == TreeNodeType.AS_FRAME + || nodeType == TreeNodeType.AS_FUNCTION + || nodeType == TreeNodeType.AS_INIT + || nodeType == TreeNodeType.AS_INTERFACE + || nodeType == TreeNodeType.AS_VAR) { + ret.add(d); + } + if (nodeType == TreeNodeType.MOVIE) { + ret.add(d); + } + if (nodeType == TreeNodeType.SOUND) { + ret.add(d); + } + if (nodeType == TreeNodeType.BINARY_DATA) { + ret.add(d); + } + if (nodeType == TreeNodeType.TEXT) { + ret.add(d); + } + if (nodeType == TreeNodeType.FONT) { + ret.add(d); + } + if (nodeType == TreeNodeType.OTHER_TAG) { + if (d instanceof SymbolClassTypeTag) { + ret.add(d); + } + } + } + + if (d instanceof Frame) { + ret.add(d); + } + if (d instanceof ScriptPack) { + ret.add(d); + } + } + return ret; + } + + public void updateSwfs(SWF[] swfs) { + AbstractTagTreeModel ttm = getModel(); + if (ttm != null) { + List> expandedNodes = View.getExpandedNodes(this); + ttm.updateSwf(null); // todo: honfika: update only the changed swfs, but there was an exception when i tried it + View.expandTreeNodes(this, expandedNodes); + } + } + + public abstract List getNestedTagIds(Tag obj); + + public abstract List getFrameNestedTagIds(); + + public TreeItem getCurrentTreeItem() { + TreeItem item = (TreeItem) getLastSelectedPathComponent(); + return item; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTreeModel.java new file mode 100644 index 000000000..c035e6374 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTreeModel.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2022 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.tagtree; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedEvent; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.ArrayList; +import java.util.List; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +/** + * + * @author JPEXS + */ +public abstract class AbstractTagTreeModel implements TreeModel { + + protected final List listeners = new ArrayList<>(); + + public abstract void updateSwfs(CollectionChangedEvent e); + + protected void fireTreeNodesRemoved(TreeModelEvent e) { + for (TreeModelListener listener : listeners) { + listener.treeNodesRemoved(e); + } + } + + protected void fireTreeNodesInserted(TreeModelEvent e) { + for (TreeModelListener listener : listeners) { + listener.treeNodesInserted(e); + } + } + + protected void fireTreeStructureChanged(TreeModelEvent e) { + for (TreeModelListener listener : listeners) { + listener.treeStructureChanged(e); + } + } + + @Override + public void addTreeModelListener(TreeModelListener l) { + listeners.add(l); + } + + @Override + public void removeTreeModelListener(TreeModelListener l) { + listeners.remove(l); + } + + public boolean treePathExists(TreePath treePath) { + TreeItem current = null; + for (Object o : treePath.getPath()) { + TreeItem item = (TreeItem) o; + if (current == null) { + if (item != getRoot()) { + return false; + } + + current = item; + } else { + int idx = getIndexOfChild(current, item); + if (idx == -1) { + return false; + } + + current = item; + } + } + + return true; + } + + public abstract Frame getFrame(SWF swf, Timelined t, int frame); + + @Override + public abstract TreeItem getChild(Object parent, int index); + + public abstract List getAllChildren(Object parent); + + @Override + public abstract TreeItem getRoot(); + + protected abstract List searchTreeItem(TreeItem obj, TreeItem parent, List path); + + public TreePath getTreePath(TreeItem obj) { + List path = new ArrayList<>(); + TreeItem root = getRoot(); + path.add(root); + if (obj != root) { + path = searchTreeItem(obj, root, path); + } + if (path == null) { + return null; + } + + TreePath tp = new TreePath(path.toArray(new Object[path.size()])); + return tp; + } + + public void updateNode(TreeItem treeItem) { + TreePath changedPath = getTreePath(treeItem); + fireTreeStructureChanged(new TreeModelEvent(this, changedPath)); + } + + public void updateNode(TreePath changedPath) { + fireTreeStructureChanged(new TreeModelEvent(this, changedPath.getParentPath())); + } + + @Override + public void valueForPathChanged(TreePath path, Object newValue) { + } + + public abstract void updateSwf(SWF swf); + +} diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java index 6be3bc2a0..f938c1e49 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java @@ -108,7 +108,6 @@ import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.RemoveTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; -import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; import com.jpexs.decompiler.flash.timeline.AS2Package; @@ -128,44 +127,18 @@ import java.awt.Component; import java.awt.Font; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; -import javax.swing.Icon; 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.TreePath; -import javax.swing.tree.TreeSelectionModel; /** * * @author JPEXS */ -public class TagTree extends JTree { - - public TagTreeContextMenu contextPopupMenu; - - private final MainPanel mainPanel; - - private static final Map ICONS; - - static { - ICONS = new HashMap<>(); - for (TreeNodeType treeNodeType : TreeNodeType.values()) { - if (treeNodeType != TreeNodeType.UNKNOWN) { - String tagTypeStr = treeNodeType.toString().toLowerCase(Locale.ENGLISH).replace("_", ""); - ICONS.put(treeNodeType, View.getIcon(tagTypeStr + "16")); - } - } - } - - public static Icon getIconForType(TreeNodeType t) { - return ICONS.get(t); - } - +public class TagTree extends AbstractTagTree { public static class TagTreeCellRenderer extends DefaultTreeCellRenderer { private Font plainFont; @@ -218,7 +191,7 @@ public class TagTree extends JTree { setIcon(View.getIcon(itemName.toLowerCase(Locale.ENGLISH) + "16")); } } else { - setIcon(ICONS.get(type)); + setIcon(getIconForType(type)); } /* boolean isModified = val instanceof Tag && ((Tag) val).isModified(); @@ -257,22 +230,8 @@ public class TagTree extends JTree { } public TagTree(TagTreeModel treeModel, MainPanel mainPanel) { - super(treeModel); - this.mainPanel = mainPanel; + super(treeModel, mainPanel); setCellRenderer(new TagTreeCellRenderer()); - setRootVisible(false); - if (View.isOceanic()) { - setBackground(Color.white); - } - setRowHeight(Math.max(getFont().getSize() + 5, 16)); - setLargeModel(true); - setUI(new BasicTreeUI() { - { - if (View.isOceanic()) { - setHashColor(Color.gray); - } - } - }); } public static TreeNodeType getTreeNodeType(TreeItem t) { @@ -521,6 +480,7 @@ public class TagTree extends JTree { return ret; } + @Override public List getFrameNestedTagIds() { return Arrays.asList(PlaceObjectTag.ID, PlaceObject2Tag.ID, PlaceObject3Tag.ID, PlaceObject4Tag.ID, RemoveObjectTag.ID, RemoveObject2Tag.ID, FrameLabelTag.ID, @@ -528,6 +488,7 @@ public class TagTree extends JTree { SoundStreamBlockTag.ID, SoundStreamHeadTag.ID, SoundStreamHead2Tag.ID); } + @Override public List getNestedTagIds(Tag obj) { if (obj instanceof DefineSpriteTag) { return Arrays.asList(PlaceObjectTag.ID, PlaceObject2Tag.ID, PlaceObject3Tag.ID, PlaceObject4Tag.ID, @@ -551,52 +512,9 @@ public class TagTree extends JTree { return null; } - public boolean hasExportableNodes() { - return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); - } - - public void getAllSubs(TreeItem o, List ret) { - TagTreeModel tm = getModel(); - for (TreeItem c : tm.getAllChildren(o)) { - ret.add(c); - getAllSubs(c, ret); - } - } - - public List getAllSelected() { - TreeSelectionModel tsm = getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); - ret.add(treeNode); - getAllSubs(treeNode, ret); - } - return ret; - } - - public List getSelected() { - if (!mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { - return new ArrayList<>(mainPanel.folderPreviewPanel.selectedItems.values()); - } - TreeSelectionModel tsm = getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); - ret.add(treeNode); - } - return ret; - } + + @Override public List getSelection(SWF swf) { List sel; if (mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { @@ -612,84 +530,6 @@ public class TagTree extends JTree { return getSelection(swf, sel); } - public static List getSelection(SWF swf, List sel) { - List ret = new ArrayList<>(); - for (TreeItem d : sel) { - if (d instanceof SWFList) { - continue; - } - if (d.getSwf() != swf) { - continue; - } - - if (d instanceof TagScript) { - Tag tag = ((TagScript) d).getTag(); - if (tag instanceof DoActionTag || tag instanceof DoInitActionTag) { - d = tag; - } - } - - if (d instanceof Tag || d instanceof ASMSource) { - TreeNodeType nodeType = TagTree.getTreeNodeType(d); - if (nodeType == TreeNodeType.IMAGE) { - ret.add(d); - } - if (nodeType == TreeNodeType.SHAPE) { - ret.add(d); - } - if (nodeType == TreeNodeType.MORPH_SHAPE) { - ret.add(d); - } - if (nodeType == TreeNodeType.SPRITE) { - ret.add(d); - } - if (nodeType == TreeNodeType.BUTTON) { - ret.add(d); - } - if (nodeType == TreeNodeType.AS - || nodeType == TreeNodeType.AS_BUTTON - || nodeType == TreeNodeType.AS_CLASS - || nodeType == TreeNodeType.AS_CLIP - || nodeType == TreeNodeType.AS_CONST - || nodeType == TreeNodeType.AS_FRAME - || nodeType == TreeNodeType.AS_FUNCTION - || nodeType == TreeNodeType.AS_INIT - || nodeType == TreeNodeType.AS_INTERFACE - || nodeType == TreeNodeType.AS_VAR) { - ret.add(d); - } - if (nodeType == TreeNodeType.MOVIE) { - ret.add(d); - } - if (nodeType == TreeNodeType.SOUND) { - ret.add(d); - } - if (nodeType == TreeNodeType.BINARY_DATA) { - ret.add(d); - } - if (nodeType == TreeNodeType.TEXT) { - ret.add(d); - } - if (nodeType == TreeNodeType.FONT) { - ret.add(d); - } - if (nodeType == TreeNodeType.OTHER_TAG) { - if (d instanceof SymbolClassTypeTag) { - ret.add(d); - } - } - } - - if (d instanceof Frame) { - ret.add(d); - } - if (d instanceof ScriptPack) { - ret.add(d); - } - } - return ret; - } - public List getTagsWithType(List list, TreeNodeType type) { List ret = new ArrayList<>(); for (AS3ClassTreeItem item : list) { @@ -701,44 +541,20 @@ public class TagTree extends JTree { return ret; } + @Override public TreeItem getCurrentTreeItem() { if (!mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { return mainPanel.folderPreviewPanel.selectedItems.entrySet().iterator().next().getValue(); } - TreeItem item = (TreeItem) getLastSelectedPathComponent(); - return item; - } - - public void updateSwfs(SWF[] swfs) { - TagTreeModel ttm = getModel(); - if (ttm != null) { - List> expandedNodes = View.getExpandedNodes(this); - ttm.updateSwf(null); // todo: honfika: update only the changed swfs, but there was an exception when i tried it - View.expandTreeNodes(this, expandedNodes); - } + return super.getCurrentTreeItem(); } @Override public TagTreeModel getModel() { return (TagTreeModel) super.getModel(); } - - public void expandRoot() { - TagTreeModel ttm = getModel(); - TreeItem root = ttm.getRoot(); - expandPath(new TreePath(new Object[]{root})); - } - - public void expandFirstLevelNodes() { - TagTreeModel ttm = getModel(); - TreeItem root = ttm.getRoot(); - int childCount = ttm.getChildCount(root); - for (int i = 0; i < childCount; i++) { - expandPath(new TreePath(new Object[]{root, ttm.getChild(root, i)})); - } - } - + public String getSelectionPathString() { StringBuilder sb = new StringBuilder(); TreePath path = getSelectionPath(); @@ -757,27 +573,5 @@ public class TagTree extends JTree { return sb.toString(); } - public void setExpandPathString(String pathStr) { - if (pathStr != null && pathStr.length() > 0) { - String[] path = pathStr.split("\\|"); - - TreePath tp = View.getTreePathByPathStrings(this, Arrays.asList(path)); - if (tp != null) { - // the current view is the Resources view, otherwise tp is null - mainPanel.tagTree.expandPath(tp.getParentPath()); - } - } - } - - public void setSelectionPathString(String pathStr) { - if (pathStr != null && pathStr.length() > 0) { - String[] path = pathStr.split("\\|"); - - TreePath tp = View.getTreePathByPathStrings(this, Arrays.asList(path)); - if (tp != null) { - // the current view is the Resources view, otherwise tp is null - mainPanel.setTagTreeSelectedNode((TreeItem) tp.getLastPathComponent()); - } - } - } + } diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index df47fccc0..d347a100a 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -36,8 +36,6 @@ import com.jpexs.decompiler.flash.gui.ViewMessages; import com.jpexs.decompiler.flash.gui.abc.AddClassDialog; import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.action.AddScriptDialog; -import com.jpexs.decompiler.flash.gui.taglistview.TagListTree; -import com.jpexs.decompiler.flash.gui.taglistview.TagListTreeNode; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineButton2Tag; @@ -121,10 +119,6 @@ public class TagTreeContextMenu extends JPopupMenu { private final MainPanel mainPanel; - private final TagTree tagTree; - - private final TagListTree tagListTree; - private JMenuItem expandRecursiveMenuItem; private JMenuItem removeMenuItem; @@ -175,11 +169,9 @@ public class TagTreeContextMenu extends JPopupMenu { private JMenuItem setTagPositionMenuItem; - public TagTreeContextMenu(final TagTree tagTree, final TagListTree tagListTree, MainPanel mainPanel) { + public TagTreeContextMenu(final List trees, MainPanel mainPanel) { this.mainPanel = mainPanel; - this.tagTree = tagTree; - this.tagListTree = tagListTree; - + expandRecursiveMenuItem = new JMenuItem(mainPanel.translate("contextmenu.expandAll")); expandRecursiveMenuItem.addActionListener(this::expandRecursiveActionPerformed); add(expandRecursiveMenuItem); @@ -280,18 +272,18 @@ public class TagTreeContextMenu extends JPopupMenu { closeMenuItem.addActionListener(this::closeSwfActionPerformed); add(closeMenuItem); - tagTree.addMouseListener(new MouseAdapter() { + MouseAdapter adapter = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { - int row = tagTree.getClosestRowForLocation(e.getX(), e.getY()); - int[] selectionRows = tagTree.getSelectionRows(); + int row = getTree().getClosestRowForLocation(e.getX(), e.getY()); + int[] selectionRows = getTree().getSelectionRows(); if (!Helper.contains(selectionRows, row)) { - tagTree.setSelectionRow(row); + getTree().setSelectionRow(row); } - TreePath[] paths = tagTree.getSelectionPaths(); + TreePath[] paths = getTree().getSelectionPaths(); if (paths == null || paths.length == 0) { return; } @@ -302,46 +294,27 @@ public class TagTreeContextMenu extends JPopupMenu { li.add(item); } - update(li, MainPanel.VIEW_RESOURCES); + update(li); show(e.getComponent(), e.getX(), e.getY()); } } - }); - - tagListTree.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (SwingUtilities.isRightMouseButton(e)) { - int row = tagListTree.getClosestRowForLocation(e.getX(), e.getY()); - int[] selectionRows = tagListTree.getSelectionRows(); - if (!Helper.contains(selectionRows, row)) { - tagListTree.setSelectionRow(row); - } - - TreePath[] paths = tagListTree.getSelectionPaths(); - if (paths == null || paths.length == 0) { - return; - } - - List li = new ArrayList<>(); - for (TreePath treePath : paths) { - TagListTreeNode node = (TagListTreeNode) treePath.getLastPathComponent(); - TreeItem item = (TreeItem) node.getData(); - li.add(item); - } - - update(li, MainPanel.VIEW_TAGLIST); - show(e.getComponent(), e.getX(), e.getY()); - } - } - }); + }; + for (AbstractTagTree tree:trees) { + tree.addMouseListener(adapter); + } + } + + private AbstractTagTree getTree() { + return mainPanel.getCurrentTree(); } - public void update(final List items, int currentView) { + public void update(final List items) { if (items.isEmpty()) { return; } + + AbstractTagTree tree = getTree(); final List swfs = mainPanel.getSwfs(); @@ -498,8 +471,7 @@ public class TagTreeContextMenu extends JPopupMenu { boolean allSelectedSameParent = !items.isEmpty(); if(allSelectedSameParent) { - if (currentView == MainPanel.VIEW_RESOURCES) { - TagTreeModel model = tagTree.getModel(); + AbstractTagTreeModel model = tree.getModel(); TreePath parent = model.getTreePath(items.get(0)).getParentPath(); for (TreeItem item : items) { @@ -510,28 +482,10 @@ public class TagTreeContextMenu extends JPopupMenu { break; } } - } - - if (currentView == MainPanel.VIEW_TAGLIST) { - TreePath parent = tagListTree.getPathForData(items.get(0)).getParentPath(); - for (TreeItem item : items) { - TreePath currentParent = tagListTree.getPathForData(item).getParentPath(); - - if(!currentParent.equals(parent)) { - allSelectedSameParent = false; - break; - } - } - } - } + } + + boolean hasExportableNodes = tree.hasExportableNodes(); - boolean hasExportableNodes = false; - if (currentView == MainPanel.VIEW_RESOURCES) { - hasExportableNodes = tagTree.hasExportableNodes(); - } else if (currentView == MainPanel.VIEW_TAGLIST) { - hasExportableNodes = tagListTree.hasExportableNodes(); - } - expandRecursiveMenuItem.setVisible(false); removeMenuItem.setVisible(canRemove); removeWithDependenciesMenuItem.setVisible(canRemove && !allDoNotHaveDependencies); @@ -627,6 +581,7 @@ public class TagTreeContextMenu extends JPopupMenu { addTagMenu.removeAll(); if (firstItem instanceof FolderItem) { + TagTree tagTree = (TagTree)tree; List allowedTagTypes; FolderItem folderItem = (FolderItem) firstItem; SWF swf = firstItem.getSwf(); @@ -645,25 +600,17 @@ public class TagTreeContextMenu extends JPopupMenu { allowedTagTypes = tagTree.getSwfFolderItemNestedTagIds(folderItem.getName(), swf.gfx); addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); } else if (firstItem instanceof Tag) { - List allowedTagTypes = tagTree.getNestedTagIds((Tag) firstItem); + List allowedTagTypes = tree.getNestedTagIds((Tag) firstItem); addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); } else if (firstItem instanceof Frame) { - List allowedTagTypes = tagTree.getFrameNestedTagIds(); + List allowedTagTypes = tree.getFrameNestedTagIds(); addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); } addTagMenu.setVisible(addTagMenu.getItemCount() > 0); - if (currentView == MainPanel.VIEW_RESOURCES) { - if (tagTree.getModel().getChildCount(firstItem) > 0) { + if (tree.getModel().getChildCount(firstItem) > 0) { expandRecursiveMenuItem.setVisible(true); - } - } - if (currentView == MainPanel.VIEW_TAGLIST) { - TagListTreeNode node = tagListTree.getNodeForData(firstItem); - if (node.getChildCount() > 0) { - expandRecursiveMenuItem.setVisible(true); - } - } + } if (firstItem instanceof CharacterIdTag && !(firstItem instanceof CharacterTag)) { jumpToCharacterMenuItem.setVisible(true); @@ -905,18 +852,9 @@ public class TagTreeContextMenu extends JPopupMenu { } } - private List getSelectedTreeItems() { - if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { - return tagTree.getSelected(); - } - if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - return tagListTree.getSelected(); - } - return new ArrayList<>(); - } private void openSwfInsideActionPerformed(ActionEvent evt) { - List sel = getSelectedTreeItems(); + List sel = getTree().getSelected(); List binaryDatas = new ArrayList<>(); for (TreeItem item : sel) { DefineBinaryDataTag binaryData = (DefineBinaryDataTag) item; @@ -926,23 +864,10 @@ public class TagTreeContextMenu extends JPopupMenu { } mainPanel.loadFromBinaryTag(binaryDatas); - } - - private TreeItem getCurrentTreeItem() { - if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { - return tagTree.getCurrentTreeItem(); - } - if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - TagListTreeNode node = (TagListTreeNode) tagListTree.getLastSelectedPathComponent(); - if (node != null) { - return (TreeItem) node.getData(); - } - } - return null; - } + } private void replaceWithTagActionPerformed(ActionEvent evt) { - TreeItem itemr = getCurrentTreeItem(); + TreeItem itemr = getTree().getCurrentTreeItem(); if (itemr == null) { return; } @@ -959,7 +884,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void replaceRefsWithTagActionPerformed(ActionEvent evt) { - TreeItem itemr = getCurrentTreeItem(); + TreeItem itemr = getTree().getCurrentTreeItem(); if (itemr == null) { return; } @@ -1007,7 +932,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void rawEditActionPerformed(ActionEvent evt) { - TreeItem itemr = getCurrentTreeItem(); + TreeItem itemr = getTree().getCurrentTreeItem(); if (itemr == null) { return; } @@ -1016,7 +941,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void jumpToCharacterActionPerformed(ActionEvent evt) { - TreeItem itemj = getCurrentTreeItem(); + TreeItem itemj = getTree().getCurrentTreeItem(); if (itemj == null || !(itemj instanceof CharacterIdTag)) { return; } @@ -1026,16 +951,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void expandRecursiveActionPerformed(ActionEvent evt) { - JTree tree = null; - if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { - tree = tagTree; - } - if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - tree = tagListTree; - } - if (tree == null) { - return; - } + JTree tree = getTree(); TreePath path = tree.getSelectionPath(); if (path == null) { return; @@ -1048,8 +964,9 @@ public class TagTreeContextMenu extends JPopupMenu { } private void addAs3ClassActionPerformed(ActionEvent evt) { + AbstractTagTree tree = getTree(); //using tagTree only here is safe since tagListTree does not have AS3 classes - List sel = getSelectedTreeItems(); + List sel = getTree().getSelected(); if (!sel.isEmpty()) { SWF swf = null; String preselected = ""; @@ -1060,7 +977,7 @@ public class TagTreeContextMenu extends JPopupMenu { if (sel.get(0) instanceof AS3Package) { AS3Package pkg = (AS3Package) sel.get(0); swf = pkg.getSwf(); - TreePath tp = tagTree.getSelectionPaths()[0]; + TreePath tp = tree.getSelectionPaths()[0]; Object[] path = tp.getPath(); for (int p = path.length - 1; p >= 0; p--) { if (path[p] instanceof ClassesListTreeModel) { @@ -1070,7 +987,7 @@ public class TagTreeContextMenu extends JPopupMenu { } } - TreePath scriptsPath = tagTree.getSelectionPaths()[0]; + TreePath scriptsPath = tree.getSelectionPaths()[0]; while (!(scriptsPath.getLastPathComponent() instanceof ClassesListTreeModel)) { scriptsPath = scriptsPath.getParentPath(); } @@ -1139,7 +1056,7 @@ public class TagTreeContextMenu extends JPopupMenu { TreePath classPath = scriptsPath; for (int i = 0; i < parts.length; i++) { - for (TreeItem ti : tagTree.getModel().getAllChildren(item)) { + for (TreeItem ti : tree.getModel().getAllChildren(item)) { if (ti instanceof AS3ClassTreeItem) { AS3ClassTreeItem cti = (AS3ClassTreeItem) ti; if (parts[i].equals(cti.getNameWithNamespaceSuffix())) { @@ -1156,7 +1073,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void addAs12ScriptActionPerformed(ActionEvent evt) { - List sel = getSelectedTreeItems(); + List sel = getTree().getSelected(); if (!sel.isEmpty()) { if (sel.get(0) instanceof FolderItem) { @@ -1558,7 +1475,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void populateScriptSubs(TreePath path, TreeItem item, List out) { - List subs = tagTree.getModel().getAllChildren(item); + List subs = getTree().getModel().getAllChildren(item); for (TreeItem t : subs) { TreePath tPath = path.pathByAddingChild(t); if ((t instanceof TagScript) && (((TagScript) t).getTag() instanceof ASMSource)) { @@ -1585,7 +1502,7 @@ public class TagTreeContextMenu extends JPopupMenu { if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { if (mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { - tpsArr = tagTree.getSelectionModel().getSelectionPaths(); + tpsArr = getTree().getSelectionModel().getSelectionPaths(); if (tpsArr == null) { return; } @@ -1594,7 +1511,7 @@ public class TagTreeContextMenu extends JPopupMenu { List sel = new ArrayList<>(); for (TreeItem treeItem : mainPanel.folderPreviewPanel.selectedItems.values()) { sel.add(treeItem); - tagTree.getAllSubs(treeItem, sel); + getTree().getAllSubs(treeItem, sel); } tps = new ArrayList<>(); for (TreeItem treeItem : sel) { @@ -1606,17 +1523,12 @@ public class TagTreeContextMenu extends JPopupMenu { return; } } - } else if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - tpsArr = tagListTree.getSelectionModel().getSelectionPaths(); + } else { + tpsArr = getTree().getSelectionModel().getSelectionPaths(); if (tpsArr == null) { return; } - tps = new ArrayList<>(); - for (TreePath tp : tpsArr) { - tps.add(mainPanel.convertViewPath(tp)); - } - } else { - tps = new ArrayList<>(); + tps = new ArrayList<>(Arrays.asList(tpsArr)); } List tagsToRemove = new ArrayList<>(); @@ -1832,7 +1744,8 @@ public class TagTreeContextMenu extends JPopupMenu { } private void undoTagActionPerformed(ActionEvent evt) { - List sel = getSelectedTreeItems(); + AbstractTagTree tree = getTree(); + List sel = getTree().getSelected(); for (TreeItem item : sel) { if (item instanceof Tag) { @@ -1840,19 +1753,18 @@ public class TagTreeContextMenu extends JPopupMenu { Tag tag = (Tag) item; tag.undo(); tag.getSwf().clearAllCache(); - tagTree.getModel().updateNode(item); + tree.getModel().updateNode(item); } catch (InterruptedException | IOException ex) { logger.log(Level.SEVERE, null, ex); } } } - tagListTree.updateSwfs(); - + mainPanel.repaintTree(); } private void closeSwfActionPerformed(ActionEvent evt) { - List sel = getSelectedTreeItems(); + List sel = getTree().getSelected(); for (TreeItem item : sel) { if (item instanceof SWF) { SWF swf = (SWF) item; @@ -1871,7 +1783,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void cloneTagActionPerformed(ActionEvent e) { - List items = getSelectedTreeItems(); + List items = getTree().getSelected(); /* Currently useless since all selected items must have the same parent * but a better way to detect for parent/child selection * could remove that limitation */ @@ -1948,16 +1860,9 @@ public class TagTreeContextMenu extends JPopupMenu { } private void setTagPositionActionPerformed(ActionEvent evt) { - List items = getSelectedTreeItems(); + List items = getTree().getSelected(); Tag t = (Tag)items.get(0); - TreePath path; - if (mainPanel.getCurrentView() == MainPanel.VIEW_RESOURCES) { - path = tagTree.getSelectionPath(); - } else if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - path = mainPanel.convertViewPath(tagListTree.getSelectionPath()); - } else { - return; - } + TreePath path = getTree().getSelectionPath(); Timelined timelined = null; for (int i = path.getPathCount() - 1 - 1 /*not last path component*/; i >= 0; i--) { if ((path.getPathComponent(i) instanceof DefineSpriteTag) || (path.getPathComponent(i) instanceof SWF)) { diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java index 16c08b467..06286a972 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java @@ -57,7 +57,7 @@ import javax.swing.tree.TreePath; * * @author JPEXS */ -public class TagTreeModel implements TreeModel { +public class TagTreeModel extends AbstractTagTreeModel { public static final String FOLDER_SHAPES = "shapes"; @@ -137,38 +137,12 @@ public class TagTreeModel implements TreeModel { } } + @Override public void updateSwf(SWF swf) { swfInfos.clear(); TreePath changedPath = getTreePath(swf == null ? root : swf); fireTreeStructureChanged(new TreeModelEvent(this, changedPath)); - } - - public void updateNode(TreeItem treeItem) { - TreePath changedPath = getTreePath(treeItem); - fireTreeStructureChanged(new TreeModelEvent(this, changedPath)); - } - - public void updateNode(TreePath changedPath) { - fireTreeStructureChanged(new TreeModelEvent(this, changedPath.getParentPath())); - } - - private void fireTreeNodesRemoved(TreeModelEvent e) { - for (TreeModelListener listener : listeners) { - listener.treeNodesRemoved(e); - } - } - - private void fireTreeNodesInserted(TreeModelEvent e) { - for (TreeModelListener listener : listeners) { - listener.treeNodesInserted(e); - } - } - - private void fireTreeStructureChanged(TreeModelEvent e) { - for (TreeModelListener listener : listeners) { - listener.treeStructureChanged(e); - } - } + } private List getSoundStreams(DefineSpriteTag sprite) { List ret = new ArrayList<>(); @@ -386,11 +360,13 @@ public class TagTreeModel implements TreeModel { return lastVisibleFrame; } + @Override public Frame getFrame(SWF swf, Timelined t, int frame) { return searchForFrame(swf, swf, t, frame); } - private List searchTreeItem(TreeItem obj, TreeItem parent, List path) { + @Override + protected List searchTreeItem(TreeItem obj, TreeItem parent, List path) { List ret = null; for (TreeItem n : getAllChildren(parent)) { List newPath = new ArrayList<>(); @@ -430,20 +406,7 @@ public class TagTreeModel implements TreeModel { } return ret; } - - public TreePath getTreePath(TreeItem obj) { - List path = new ArrayList<>(); - path.add(root); - if (obj != root) { - path = searchTreeItem(obj, root, path); - } - if (path == null) { - return null; - } - - TreePath tp = new TreePath(path.toArray(new Object[path.size()])); - return tp; - } + @Override public TreeItem getRoot() { @@ -485,6 +448,7 @@ public class TagTreeModel implements TreeModel { return swfInfo.tagScriptCache; } + @Override public List getAllChildren(Object parent) { TreeItem parentNode = (TreeItem) parent; if (parentNode == root) { @@ -678,11 +642,7 @@ public class TagTreeModel implements TreeModel { @Override public boolean isLeaf(Object node) { return (getChildCount(node) == 0); - } - - @Override - public void valueForPathChanged(TreePath path, Object newValue) { - } + } private int indexOfAdd(int prevSize, int index) { if (index == -1) { @@ -745,39 +705,6 @@ public class TagTreeModel implements TreeModel { return indexOfAdd(baseIndex, getMappedCharacters(((CharacterTag) parentNode).getSwf(), (CharacterTag) parentNode).indexOf(childNode)); } - throw new Error("Unsupported parent type: " + parentNode.getClass().getName()); - } - - public boolean treePathExists(TreePath treePath) { - TreeItem current = null; - for (Object o : treePath.getPath()) { - TreeItem item = (TreeItem) o; - if (current == null) { - if (item != getRoot()) { - return false; - } - - current = item; - } else { - int idx = getIndexOfChild(current, item); - if (idx == -1) { - return false; - } - - current = item; - } - } - - return true; - } - - @Override - public void addTreeModelListener(TreeModelListener l) { - listeners.add(l); - } - - @Override - public void removeTreeModelListener(TreeModelListener l) { - listeners.remove(l); - } + return -1; + } }