From a1dcd67dc675e5282cdacbfd3dba15b6771ec973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sun, 16 Feb 2014 20:04:29 +0100 Subject: [PATCH] Generic tag editor: Add+Remove item from List/Array, match countField --- .../decompiler/flash/gui/GenericTagPanel.java | 231 +++++++++++++++--- .../generictageditors/ReflectionTools.java | 161 +++++++++++- .../decompiler/flash/gui/graphics/add16.png | Bin 0 -> 733 bytes .../tags/DefineSceneAndFrameLabelDataTag.java | 7 +- .../flash/tags/ExportAssetsTag.java | 5 +- .../flash/tags/ImportAssets2Tag.java | 32 ++- .../flash/tags/ImportAssetsTag.java | 34 ++- .../decompiler/flash/tags/SymbolClassTag.java | 3 +- .../decompiler/flash/tags/base/ImportTag.java | 5 +- .../decompiler/flash/types/BasicType.java | 3 +- .../flash/types/annotations/SWFType.java | 2 +- .../types/filters/GRADIENTBEVELFILTER.java | 3 +- .../types/filters/GRADIENTGLOWFILTER.java | 3 +- 13 files changed, 418 insertions(+), 71 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/graphics/add16.png diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java index 0415344ac..45b600634 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java @@ -37,22 +37,33 @@ import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator; import com.jpexs.decompiler.flash.types.annotations.parser.ParseException; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.Box; +import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; /** * @@ -72,6 +83,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener { private Map> fieldPaths = new HashMap<>(); private Map> fieldIndices = new HashMap<>(); private HeaderLabel hdr; + private Set addKeys = new HashSet<>(); + private Map addButtons = new HashMap<>(); + private Map removeButtons = new HashMap<>(); public GenericTagPanel() { super(new BorderLayout()); @@ -101,6 +115,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener { labels.clear(); types.clear(); keys.clear(); + addKeys.clear(); + addButtons.clear(); + removeButtons.clear(); genericTagPropertiesEditPanel.removeAll(); genericTagPropertiesEditPanel.setSize(0, 0); } @@ -125,21 +142,21 @@ public class GenericTagPanel extends JPanel implements ChangeListener { for (String key : keys) { GenericTagEditor ed = editors.get(key); if (((Component) ed).isVisible()) { - val += key + " : " + ed.getReadOnlyValue()+ "
"; + val += key + " : " + ed.getReadOnlyValue() + "
"; } } //HTML for colors: - val = ""+val+""; + val = "" + val + ""; genericTagPropertiesEditorPane.setContentType("text/html"); genericTagPropertiesEditorPane.setText(val); genericTagPropertiesEditorPane.setCaretPosition(0); - hdr.setText(tag.toString()); + hdr.setText(tag.toString()); } public void generateEditControls(Tag tag, boolean readonly) { clear(); this.tag = tag; - generateEditControlsRecursive(tag, "", new ArrayList(),new ArrayList(), readonly); + generateEditControlsRecursive(tag, "", new ArrayList(), new ArrayList(), readonly); change(null); } @@ -152,37 +169,81 @@ public class GenericTagPanel extends JPanel implements ChangeListener { repaint(); } - private int generateEditControlsRecursive(Object obj, String parent, List parentFields, List parentIndices, boolean readonly) { + private int generateEditControlsRecursive(final Object obj, String parent, List parentFields, List parentIndices, boolean readonly) { if (obj == null) { return 0; } Field[] fields = obj.getClass().getDeclaredFields(); int propCount = 0; - for (Field field : fields) { + for (final Field field : fields) { try { if (Modifier.isStatic(field.getModifiers())) { continue; } field.setAccessible(true); String name = parent + field.getName(); - Object value = field.get(obj); + final Object value = field.get(obj); if (List.class.isAssignableFrom(field.getType())) { if (value != null) { int i = 0; for (Object obj1 : (Iterable) value) { - propCount += addEditor(name + "[" + i + "]", obj, field, i, obj1.getClass(), obj1, parentFields,parentIndices, readonly); + final String subname = name + "[" + i + "]"; + propCount += addEditor(subname, obj, field, i, obj1.getClass(), obj1, parentFields, parentIndices, readonly); + final int fi = i; i++; + JButton removeButton = new JButton(View.getIcon("close16")); + removeButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + removeItem(obj, field, fi); + } + }); + removeButtons.put(subname, removeButton); } } } else if (field.getType().isArray()) { if (value != null) { for (int i = 0; i < Array.getLength(value); i++) { Object item = Array.get(value, i); - propCount += addEditor(name + "[" + i + "]", obj, field, i, item.getClass(), item, parentFields,parentIndices, readonly); + String subname = name + "[" + i + "]"; + propCount += addEditor(subname, obj, field, i, item.getClass(), item, parentFields, parentIndices, readonly); + final int fi = i; + JButton removeButton = new JButton(View.getIcon("close16")); + removeButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + removeItem(obj, field, fi); + } + }); + removeButtons.put(subname, removeButton); } } } else { - propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields,parentIndices, readonly); + propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields, parentIndices, readonly); + } + if (ReflectionTools.needsIndex(field) && !readonly) { + JButton addButton = new JButton(View.getIcon("add16")); + addButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + addItem(obj, field); + } + }); + name += "[]"; + + List parList = new ArrayList<>(parentFields); + parList.add(field); + fieldPaths.put(name, parList); + + List parIndices = new ArrayList<>(parentIndices); + parIndices.add(0); + fieldIndices.put(name, parIndices); + + addRow(name, addButton, field); + addKeys.add(name); + addButtons.put(name, addButton); } } catch (IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); @@ -191,14 +252,114 @@ public class GenericTagPanel extends JPanel implements ChangeListener { return propCount; } - private int addEditor(String name, Object obj, Field field, int index, Class type, Object value, List parentList,List parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException { + private void removeItem(Object obj, Field field, int index) { + final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar(); + final int val = sb.getValue(); //save scroll top + SWFType swfType = field.getAnnotation(SWFType.class); + if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be removed from too + Field fields[] = obj.getClass().getDeclaredFields(); + for (int f = 0; f < fields.length; f++) { + SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class); + if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) { + ReflectionTools.removeFromField(obj, fields[f], index); + } + } + try { + //If countField exists, decrement, otherwise do nothing + Field countField = obj.getClass().getDeclaredField(swfType.countField()); + if(countField!=null){ + int cnt = countField.getInt(obj); + cnt--; + countField.setInt(obj, cnt); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + //ignored + } + } else { + ReflectionTools.removeFromField(obj, field, index); + } + + + generateEditControls(tag, false); + + //Restore scroll top after some time. TODO: Handle this better. I don't know how :-(. + new Thread() { + + @Override + public void run() { + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + } + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); + } + }); + } + + }.start(); + } + + private void addItem(Object obj, Field field) { + final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar(); + final int val = sb.getValue(); //save scroll top + SWFType swfType = field.getAnnotation(SWFType.class); + if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be enlarged too + Field fields[] = obj.getClass().getDeclaredFields(); + for (int f = 0; f < fields.length; f++) { + SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class); + if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) { + ReflectionTools.enlargeField(obj, fields[f], true); + } + } + try { + //If countField exists, increment, otherwise do nothing + Field countField = obj.getClass().getDeclaredField(swfType.countField()); + if(countField!=null){ + int cnt = countField.getInt(obj); + cnt++; + countField.setInt(obj, cnt); + } + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + //ignored + } + } else { + ReflectionTools.enlargeField(obj, field, true); + } + generateEditControls(tag, false); + + //Restore scroll top after some time. TODO: Handle this better. I don't know how :-(. + new Thread() { + + @Override + public void run() { + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); + } + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); + } + }); + } + + }.start(); + } + + private int addEditor(String name, Object obj, Field field, int index, Class type, Object value, List parentList, List parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException { Calculated calculated = field.getAnnotation(Calculated.class); if (calculated != null) { return 0; } List parList = new ArrayList<>(parentList); parList.add(field); - + List parIndices = new ArrayList<>(parentIndices); parIndices.add(index); Internal inter = field.getAnnotation(Internal.class); @@ -217,9 +378,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener { editor = new BooleanEditor(name, obj, field, index, type); } else if (type.equals(String.class)) { editor = new StringEditor(name, obj, field, index, type); - } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)){ + } else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) { editor = new ColorEditor(name, obj, field, index, type); - }else { + } else { if (value == null) { if (readonly) { return 0; @@ -227,7 +388,7 @@ public class GenericTagPanel extends JPanel implements ChangeListener { Optional opt = field.getAnnotation(Optional.class); if (opt == null) { try { - value = field.getType().newInstance(); + value = ReflectionTools.newInstanceOf(field.getType()); field.set(obj, value); } catch (InstantiationException | IllegalAccessException ex) { Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); @@ -237,28 +398,31 @@ public class GenericTagPanel extends JPanel implements ChangeListener { return 0; } } - return generateEditControlsRecursive(value, name + ".", parList,parIndices, readonly); + return generateEditControlsRecursive(value, name + ".", parList, parIndices, readonly); } if (editor instanceof GenericTagEditor) { GenericTagEditor ce = (GenericTagEditor) editor; ce.addChangeListener(this); editors.put(name, ce); fieldPaths.put(name, parList); - fieldIndices.put(name,parIndices); + fieldIndices.put(name, parIndices); + addRow(name, editor, field); } + return 1; + } + private void addRow(String name, Component editor, Field field) { JLabel label = new JLabel(name + ":", JLabel.TRAILING); label.setVerticalAlignment(JLabel.TOP); genericTagPropertiesEditPanel.add(label); label.setLabelFor(editor); labels.put(name, label); genericTagPropertiesEditPanel.add(editor); - JLabel typeLabel = new JLabel(swfTypeToString(swfType), JLabel.TRAILING); + JLabel typeLabel = new JLabel(swfTypeToString(field.getAnnotation(SWFType.class)), JLabel.TRAILING); + typeLabel.setVerticalAlignment(JLabel.TOP); genericTagPropertiesEditPanel.add(typeLabel); types.put(name, typeLabel); keys.add(name); - - return 1; } public String swfTypeToString(SWFType swfType) { @@ -305,17 +469,17 @@ public class GenericTagPanel extends JPanel implements ChangeListener { List path = fieldPaths.get(key); List indices = fieldIndices.get(key); String p = ""; - boolean conditionMet = true; - for (int i=0;i parameterClass = (Class) listType.getActualTypeArguments()[0]; + try { + Object val = newInstanceOf(parameterClass); + list.add(val); + } catch (InstantiationException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + return true; + } + + public static boolean enlargeArray(Object object, Field field, boolean notnull) { + if (!field.getType().isArray()) { + return false; + } + Object arrValue; + try { + arrValue = field.get(object); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + Class componentClass = arrValue.getClass().getComponentType(); + int originalSize = Array.getLength(arrValue); + Object copy = Array.newInstance(componentClass, originalSize + 1); + for (int i = 0; i < originalSize; i++) { + Array.set(copy, i, Array.get(arrValue, i)); + } + if (!componentClass.isPrimitive() && notnull) { + try { + Array.set(copy, originalSize, componentClass.newInstance()); + } catch (InstantiationException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + } + try { + field.set(object, copy); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + return true; + } + + public static boolean enlargeField(Object object, Field field, boolean notnull) { + if (List.class.isAssignableFrom(field.getType())) { + return enlargeList(object, field); + } + + if (field.getType().isArray()) { + return enlargeArray(object, field, notnull); + } + return false; + } + + public static boolean removeFromField(Object object, Field field,int index){ + if (List.class.isAssignableFrom(field.getType())) { + return removeFromList(object, field,index); + } + + if (field.getType().isArray()) { + return removeFromArray(object, field, index); + } + return false; + } + + public static boolean removeFromList(Object object, Field field,int index){ + List list; + try { + list=(List)field.get(object); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + if(index<0 || index>=list.size()){ + return false; + } + list.remove(index); + return true; + } + + public static boolean removeFromArray(Object object, Field field, int index){ + Object arrValue; + try { + arrValue = field.get(object); + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + Class componentClass = arrValue.getClass().getComponentType(); + int originalSize = Array.getLength(arrValue); + Object copy = Array.newInstance(componentClass, originalSize - 1); + int pos=0; + //copy all before index + for (int i = 0; i < index; i++) { + Array.set(copy, pos, Array.get(arrValue, i)); + pos++; + } + //copy all after index + for (int i = index+1; i 9VHk(~TedF+gQSL8D5xnVSSWAVY>J9b+m>@{iq7_KE}go~11+5s4;8hc+i0Xa zI1j@EX5!S+Me6HNqKzU5YQwL;-W5$p%ZMKMeR<%zp69-~?<4?8|C8S?bklXr4v&Ov zb&06v2|-x?qB`90yn>Qi%Sh2^G4n)$ZdyvTPf9}1)_buUT7>`e2G&2VU@~Bb(o+Mz zi4)>IxlSY${Dj4k={-9RzU^W5g9|2V5RZ2ZulL9s2xQbZ@r6eP9Ra5u(s|C0Nj#&4>wTSkb?%#=9?@ z^oxDy-O@tyN{L@by(WWvQ3%CyEu8x{+#Jb4-h&K9Owi)2pgg+heWDyked|3R$$kL@A z#sp1v-r+=G4B8D6DqsDH0@7OztA7aT9qc1Py{()w`m``?Y0&gi2=ROcc-9+nU^I6< zT=e_Y=vSnG@?3Ue{BW5ONFttcE!R-R_W4O01|0-|K-YNXLo2`4Qv z`r1LxR6#yf3FB%T95gJnaKKivA~Z}S9A(ZxEDK}O3T04USJ P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java index a267f72af..0da758e58 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSceneAndFrameLabelDataTag.java @@ -33,14 +33,15 @@ import java.io.OutputStream; */ public class DefineSceneAndFrameLabelDataTag extends Tag { - @SWFType(BasicType.EncodedU32) + @SWFType(value=BasicType.EncodedU32,countField="sceneCount") public long[] sceneOffsets; - + @SWFType(countField="sceneCount") public String[] sceneNames; - @SWFType(BasicType.EncodedU32) + @SWFType(value=BasicType.EncodedU32,countField="frameLabelCount") public long[] frameNums; + @SWFType(countField = "frameLabelCount") public String[] frameNames; public static final int ID = 86; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java index 17501f5bb..f4c1308b2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java @@ -38,15 +38,16 @@ public class ExportAssetsTag extends Tag { /** * HashMap with assets */ - @SWFType(BasicType.UI16) + @SWFType(value = BasicType.UI16,countField = "count") public List tags; + @SWFType(countField = "count") public List names; public static final int ID = 56; public ExportAssetsTag() { super(null, ID, "ExportAssets", new byte[]{}, 0); tags = new ArrayList<>(); - names = new ArrayList<>(); + names = new ArrayList<>(); } /** diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java index 8938ddaf6..0de5cfcb0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssets2Tag.java @@ -27,7 +27,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Imports characters from another file, v2 @@ -46,7 +49,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag { /** * HashMap with assets */ - public HashMap assets; + @SWFType(value=BasicType.UI16,countField = "count") + public List characterIds; + @SWFType(countField = "count") + public List names; public static final int ID = 71; /** @@ -60,16 +66,18 @@ public class ImportAssets2Tag extends Tag implements ImportTag { */ public ImportAssets2Tag(SWF swf, byte[] data, int version, long pos) throws IOException { super(swf, ID, "ImportAssets2", data, pos); - assets = new HashMap<>(); + characterIds = new ArrayList<>(); + names = new ArrayList<>(); SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version); url = sis.readString(); reserved1 = sis.readUI8();//reserved, must be 1 reserved2 = sis.readUI8();//reserved, must be 0 int count = sis.readUI16(); for (int i = 0; i < count; i++) { - int characterId = sis.readUI16(); - String name = sis.readString(); - assets.put(characterId, name); + int charId = sis.readUI16(); + String tagName = sis.readString(); + characterIds.add(charId); + names.add(tagName); } } @@ -88,10 +96,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag { sos.writeString(url); sos.writeUI8(reserved1); sos.writeUI8(reserved2); - sos.writeUI16(assets.size()); - for (int characterId : assets.keySet()) { - sos.writeUI16(characterId); - sos.writeString(assets.get(characterId)); + sos.writeUI16(characterIds.size()); + for (int i=0;i getAssets() { + public Map getAssets() { + Map assets = new HashMap<>(); + for (int i = 0; i < characterIds.size(); i++) { + assets.put(characterIds.get(i), names.get(i)); + } return assets; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java index 5afedfe74..49289c5f5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/ImportAssetsTag.java @@ -20,11 +20,16 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ImportTag; +import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.SWFType; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Imports characters from another file @@ -37,7 +42,10 @@ public class ImportAssetsTag extends Tag implements ImportTag { /** * HashMap with assets */ - public HashMap assets; + @SWFType(value=BasicType.UI16,countField = "count") + public List characterIds; + @SWFType(countField = "count") + public List names; public static final int ID = 57; /** @@ -51,14 +59,16 @@ public class ImportAssetsTag extends Tag implements ImportTag { */ public ImportAssetsTag(SWF swf, byte[] data, int version, long pos) throws IOException { super(swf, ID, "ImportAssets", data, pos); - assets = new HashMap<>(); + characterIds = new ArrayList<>(); + names = new ArrayList<>(); SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version); url = sis.readString(); int count = sis.readUI16(); for (int i = 0; i < count; i++) { - int characterId = sis.readUI16(); - String name = sis.readString(); - assets.put(characterId, name); + int charId = sis.readUI16(); + String tagName = sis.readString(); + characterIds.add(charId); + names.add(tagName); } } @@ -75,10 +85,10 @@ public class ImportAssetsTag extends Tag implements ImportTag { SWFOutputStream sos = new SWFOutputStream(os, version); try { sos.writeString(url); - sos.writeUI16(assets.size()); - for (int characterId : assets.keySet()) { - sos.writeUI16(characterId); - sos.writeString(assets.get(characterId)); + sos.writeUI16(characterIds.size()); + for (int i = 0; i < characterIds.size(); i++) { + sos.writeUI16(characterIds.get(i)); + sos.writeString(names.get(i)); } } catch (IOException e) { } @@ -86,7 +96,11 @@ public class ImportAssetsTag extends Tag implements ImportTag { } @Override - public HashMap getAssets() { + public Map getAssets() { + Map assets = new HashMap<>(); + for (int i = 0; i < characterIds.size(); i++) { + assets.put(characterIds.get(i), names.get(i)); + } return assets; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java index 36c2ccaa4..26a55d9b5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/SymbolClassTag.java @@ -28,8 +28,9 @@ import java.io.OutputStream; public class SymbolClassTag extends Tag { - @SWFType(BasicType.UI16) + @SWFType(value=BasicType.UI16,countField = "numSymbols") public int[] tagIDs; + @SWFType(countField = "numSymbols") public String[] classNames; public static final int ID = 76; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/ImportTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/ImportTag.java index ceb3b0f4b..358dad0c4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/ImportTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/ImportTag.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.tags.base; import java.util.HashMap; +import java.util.Map; /** * @@ -25,6 +26,6 @@ import java.util.HashMap; public interface ImportTag { public String getUrl(); - - public HashMap getAssets(); + + public Map getAssets(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/BasicType.java b/trunk/src/com/jpexs/decompiler/flash/types/BasicType.java index 91092a1d6..ec441c89c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/BasicType.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/BasicType.java @@ -36,5 +36,6 @@ public enum BasicType { FLOAT16, FIXED, FIXED8, - NONE + NONE, + OTHER } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/annotations/SWFType.java b/trunk/src/com/jpexs/decompiler/flash/types/annotations/SWFType.java index 11a9e862e..948136e6c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/annotations/SWFType.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/annotations/SWFType.java @@ -32,7 +32,7 @@ import java.lang.annotation.Target; public @interface SWFType { /// Type of value - BasicType value(); + BasicType value() default BasicType.OTHER; /// Alternate type when condition is met BasicType alternateValue() default BasicType.NONE; diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java index 1338854e1..e8dc1dbfd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java @@ -34,11 +34,12 @@ public class GRADIENTBEVELFILTER extends FILTER { /** * Gradient colors */ + @SWFType(countField = "numColors") public RGBA[] gradientColors = new RGBA[0]; /** * Gradient ratios */ - @SWFType(BasicType.UI8) + @SWFType(value=BasicType.UI8,countField = "numColors") public int[] gradientRatio = new int[0]; /** * Horizontal blur amount diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java index 3489d809c..9fe5d3347 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java @@ -34,11 +34,12 @@ public class GRADIENTGLOWFILTER extends FILTER { /** * Gradient colors */ + @SWFType(countField = "numColors") public RGBA[] gradientColors = new RGBA[0]; /** * Gradient ratios */ - @SWFType(BasicType.UI8) + @SWFType(value=BasicType.UI8,countField = "numColors") public int[] gradientRatio; /** * Horizontal blur amount