Changed: AS1/2 - Single DoAction tag inside frame as frame node

This commit is contained in:
Jindra Petřík
2025-05-25 21:46:09 +02:00
parent ceee0afb12
commit 50b82c363f
10 changed files with 207 additions and 25 deletions
@@ -47,12 +47,12 @@ import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
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.AS3ClassTreeItem;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
@@ -103,7 +103,7 @@ public class ExportDialog extends AppDialog {
{ImageTag.class},
{DefineVideoStreamTag.class},
{SoundTag.class},
{ASMSource.class, ScriptPack.class, TagScript.class},
{ASMSource.class, ScriptPack.class, TagScript.class, FrameScript.class},
{BinaryDataInterface.class},
{Frame.class},
{Frame.class},
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.FrameScript;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
@@ -242,6 +243,10 @@ public class FolderListPanel extends JPanel {
TreeItem treeItem = items.get(index);
TreeNodeType type = AbstractTagTree.getTreeNodeType(treeItem);
if ((treeItem instanceof FrameScript) && ((FrameScript) treeItem).getSingleDoActionTag() != null) {
type = TreeNodeType.AS_FRAME;
}
Icon icon = ICONS.get(type);
icon.paintIcon(l, g, x * CELL_WIDTH + BORDER_SIZE + PREVIEW_SIZE / 2 - icon.getIconWidth() / 2, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE / 2 - icon.getIconHeight() / 2);
String s = null;
@@ -182,6 +182,7 @@ import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
import com.jpexs.decompiler.flash.tags.text.TextParseException;
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.Scene;
import com.jpexs.decompiler.flash.timeline.SceneFrame;
import com.jpexs.decompiler.flash.timeline.SoundStreamFrameRange;
@@ -2958,6 +2959,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (ts.getTag() instanceof ASMSource) {
as = (ASMSource) ts.getTag();
}
} else if (t instanceof FrameScript) {
FrameScript fs = (FrameScript) t;
if (fs.getSingleDoActionTag() != null) {
as = fs.getSingleDoActionTag();
}
}
if (as != null) {
SWF s = as.getSourceTag().getSwf();
@@ -6152,6 +6158,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
treeItem = ((TagScript) treeItem).getTag();
preferScript = true;
}
if (treeItem instanceof FrameScript) {
FrameScript fs = (FrameScript) treeItem;
DoActionTag doAction = fs.getSingleDoActionTag();
if (doAction != null) {
treeItem = doAction;
}
}
folderPreviewPanel.clear();
folderListPanel.clear();
@@ -541,9 +541,15 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
@Override
protected Void doInBackground() throws Exception {
if (isCancelled()) {
return null;
}
ActionList innerActions = actions;
if (disassemblingNeeded) {
View.execInEventDispatch(() -> {
if (isCancelled()) {
return;
}
editor.setShowMarkers(false);
setEditorText(asm.getScriptName(), asm.getExportedScriptName(), "; " + AppStrings.translate("work.disassembling") + "...", "text/flasm");
if (decompileNeeded) {
@@ -552,12 +558,18 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
}
});
if (isCancelled()) {
return null;
}
DisassemblyListener listener = getDisassemblyListener();
asm.addDisassemblyListener(listener);
innerActions = asm.getActions();
asm.removeDisassemblyListener(listener);
}
if (isCancelled()) {
return null;
}
if (decompileNeeded) {
View.execInEventDispatch(() -> {
decompiledEditor.setShowMarkers(false);
@@ -189,8 +189,17 @@ public abstract class AbstractTagTree extends JTree {
return View.getIcon("folderscripts16");
}
TreeNodeType type = getTreeNodeType(val);
if (val instanceof FrameScript) {
FrameScript fs = (FrameScript) val;
if (fs.getSingleDoActionTag() != null) {
type = TreeNodeType.AS_FRAME;
}
}
if (type == TreeNodeType.FOLDER && folderExpanded) {
type = TreeNodeType.FOLDER_OPEN;
}
@@ -653,6 +662,12 @@ public abstract class AbstractTagTree extends JTree {
d = tag;
}
}
if (d instanceof FrameScript) {
DoActionTag tag = ((FrameScript) d).getSingleDoActionTag();
if (tag != null) {
d = tag;
}
}
if (d instanceof Tag
|| d instanceof ASMSource
@@ -374,6 +374,24 @@ public class TagTreeContextMenu extends JPopupMenu {
return items;
}
private List<TreeItem> filterOutScriptItems(List<TreeItem> items) {
List<TreeItem> noScriptItems = new ArrayList<>();
for (TreeItem item : items) {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
noScriptItems.add(item);
}
return noScriptItems;
}
private List<TreeItem> getSelectedNoScriptItems() {
return filterOutScriptItems(items);
}
public TagTreeContextMenu(final List<AbstractTagTree> trees, MainPanel mainPanel) {
this.mainPanel = mainPanel;
@@ -1163,6 +1181,12 @@ public class TagTreeContextMenu extends JPopupMenu {
continue;
}
}
if (item instanceof FrameScript) {
DoActionTag tag = ((FrameScript) item).getSingleDoActionTag();
if (tag != null) {
continue;
}
}
allSelectedIsTag = false;
allSelectedIsTagWithClassName = false;
@@ -1179,6 +1203,11 @@ public class TagTreeContextMenu extends JPopupMenu {
if (tag instanceof DoActionTag || tag instanceof DoInitActionTag) {
continue;
}
} else if (item instanceof FrameScript) {
DoActionTag tag = ((FrameScript) item).getSingleDoActionTag();
if (tag != null) {
continue;
}
} else if (item instanceof Frame) {
continue;
}
@@ -1352,6 +1381,12 @@ public class TagTreeContextMenu extends JPopupMenu {
if (allSelectedIsTag) {
boolean canUndo = false;
for (TreeItem item : items) {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Tag) {
Tag tag = (Tag) item;
if (tag.canUndo()) {
@@ -1695,7 +1730,10 @@ public class TagTreeContextMenu extends JPopupMenu {
if ((firstItem instanceof SWF) || (firstItem instanceof DefineSpriteTag) || (firstItem instanceof Frame)) {
pasteInsideMenuItem.setVisible(true);
}
if ((firstItem instanceof Tag) || (firstItem instanceof Frame)) {
if ((firstItem instanceof Tag)
|| (firstItem instanceof Frame)
|| (firstItem instanceof TagScript)
|| ((firstItem instanceof FrameScript) && ((FrameScript) firstItem).getSingleDoActionTag() != null)) {
pasteAfterMenuItem.setVisible(true);
pasteBeforeMenuItem.setVisible(true);
}
@@ -1760,6 +1798,8 @@ public class TagTreeContextMenu extends JPopupMenu {
for (TreeItem item : items) {
if (item instanceof TagScript) {
tagItems.add(((TagScript) item).getTag());
} else if (item instanceof FrameScript) {
tagItems.add(((FrameScript) item).getSingleDoActionTag());
} else {
tagItems.add((Tag) item);
}
@@ -2260,6 +2300,13 @@ public class TagTreeContextMenu extends JPopupMenu {
Timelined timelined = null;
int index = -1;
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Tag) {
Tag itemTag = (Tag) item;
timelined = itemTag.getTimelined();
@@ -2301,6 +2348,12 @@ public class TagTreeContextMenu extends JPopupMenu {
Timelined timelined = null;
int index = -1;
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Tag) {
Tag itemTag = (Tag) item;
timelined = itemTag.getTimelined();
@@ -3485,8 +3538,11 @@ public class TagTreeContextMenu extends JPopupMenu {
if (subItem instanceof FrameScript) {
if (((FrameScript) subItem).getFrame().frame + 1 == targetFrame) {
TreePath framePath = scriptsPath.pathByAddingChild(subItem);
List<? extends TreeItem> doActionTags = mainPanel.tagTree.getFullModel().getAllChildren(subItem);
TreePath doActionPath = framePath.pathByAddingChild(doActionTags.get(doActionTags.size() - 1));
TreePath doActionPath = framePath;
if (((FrameScript) subItem).getSingleDoActionTag() == null) {
List<? extends TreeItem> doActionTags = mainPanel.tagTree.getFullModel().getAllChildren(subItem);
doActionPath = framePath.pathByAddingChild(doActionTags.get(doActionTags.size() - 1));
}
mainPanel.tagTree.setSelectionPath(doActionPath);
mainPanel.tagTree.scrollPathToVisible(doActionPath);
break;
@@ -3982,6 +4038,8 @@ public class TagTreeContextMenu extends JPopupMenu {
out.add(t);
} else if (t instanceof ASMSource) {
out.add(t);
} else if ((t instanceof FrameScript) && (((FrameScript) t).getSingleDoActionTag() != null)) {
out.add(t);
} else {
populateScriptSubs(t, out);
}
@@ -4038,6 +4096,8 @@ public class TagTreeContextMenu extends JPopupMenu {
tagsToRemove.add((Tag) item);
} else if ((item instanceof TagScript) && (((TagScript) item).getTag() instanceof ASMSource)) {
tagsToRemove.add(((TagScript) item).getTag());
} else if ((item instanceof FrameScript) && (((FrameScript) item).getSingleDoActionTag() != null)) {
tagsToRemove.add(((FrameScript) item).getSingleDoActionTag());
} else if (item instanceof Frame) {
Frame frameNode = (Frame) item;
Frame frame = frameNode.timeline.getFrame(frameNode.frame);
@@ -4334,6 +4394,12 @@ public class TagTreeContextMenu extends JPopupMenu {
Set<SWF> computeSWFs = new LinkedIdentityHashSet<>();
for (TreeItem item : sel) {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Tag) {
try {
Tag tag = (Tag) item;
@@ -4389,7 +4455,7 @@ public class TagTreeContextMenu extends JPopupMenu {
}
private void cloneActionPerformed(ActionEvent e) {
List<TreeItem> items = getSelectedItems();
List<TreeItem> items = getSelectedNoScriptItems();
/* 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 */
@@ -4500,6 +4566,9 @@ public class TagTreeContextMenu extends JPopupMenu {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof SceneFrame) {
item = ((SceneFrame) item).getFrame();
}
@@ -4802,12 +4871,12 @@ public class TagTreeContextMenu extends JPopupMenu {
}
public void copyTagOrFrameToClipboardActionPerformed(ActionEvent evt) {
List<TreeItem> items = getSelectedItems();
List<TreeItem> items = getSelectedNoScriptItems();
copyTagOrFrameToClipboardActionPerformed(evt, items);
}
public void copyTagOrFrameToClipboardActionPerformed(ActionEvent evt, List<TreeItem> items) {
mainPanel.copyToClipboard(items);
mainPanel.copyToClipboard(filterOutScriptItems(items));
}
private Set<TreeItem> getDependenciesSet(List<TreeItem> items) {
@@ -4846,17 +4915,17 @@ public class TagTreeContextMenu extends JPopupMenu {
}
public void copyTagToClipboardWithDependenciesActionPerformed(ActionEvent evt, List<TreeItem> items) {
mainPanel.copyToClipboard(getDependenciesSet(items));
mainPanel.copyToClipboard(getDependenciesSet(filterOutScriptItems(items)));
}
public void cutTagOrFrameToClipboardActionPerformed(ActionEvent evt) {
List<TreeItem> items = getSelectedItems();
List<TreeItem> items = getSelectedNoScriptItems();
mainPanel.cutToClipboard(items);
mainPanel.repaintTree();
}
public void cutTagToClipboardWithDependenciesActionPerformed(ActionEvent evt) {
List<TreeItem> items = getSelectedItems();
List<TreeItem> items = getSelectedNoScriptItems();
mainPanel.cutToClipboard(getDependenciesSet(items));
mainPanel.repaintTree();
}
@@ -4873,6 +4942,12 @@ public class TagTreeContextMenu extends JPopupMenu {
Timelined timelined;
Tag position;
int positionInt;
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Frame) {
Frame frame = (Frame) item;
timelined = frame.timeline.timelined;
@@ -4901,6 +4976,12 @@ public class TagTreeContextMenu extends JPopupMenu {
Timelined timelined;
Tag position;
int positionInt;
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Frame) {
Frame frame = (Frame) item;
timelined = frame.timeline.timelined;
@@ -4928,6 +5009,12 @@ public class TagTreeContextMenu extends JPopupMenu {
} else {
Timelined timelined;
Tag position;
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) {
item = ((FrameScript) item).getSingleDoActionTag();
}
if (item instanceof Frame) {
Frame frame = (Frame) item;
position = frame.allInnerTags.get(frame.allInnerTags.size() - 1);
@@ -404,14 +404,14 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
}
}
List<String> ret = new ArrayList<>();
for (String f : FOLDERS_ORDER) {
if (folderNames.contains(f)) {
ret.add(f);
}
}
return ret;
}
@@ -579,6 +579,20 @@ public class TagTreeModel extends AbstractTagTreeModel {
if (objNoTs == nNoTs) {
return true;
}
TreeItem objNoFs = obj;
if ((obj instanceof FrameScript) && ((FrameScript) obj).getSingleDoActionTag() != null) {
objNoFs = ((FrameScript) obj).getSingleDoActionTag();
}
TreeItem nNoFs = n;
if ((n instanceof FrameScript) && ((FrameScript) n).getSingleDoActionTag() != null) {
nNoFs = ((FrameScript) n).getSingleDoActionTag();
}
if (objNoFs == nNoFs) {
return true;
}
}
return false;
}
@@ -710,6 +724,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
} else if (parentNode instanceof AS2Package) {
return ((AS2Package) parentNode).getAllChildren();
} else if (parentNode instanceof FrameScript) {
if (((FrameScript) parentNode).getSingleDoActionTag() != null) {
return new ArrayList<>();
}
Frame parentFrame = ((FrameScript) parentNode).getFrame();
result.addAll(parentFrame.actionContainers);
result.addAll(parentFrame.actions);
@@ -807,6 +824,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
} else if (parentNode instanceof AS2Package) {
return ((AS2Package) parentNode).getChild(index);
} else if (parentNode instanceof FrameScript) {
if (((FrameScript) parentNode).getSingleDoActionTag() != null) {
return null;
}
Frame parentFrame = ((FrameScript) parentNode).getFrame();
TreeItem result;
if (index < parentFrame.actionContainers.size()) {
@@ -884,6 +904,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
} else if (parentNode instanceof AS2Package) {
return mappedSize + ((AS2Package) parentNode).getChildCount();
} else if (parentNode instanceof FrameScript) {
if (((FrameScript) parentNode).getSingleDoActionTag() != null) {
return 0;
}
Frame parentFrame = ((FrameScript) parentNode).getFrame();
return mappedSize + parentFrame.actionContainers.size() + parentFrame.actions.size();
} else if (parentNode instanceof TagScript) {
@@ -956,6 +979,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
} else if (parentNode instanceof AS2Package) {
return indexOfAdd(baseIndex, ((AS2Package) parentNode).getIndexOfChild(childNode));
} else if (parentNode instanceof FrameScript) {
if (((FrameScript) parentNode).getSingleDoActionTag() != null) {
return -1;
}
Frame parentFrame = ((FrameScript) parentNode).getFrame();
if (childNode instanceof TagScript) {
childNode = ((TagScript) childNode).getTag();