diff --git a/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 5aaf1c78e..430ab426f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -763,7 +763,7 @@ public class CommandLineArgumentParser { args.remove(); } } - + if (args.size() > 0) { String modeStr = args.remove().toLowerCase(); switch (modeStr) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java index 7161f4ab7..5b0a154e9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagTreePanel.java @@ -29,10 +29,13 @@ import com.jpexs.decompiler.flash.types.ARGB; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.Multiline; import com.jpexs.decompiler.flash.types.annotations.SWFArray; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator; +import com.jpexs.decompiler.flash.types.annotations.parser.ParseException; import com.jpexs.helpers.Helper; import java.awt.BorderLayout; import java.awt.Color; @@ -48,7 +51,9 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.EventObject; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -58,6 +63,7 @@ import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeModelListener; import javax.swing.plaf.basic.BasicLabelUI; @@ -102,6 +108,7 @@ public class GenericTagTreePanel extends GenericTagPanel { private GenericTagEditor editor = null; private final JTree tree; + private FieldNode fnode; public MyTreeCellEditor(JTree tree) { this.tree = tree; @@ -110,7 +117,7 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { if (value instanceof FieldNode) { - FieldNode fnode = (FieldNode) value; + fnode = (FieldNode) value; Field field = fnode.field; int index = fnode.index; Object obj = fnode.obj; @@ -193,8 +200,15 @@ public class GenericTagTreePanel extends GenericTagPanel { @Override public boolean stopCellEditing() { super.stopCellEditing(); + + /*List depends = ((MyTreeModel) tree.getModel()).getDependentFields(fnode); + boolean dep = false; + if (!depends.isEmpty()) { + dep = true; + } */ editor.save(); ((MyTreeModel) tree.getModel()).vchanged(tree.getSelectionPath()); + refreshTree(); return true; } @@ -204,7 +218,7 @@ public class GenericTagTreePanel extends GenericTagPanel { setLayout(new BorderLayout()); tree = new MyTree(); - add(tree, BorderLayout.CENTER); + add(new JScrollPane(tree), BorderLayout.CENTER); tree.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { @@ -404,7 +418,17 @@ public class GenericTagTreePanel extends GenericTagPanel { if (ReflectionTools.needsIndex(field) && (index == -1)) { return obj; } - return ReflectionTools.getValue(obj, field, index); + Object val = ReflectionTools.getValue(obj, field, index); + if (val == null) { + try { + val = ReflectionTools.newInstanceOf(field.getType()); + ReflectionTools.setValue(obj, field, index, val); + } catch (InstantiationException | IllegalAccessException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + } + return val; } catch (IllegalArgumentException | IllegalAccessException ex) { return null; } @@ -439,30 +463,93 @@ public class GenericTagTreePanel extends GenericTagPanel { } return true; } - - DefaultTreeModel d; } private static class MyTreeModel extends DefaultTreeModel { - private final Object root; + private final Object mtroot; private final List listeners = new ArrayList<>(); - private DefaultMutableTreeNode rootNode; + private Map nodeCache = new HashMap<>(); + + private Object getNodeByPath(String path) { + if (nodeCache.containsKey(path)) { + return nodeCache.get(path); + } + return null; + } + + public List getDependentFields(FieldNode fnode) { + List ret = new ArrayList<>(); + getDependentFields(getNodePathName(fnode), mtroot.getClass().getSimpleName(), mtroot, ret); + return ret; + } + + public void getDependentFields(String dependence, String currentPath, Object node, List ret) { + if (node instanceof FieldNode) { + FieldNode fnode = (FieldNode) node; + Conditional cond = fnode.field.getAnnotation(Conditional.class); + if (cond != null) { + ConditionEvaluator ev = new ConditionEvaluator(cond); + String parentPath = currentPath.indexOf(".") == -1 ? "" : currentPath.substring(0, currentPath.lastIndexOf(".")); + try { + for (String cname : ev.getFields()) { + String fullParh = parentPath + "." + cname; + if (fullParh.equals(dependence)) { + ret.add(fnode); + break; + } + } + } catch (ParseException ex) { + Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + for (int i = 0; i < getChildCount(node); i++) { + FieldNode f = (FieldNode) getChild(node, i); + getDependentFields(dependence, currentPath + "." + f.getName(), f, ret); + } + } + + public String getNodePathName(Object find) { + + for (Map.Entry en : nodeCache.entrySet()) { + if (en.getValue().equals(find)) { + return en.getKey(); + } + } + return null; + } public MyTreeModel(Tag root) { super(new DefaultMutableTreeNode(root)); - this.root = root; + this.mtroot = root; + buildCache(root, ""); + } + + private void buildCache(Object obj, String parentPath) { + if (!"".equals(parentPath)) { + parentPath += "."; + } + if (obj instanceof FieldNode) { + FieldNode fn = (FieldNode) obj; + parentPath += fn.getName(); + } else { + parentPath += obj.getClass().getSimpleName(); + } + nodeCache.put(parentPath, obj); + for (int i = 0; i < getChildCount(obj, false); i++) { + buildCache(getChild(obj, i, false), parentPath); + } } @Override public Object getRoot() { - return root; + return mtroot; } - @Override - public Object getChild(Object parent, int index) { - if (parent == root) { - return new FieldNode(root, getAvailableFields(root.getClass()).get(index), -1); + private Object getChild(Object parent, int index, boolean limited) { + if (parent == mtroot) { + return new FieldNode(mtroot, filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).get(index), -1); } FieldNode fnode = (FieldNode) parent; Field field = fnode.field; @@ -470,13 +557,22 @@ public class GenericTagTreePanel extends GenericTagPanel { return new FieldNode(fnode.obj, field, index); } parent = fnode.getValue(); - return new FieldNode(parent, getAvailableFields(parent.getClass()).get(index), -1); + return new FieldNode(parent, filterFields(this, getNodePathName(fnode), parent.getClass(), limited).get(index), -1); + } + + @Override + public Object getChild(Object parent, int index) { + return getChild(parent, index, true); } @Override public int getChildCount(Object parent) { - if (parent == root) { - return getAvailableFields(root.getClass()).size(); + return getChildCount(parent, true); + } + + private int getChildCount(Object parent, boolean limited) { + if (parent == mtroot) { + return filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).size(); } FieldNode fnode = (FieldNode) parent; if (isLeaf(fnode)) { @@ -488,12 +584,12 @@ public class GenericTagTreePanel extends GenericTagPanel { } parent = fnode.getValue(); - return getAvailableFields(parent.getClass()).size(); + return filterFields(this, getNodePathName(fnode), parent.getClass(), limited).size(); } @Override public boolean isLeaf(Object node) { - if (node == root) { + if (node == mtroot) { return false; } @@ -639,6 +735,39 @@ public class GenericTagTreePanel extends GenericTagPanel { } } + private static List filterFields(MyTreeModel mod, String parentPath, Class cls, boolean limited) { + List ret = new ArrayList<>(); + List fields = getAvailableFields(cls); + for (Field f : fields) { + if (limited) { + Conditional cond = f.getAnnotation(Conditional.class); + if (cond != null) { + ConditionEvaluator ev = new ConditionEvaluator(cond); + try { + Map fieldMap = new HashMap<>(); + for (String sf : ev.getFields()) { + String fulldf = parentPath + "." + sf; + FieldNode condnode = (FieldNode) (mod).getNodeByPath(fulldf); + + if (condnode != null) { + fieldMap.put(sf, (Boolean) ReflectionTools.getValue(condnode.obj, condnode.field, condnode.index)); + } else { + fieldMap.put(sf, true); + } + } + if (!ev.eval(fieldMap)) { + continue; + } + } catch (ParseException | IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + ret.add(f); + } + return ret; + } + private static List getAvailableFields(Class cls) { List ret = new ArrayList<>(); Field fields[] = cls.getFields(); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index a2eee7e47..fa88a0858 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -670,7 +670,7 @@ public class DefineEditTextTag extends TextTag implements DrawableTag { staticTextToImage(swf, characters, textRecords, 1, image, getTextMatrix(), transformation); } } - + private String getInnerText(String html) { String result = ""; boolean inTag = false; @@ -686,7 +686,7 @@ public class DefineEditTextTag extends TextTag implements DrawableTag { } return result; } - + @Override public Point getImagePos(int frame, Map characters, Stack visited) { return new Point(bounds.Xmin / SWF.unitDivisor, bounds.Ymin / SWF.unitDivisor); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java index 0aa753c42..3fbd20439 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java @@ -388,7 +388,7 @@ public class PlaceObject2Tag extends CharacterIdTag implements Container, PlaceO @Override public String toString() { - if (name != null) { + if (placeFlagHasName) { return super.toString() + " (" + name + ")"; } else { return super.toString(); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java index 648eb7c6f..5395988c7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java @@ -518,7 +518,7 @@ public class PlaceObject3Tag extends CharacterIdTag implements Container, PlaceO @Override public String toString() { - if (name != null) { + if (placeFlagHasName) { return super.toString() + " (" + name + ")"; } else { return super.toString(); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java index b52c762a3..2304a7fcc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java @@ -521,7 +521,7 @@ public class PlaceObject4Tag extends CharacterIdTag implements Container, PlaceO @Override public String toString() { - if (name != null) { + if (placeFlagHasName) { return super.toString() + " (" + name + ")"; } else { return super.toString(); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/Tag.java index 9b30975fd..b56e2ad12 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -60,7 +60,7 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ public boolean forceWriteAsLong = false; @Internal private final long pos; - protected String name; + protected String tagName; @Internal public Tag previousTag; @Internal @@ -69,7 +69,7 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ private boolean modified; public String getName() { - return name; + return tagName; } @Override @@ -106,7 +106,7 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ */ public Tag(SWF swf, int id, String name, byte[] data, long pos) { this.id = id; - this.name = name; + this.tagName = name; this.data = data; this.pos = pos; this.swf = swf; @@ -266,7 +266,7 @@ public class Tag implements NeedsCharacters, Exportable, ContainerItem, Serializ public byte[] getData() { return data; } - + public int getVersion() { if (swf == null) { return SWF.DEFAULT_VERSION; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/CharacterIdTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/CharacterIdTag.java index 8e7eefe3e..a61da53da 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/CharacterIdTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/CharacterIdTag.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.tags.ExportAssetsTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.types.annotations.Internal; import java.util.ArrayList; import java.util.List; @@ -36,6 +37,7 @@ public abstract class CharacterIdTag extends Tag { /** * List of ExportAssetsTag used for converting to String */ + @Internal public List exportAssetsTags = new ArrayList<>(); protected String className; protected String exportName; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index 8169acf06..a2a62eb82 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -138,7 +138,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable if (fontName != null) { nameAppend = ": " + fontName; } - return name + " (" + getCharacterId() + nameAppend + ")"; + return tagName + " (" + getCharacterId() + nameAppend + ")"; } public String getSystemFontName() {