diff --git a/CHANGELOG.md b/CHANGELOG.md index 483a6aef8..e8c2139f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. - File path in window title for SWFs inside DefineBinaryData - [#1863] Export to PDF - cannot read fonts with long CMAP - Go to document class when switched to tag list view +- Copy/Move with dependencies order of tags ## [16.2.0] - 2022-11-08 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java index 8e7a6929b..0e388f069 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -49,6 +49,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -643,23 +644,34 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable { } public void getNeededCharactersDeep(Set needed) { - Set visited = new HashSet<>(); Set needed2 = new LinkedHashSet<>(); getNeededCharacters(needed2); + List needed3 = new ArrayList<>(needed2); - while (visited.size() != needed2.size()) { - for (int characterId : needed2) { - if (!visited.contains(characterId)) { - visited.add(characterId); - if (swf.getCharacters().containsKey(characterId)) { - swf.getCharacter(characterId).getNeededCharacters(needed2); - break; + for (int i = 0; i < needed3.size(); i++) { + int characterId = needed3.get(i); + if (swf.getCharacters().containsKey(characterId)) { + Set needed4 = new LinkedHashSet<>(); + CharacterTag character = swf.getCharacter(characterId); + character.getNeededCharacters(needed4); + List newItems = new ArrayList<>(); + for(int n : needed4) { + int index = needed3.indexOf((Integer) n); + if (index > i) { + needed3.remove(index); + } + if (!needed3.contains(n) && !newItems.contains(n)) { + newItems.add(n); } } - } + if (!newItems.isEmpty()) { + needed3.addAll(i, newItems); + i--; + } + } } - for (Integer characterId : needed2) { + for (Integer characterId : needed3) { if (swf.getCharacters().containsKey(characterId)) { needed.add(characterId); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java index e85c3240b..aabe7d313 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java @@ -192,4 +192,12 @@ public abstract class ButtonTag extends DrawableTag implements Timelined { replaceTag(index, newTag); } } + + @Override + public void setSwf(SWF swf, boolean deep) { + this.swf = swf; + for(BUTTONRECORD record:getRecords()) { + record.setSwfAndTag(swf, this); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java index 1313ea546..5a428373b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONRECORD.java @@ -35,7 +35,7 @@ import java.util.List; * * @author JPEXS */ -public class BUTTONRECORD implements Serializable, TreeItem { +public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag { @Reserved @SWFType(value = BasicType.UB, count = 2) @@ -149,7 +149,14 @@ public class BUTTONRECORD implements Serializable, TreeItem { return false; } + @Override public ButtonTag getTag() { return tag; } + + @Override + public void setSwfAndTag(SWF swf, Tag tag) { + this.swf = swf; + this.tag = (ButtonTag) tag; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java index acf056e26..d2b65a80c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java @@ -42,7 +42,7 @@ import java.util.List; * * @author JPEXS */ -public class CLIPACTIONRECORD implements ASMSource, Serializable { +public class CLIPACTIONRECORD implements ASMSource, Serializable, HasSwfAndTag { private String scriptName = "-"; private CLIPACTIONS parentClipActions; @@ -143,6 +143,18 @@ public class CLIPACTIONRECORD implements ASMSource, Serializable { public void setParentClipActions(CLIPACTIONS parentClipActions) { this.parentClipActions = parentClipActions; } + + @Override + public void setSwfAndTag(SWF swf, Tag tag) { + this.swf = swf; + this.tag = tag; + } + + @Override + public Tag getTag() { + return tag; + } + public CLIPACTIONRECORD(SWF swf, SWFInputStream sis, Tag tag, CLIPACTIONS parentClipActions) throws IOException { this.swf = swf; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/HasSwfAndTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/HasSwfAndTag.java new file mode 100644 index 000000000..f837ddbfc --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/HasSwfAndTag.java @@ -0,0 +1,16 @@ +package com.jpexs.decompiler.flash.types; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.tags.Tag; + +/** + * + * @author JPEXS + */ +public interface HasSwfAndTag { + public void setSwfAndTag(SWF swf, Tag tag); + + public SWF getSwf(); + + public Tag getTag(); +} diff --git a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java index eacef83b3..ae4a325ae 100644 --- a/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java @@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.types.ARGB; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; import com.jpexs.decompiler.flash.types.CLIPACTIONS; +import com.jpexs.decompiler.flash.types.HasSwfAndTag; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.annotations.Conditional; @@ -1228,6 +1229,9 @@ public class GenericTagTreePanel extends GenericTagPanel { ASMSource asv = (ASMSource) v; asv.setSourceTag(editedTag); } + if (v instanceof HasSwfAndTag) { + ((HasSwfAndTag) obj).setSwfAndTag(editedTag.getSwf(), editedTag); + } } catch (IllegalArgumentException | IllegalAccessException ex) { //ignore } @@ -1259,6 +1263,10 @@ public class GenericTagTreePanel extends GenericTagPanel { if ((obj instanceof CLIPACTIONS) && (v instanceof CLIPACTIONRECORD)) { ((CLIPACTIONRECORD) v).setParentClipActions((CLIPACTIONS) obj); } + + if (obj instanceof HasSwfAndTag) { + ((HasSwfAndTag) obj).setSwfAndTag(editedTag.getSwf(), editedTag); + } } catch (IllegalArgumentException | IllegalAccessException ex) { //ignore diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 95772d596..0f89f3c6f 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -2686,20 +2686,13 @@ public class TagTreeContextMenu extends JPopupMenu { Set needed = new LinkedHashSet<>(); Tag tag = (Tag) item; tag.getNeededCharactersDeep(needed); - List neededList = new ArrayList<>(); + if (tag instanceof CharacterTag) { + needed.add(((CharacterTag) tag).getCharacterId()); + } for (Integer characterId : needed) { - neededList.add(characterId); - } - - // first add dependencies in reverse order - for (int n = neededList.size() - 1; n >= 0; n--) { - int characterId = neededList.get(n); CharacterTag neededTag = sourceSwf.getCharacter(characterId); - if (!newItems.contains(neededTag)) { - newItems.add(neededTag); - } + newItems.add(neededTag); } - newItems.add(item); } return newItems; }