diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 2512056d7..20b0a059b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -971,6 +971,17 @@ public final class SWF implements TreeItem { } return ret; } + + public static void getTagsFromTreeNodes(List treeNodes, List result) { + for (TreeNode treeNode : treeNodes) { + TreeItem treeItem = treeNode.getItem(); + if (treeItem instanceof Tag) { + result.add((Tag) treeItem); + } + getTagsFromTreeNodes(treeNode.subNodes, result); + } + } + private final HashSet listeners = new HashSet<>(); public final void addEventListener(EventListener listener) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 6fa448e92..0cd1e2698 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.gui.player.PlayerControls; import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode; import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.helpers.Freed; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; @@ -140,6 +141,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -158,6 +160,7 @@ import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JColorChooser; +import javax.swing.JEditorPane; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; @@ -207,6 +210,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private final JPanel displayPanel; private ImagePanel imagePanel; private BinaryPanel binaryPanel; + private JEditorPane genericTagPropertiesEditorPane; private final ImagePanel previewImagePanel; private final SWFPreviwPanel swfPreviewPanel; private boolean isWelcomeScreen = true; @@ -215,6 +219,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private static final String CARDDRAWPREVIEWPANEL = "Draw card"; private static final String CARDIMAGEPANEL = "Image card"; private static final String CARDBINARYPANEL = "Binary card"; + private static final String CARDGENEICTAGPANEL = "Generic tag card"; private static final String CARDEMPTYPANEL = "Empty card"; private static final String CARDACTIONSCRIPTPANEL = "ActionScript card"; private static final String CARDACTIONSCRIPT3PANEL = "ActionScript3 card"; @@ -488,6 +493,15 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return binaryCard; } + private JPanel createGenericTagCard() { + JPanel genericTagCard = new JPanel(new BorderLayout()); + genericTagPropertiesEditorPane = new JEditorPane(); + genericTagPropertiesEditorPane.setEditable(false); + genericTagCard.add(genericTagPropertiesEditorPane, BorderLayout.CENTER); + + return genericTagCard; + } + private void showHideImageReplaceButton(boolean show) { imageReplaceButton.setVisible(show); setImageButtonPanelVisibility(); @@ -730,6 +744,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec displayPanel.add(createImagesCard(), CARDIMAGEPANEL); displayPanel.add(createBinaryCard(), CARDBINARYPANEL); + displayPanel.add(createGenericTagCard(), CARDGENEICTAGPANEL); JPanel shapesCard = new JPanel(new BorderLayout()); @@ -2368,11 +2383,29 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec parametersPanel.setVisible(false); } + } else if (tagObj instanceof Tag) { + showCard(CARDGENEICTAGPANEL); + showGenericTag((Tag) tagObj); } else { showCard(CARDEMPTYPANEL); } } + private void showGenericTag(Tag tag) { + StringBuilder sb = new StringBuilder(); + Field[] fields = tag.getClass().getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + sb.append(field.getName()).append(": ").append(field.get(tag)); + sb.append(GraphTextWriter.NEW_LINE); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + genericTagPropertiesEditorPane.setText(sb.toString()); + } + private void createAndShowTempSwf(Object tagObj) { SWF swf; try { @@ -2473,7 +2506,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } if (t instanceof CharacterTag) { - doneCharacters.add(((CharacterTag) t).getCharacterId()); + int characterId = ((CharacterTag) t).getCharacterId(); + if (!doneCharacters.contains(characterId)) { + doneCharacters.add(((CharacterTag) t).getCharacterId()); + } } sos2.writeTag(classicTag(t)); @@ -2728,7 +2764,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { - SWFOutputStream sos = new SWFOutputStream(fos, 10); + SWFOutputStream sos = new SWFOutputStream(fos, Math.max(10, swf.version)); sos.write("FWS".getBytes()); sos.write(swf.version); sos.writeUI32(sos.getPos() + data.length + 4); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java index 756472063..3f1e95af7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java @@ -26,17 +26,15 @@ import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.gui.treenodes.StringNode; import com.jpexs.decompiler.flash.gui.treenodes.TagTreeRoot; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; -import com.jpexs.decompiler.flash.tags.ExportAssetsTag; import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; import com.jpexs.decompiler.flash.treeitems.StringItem; import com.jpexs.decompiler.flash.treeitems.TreeElementItem; import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.ContainerNode; import com.jpexs.decompiler.flash.treenodes.FrameNode; +import com.jpexs.decompiler.flash.treenodes.TagNode; import com.jpexs.decompiler.flash.treenodes.TreeNode; import java.util.ArrayList; import java.util.HashMap; @@ -72,11 +70,9 @@ public class TagTreeModel implements TreeModel { } private SWFNode createSwfNode(SWF swf) { - List objs = new ArrayList<>(); - objs.addAll(swf.tags); ClassesListTreeModel classTreeModel = new ClassesListTreeModel(swf); SWFNode swfNode = new SWFNode(swf, swf.getShortFileName()); - swfNode.list = createTagList(objs, null, swf, swfNode, classTreeModel); + swfNode.list = createTagList(swf.tags, null, swf, swfNode, classTreeModel); swfToSwfNode.put(swf, swfNode); return swfNode; } @@ -85,36 +81,49 @@ public class TagTreeModel implements TreeModel { return mainFrame.translate(key); } - public List getTagNodesWithType(List list, TreeNodeType type, Tag parent, boolean display) { - List ret = new ArrayList<>(); - int frameCnt = 0; - for (ContainerItem o : list) { - TreeNodeType ttype = TagTree.getTreeNodeType(o); - if (ttype == TreeNodeType.SHOW_FRAME && type == TreeNodeType.FRAME) { - frameCnt++; - ret.add(new FrameNode(new FrameNodeItem(o.getSwf(), frameCnt, parent, display))); - } else if (type == ttype) { - ret.add(new ContainerNode(o)); - } - } - return ret; - } - - private List createTagList(List list, Tag parent, SWF swf, SWFNode swfNode, ClassesListTreeModel classTreeModel) { + private List createTagList(List list, Tag parent, SWF swf, SWFNode swfNode, ClassesListTreeModel classTreeModel) { boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty(); List ret = new ArrayList<>(); - List frames = getTagNodesWithType(list, TreeNodeType.FRAME, parent, true); - List shapes = getTagNodesWithType(list, TreeNodeType.SHAPE, parent, true); - List morphShapes = getTagNodesWithType(list, TreeNodeType.MORPH_SHAPE, parent, true); - List sprites = getTagNodesWithType(list, TreeNodeType.SPRITE, parent, true); - List buttons = getTagNodesWithType(list, TreeNodeType.BUTTON, parent, true); - List images = getTagNodesWithType(list, TreeNodeType.IMAGE, parent, true); - List fonts = getTagNodesWithType(list, TreeNodeType.FONT, parent, true); - List texts = getTagNodesWithType(list, TreeNodeType.TEXT, parent, true); - List movies = getTagNodesWithType(list, TreeNodeType.MOVIE, parent, true); - List sounds = getTagNodesWithType(list, TreeNodeType.SOUND, parent, true); - List binaryData = getTagNodesWithType(list, TreeNodeType.BINARY_DATA, parent, true); + List frames = new ArrayList<>(); + List shapes = new ArrayList<>(); + List morphShapes = new ArrayList<>(); + List sprites = new ArrayList<>(); + List buttons = new ArrayList<>(); + List images = new ArrayList<>(); + List fonts = new ArrayList<>(); + List texts = new ArrayList<>(); + List movies = new ArrayList<>(); + List sounds = new ArrayList<>(); + List binaryData = new ArrayList<>(); + List others = new ArrayList<>(); + + List actionScript = SWF.createASTagList(list, null); + List actionScriptTags = new ArrayList<>(); + SWF.getTagsFromTreeNodes(actionScript, actionScriptTags); + + int frameCnt = 0; + for (Tag t : list) { + TreeNodeType ttype = TagTree.getTreeNodeType(t); + switch (ttype) { + case SHOW_FRAME: frames.add(new FrameNode(new FrameNodeItem(t.getSwf(), ++frameCnt, parent, true))); break; + case SHAPE: shapes.add(new TagNode(t)); break; + case MORPH_SHAPE: morphShapes.add(new TagNode(t)); break; + case SPRITE: sprites.add(new TagNode(t)); break; + case BUTTON: buttons.add(new TagNode(t)); break; + case IMAGE: images.add(new TagNode(t)); break; + case FONT: fonts.add(new TagNode(t)); break; + case TEXT: texts.add(new TagNode(t)); break; + case MOVIE: movies.add(new TagNode(t)); break; + case SOUND: sounds.add(new TagNode(t)); break; + case BINARY_DATA: binaryData.add(new TagNode(t)); break; + default: + if (!actionScriptTags.contains(t)) { + others.add(new TagNode(t)); + } + break; + } + } for (int i = 0; i < sounds.size(); i++) { if (sounds.get(i).getItem() instanceof SoundStreamHeadTypeTag) { @@ -129,17 +138,9 @@ public class TagTreeModel implements TreeModel { for (TreeNode n : sprites) { Tag tag = n.getItem() instanceof Tag ? (Tag) n.getItem() : null; - n.subNodes = getTagNodesWithType(((DefineSpriteTag) n.getItem()).subTags, TreeNodeType.FRAME, tag, true); + n.subNodes = createSubTagList(((DefineSpriteTag) n.getItem()).subTags, tag, swf, actionScriptTags); } - List exportAssetsTags = new ArrayList<>(); - for (ContainerItem t : list) { - if (t instanceof ExportAssetsTag) { - exportAssetsTags.add((ExportAssetsTag) t); - } - } - - List actionScript = SWF.createASTagList(list, null); StringNode textsNode = new StringNode(new StringItem(translate("node.texts"), swf)); textsNode.subNodes.addAll(texts); @@ -173,6 +174,9 @@ public class TagTreeModel implements TreeModel { StringNode framesNode = new StringNode(new StringItem(translate("node.frames"), swf)); framesNode.subNodes.addAll(frames); + StringNode otherNode = new StringNode(new StringItem(translate("node.others"), swf)); + otherNode.subNodes.addAll(others); + TreeNode actionScriptNode; if (hasAbc) { actionScriptNode = new ClassesListNode(classTreeModel); @@ -215,6 +219,9 @@ public class TagTreeModel implements TreeModel { if (!framesNode.subNodes.isEmpty()) { ret.add(framesNode); } + if (!otherNode.subNodes.isEmpty()) { + ret.add(otherNode); + } if ((!actionScriptNode.subNodes.isEmpty()) || hasAbc) { ret.add(actionScriptNode); @@ -223,6 +230,35 @@ public class TagTreeModel implements TreeModel { return ret; } + private List createSubTagList(List list, Tag parent, SWF swf, List actionScriptTags) { + List ret = new ArrayList<>(); + List frames = new ArrayList<>(); + List others = new ArrayList<>(); + + int frameCnt = 0; + for (Tag t : list) { + TreeNodeType ttype = TagTree.getTreeNodeType(t); + switch (ttype) { + case SHOW_FRAME: frames.add(new FrameNode(new FrameNodeItem(t.getSwf(), ++frameCnt, parent, true))); break; + default: + if (!actionScriptTags.contains(t)) { + others.add(new TagNode(t)); + } + break; + } + } + + ret.addAll(frames); + + if (!others.isEmpty()) { + StringNode otherNode = new StringNode(new StringItem(translate("node.others"), swf)); + otherNode.subNodes.addAll(others); + ret.add(otherNode); + } + + return ret; + } + private List searchTag(TreeItem obj, TreeNode parent, List path) { List ret = null; int cnt = getChildCount(parent); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 80f47ce0b..9502ca857 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -432,3 +432,5 @@ filter.binary = Binary search - all files (*.*) open.error = Error open.error.fileNotFound = File not found open.error.cannotOpen = Cannot open file + +node.others = others diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties index 393a45600..47368a960 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties +++ b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties @@ -428,3 +428,5 @@ contextmenu.moveTag = \u00c1thelyez\u00e9s ide open.error = Hiba open.error.fileNotFound = F\u00e1jl nem tal\u00e1lhat\u00f3 open.error.cannotOpen = Nem lehet megnyitni a f\u00e1jlt + +node.others = egyebek diff --git a/trunk/src/com/jpexs/decompiler/flash/types/RGB.java b/trunk/src/com/jpexs/decompiler/flash/types/RGB.java index 492d0e2fd..6f88dfcdb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/RGB.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/RGB.java @@ -72,4 +72,9 @@ public class RGB { this.green = color.getGreen(); this.blue = color.getBlue(); } + + @Override + public String toString() { + return "[RGB red:" + red + ", green:" + green + ", blue:" + blue + "]"; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/RGBA.java b/trunk/src/com/jpexs/decompiler/flash/types/RGBA.java index bc201c240..aa0f4756a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/RGBA.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/RGBA.java @@ -71,4 +71,9 @@ public class RGBA extends RGB { public Color toColor() { return new Color(red, green, blue, alpha); } + + @Override + public String toString() { + return "[RGB red:" + red + ", green:" + green + ", blue:" + blue + ", alpha:" + alpha + "]"; + } }