diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 7f837e743..f49d54729 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -3028,6 +3028,93 @@ public final class SWF implements SWFContainerItem, Timelined { } } + /** + * Adds a tag to the SWF + * If targetTreeItem is: + * - Frame: adds the tag to the Frame. Frame can be a frame of the main + * timeline or a DefineSprite frame + * - DefineSprite: adds the tag to the and of the DefineSprite's tag list + * - Any other tag in the SWF: adds the new tag exactly before the specified + * tag + * - Other: adds the tag to the end of the SWF's tag list + * + * @param tag + * @param targetTreeItem + */ + public void addTag(Tag tag, TreeItem targetTreeItem) { + SWF swf = tag.getSwf(); + Frame frame = targetTreeItem instanceof Frame ? (Frame) targetTreeItem : null; + Timelined timelined; + if (frame != null) { + timelined = frame.timeline.timelined; + } else { + timelined = swf.getTimelined(targetTreeItem); + } + + tag.setTimelined(timelined); + + List tags; + if (timelined instanceof DefineSpriteTag) { + DefineSpriteTag sprite = (DefineSpriteTag) timelined; + tags = sprite.subTags; + } else { + tags = swf.tags; + } + + int index; + if (frame != null) { + if (frame.showFrameTag != null) { + index = tags.indexOf(frame.showFrameTag); + } else { + index = -1; + } + } else if (timelined instanceof DefineSpriteTag) { + index = -1; + } else if (targetTreeItem instanceof Tag) { + if (tag instanceof CharacterIdTag && targetTreeItem instanceof CharacterTag) { + ((CharacterIdTag) tag).setCharacterId(((CharacterTag) targetTreeItem).getCharacterId()); + } + + index = tags.indexOf(targetTreeItem); // todo: honfika: why not index + 1? + } else { + index = -1; + if (tag instanceof CharacterTag) { + // add before the last ShowFrame tag + for (int i = tags.size() - 1; i >= 0; i--) { + if (tags.get(i) instanceof ShowFrameTag) { + index = i; + break; + } + } + } + } + + if (index > -1) { + tags.add(index, tag); + } else { + tags.add(tag); + } + + timelined.resetTimeline(); + + if (timelined instanceof DefineSpriteTag) { + DefineSpriteTag sprite = (DefineSpriteTag) timelined; + sprite.frameCount = timelined.getTimeline().getFrameCount(); + } + } + + public Timelined getTimelined(TreeItem treeItem) { + if (treeItem instanceof Frame) { + return ((Frame) treeItem).timeline.timelined; + } + + if (treeItem instanceof DefineSpriteTag) { + return (DefineSpriteTag) treeItem; + } + + return treeItem.getSwf(); + } + public void packCharacterIds() { int maxId = getNextCharacterId(); int id = 1; diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 07280a4ed..12f7a720a 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -24,10 +24,8 @@ import com.jpexs.decompiler.flash.gui.ReplaceCharacterDialog; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineSoundTag; -import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DoActionTag; import com.jpexs.decompiler.flash.tags.DoInitActionTag; -import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -35,7 +33,6 @@ import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.TagScript; -import com.jpexs.decompiler.flash.timeline.Timelined; import com.jpexs.decompiler.flash.treeitems.FolderItem; import com.jpexs.decompiler.flash.treeitems.SWFList; import com.jpexs.decompiler.flash.treeitems.TreeItem; @@ -358,9 +355,8 @@ public class TagTreeContextMenu extends JPopupMenu { List allowedTagTypes = tagTree.getNestedTagIds((Tag) firstItem); addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); } else if (firstItem instanceof Frame) { - // todo: honfika: add to the selected frame - //List allowedTagTypes = tagTree.getFrameNestedTagIds(); - //addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); + List allowedTagTypes = tagTree.getFrameNestedTagIds(); + addAddTagMenuItems(allowedTagTypes, addTagMenu, firstItem); } addTagMenu.setVisible(addTagMenu.getItemCount() > 0); @@ -444,43 +440,7 @@ public class TagTreeContextMenu extends JPopupMenu { try { SWF swf = firstItem.getSwf(); Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf}); - boolean isDefineSprite = firstItem instanceof DefineSpriteTag; - Timelined timelined = isDefineSprite ? (DefineSpriteTag) firstItem : swf; - t.setTimelined(timelined); - if (isDefineSprite) { - DefineSpriteTag sprite = (DefineSpriteTag) firstItem; - timelined.resetTimeline(); - sprite.subTags.add(t); - sprite.frameCount = timelined.getTimeline().getFrameCount(); - } else { - int index; - if (firstItem instanceof Tag) { - if ((t instanceof CharacterIdTag) && (firstItem instanceof CharacterTag)) { - ((CharacterIdTag) t).setCharacterId(((CharacterTag) firstItem).getCharacterId()); - } - index = swf.tags.indexOf(firstItem); - } else { - index = -1; - if (t instanceof CharacterTag) { - // add before the last ShowFrame tag - for (int i = swf.tags.size() - 1; i >= 0; i--) { - if (swf.tags.get(i) instanceof ShowFrameTag) { - index = i; - break; - } - } - } - } - - if (index > -1) { - swf.tags.add(index, t); - } else { - swf.tags.add(t); - } - - timelined.resetTimeline(); - } - + swf.addTag(t, firstItem); swf.updateCharacters(); mainPanel.refreshTree(swf); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) {