diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/BinarySWFBundle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/BinarySWFBundle.java index 9358e101d..18ece7a77 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/BinarySWFBundle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/BinarySWFBundle.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; import com.jpexs.helpers.SwfHeaderStreamSearch; 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 050caa440..6632585dd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -69,6 +69,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter; import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings; import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings; import com.jpexs.decompiler.flash.exporters.settings.FramesExportSettings; @@ -82,8 +83,7 @@ import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.DefineButton2Tag; -import com.jpexs.decompiler.flash.tags.DefineButtonTag; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DoInitActionTag; import com.jpexs.decompiler.flash.tags.EndTag; @@ -117,16 +117,7 @@ import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.SvgClip; import com.jpexs.decompiler.flash.timeline.Timeline; import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem; -import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; import com.jpexs.decompiler.flash.treeitems.SWFList; -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.AS2PackageNode; -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 com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; @@ -212,7 +203,7 @@ import org.monte.media.avi.AVIWriter; * * @author JPEXS */ -public final class SWF implements TreeItem, Timelined { +public final class SWF implements SWFContainerItem, Timelined { /** * Default version of SWF file format @@ -278,6 +269,7 @@ public final class SWF implements TreeItem, Timelined { private Timeline timeline; public DumpInfoSwfNode dumpInfo; + public DefineBinaryDataTag binaryData; public void updateCharacters() { characters.clear(); @@ -285,10 +277,8 @@ public final class SWF implements TreeItem, Timelined { } public void resetTimelines(Timelined timelined) { - timelined.resetTimeline(); - List tags = timelined.getTimeline().tags; - for (int i = 0; i < tags.size(); i++) { - Tag t = tags.get(i); + timelined.getTimeline().reset(); + for (Tag t : timelined.getTimeline().tags) { if (t instanceof Timelined) { resetTimelines((Timelined) t); } @@ -344,11 +334,6 @@ public final class SWF implements TreeItem, Timelined { return timeline; } - @Override - public void resetTimeline() { - timeline = null; - } - /** * Gets all tags with specified id * @@ -619,7 +604,7 @@ public final class SWF implements TreeItem, Timelined { ArrayList newAbcList = new ArrayList<>(); getABCTags(objs, newAbcList); - isAS3 = !newAbcList.isEmpty(); + isAS3 = (fileAttributes != null && fileAttributes.actionScript3) || (fileAttributes == null && !newAbcList.isEmpty()); abcList = newAbcList; } @@ -649,8 +634,10 @@ public final class SWF implements TreeItem, Timelined { if (t instanceof ExportAssetsTag) { ExportAssetsTag eat = (ExportAssetsTag) t; for (int i = 0; i < eat.tags.size(); i++) { - if ((!exportNames.containsKey(eat.tags.get(i))) && (!exportNames.containsValue(eat.names.get(i)))) { - exportNames.put(eat.tags.get(i), eat.names.get(i)); + Integer tagId = eat.tags.get(i); + String name = eat.names.get(i); + if ((!exportNames.containsKey(tagId)) && (!exportNames.containsValue(name))) { + exportNames.put(tagId, name); } } } @@ -821,19 +808,10 @@ public final class SWF implements TreeItem, Timelined { } public boolean exportAS3Class(String className, String outdir, ScriptExportMode exportMode, boolean parallel) throws Exception { - List abcTags = new ArrayList<>(); - - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - ABCContainerTag cnt = (ABCContainerTag) t; - abcTags.add(cnt); - } - } - boolean exported = false; - for (int i = 0; i < abcTags.size(); i++) { - ABC abc = abcTags.get(i).getABC(); + for (int i = 0; i < abcList.size(); i++) { + ABC abc = abcList.get(i).getABC(); List scrs = abc.findScriptPacksByPath(className); for (int j = 0; j < scrs.size(); j++) { ScriptPack scr = scrs.get(j); @@ -841,10 +819,10 @@ public final class SWF implements TreeItem, Timelined { if (scrs.size() > 1) { cnt = "script " + (j + 1) + "/" + scrs.size() + " "; } - String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + scr.getPath() + " ..."; + String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcList.size() + " " + cnt + scr.getPath() + " ..."; informListeners("exporting", exStr); - scr.export(outdir, abcTags, exportMode, parallel); - exStr = "Exported " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + scr.getPath() + " ..."; + scr.export(outdir, abcList, exportMode, parallel); + exStr = "Exported " + "tag " + (i + 1) + "/" + abcList.size() + " " + cnt + scr.getPath() + " ..."; informListeners("exported", exStr); exported = true; } @@ -868,11 +846,8 @@ public final class SWF implements TreeItem, Timelined { public List> getAS3Packs() { List> packs = new ArrayList<>(); - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - ABCContainerTag abcTag = (ABCContainerTag) t; - packs.addAll(abcTag.getABC().getScriptPacks()); - } + for (ABCContainerTag abcTag : abcList) { + packs.addAll(abcTag.getABC().getScriptPacks()); } return uniqueAS3Packs(packs); } @@ -932,28 +907,20 @@ public final class SWF implements TreeItem, Timelined { } } - public List exportActionScript2(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException { + private List exportActionScript2(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException { List ret = new ArrayList<>(); - List list2 = new ArrayList<>(); - list2.addAll(tags); - List list = createASTagList(list2, this); + Map asms = getASMs(); if (!outdir.endsWith(File.separator)) { outdir += File.separator; } outdir += "scripts" + File.separator; - ret.addAll(TagNode.exportNodeAS(handler, list, list, outdir, exportMode, evl)); + ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, outdir, asms.values(), exportMode, evl)); return ret; } - public List exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel) { + private List exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel) { final AtomicInteger cnt = new AtomicInteger(1); - final List abcTags = new ArrayList<>(); - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - abcTags.add((ABCContainerTag) t); - } - } final List ret = new ArrayList<>(); final List> packs = getAS3Packs(); @@ -964,7 +931,7 @@ public final class SWF implements TreeItem, Timelined { @Override public Void call() throws Exception { for (MyEntry item : packs) { - ExportPackTask task = new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, abcTags, exportMode, parallel); + ExportPackTask task = new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, abcList, exportMode, parallel); ret.add(task.call()); } return null; @@ -979,7 +946,7 @@ public final class SWF implements TreeItem, Timelined { ExecutorService executor = Executors.newFixedThreadPool(Configuration.parallelThreadCount.get()); List> futureResults = new ArrayList<>(); for (MyEntry item : packs) { - Future future = executor.submit(new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, abcTags, exportMode, parallel)); + Future future = executor.submit(new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, abcList, exportMode, parallel)); futureResults.add(future); } @@ -1009,7 +976,6 @@ public final class SWF implements TreeItem, Timelined { } public List exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel) throws Exception { - boolean asV3Found = false; List ret = new ArrayList<>(); final EventListener evl = new EventListener() { @Override @@ -1019,13 +985,8 @@ public final class SWF implements TreeItem, Timelined { } } }; - for (Tag t : tags) { - if (t instanceof ABCContainerTag) { - asV3Found = true; - } - } - if (asV3Found) { + if (isAS3) { ret.addAll(exportActionScript3(handler, outdir, exportMode, parallel)); } else { ret.addAll(exportActionScript2(handler, outdir, exportMode, parallel, evl)); @@ -1033,160 +994,30 @@ public final class SWF implements TreeItem, Timelined { return ret; } - public static List createASTagList(List list, Timelined parent) { - List ret = new ArrayList<>(); - int frame = 0; - List frames = new ArrayList<>(); - - for (ContainerItem t : list) { - TreeNode addNode = null; - if (t instanceof ShowFrameTag) { - // do not add PlaceObjects (+etc) to script nodes - FrameNode tti = new FrameNode(new FrameNodeItem(t.getSwf(), frame, parent, false), null, true); - - for (int r = ret.size() - 1; r >= 0; r--) { - TreeNode node = ret.get(r); - TreeItem item = node.getItem(); - if (!(item instanceof DefineSpriteTag - || item instanceof DefineButtonTag - || item instanceof DefineButton2Tag - || item instanceof DoInitActionTag - || item instanceof AS2PackageNodeItem)) { - tti.subNodes.add(node); - ret.remove(r); - } - } - frame++; - frames.add(tti); - } else if (t instanceof ASMSource) { - ContainerNode tti = new ContainerNode(t); - addNode = tti; - } else if (t instanceof Container) { - if (((Container) t).getItemCount() > 0) { - - ContainerNode tti = new ContainerNode(t); - List subItems = ((Container) t).getSubItems(); - - Timelined timelined = t instanceof Timelined ? (Timelined) t : null; - tti.subNodes = createASTagList(subItems, timelined); - addNode = tti; - } - } - if (addNode != null) { - if (addNode.getItem() instanceof CharacterIdTag) { - CharacterIdTag cit = (CharacterIdTag) addNode.getItem(); - String path = cit.getExportName(); - if (path == null) { - path = ""; - } - String[] pathParts = path.contains(".") ? path.split("\\.") : new String[]{path}; - List items = ret; - for (int pos = 0; pos < pathParts.length - 1; pos++) { - String pathPart = pathParts[pos]; - TreeNode selNode = null; - for (TreeNode node : items) { - if (node.getItem() instanceof AS2PackageNodeItem) { - AS2PackageNodeItem pkg = (AS2PackageNodeItem) node.getItem(); - if (pkg.packageName.equals(pathPart)) { - selNode = node; - break; - } - } - } - int pkgCount = 0; - for (; pkgCount < items.size(); pkgCount++) { - if (items.get(pkgCount).getItem() instanceof AS3PackageNodeItem) { - AS3PackageNodeItem pkg = (AS3PackageNodeItem) items.get(pkgCount).getItem(); - if (pkg.packageName.compareTo(pathPart) > 0) { - break; - } - } else { - break; - } - } - if (selNode == null) { - items.add(pkgCount, selNode = new AS2PackageNode(new AS2PackageNodeItem(pathPart, t.getSwf()))); - } - pos++; - items = selNode.subNodes; - } - - int clsCount = 0; - String addNodeName = addNode.getItem().getClass().getName() + "_" + pathParts[pathParts.length - 1]; - for (; clsCount < items.size(); clsCount++) { - if (items.get(clsCount).getItem() instanceof CharacterIdTag) { - CharacterIdTag ct = (CharacterIdTag) items.get(clsCount).getItem(); - String expName = ct.getExportName(); - if (expName == null) { - expName = ""; - } - if (expName.contains(".")) { - expName = expName.substring(expName.lastIndexOf('.') + 1); - } - if ((ct.getClass().getName() + "_" + expName).compareTo(addNodeName) > 0) { - break; - } - } - } - items.add(clsCount, addNode); - } else { - ret.add(addNode); - } - } - - } - ret.addAll(frames); - for (int i = ret.size() - 1; i >= 0; i--) { - TreeNode node = ret.get(i); - TreeItem item = node.getItem(); - if (item instanceof ASMSource) { - ASMSource ass = (ASMSource) item; - if (ass.containsSource()) { - continue; - } - } - if (node.subNodes.isEmpty()) { - ret.remove(i); - } - } - return ret; - } - public Map getASMs() { - List list = createASTagList(tags, this); - Map asms = new HashMap<>(); - getASMs("", list, asms); - return asms; + Map asms2 = new HashMap<>(); + getASMs("", tags, asms2); + return asms2; } - private static void getASMs(String path, List nodes, Map result) { - for (TreeNode n : nodes) { - String subPath = path + "/" + n.toString(); - if (n.getItem() instanceof ASMSource) { - //cacheScript((ASMSource) n.tag); + private static void getASMs(String path, List items, Map asms) { + for (ContainerItem item : items) { + String subPath = path + "/" + item.toString(); + if (item instanceof ASMSource) { String npath = subPath; int ppos = 1; - while (result.containsKey(npath)) { + while (asms.containsKey(npath)) { ppos++; npath = subPath + "[" + ppos + "]"; } - result.put(npath, (ASMSource) n.getItem()); + asms.put(npath, (ASMSource) item); + } + if (item instanceof Container) { + getASMs(subPath, ((Container) item).getSubItems(), asms); } - - getASMs(subPath, n.subNodes, result); } } - - 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) { @@ -1401,7 +1232,7 @@ public final class SWF implements TreeItem, Timelined { path = File.separator + Helper.makeFileName(characters.get(containerId).getExportFileName()); } if (frames == null) { - int frameCnt = tim.frames.size(); + int frameCnt = tim.getFrames().size(); frames = new ArrayList<>(); for (int i = 0; i < frameCnt; i++) { frames.add(i); @@ -2253,7 +2084,7 @@ public final class SWF implements TreeItem, Timelined { Stack clipDepths = new Stack<>(); for (int frame : frames) { sb.append("\t\tcase ").append(frame).append(":\r\n"); - Frame frameObj = timeline.frames.get(frame); + Frame frameObj = timeline.getFrames().get(frame); for (int i = 1; i <= maxDepth + 1; i++) { while (!clipDepths.isEmpty() && clipDepths.peek() <= i) { clipDepths.pop(); @@ -2467,10 +2298,10 @@ public final class SWF implements TreeItem, Timelined { } public static void frameToSvg(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level, double zoom) throws IOException { - if (timeline.frames.size() <= frame) { + if (timeline.getFrames().size() <= frame) { return; } - Frame frameObj = timeline.frames.get(frame); + Frame frameObj = timeline.getFrames().get(frame); List clips = new ArrayList<>(); List prevClips = new ArrayList<>(); @@ -2570,7 +2401,7 @@ public final class SWF implements TreeItem, Timelined { } } - if (timeline.frames.isEmpty()) { + if (timeline.getFrames().isEmpty()) { return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB); } @@ -2595,7 +2426,7 @@ public final class SWF implements TreeItem, Timelined { public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, DepthState stateUnderCursor, int mouseButton, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform, double zoom) { RECT rect = displayRect; - for (int f = 0; f < timeline.frames.size(); f++) { + for (int f = 0; f < timeline.getFrames().size(); f++) { SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1, (int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); image.fillTransparent(); @@ -2608,10 +2439,10 @@ public final class SWF implements TreeItem, Timelined { public static void frameToImage(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { double unzoom = SWF.unitDivisor; - if (timeline.frames.size() <= frame) { + if (timeline.getFrames().size() <= frame) { return; } - Frame frameObj = timeline.frames.get(frame); + Frame frameObj = timeline.getFrames().get(frame); Graphics2D g = (Graphics2D) image.getGraphics(); g.setPaint(frameObj.backgroundColor.toColor()); g.fill(new Rectangle(image.getWidth(), image.getHeight())); @@ -2958,7 +2789,7 @@ public final class SWF implements TreeItem, Timelined { tags = this.tags; } tags.remove(t); - timelined.resetTimeline(); + timelined.getTimeline().reset(); } else { // timeline should be always the swf here if (removeDependencies) { @@ -2971,4 +2802,9 @@ public final class SWF implements TreeItem, Timelined { updateCharacters(); clearImageCache(); } + + @Override + public String toString() { + return getShortFileName(); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFBundle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFBundle.java index 961d9b096..fa227cde8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFBundle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFBundle.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; import com.jpexs.helpers.streams.SeekableInputStream; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeElementItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFContainerItem.java similarity index 72% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeElementItem.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFContainerItem.java index a00118239..2831af965 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeElementItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFContainerItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. + * Copyright (C) 2014 JPEXS, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -12,13 +12,16 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.flash.treeitems; + * License along with this library. + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.treeitems.TreeItem; /** * * @author JPEXS */ -public interface TreeElementItem extends TreeItem { - +public interface SWFContainerItem extends TreeItem { + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedSWFBundle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedSWFBundle.java index b76ac20a7..affc75995 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedSWFBundle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedSWFBundle.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; import com.jpexs.helpers.Helper; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index 46430a238..06a0fd634 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -1207,7 +1207,7 @@ public class ABC { } } } - boolean isDocumentClass = documentClass.equals(pack.getPath().toString()); + boolean isDocumentClass = documentClass.equals(pack.getClassPath().toString()); ScriptInfo si = script_info.get(oldIndex); si.delete(this, true); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java index 571efc230..e32db0bc1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java @@ -245,7 +245,7 @@ public class ABCInputStream implements AutoCloseable { return is.available(); } - private final long readLong() throws IOException { + private long readLong() throws IOException { byte[] readBuffer = safeRead(8); return (((long) readBuffer[7] << 56) + ((long) (readBuffer[6] & 255) << 48) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index be86d89ca..994cc5104 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -26,7 +26,7 @@ import com.jpexs.decompiler.flash.helpers.FileTextWriter; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.treeitems.TreeElementItem; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import java.io.File; @@ -46,7 +46,7 @@ import java.util.logging.Logger; * * @author JPEXS */ -public class ScriptPack implements TreeElementItem { +public class ScriptPack extends AS3ClassTreeItem { public final ABC abc; public final int scriptIndex; @@ -58,11 +58,12 @@ public class ScriptPack implements TreeElementItem { return abc.swf; } - public ClassPath getPath() { + public ClassPath getClassPath() { return path; } public ScriptPack(ClassPath path, ABC abc, int scriptIndex, List traitIndices) { + super(path.className, path.toString()); this.abc = abc; this.scriptIndex = scriptIndex; this.traitIndices = traitIndices; @@ -178,7 +179,7 @@ public class ScriptPack implements TreeElementItem { public File export(String directory, List abcList, ScriptExportMode exportMode, boolean parallel) throws IOException { String scriptName = getPathScriptName(); String packageName = getPathPackage(); - File outDir = new File(directory + File.separatorChar + makeDirPath(packageName)); + File outDir = new File(directory + File.separatorChar + "scripts" + File.separatorChar + makeDirPath(packageName)); if (!outDir.exists()) { if (!outDir.mkdirs()) { if (!outDir.exists()) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java index 83d50edb7..b01e02478 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java @@ -44,7 +44,7 @@ public class Multiname { public List params; //for TypeName public boolean deleted; - public boolean validType() { + private boolean validType() { boolean cnt = false; for (int i = 0; i < multinameKinds.length; i++) { if (multinameKinds[i] == kind) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java new file mode 100644 index 000000000..b6b2e0932 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2014 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.exporters.script; + +import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; +import com.jpexs.decompiler.flash.EventListener; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.FileTextWriter; +import com.jpexs.decompiler.flash.tags.DoInitActionTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.timeline.Timeline; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class AS2ScriptExporter { + + public List exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Collection asms, final ScriptExportMode exportMode, final EventListener ev) throws IOException { + try { + List result = CancellableWorker.call(new Callable>() { + + @Override + public List call() throws Exception { + return exportAS2Scripts(handler, outdir, asms, exportMode, ev); + } + }, Configuration.exportTimeout.get(), TimeUnit.SECONDS); + return result; + } catch (ExecutionException | InterruptedException | TimeoutException ex) { + } + return new ArrayList<>(); + } + + private List exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Collection asms, ScriptExportMode exportMode, EventListener ev) throws IOException { + List ret = new ArrayList<>(); + if (!outdir.endsWith(File.separator)) { + outdir += File.separator; + } + + outdir += "scripts" + File.separator; + + Map> existingNamesMap = new HashMap<>(); + AtomicInteger cnt = new AtomicInteger(1); + for (ASMSource asm : asms) { + String currentOutDir = outdir + getFilePath(asm) + File.separator; + currentOutDir = new File(currentOutDir).getParentFile().toString() + File.separator; + + List existingNames = existingNamesMap.get(currentOutDir); + if (existingNames == null) { + existingNames = new ArrayList<>(); + existingNamesMap.put(currentOutDir, existingNames); + } + + String name = Helper.makeFileName(asm.getExportFileName()); + int i = 1; + String baseName = name; + while (existingNames.contains(name)) { + i++; + name = baseName + "_" + i; + } + existingNames.add(name); + + File f = exportAS2Script(handler, currentOutDir, asm, exportMode, ev, cnt, asms.size(), name); + if (f != null) { + ret.add(f); + } + } + + return ret; + } + + private File exportAS2Script(AbortRetryIgnoreHandler handler, String outdir, ASMSource asm, ScriptExportMode exportMode, EventListener ev, AtomicInteger index, int count, String name) throws IOException { + boolean retry; + do { + retry = false; + try { + int currentIndex = index.getAndIncrement(); + + File dir = new File(outdir); + if (!dir.exists()) { + if (!dir.mkdirs()) { + if (!dir.exists()) { + throw new IOException("Cannot create directory " + outdir); + } + } + } + + String f = outdir + name + ".as"; + if (ev != null) { + ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f); + } + + long startTime = System.currentTimeMillis(); + + File file = new File(f); + try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) { + if (exportMode == ScriptExportMode.HEX) { + asm.getActionSourcePrefix(writer); + asm.getActionBytesAsHex(writer); + asm.getActionSourceSuffix(writer); + } else if (exportMode != ScriptExportMode.AS) { + asm.getActionSourcePrefix(writer); + asm.getASMSource(exportMode, writer, null); + asm.getActionSourceSuffix(writer); + } else { + List as = asm.getActions(); + Action.setActionsAddresses(as, 0); + Action.actionsToSource(asm, as, ""/*FIXME*/, writer); + } + } + + long stopTime = System.currentTimeMillis(); + + if (ev != null) { + long time = stopTime - startTime; + ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time)); + } + + return file; + } catch (InterruptedException ex) { + } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { + Logger.getLogger(AS2ScriptExporter.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); + if (handler != null) { + int action = handler.getNewInstance().handle(ex); + switch (action) { + case AbortRetryIgnoreHandler.ABORT: + throw ex; + case AbortRetryIgnoreHandler.RETRY: + retry = true; + break; + case AbortRetryIgnoreHandler.IGNORE: + retry = false; + break; + } + } + } + } while (retry); + + return null; + } + + // todo: honfika: get the path from the tree + private String getFilePath(ASMSource asm) { + if (asm instanceof DoInitActionTag) { + String exportName = ((DoInitActionTag) asm).getExportName(); + + if (exportName != null) { + String path = ""; + StringTokenizer st = new StringTokenizer(exportName, "."); + while (st.hasMoreTokens()) { + String pathElement = st.nextToken(); + if (path.length() > 0) { + path += File.separator; + } + + path += Helper.makeFileName(pathElement); + } + + return path; + } + } + + if (!(asm instanceof Tag)) { + return Helper.makeFileName(asm.getSourceTag().getExportFileName()) + File.separator + Helper.makeFileName(asm.getExportFileName()); + } else { + String result = ""; + Timelined timelined = asm.getSourceTag().getTimelined(); + if (timelined instanceof Tag) { + result += Helper.makeFileName(((Tag) timelined).getExportFileName()) + File.separator; + } + + Timeline timeline = timelined.getTimeline(); + int frame = timeline.getFrameForAction(asm); + if (frame != -1) { + result += "frame_" + (frame + 1) + File.separator; + } + + return result + Helper.makeFileName(asm.getExportFileName()); + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FileTextWriter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FileTextWriter.java index 842d85fa7..eb7080d5c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FileTextWriter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FileTextWriter.java @@ -54,6 +54,12 @@ public class FileTextWriter extends GraphTextWriter implements AutoCloseable { return this; } + @Override + public GraphTextWriter hilightSpecial(String text, String type, int index, Map data) { + writeToFile(text); + return this; + } + @Override public FileTextWriter append(String str) { writeToFile(str); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java index af0cbcf1d..b076f65b3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java @@ -12,13 +12,16 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags; +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.CharacterTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; @@ -39,6 +42,9 @@ public class DefineBinaryDataTag extends CharacterTag { public static final int ID = 87; + @Internal + public SWF innerSwf; + /** * Gets data bytes * diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java index 39fad0d93..9e0a64cb0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java @@ -255,13 +255,13 @@ public class DefineButton2Tag extends ButtonTag implements Container { if (timeline != null) { return timeline; } - timeline = new Timeline(swf, new ArrayList(), buttonId, getRect(new HashSet())); + timeline = new Timeline(swf, this, new ArrayList(), buttonId, getRect(new HashSet())); int maxDepth = 0; - Frame frameUp = new Frame(timeline); - Frame frameDown = new Frame(timeline); - Frame frameOver = new Frame(timeline); - Frame frameHit = new Frame(timeline); + Frame frameUp = new Frame(timeline, 0); + Frame frameDown = new Frame(timeline, 0); + Frame frameOver = new Frame(timeline, 0); + Frame frameHit = new Frame(timeline, 0); for (BUTTONRECORD r : this.characters) { DepthState layer = new DepthState(swf, null); @@ -288,24 +288,19 @@ public class DefineButton2Tag extends ButtonTag implements Container { } } - timeline.frames.add(frameUp); + timeline.getFrames().add(frameUp); if (frameOver.layers.isEmpty()) { frameOver = frameUp; } - timeline.frames.add(frameOver); + timeline.getFrames().add(frameOver); if (frameDown.layers.isEmpty()) { frameDown = frameOver; } - timeline.frames.add(frameDown); + timeline.getFrames().add(frameDown); if (frameHit.layers.isEmpty()) { frameHit = frameUp; } - timeline.frames.add(frameHit); + timeline.getFrames().add(frameHit); return timeline; } - - @Override - public void resetTimeline() { - timeline = null; - } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index 7f8c76051..97fc1acb6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -326,7 +326,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { if (timeline != null) { return timeline; } - timeline = new Timeline(swf, new ArrayList(), buttonId, getRect(new HashSet())); + timeline = new Timeline(swf, this, new ArrayList(), buttonId, getRect(new HashSet())); ColorTransform clrTrans = null; for (Tag t : swf.tags) { @@ -336,10 +336,10 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { } } int maxDepth = 0; - Frame frameUp = new Frame(timeline); - Frame frameDown = new Frame(timeline); - Frame frameOver = new Frame(timeline); - Frame frameHit = new Frame(timeline); + Frame frameUp = new Frame(timeline, 0); + Frame frameDown = new Frame(timeline, 0); + Frame frameOver = new Frame(timeline, 0); + Frame frameHit = new Frame(timeline, 0); for (BUTTONRECORD r : this.characters) { DepthState layer = new DepthState(swf, null); @@ -366,28 +366,23 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { } } - timeline.frames.add(frameUp); + timeline.getFrames().add(frameUp); if (frameOver.layers.isEmpty()) { frameOver = frameUp; } - timeline.frames.add(frameOver); + timeline.getFrames().add(frameOver); if (frameDown.layers.isEmpty()) { frameDown = frameOver; } - timeline.frames.add(frameDown); + timeline.getFrames().add(frameDown); if (frameHit.layers.isEmpty()) { frameHit = frameUp; } - timeline.frames.add(frameHit); + timeline.getFrames().add(frameHit); return timeline; } - @Override - public void resetTimeline() { - timeline = null; - } - @Override public Tag getSourceTag() { return this; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java index 8225cee0c..c4182d0cb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java @@ -263,7 +263,7 @@ public class DefineFont2Tag extends FontTag { fontBoundsTable.add(sis.readRECT("rect")); } int kerningCount = sis.readUI16("kerningCount"); - fontKerningTable = new ArrayList(); + fontKerningTable = new ArrayList<>(); for (int i = 0; i < kerningCount; i++) { fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record")); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java index f05b6dd9b..0ac8d9c4d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java @@ -168,7 +168,7 @@ public class DefineFont3Tag extends FontTag { fontBoundsTable.add(sis.readRECT("rect")); } int kerningCount = sis.readUI16("kerningCount"); - fontKerningTable = new ArrayList(); + fontKerningTable = new ArrayList<>(); for (int i = 0; i < kerningCount; i++) { fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record")); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index 22b2b8c6e..183a82a9b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -84,16 +84,11 @@ public class DefineSpriteTag extends CharacterTag implements Container, Drawable @Override public Timeline getTimeline() { if (timeline == null) { - timeline = new Timeline(swf, subTags, spriteId, getRect(new HashSet())); + timeline = new Timeline(swf, this, subTags, spriteId, getRect(new HashSet())); } return timeline; } - @Override - public void resetTimeline() { - timeline = null; - } - @Override public int getCharacterId() { return spriteId; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index e31738704..6e3812105 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.DisassemblyListener; @@ -199,5 +200,4 @@ public class DoActionTag extends Tag implements ASMSource { public Tag getSourceTag() { return this; } - } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index 5cc176d4d..99b8147a0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -179,7 +179,7 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { public String getExportFileName() { String expName = getExportName(); if ((expName == null) || expName.isEmpty()) { - return super.toString(); + return super.getExportFileName(); } String[] pathParts; if (expName.contains(".")) { @@ -229,5 +229,4 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { public Tag getSourceTag() { return this; } - } 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 5f9f94bb8..2732553b3 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java index 58828d64b..e31a9d41b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.DisassemblyListener; @@ -21,7 +22,6 @@ import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.treeitems.TreeItem; import java.util.List; /** @@ -29,7 +29,7 @@ import java.util.List; * * @author JPEXS */ -public interface ASMSource extends TreeItem { +public interface ASMSource extends Exportable { /** * Converts actions to ASM source diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/Exportable.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/Exportable.java index 77f13c0a6..afdff6c5b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/Exportable.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/Exportable.java @@ -12,14 +12,17 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags.base; +import com.jpexs.decompiler.flash.treeitems.TreeItem; + /** * * @author JPEXS */ -public interface Exportable { +public interface Exportable extends TreeItem { public String getExportFileName(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS2Package.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS2Package.java new file mode 100644 index 000000000..f1aed4f09 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS2Package.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010-2014 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.timeline; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.Map; +import java.util.TreeMap; + +/** + * + * @author JPEXS + */ +public class AS2Package implements TreeItem { + + private final SWF swf; + private final String name; + private final AS2Package parent; + + public Map subPackages = new TreeMap<>(); + + public Map scripts = new TreeMap<>(); + + public AS2Package(String name, AS2Package parent, SWF swf) { + this.name = name; + this.parent = parent; + this.swf = swf; + } + + @Override + public SWF getSwf() { + return swf; + } + + public TreeItem getChild(int index) { + if (index < subPackages.size()) { + for (AS2Package subPackage : subPackages.values()) { + if (index == 0) { + return subPackage; + } + + index--; + } + } + + index -= subPackages.size(); + + for (ASMSource pack : scripts.values()) { + if (index == 0) { + return pack; + } + + index--; + } + + return null; + } + + public int getChildCount() { + return subPackages.size() + scripts.size(); + } + + public int getIndexOfChild(TreeItem child) { + int res = 0; + if (child instanceof AS2Package) { + for (AS2Package pkg : subPackages.values()) { + if (pkg.equals(child)) { + break; + } + res++; + } + return res; + } + + res = subPackages.size(); + for (ASMSource pack : scripts.values()) { + if (pack.equals(child)) { + break; + } + res++; + } + + return res; + } + @Override + public String toString() { + return name; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS3Package.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS3Package.java new file mode 100644 index 000000000..847add9ff --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/AS3Package.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010-2014 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.timeline; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; +import java.util.Map; +import java.util.TreeMap; + +/** + * + * @author JPEXS + */ +public class AS3Package extends AS3ClassTreeItem { + + private final SWF swf; + public String packageName; + public Map subPackages = new TreeMap<>(); + public Map scripts = new TreeMap<>(); + + public AS3Package(String packageName, SWF swf) { + super(packageName, null); + this.swf = swf; + this.packageName = packageName; + } + + @Override + public SWF getSwf() { + return swf; + } + + public AS3ClassTreeItem getChild(int index) { + if (index < subPackages.size()) { + for (AS3Package subPackage : subPackages.values()) { + if (index == 0) { + return subPackage; + } + + index--; + } + } + + index -= subPackages.size(); + + for (ScriptPack pack : scripts.values()) { + if (index == 0) { + return pack; + } + + index--; + } + + return null; + } + + public int getChildCount() { + return subPackages.size() + scripts.size(); + } + + public int getIndexOfChild(AS3ClassTreeItem child) { + int res = 0; + if (child instanceof AS3Package) { + for (AS3Package pkg : subPackages.values()) { + if (pkg.equals(child)) { + break; + } + res++; + } + return res; + } + + res = subPackages.size(); + for (ScriptPack pack : scripts.values()) { + if (pack.equals(child)) { + break; + } + res++; + } + + return res; + } + + @Override + public String toString() { + return packageName; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Frame.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Frame.java index 6d067ddbb..02bb07b15 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Frame.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Frame.java @@ -12,12 +12,15 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.timeline; +import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.tags.DoActionTag; import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.RGBA; import java.util.ArrayList; @@ -28,22 +31,25 @@ import java.util.TreeMap; * * @author JPEXS */ -public class Frame { +public class Frame implements TreeItem { + public final int frame; public TreeMap layers = new TreeMap<>(); - public DoActionTag action; public RGB backgroundColor = new RGBA(0, 0, 0, 0); public Timeline timeline; public List sounds = new ArrayList<>(); public List soundClasses = new ArrayList<>(); + public List actions = new ArrayList<>(); public List innerTags = new ArrayList<>(); public ShowFrameTag showFrameTag = null; // can be null for the last frame - public Frame(Timeline timeline) { + public Frame(Timeline timeline, int frame) { this.timeline = timeline; + this.frame = frame; } - public Frame(Frame obj) { + public Frame(Frame obj, int frame) { + this.frame = frame; layers = new TreeMap<>(); backgroundColor = obj.backgroundColor; timeline = obj.timeline; @@ -52,4 +58,14 @@ public class Frame { } //Do not copy sounds } + + @Override + public SWF getSwf() { + return timeline.swf; + } + + @Override + public String toString() { + return "frame " + (frame + 1); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS2PackageNodeItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java similarity index 69% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS2PackageNodeItem.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java index da281cd40..fd4938a1f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS2PackageNodeItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java @@ -12,25 +12,31 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.flash.treeitems; + * License along with this library. + */ +package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.treeitems.TreeItem; /** * * @author JPEXS */ -public class AS2PackageNodeItem implements TreeItem { +public class FrameScript implements TreeItem { private final SWF swf; - public String packageName; + private final Frame frame; - public AS2PackageNodeItem(String packageName, SWF swf) { + public FrameScript(SWF swf, Frame frame) { this.swf = swf; - this.packageName = packageName; + this.frame = frame; } - + + public Frame getFrame() { + return frame; + } + @Override public SWF getSwf() { return swf; @@ -38,6 +44,6 @@ public class AS2PackageNodeItem implements TreeItem { @Override public String toString() { - return packageName; + return frame.toString(); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FrameNodeItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/TagScript.java similarity index 59% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FrameNodeItem.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/TagScript.java index 9151fa5d1..0307b13b6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FrameNodeItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/TagScript.java @@ -14,49 +14,44 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.treeitems; +package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.List; /** * * @author JPEXS */ -public class FrameNodeItem implements TreeItem { - +public class TagScript implements TreeItem { + private final SWF swf; - private final int frame; - private final Timelined parent; - private final boolean display; - - public FrameNodeItem(SWF swf, int frame, Timelined parent, boolean display) { + private final Tag tag; + private final List frames; + public TagScript(SWF swf, Tag tag, List frames) { this.swf = swf; - this.frame = frame; - this.parent = parent; - this.display = display; + this.tag = tag; + this.frames = frames; } - + + public Tag getTag() { + return tag; + } + + public List getFrames() { + return frames; + } + @Override public SWF getSwf() { return swf; } - public boolean isDisplayed() { - return display; - } - @Override public String toString() { - return "frame " + (frame + 1); - } - - public int getFrame() { - return frame; - } - - public Timelined getParent() { - return parent; + return tag.toString(); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 062c8313e..0873f514f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -19,11 +19,13 @@ package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.tags.DoActionTag; +import com.jpexs.decompiler.flash.tags.DoInitActionTag; import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; import com.jpexs.decompiler.flash.tags.ShowFrameTag; import com.jpexs.decompiler.flash.tags.StartSound2Tag; import com.jpexs.decompiler.flash.tags.StartSoundTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.ButtonTag; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -52,15 +54,59 @@ import java.util.Stack; */ public class Timeline { - public List frames = new ArrayList<>(); public int id; public SWF swf; public RECT displayRect; public int frameRate; + public Timelined timelined; + public Tag parentTag; public List tags; - public Map depthMaxFrame = new HashMap<>(); - public int getMaxDepth() { + private final List frames = new ArrayList<>(); + private final Map depthMaxFrame = new HashMap<>(); + private final List asmSources = new ArrayList<>(); + private final Map actionFrames = new HashMap<>(); + private AS2Package as2RootPackage; + private final List otherTags = new ArrayList<>(); + private boolean initialized = false; + + private void ensureInitialized() { + if (!initialized) { + initialize(); + } + } + + public List getFrames() { + ensureInitialized(); + return frames; + } + + public AS2Package getAS2RootPackage() { + ensureInitialized(); + return as2RootPackage; + } + + public Map getDepthMaxFrame() { + ensureInitialized(); + return depthMaxFrame; + } + + public void reset() { + initialized = false; + frames.clear(); + depthMaxFrame.clear(); + asmSources.clear(); + actionFrames.clear(); + otherTags.clear(); + as2RootPackage = new AS2Package(null, null, swf); + } + + public final int getMaxDepth() { + ensureInitialized(); + return getMaxDepthInternal(); + } + + public final int getMaxDepthInternal() { int max_depth = 0; for (Frame f : frames) { for (int depth : f.layers.keySet()) { @@ -76,39 +122,49 @@ public class Timeline { } public int getFrameCount() { - return frames.size(); + return getFrames().size(); + } + + public int getFrameForAction(ASMSource asm) { + Integer frame = actionFrames.get(asm); + if (frame == null) { + return -1; + } + + return frame; } public Timeline(SWF swf) { - this(swf, swf.tags, 0, swf.displayRect); + this(swf, null, swf.tags, 0, swf.displayRect); } - public Timeline(SWF swf, List tags, int id, RECT displayRect) { + public Timeline(SWF swf, Tag parentTag, List tags, int id, RECT displayRect) { this.id = id; this.swf = swf; this.displayRect = displayRect; this.frameRate = swf.frameRate; + this.timelined = parentTag == null ? swf : (Timelined) parentTag; + this.parentTag = parentTag; this.tags = tags; - Frame frame = new Frame(this); + as2RootPackage = new AS2Package(null, null, swf); + } + + private void initialize() { + int frameIdx = 0; + Frame frame = new Frame(this, frameIdx++); boolean tagAdded = false; for (Tag t : tags) { + tagAdded = true; if (ShowFrameTag.isNestedTagType(t.getId())) { frame.innerTags.add(t); - tagAdded = true; } if (t instanceof StartSoundTag) { frame.sounds.add(((StartSoundTag) t).soundId); - tagAdded = true; - } - if (t instanceof StartSound2Tag) { + } else if (t instanceof StartSound2Tag) { frame.soundClasses.add(((StartSound2Tag) t).soundClassName); - tagAdded = true; - } - if (t instanceof SetBackgroundColorTag) { + } else if (t instanceof SetBackgroundColorTag) { frame.backgroundColor = ((SetBackgroundColorTag) t).backgroundColor; - tagAdded = true; - } - if (t instanceof PlaceObjectTypeTag) { + } else if (t instanceof PlaceObjectTypeTag) { PlaceObjectTypeTag po = (PlaceObjectTypeTag) t; int depth = po.getDepth(); if (!frame.layers.containsKey(depth)) { @@ -168,30 +224,30 @@ public class Timeline { fl.clipDepth = po.getClipDepth(); } fl.key = true; - tagAdded = true; - } - if (t instanceof RemoveTag) { + } else if (t instanceof RemoveTag) { RemoveTag r = (RemoveTag) t; int depth = r.getDepth(); frame.layers.remove(depth); - tagAdded = true; - } - if (t instanceof DoActionTag) { - frame.action = (DoActionTag) t; - tagAdded = true; - } - if (t instanceof ShowFrameTag) { + } else if (t instanceof DoActionTag) { + frame.actions.add((DoActionTag) t); + actionFrames.put((DoActionTag) t, frame.frame); + } else if (t instanceof ShowFrameTag) { frame.showFrameTag = (ShowFrameTag) t; frames.add(frame); - frame = new Frame(frame); + frame = new Frame(frame, frameIdx++); tagAdded = false; + } else if (t instanceof ASMSource) { + asmSources.add((ASMSource) t); + } else { + otherTags.add(t); } } if (tagAdded) { frames.add(frame); } + detectTweens(); - for (int d = 1; d <= getMaxDepth(); d++) { + for (int d = 1; d <= getMaxDepthInternal(); d++) { for (int f = frames.size() - 1; f >= 0; f--) { if (frames.get(f).layers.get(d) != null) { depthMaxFrame.put(d, f + 1); @@ -199,6 +255,10 @@ public class Timeline { } } } + + createASPackages(); + + initialized = true; } private boolean compare(int a, int b, int c, int tolerance) { @@ -206,7 +266,7 @@ public class Timeline { } private void detectTweens() { - for (int d = 1; d <= getMaxDepth(); d++) { + for (int d = 1; d <= getMaxDepthInternal(); d++) { int characterId = -1; int len = 0; for (int f = 0; f <= frames.size(); f++) { @@ -237,6 +297,33 @@ public class Timeline { } } + private void createASPackages() { + for (ASMSource asm : asmSources) { + if (asm instanceof DoInitActionTag) { + DoInitActionTag initAction = (DoInitActionTag) asm; + String path = initAction.getExportName(); + if (path == null || path.isEmpty()) { + path = initAction.getExportFileName(); + } + + String[] pathParts = path.contains(".") ? path.split("\\.") : new String[]{path}; + AS2Package pkg = as2RootPackage; + for (int pos = 0; pos < pathParts.length - 1; pos++) { + String pathPart = pathParts[pos]; + AS2Package subPkg = pkg.subPackages.get(pathPart); + if (subPkg == null) { + subPkg = new AS2Package(pathPart, pkg, swf); + pkg.subPackages.put(pathPart, subPkg); + } + + pkg = subPkg; + } + + pkg.scripts.put(pathParts[pathParts.length - 1], asm); + } + } + } + public void getNeededCharacters(Set usedCharacters) { for (int i = 0; i < getFrameCount(); i++) { getNeededCharacters(i, usedCharacters); @@ -244,13 +331,13 @@ public class Timeline { } public void getNeededCharacters(List frames, Set usedCharacters) { - for (int frame = 0; frame < frames.size(); frame++) { + for (int frame = 0; frame < getFrameCount(); frame++) { getNeededCharacters(frame, usedCharacters); } } public void getNeededCharacters(int frame, Set usedCharacters) { - Frame frameObj = frames.get(frame); + Frame frameObj = getFrames().get(frame); for (int depth : frameObj.layers.keySet()) { DepthState layer = frameObj.layers.get(depth); if (layer.characterId != -1) { @@ -285,10 +372,10 @@ public class Timeline { } public void getSounds(int frame, int time, DepthState stateUnderCursor, int mouseButton, List sounds, List soundClasses) { - Frame fr = this.frames.get(frame); + Frame fr = getFrames().get(frame); sounds.addAll(fr.sounds); soundClasses.addAll(fr.soundClasses); - int maxDepth = this.getMaxDepth(); + int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { DepthState ds = fr.layers.get(d); if (ds != null) { @@ -317,9 +404,9 @@ public class Timeline { } public void getObjectsOutlines(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List objs, List outlines) { - Frame fr = this.frames.get(frame); + Frame fr = getFrames().get(frame); Stack clips = new Stack<>(); - int maxDepth = this.getMaxDepth(); + int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { Clip currentClip = null; for (int i = clips.size() - 1; i >= 0; i--) { @@ -386,10 +473,10 @@ public class Timeline { } public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { - Frame fr = this.frames.get(frame); + Frame fr = getFrames().get(frame); Area area = new Area(); Stack clips = new Stack<>(); - int maxDepth = this.getMaxDepth(); + int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { Clip currentClip = null; for (int i = clips.size() - 1; i >= 0; i--) { @@ -448,7 +535,7 @@ public class Timeline { } public boolean isSingleFrame() { - for (int i = 0; i < frames.size(); i++) { + for (int i = 0; i < getFrameCount(); i++) { if (!isSingleFrame(i)) { return false; } @@ -458,7 +545,7 @@ public class Timeline { private boolean isSingleFrame(int frame) { Frame frameObj = frames.get(frame); - int maxDepth = this.getMaxDepth(); + int maxDepth = getMaxDepthInternal(); for (int i = 1; i <= maxDepth; i++) { if (!frameObj.layers.containsKey(i)) { continue; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timelined.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timelined.java index 404be0836..914446ea8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timelined.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timelined.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.tags.base.BoundedTag; @@ -24,6 +25,4 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; public interface Timelined extends BoundedTag { public Timeline getTimeline(); - - public void resetTimeline(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3PackageNodeItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3ClassTreeItem.java similarity index 65% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3PackageNodeItem.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3ClassTreeItem.java index c61e8f5e0..d53faeb40 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3PackageNodeItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/AS3ClassTreeItem.java @@ -12,32 +12,34 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.treeitems; -import com.jpexs.decompiler.flash.SWF; - /** * * @author JPEXS */ -public class AS3PackageNodeItem implements TreeElementItem { +public abstract class AS3ClassTreeItem implements TreeItem { + + private final String name; + private final String path; - private final SWF swf; - public String packageName; - - public AS3PackageNodeItem(String packageName, SWF swf) { - this.swf = swf; - this.packageName = packageName; + public AS3ClassTreeItem(String name, String path) { + this.name = name; + this.path = path; } - @Override - public SWF getSwf() { - return swf; + public String getName() { + return name; + } + + public String getPath() { + return path; } @Override public String toString() { - return packageName; + return name; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/StringItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FolderItem.java similarity index 80% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/StringItem.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FolderItem.java index 6172f6aa0..8e9fc5f73 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/StringItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/FolderItem.java @@ -12,25 +12,29 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.treeitems; import com.jpexs.decompiler.flash.SWF; +import java.util.List; /** * * @author JPEXS */ -public class StringItem implements TreeItem { +public class FolderItem implements TreeItem { public SWF swf; private final String str; private final String name; + public final List subItems; - public StringItem(String str, String name, SWF swf) { + public FolderItem(String str, String name, SWF swf, List subItems) { this.swf = swf; this.str = str; this.name = name; + this.subItems = subItems; } public String getName() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java index 2af12c7d1..d9ae64567 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java @@ -41,5 +41,4 @@ public class HeaderItem implements TreeItem { public String toString() { return name; } - } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/SWFList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/SWFList.java index 3ff896ba0..324174477 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/SWFList.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/SWFList.java @@ -12,10 +12,12 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.treeitems; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFContainerItem; import com.jpexs.decompiler.flash.SWFSourceInfo; import java.util.ArrayList; import java.util.Collection; @@ -27,7 +29,7 @@ import java.util.ListIterator; * * @author JPEXS */ -public class SWFList implements List, TreeItem { +public class SWFList implements List, SWFContainerItem { public String name; public boolean isBundle; @@ -39,6 +41,11 @@ public class SWFList implements List, TreeItem { throw new UnsupportedOperationException("Not supported."); } + @Override + public String toString() { + return name; + } + @Override public Iterator iterator() { return swfs.iterator(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/ScriptContainer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/ScriptContainer.java new file mode 100644 index 000000000..1042c0477 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/ScriptContainer.java @@ -0,0 +1,18 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package com.jpexs.decompiler.flash.treeitems; + +import java.util.Map; + +/** + * + * @author JPEXS + */ +public interface ScriptContainer { + + public Map getInnerScripts(); +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeItem.java index ccd1126cf..1c67b8d2d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treeitems/TreeItem.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.treeitems; import com.jpexs.decompiler.flash.SWF; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/AS2PackageNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/AS2PackageNode.java deleted file mode 100644 index c5cc641d4..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/AS2PackageNode.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem; - -/** - * - * @author JPEXS - */ -public class AS2PackageNode extends TreeNode { - - public AS2PackageNode(AS2PackageNodeItem item) { - super(item); - } - - @Override - public AS2PackageNodeItem getItem() { - return (AS2PackageNodeItem) item; - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/ContainerNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/ContainerNode.java deleted file mode 100644 index 15e2cc37c..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/ContainerNode.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.tags.base.ContainerItem; - -/** - * - * @author JPEXS - */ -public class ContainerNode extends TreeNode { - - public ContainerNode(ContainerItem item) { - super(item); - } - - @Override - public ContainerItem getItem() { - return (ContainerItem) item; - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/FrameNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/FrameNode.java deleted file mode 100644 index db27fa2c0..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/FrameNode.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class FrameNode extends TreeNode { - - public boolean scriptsNode = false; - - public FrameNode(FrameNodeItem item, List innerTags, boolean scriptsNode) { - super(item); - this.scriptsNode = scriptsNode; - if (innerTags != null) { - for (Tag tag : innerTags) { - subNodes.add(new TagNode(tag)); - } - } - } - - @Override - public FrameNodeItem getItem() { - return (FrameNodeItem) item; - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java deleted file mode 100644 index 258de9cd5..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.treeitems.HeaderItem; - -/** - * - * @author JPEXS - */ -public class HeaderNode extends TreeNode { - - public HeaderNode(HeaderItem item) { - super(item); - } - - @Override - public HeaderItem getItem() { - return (HeaderItem) item; - } - -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TagNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TagNode.java deleted file mode 100644 index 7ea8712d5..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TagNode.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; -import com.jpexs.decompiler.flash.EventListener; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.FileTextWriter; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.Exportable; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TagNode extends ContainerNode { - - public TagNode(Tag tag) { - super(tag); - } - - @Override - public Tag getItem() { - return (Tag) item; - } - - public static int getTagCountRecursive(List nodeList) { - int count = 0; - - for (TreeNode node : nodeList) { - if (node.item instanceof ASMSource) { - count += 1; - } - if (!node.subNodes.isEmpty()) { - count += getTagCountRecursive(node.subNodes); - } - } - - return count; - } - - public static List exportNodeAS(final AbortRetryIgnoreHandler handler, final List nodesList, final List nodesToExport, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException { - try { - List result = CancellableWorker.call(new Callable>() { - - @Override - public List call() throws Exception { - AtomicInteger cnt = new AtomicInteger(1); - int totalCount = TagNode.getTagCountRecursive(nodesToExport); - return exportNodeAS(handler, nodesList, nodesToExport, false, outdir, exportMode, cnt, totalCount, ev); - } - }, Configuration.exportTimeout.get(), TimeUnit.SECONDS); - return result; - } catch (ExecutionException | InterruptedException | TimeoutException ex) { - } - return new ArrayList<>(); - } - - private static List exportNodeAS(AbortRetryIgnoreHandler handler, List nodesList, List nodesToExport, boolean exportAll, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException { - File dir = new File(outdir); - List ret = new ArrayList<>(); - if (!outdir.endsWith(File.separator)) { - outdir += File.separator; - } - List existingNames = new ArrayList<>(); - for (TreeNode node : nodesList) { - String name = ""; - if (node.item instanceof Exportable) { - name = Helper.makeFileName(((Exportable) node.item).getExportFileName()); - } else { - name = Helper.makeFileName(node.item.toString()); - } - int i = 1; - String baseName = name; - while (existingNames.contains(name)) { - i++; - name = baseName + "_" + i; - } - existingNames.add(name); - boolean exportNode = nodesToExport.contains(node); - if (node.item instanceof ASMSource && (exportAll || exportNode)) { - boolean retry; - do { - retry = false; - try { - int currentIndex = index.getAndIncrement(); - - if (!dir.exists()) { - if (!dir.mkdirs()) { - if (!dir.exists()) { - throw new IOException("Cannot create directory " + outdir); - } - } - } - - String f = outdir + name + ".as"; - if (ev != null) { - ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f); - } - - long startTime = System.currentTimeMillis(); - - File file = new File(f); - ASMSource asm = ((ASMSource) node.item); - try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) { - if (exportMode == ScriptExportMode.HEX) { - asm.getActionSourcePrefix(writer); - asm.getActionBytesAsHex(writer); - asm.getActionSourceSuffix(writer); - } else if (exportMode != ScriptExportMode.AS) { - asm.getActionSourcePrefix(writer); - asm.getASMSource(exportMode, writer, null); - asm.getActionSourceSuffix(writer); - } else { - List as = asm.getActions(); - Action.setActionsAddresses(as, 0); - Action.actionsToSource(asm, as, ""/*FIXME*/, writer); - } - } - - long stopTime = System.currentTimeMillis(); - - if (ev != null) { - long time = stopTime - startTime; - ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time)); - } - - ret.add(file); - } catch (InterruptedException ex) { - } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { - Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); - if (handler != null) { - int action = handler.getNewInstance().handle(ex); - switch (action) { - case AbortRetryIgnoreHandler.ABORT: - throw ex; - case AbortRetryIgnoreHandler.RETRY: - retry = true; - break; - case AbortRetryIgnoreHandler.IGNORE: - retry = false; - break; - } - } - } - } while (retry); - } - if (!node.subNodes.isEmpty()) { - ret.addAll(exportNodeAS(handler, node.subNodes, nodesToExport, exportAll || exportNode, outdir + name, exportMode, index, count, ev)); - } - - } - return ret; - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TreeNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TreeNode.java deleted file mode 100644 index 6c9ea5379..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/treenodes/TreeNode.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. - */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author JPEXS - */ -public abstract class TreeNode { - - protected TreeItem item; - public List subNodes; - - public TreeNode(TreeItem item) { - if (item == null) { - throw new Error("TreeItem should not be null."); - } - this.item = item; - this.subNodes = new ArrayList<>(); - } - - public TreeItem getItem() { - return item; - } - - @Override - public String toString() { - if (item == null) { - Logger.getLogger(TreeNode.class.getName()).log(Level.FINE, "Tree item is null"); - return null; - } - return item.toString(); - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java index 60ecfae52..dc9806ca4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.types; import com.jpexs.decompiler.flash.DisassemblyListener; 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 173a4ea11..a3109d17a 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 @@ -284,5 +284,4 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S public Tag getSourceTag() { return tag; } - } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java index e591c29a3..c3a79498d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter; -import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.NeedsCharacters; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.types.ColorTransform; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java index eaf9d778b..d351cfddb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java @@ -59,7 +59,7 @@ public abstract class GraphTargetItem implements Serializable { public List moreSrc = new ArrayList<>(); public GraphPart firstPart; public GraphTargetItem value; - protected Map srcData = new HashMap(); + protected Map srcData = new HashMap<>(); public GraphPart getFirstPart() { if (value == null) { diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/RecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/RecompileTest.java index 40c20854b..84485f140 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/RecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/RecompileTest.java @@ -31,9 +31,6 @@ import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.ContainerItem; -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.TranslateException; import java.io.BufferedInputStream; @@ -44,6 +41,7 @@ import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static org.testng.Assert.fail; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -77,54 +75,12 @@ public class RecompileTest { } } - private void testAS2DirectEditingOneRecursive(int swfVersion, List nodeList) { - for (TreeNode node : nodeList) { - if (node.subNodes.isEmpty()) { - TreeItem item = node.getItem(); - if (item instanceof ASMSource) { - try { - ASMSource asm = ((ASMSource) item); - HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as = writer.toString(); - as = asm.removePrefixAndSuffix(as); - ActionScriptParser par = new ActionScriptParser(swfVersion); - try { - asm.setActions(par.actionsFromString(as)); - } catch (ActionParseException | CompilationException ex) { - fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as2 = writer.toString(); - as2 = asm.removePrefixAndSuffix(as2); - try { - asm.setActions(par.actionsFromString(as2)); - } catch (ActionParseException | CompilationException ex) { - fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as3 = writer.toString(); - as3 = asm.removePrefixAndSuffix(as3); - if (!as3.equals(as2)) { - fail("ActionScript is different: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { - } - } - } else { - testAS2DirectEditingOneRecursive(swfVersion, node.subNodes); - } - } - } - @Test(dataProvider = "provideFiles") public void testDirectEditing(String filename) throws IOException, InterruptedException, AVM2ParseException, CompilationException { Configuration.autoDeobfuscate.set(false); try { SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); - if ((swf.fileAttributes != null && swf.fileAttributes.actionScript3) || (swf.fileAttributes == null && swf.isAS3)) { + if (swf.isAS3) { boolean dotest = false; List allAbcs = new ArrayList<>(); for (ABCContainerTag ct : swf.abcList) { @@ -148,15 +104,43 @@ public class RecompileTest { en.getValue().toSource(htw, swf.abcList, abc.script_info.get(s).traits.traits, ScriptExportMode.AS, false); String original = htw.toString(); ABC nabc = new ABC(swf); - com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(original, nabc, allAbcs, false, en.getKey().className + ".as",abc.instance_info.size()); + com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(original, nabc, allAbcs, false, en.getKey().className + ".as", abc.instance_info.size()); } } } else { - List list2 = new ArrayList<>(); - list2.addAll(swf.tags); - List list = SWF.createASTagList(list2, null); + Map asms = swf.getASMs(); - testAS2DirectEditingOneRecursive(swf.version, list); + for (ASMSource asm : asms.values()) { + try { + HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as = writer.toString(); + as = asm.removePrefixAndSuffix(as); + ActionScriptParser par = new ActionScriptParser(swf.version); + try { + asm.setActions(par.actionsFromString(as)); + } catch (ActionParseException | CompilationException ex) { + fail("Unable to parse: " + asm.getSwf().getShortFileName() + "/" + asm.toString()); + } + writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as2 = writer.toString(); + as2 = asm.removePrefixAndSuffix(as2); + try { + asm.setActions(par.actionsFromString(as2)); + } catch (ActionParseException | CompilationException ex) { + fail("Unable to parse: " + asm.getSwf().getShortFileName() + "/" + asm.toString()); + } + writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as3 = writer.toString(); + as3 = asm.removePrefixAndSuffix(as3); + if (!as3.equals(as2)) { + fail("ActionScript is different: " + asm.getSwf().getShortFileName() + "/" + asm.toString()); + } + } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { + } + } } } catch (Exception ex) { System.out.println("FAIL"); diff --git a/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java b/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java index 3c5acc243..3e486e6bb 100644 --- a/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.gui.hexview.HexView; -import com.jpexs.decompiler.flash.treenodes.TagNode; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.helpers.utf8.Utf8Helper; import java.awt.BorderLayout; import java.awt.Color; @@ -43,7 +43,7 @@ public final class BinaryPanel extends JPanel implements ComponentListener { public HexView hexEditor = new HexView(); private byte[] data; private JPanel swfInsidePanel; - private TagNode node = null; + private DefineBinaryDataTag binaryDataTag = null; private final MainPanel mainPanel; public BinaryPanel(final MainPanel mainPanel) { @@ -67,7 +67,7 @@ public final class BinaryPanel extends JPanel implements ComponentListener { @Override public void mouseClicked(MouseEvent e) { - mainPanel.loadFromBinaryTag(node); + mainPanel.loadFromBinaryTag(binaryDataTag); swfInsidePanel.setVisible(false); } @@ -76,14 +76,15 @@ public final class BinaryPanel extends JPanel implements ComponentListener { swfInsidePanel.setVisible(false); } - public void setBinaryData(byte[] data, TagNode node) { - this.node = node; + public void setBinaryData(byte[] data, DefineBinaryDataTag binaryDataTag) { + this.binaryDataTag = binaryDataTag; this.data = data; if (data != null) { hexEditor.setData(data, null, null); - if (node != null) { - if (node.subNodes.isEmpty() && data.length > 8) { + boolean binaryIsSwf = false; + if (binaryDataTag != null) { + if (binaryDataTag.innerSwf == null && data.length > 8) { try { String signature = new String(data, 0, 3, Utf8Helper.charset); if (Arrays.asList( @@ -93,18 +94,14 @@ public final class BinaryPanel extends JPanel implements ComponentListener { "GFX", //Uncompressed ScaleForm GFx "CFX" //Compressed ScaleForm GFx ).contains(signature)) { - swfInsidePanel.setVisible(true); + binaryIsSwf = true; } } catch (Exception ex) { - swfInsidePanel.setVisible(false); } - } else { - swfInsidePanel.setVisible(false); } - } else { - swfInsidePanel.setVisible(false); } + swfInsidePanel.setVisible(binaryIsSwf); } else { hexEditor.setData(new byte[0], null, null); swfInsidePanel.setVisible(false); @@ -115,7 +112,7 @@ public final class BinaryPanel extends JPanel implements ComponentListener { @Override public void componentResized(ComponentEvent e) { - setBinaryData(data, node); + setBinaryData(data, binaryDataTag); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/DebugLogDialog.java b/src/com/jpexs/decompiler/flash/gui/DebugLogDialog.java index 789ae59c6..48ebef758 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugLogDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugLogDialog.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.gui.debugger.DebugListener; @@ -26,15 +25,10 @@ import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.DefaultListModel; import javax.swing.JButton; -import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; -import javax.swing.ListModel; import javax.swing.text.BadLocationException; import javax.swing.text.Document; @@ -44,56 +38,56 @@ import javax.swing.text.Document; */ public class DebugLogDialog extends AppDialog implements ActionListener { - private JTextArea logTextArea = new JTextArea(); + private final JTextArea logTextArea = new JTextArea(); private final String ACTION_CLOSE = "CLOSE"; private final String ACTION_CLEAR = "CLEAR"; - private Debugger debug; - + private final Debugger debug; + public DebugLogDialog(Debugger debug) { - setSize(800, 600); - this.debug = debug; + setSize(800, 600); + this.debug = debug; setTitle(translate("dialog.title")); logTextArea.setBackground(Color.white); logTextArea.setEditable(false); JScrollPane spane = new JScrollPane(logTextArea); - spane.setPreferredSize(new Dimension(800,500)); - + spane.setPreferredSize(new Dimension(800, 500)); + debug.addMessageListener(new DebugListener() { @Override public void onMessage(String clientId, String msg) { - log(translate("msg.header").replace("%clientid%", clientId)+msg); + log(translate("msg.header").replace("%clientid%", clientId) + msg); } @Override public void onFinish(String clientId) { - + } }); Container cnt = getContentPane(); cnt.setLayout(new BorderLayout()); - cnt.add(spane,BorderLayout.CENTER); - + cnt.add(spane, BorderLayout.CENTER); + JPanel buttonsPanel = new JPanel(new FlowLayout()); JButton clearButton = new JButton(translate("button.clear")); clearButton.setActionCommand(ACTION_CLEAR); clearButton.addActionListener(this); - + JButton closeButton = new JButton(translate("button.close")); closeButton.setActionCommand(ACTION_CLOSE); closeButton.addActionListener(this); - + buttonsPanel.add(clearButton); buttonsPanel.add(closeButton); - cnt.add(buttonsPanel,BorderLayout.SOUTH); + cnt.add(buttonsPanel, BorderLayout.SOUTH); View.setWindowIcon(this); View.centerScreen(this); } - - public void log(String msg){ + + public void log(String msg) { Document d = logTextArea.getDocument(); try { - d.insertString(d.getLength(), msg+"\r\n", null); + d.insertString(d.getLength(), msg + "\r\n", null); } catch (BadLocationException ex) { //ignore } @@ -101,7 +95,7 @@ public class DebugLogDialog extends AppDialog implements ActionListener { @Override public void actionPerformed(ActionEvent e) { - switch(e.getActionCommand()){ + switch (e.getActionCommand()) { case ACTION_CLEAR: logTextArea.setText(""); break; @@ -110,5 +104,5 @@ public class DebugLogDialog extends AppDialog implements ActionListener { break; } } - + } diff --git a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java index b818514be..fe31aed7b 100644 --- a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java @@ -30,14 +30,15 @@ import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode; import com.jpexs.decompiler.flash.exporters.modes.TextExportMode; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.TextTag; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.treeitems.TreeItem; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; @@ -83,9 +84,9 @@ public class ExportDialog extends AppDialog { {ImageTag.class}, {DefineVideoStreamTag.class}, {SoundTag.class}, - {TreeNode.class, ScriptPack.class}, + {ASMSource.class, ScriptPack.class}, {DefineBinaryDataTag.class}, - {FrameNodeItem.class}, + {Frame.class}, {FontTag.class}, {MorphShapeTag.class} }; @@ -144,7 +145,7 @@ public class ExportDialog extends AppDialog { Configuration.lastSelectedExportFormats.set(cfg); } - public ExportDialog(List exportables) { + public ExportDialog(List exportables) { setTitle(translate("dialog.title")); addWindowListener(new WindowAdapter() { @Override @@ -205,7 +206,7 @@ public class ExportDialog extends AppDialog { if (exportables == null) { exportableExists = true; } else { - for (Object e : exportables) { + for (TreeItem e : exportables) { for (int j = 0; j < objClasses[i].length; j++) { if (objClasses[i][j].isInstance(e)) { exportableExists = true; diff --git a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java index 9f64487a2..5a0c2f20e 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java @@ -80,7 +80,7 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { if (ttfFileRadio.isSelected() && customFont != null) { return customFont; } - return ((FontFace)faceSelection.getSelectedItem()).font; + return ((FontFace) faceSelection.getSelectedItem()).font; } public boolean hasUpdateTexts() { @@ -123,8 +123,8 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { private JRadioButton ttfFileRadio; private JRadioButton installedRadio; - private void updateFaceSelection() { - faceSelection.setModel(FontPanel.getFaceModel((FontFamily)familyNamesSelection.getSelectedItem())); + private void updateFaceSelection() { + faceSelection.setModel(FontPanel.getFaceModel((FontFamily) familyNamesSelection.getSelectedItem())); } public FontEmbedDialog(FontFace selectedFace, String selectedChars) { @@ -147,7 +147,7 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { installedRadio.setSelected(true); individialSample = new JLabel(); - familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel()); + familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel()); familyNamesSelection.setSelectedItem(new FontFamily(selectedFace.font)); faceSelection = new JComboBox<>(); updateFaceSelection(); diff --git a/src/com/jpexs/decompiler/flash/gui/FontFace.java b/src/com/jpexs/decompiler/flash/gui/FontFace.java index 82f162cef..fc843c221 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontFace.java +++ b/src/com/jpexs/decompiler/flash/gui/FontFace.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.gui; import java.awt.Font; @@ -24,46 +23,48 @@ import java.util.Objects; * * @author JPEXS */ -public class FontFace implements Comparable{ - public Font font; - public FontFace(Font font) { - this.font = font; - } +public class FontFace implements Comparable { - @Override - public String toString() { - String face = font.getFontName(); - String fam = font.getFamily(); - if(face.startsWith(fam)){ - face = face.substring(fam.length()).trim(); - } - if(face.startsWith(".")){ - face=face.substring(1); - } - return face; - } + public Font font; - @Override - public int hashCode() { - int hash = 7; - hash = 79 * hash + Objects.hashCode(this.font); - return hash; - } + public FontFace(Font font) { + this.font = font; + } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final FontFace other = (FontFace) obj; - if (!Objects.equals(this.font, other.font)) { - return false; - } - return true; + @Override + public String toString() { + String face = font.getFontName(); + String fam = font.getFamily(); + if (face.startsWith(fam)) { + face = face.substring(fam.length()).trim(); } + if (face.startsWith(".")) { + face = face.substring(1); + } + return face; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 79 * hash + Objects.hashCode(this.font); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FontFace other = (FontFace) obj; + if (!Objects.equals(this.font, other.font)) { + return false; + } + return true; + } @Override public int compareTo(FontFace o) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontFamily.java b/src/com/jpexs/decompiler/flash/gui/FontFamily.java index 1418559fe..a3581c2b7 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontFamily.java +++ b/src/com/jpexs/decompiler/flash/gui/FontFamily.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.gui; import java.awt.Font; @@ -25,45 +24,46 @@ import java.util.Objects; * * @author JPEXS */ -public class FontFamily implements Comparable{ - public String familyEn; - public String family; +public class FontFamily implements Comparable { - public FontFamily(Font font){ - this(font.getFamily(Locale.ENGLISH),font.getFamily()); - } - - public FontFamily(String familyEn, String family) { - this.familyEn = familyEn; - this.family = family; - } + public String familyEn; + public String family; - @Override - public String toString() { - return family; - } + public FontFamily(Font font) { + this(font.getFamily(Locale.ENGLISH), font.getFamily()); + } - @Override - public int hashCode() { - int hash = 7; - hash = 89 * hash + Objects.hashCode(this.familyEn); - return hash; - } + public FontFamily(String familyEn, String family) { + this.familyEn = familyEn; + this.family = family; + } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final FontFamily other = (FontFamily) obj; - if (!Objects.equals(this.familyEn, other.familyEn)) { - return false; - } - return true; + @Override + public String toString() { + return family; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + Objects.hashCode(this.familyEn); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; } + if (getClass() != obj.getClass()) { + return false; + } + final FontFamily other = (FontFamily) obj; + if (!Objects.equals(this.familyEn, other.familyEn)) { + return false; + } + return true; + } @Override public int compareTo(FontFamily o) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 272fdc703..ab0c88629 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -77,21 +77,21 @@ public class FontPanel extends javax.swing.JPanel { } public static ComboBoxModel getFamilyModel() { - Set famSet=new TreeSet<>(); - for(Font f:FontTag.installedFontsByName.values()){ + Set famSet = new TreeSet<>(); + for (Font f : FontTag.installedFontsByName.values()) { famSet.add(new FontFamily(f)); } - return new DefaultComboBoxModel<>(new Vector(famSet)); + return new DefaultComboBoxModel<>(new Vector<>(famSet)); } - public static ComboBoxModel getFaceModel(FontFamily family) { - - Set faceSet=new TreeSet<>(); - for(Font f:FontTag.installedFontsByFamily.get(family.familyEn).values()){ + public static ComboBoxModel getFaceModel(FontFamily family) { + + Set faceSet = new TreeSet<>(); + for (Font f : FontTag.installedFontsByFamily.get(family.familyEn).values()) { faceSet.add(new FontFace(f)); } - - return new DefaultComboBoxModel<>(new Vector(faceSet)); + + return new DefaultComboBoxModel<>(new Vector<>(faceSet)); } private void setEditable(boolean editable) { @@ -183,7 +183,7 @@ public class FontPanel extends javax.swing.JPanel { public void showFontTag(FontTag ft) { SWF swf = ft.getSwf(); - fontTag = ft; + fontTag = ft; fontNameIntagLabel.setText(ft.getFontNameIntag()); fontNameTextArea.setText(ft.getFontName()); fontCopyrightTextArea.setText(ft.getFontCopyright()); @@ -197,9 +197,9 @@ public class FontPanel extends javax.swing.JPanel { fontCharactersTextArea.setText(chars); setAllowSave(false); String key = swf.getShortFileName() + "_" + ft.getFontId() + "_" + ft.getFontName(); - + String selectedFont = ""; - + if (swf.sourceFontNamesMap.containsKey(ft.getFontId())) { selectedFont = swf.sourceFontNamesMap.get(ft.getFontId()); } else if (Configuration.getFontToNameMap().containsKey(key)) { @@ -209,17 +209,16 @@ public class FontPanel extends javax.swing.JPanel { } else { selectedFont = FontTag.findInstalledFontName(ft.getFontName()); } - + Font selFont = FontTag.installedFontsByName.get(selectedFont); - if(selFont == null){ + if (selFont == null) { selectedFont = FontTag.findInstalledFontName(ft.getFontName()); selFont = FontTag.installedFontsByName.get(selectedFont); } - + fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); fontFaceSelection.setSelectedItem(new FontFace(selFont)); - - + setAllowSave(true); setEditable(false); } @@ -385,6 +384,7 @@ public class FontPanel extends javax.swing.JPanel { fontAddCharsButton.setText(AppStrings.translate("button.ok")); // NOI18N fontAddCharsButton.addActionListener(new java.awt.event.ActionListener() { + @Override public void actionPerformed(java.awt.event.ActionEvent evt) { fontAddCharsButtonActionPerformed(evt); } @@ -396,7 +396,7 @@ public class FontPanel extends javax.swing.JPanel { fontFamilyNameSelection.setModel(getFamilyModel()); fontFamilyNameSelection.setSelectedItem(FontTag.defaultFontName); - fontFaceSelection.setModel(getFaceModel((FontFamily)fontFamilyNameSelection.getSelectedItem())); + fontFaceSelection.setModel(getFaceModel((FontFamily) fontFamilyNameSelection.getSelectedItem())); fontFamilyNameSelection.addItemListener(new java.awt.event.ItemListener() { @Override public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -509,7 +509,7 @@ public class FontPanel extends javax.swing.JPanel { for (int c = 0; c < newchars.length(); c++) { selChars.add(newchars.codePointAt(c)); } - fontAddChars((FontTag) item, selChars, ((FontFace)fontFaceSelection.getSelectedItem()).font); + fontAddChars((FontTag) item, selChars, ((FontFace) fontFaceSelection.getSelectedItem()).font); fontAddCharactersField.setText(""); mainPanel.reload(true); } @@ -519,7 +519,7 @@ public class FontPanel extends javax.swing.JPanel { TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof FontTag) { FontTag ft = (FontTag) item; - FontEmbedDialog fed = new FontEmbedDialog((FontFace)fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText()); + FontEmbedDialog fed = new FontEmbedDialog((FontFace) fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText()); if (fed.display()) { Set selChars = fed.getSelectedChars(); if (!selChars.isEmpty()) { @@ -548,8 +548,8 @@ public class FontPanel extends javax.swing.JPanel { TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof FontTag) { FontTag f = (FontTag) item; - SWF swf = f.getSwf(); - String selectedName = ((FontFace)fontFaceSelection.getSelectedItem()).font.getFontName(Locale.ENGLISH); + SWF swf = f.getSwf(); + String selectedName = ((FontFace) fontFaceSelection.getSelectedItem()).font.getFontName(Locale.ENGLISH); swf.sourceFontNamesMap.put(f.getFontId(), selectedName); Configuration.addFontPair(swf.getShortFileName(), f.getFontId(), f.getFontName(), selectedName); } @@ -558,7 +558,7 @@ public class FontPanel extends javax.swing.JPanel { private void fontFamilySelectionItemStateChanged() { savePair(); - fontFaceSelection.setModel(getFaceModel((FontFamily)fontFamilyNameSelection.getSelectedItem())); + fontFaceSelection.setModel(getFaceModel((FontFamily) fontFamilyNameSelection.getSelectedItem())); } private void fontFaceSelectionItemStateChanged() { @@ -584,8 +584,8 @@ public class FontPanel extends javax.swing.JPanel { setEditable(false); } - private void buttonPreviewFontActionPerformed(java.awt.event.ActionEvent evt) { - new FontPreviewDialog(null, true, ((FontFace)fontFaceSelection.getSelectedItem()).font).setVisible(true); + private void buttonPreviewFontActionPerformed(java.awt.event.ActionEvent evt) { + new FontPreviewDialog(null, true, ((FontFace) fontFaceSelection.getSelectedItem()).font).setVisible(true); } private void formComponentResized(java.awt.event.ComponentEvent evt) { @@ -669,5 +669,5 @@ public class FontPanel extends javax.swing.JPanel { private javax.swing.JPanel addCharsPanel; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JCheckBox updateTextsCheckBox; - + } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index a483484af..46092a925 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -282,7 +282,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis private void showSelectedName() { if (selectedDepth > -1 && frame > -1) { - DepthState ds = timelined.getTimeline().frames.get(frame).layers.get(selectedDepth); + DepthState ds = timelined.getTimeline().getFrames().get(frame).layers.get(selectedDepth); if (ds != null) { CharacterTag cht = timelined.getTimeline().swf.characters.get(ds.characterId); if (cht != null) { @@ -464,7 +464,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } loaded = true; - if (drawable.getTimeline().frames.isEmpty()) { + if (drawable.getTimeline().getFrames().isEmpty()) { iconPanel.setImg(null); iconPanel.setOutlines(new ArrayList(), new ArrayList()); return; @@ -498,7 +498,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis if (stillFrame) { return 0; } - return timelined.getTimeline().frames.size(); + return timelined.getTimeline().getFrameCount(); } @Override @@ -520,7 +520,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis private void nextFrame() { drawFrame(); - int newframe = (frame + 1) % timelined.getTimeline().frames.size(); + int newframe = (frame + 1) % timelined.getTimeline().getFrameCount(); if (stillFrame) { newframe = frame; } @@ -561,7 +561,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); List dss = new ArrayList<>(); List os = new ArrayList<>(); - DepthState ds = drawable.getTimeline().frames.get(frame).layers.get(selectedDepth); + DepthState ds = drawable.getTimeline().getFrames().get(frame).layers.get(selectedDepth); if (ds != null) { CharacterTag cht = swf.characters.get(ds.characterId); if (cht != null) { @@ -604,7 +604,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis return; } Timeline timeline = timelined.getTimeline(); - if (frame >= timeline.frames.size()) { + if (frame >= timeline.getFrameCount()) { return; } @@ -692,7 +692,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis @Override public void run() { Timeline timeline = timelined.getTimeline(); - if (timeline.frames.size() <= 1 && timeline.isSingleFrame()) { + if (timeline.getFrameCount() <= 1 && timeline.isSingleFrame()) { if (first) { drawFrame(); first = false; @@ -721,7 +721,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis if (stillFrame) { return false; } - return (timelined.getTimeline().frames.size() <= 1) || (timer != null); + return (timelined.getTimeline().getFrameCount() <= 1) || (timer != null); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index f66198f67..a2d8550ed 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -32,7 +32,6 @@ import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.console.CommandLineArgumentParser; import com.jpexs.decompiler.flash.console.ContextMenuTools; -import com.jpexs.decompiler.flash.gui.debugger.DebugListener; import com.jpexs.decompiler.flash.gui.debugger.Debugger; import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame; import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; @@ -1144,18 +1143,18 @@ public class Main { Random rnd = new Random(); byte rb[] = new byte[16]; rnd.nextBytes(rb); - String rhex = byteArrayToHex(rb); + String rhex = byteArrayToHex(rb); try { //load debug swf SWF debugSWF = new SWF(Main.class.getClassLoader().getResourceAsStream("com/jpexs/decompiler/flash/gui/debugger/debug.swf"), false); ABCContainerTag firstAbc = swf.abcList.get(0); String newdebuggerpkg = DEBUGGER_PACKAGE; - - if(Configuration.randomDebuggerPackage.get()){ - newdebuggerpkg += ".pkg"+rhex; + + if (Configuration.randomDebuggerPackage.get()) { + newdebuggerpkg += ".pkg" + rhex; } - + //add debug ABC tags to main SWF for (ABCContainerTag ds : debugSWF.abcList) { ABC a = ds.getABC(); @@ -1178,7 +1177,7 @@ public class Main { ((Tag) ds).setModified(true); } - } catch (Exception ex) { + } catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "Error while attaching debugger", ex); //ignore } diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java index d496ceda9..e4a4e5196 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.console.ContextMenuTools; -import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.helpers.Cache; import com.sun.jna.Platform; @@ -482,14 +481,13 @@ public class MainFrameClassicMenu implements MainFrameMenu, ActionListener { case ACTION_SAVE: { SWF swf = mainFrame.panel.getCurrentSwf(); if (swf != null) { - SWFNode snode = ((TagTreeModel) mainFrame.panel.tagTree.getModel()).getSwfNode(swf); boolean saved = false; - if (snode.binaryData != null) { + if (swf.binaryData != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { swf.saveTo(baos); - snode.binaryData.binaryData = baos.toByteArray(); - snode.binaryData.setModified(true); + swf.binaryData.binaryData = baos.toByteArray(); + swf.binaryData.setModified(true); saved = true; } catch (IOException ex) { Logger.getLogger(MainFrameClassicMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex); diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java index c34d4bd02..b43a9484d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java @@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.console.ContextMenuTools; import com.jpexs.decompiler.flash.gui.helpers.CheckResources; -import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.helpers.Cache; import com.jpexs.helpers.utf8.Utf8Helper; @@ -392,43 +391,38 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { } private RibbonTask createToolsRibbonTask() { - - + JRibbonBand debuggerBand = new JRibbonBand(translate("menu.debugger"), null); debuggerBand.setResizePolicies(getResizePolicies(debuggerBand)); - - debuggerSwitchCommandButton = new JCommandToggleButton(translate("menu.debugger.switch"),View.getResizableIcon("debugger32")); + + debuggerSwitchCommandButton = new JCommandToggleButton(translate("menu.debugger.switch"), View.getResizableIcon("debugger32")); assignListener(debuggerSwitchCommandButton, ACTION_DEBUGGER_SWITCH); - + //debuggerDetachCommandButton = new JCommandButton("Detach debugger",View.getResizableIcon("debuggerremove16")); //assignListener(debuggerDetachCommandButton, ACTION_DEBUGGER_DETACH); - debuggerReplaceTraceCommandButton = new JCommandButton(translate("menu.debugger.replacetrace"), View.getResizableIcon("debuggerreplace16")); assignListener(debuggerReplaceTraceCommandButton, ACTION_DEBUGGER_REPLACE_TRACE); - + debuggerLogCommandButton = new JCommandButton(translate("menu.debugger.showlog"), View.getResizableIcon("debuggerlog16")); assignListener(debuggerLogCommandButton, ACTION_DEBUGGER_LOG); - + debuggerSwitchGroup = new CommandToggleButtonGroup(); debuggerSwitchGroup.add(debuggerSwitchCommandButton); - - debuggerSwitchCommandButton.setEnabled(false); - - debuggerReplaceTraceCommandButton.setEnabled(false); - - debuggerBand.addCommandButton(debuggerSwitchCommandButton, RibbonElementPriority.TOP); - debuggerBand.addCommandButton(debuggerReplaceTraceCommandButton, RibbonElementPriority.MEDIUM); - debuggerBand.addCommandButton(debuggerLogCommandButton, RibbonElementPriority.MEDIUM); - - - - //----------------------------------------- TOOLS ----------------------------------- + debuggerSwitchCommandButton.setEnabled(false); + + debuggerReplaceTraceCommandButton.setEnabled(false); + + debuggerBand.addCommandButton(debuggerSwitchCommandButton, RibbonElementPriority.TOP); + debuggerBand.addCommandButton(debuggerReplaceTraceCommandButton, RibbonElementPriority.MEDIUM); + debuggerBand.addCommandButton(debuggerLogCommandButton, RibbonElementPriority.MEDIUM); + + //----------------------------------------- TOOLS ----------------------------------- JRibbonBand toolsBand = new JRibbonBand(translate("menu.tools"), null); toolsBand.setResizePolicies(getResizePolicies(toolsBand)); searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.search")), View.getResizableIcon("search32")); - assignListener(searchCommandButton, ACTION_SEARCH); + assignListener(searchCommandButton, ACTION_SEARCH); timeLineToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32")); assignListener(timeLineToggleButton, ACTION_TIMELINE); @@ -636,7 +630,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { boolean swfLoaded = swf != null; boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty(); boolean hasDebugger = hasAbc && Main.hasDebugger(swf); - + exportAllMenu.setEnabled(swfLoaded); exportFlaMenu.setEnabled(swfLoaded); exportSelMenu.setEnabled(swfLoaded); @@ -668,7 +662,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { //debuggerSwitchCommandButton. //debuggerDetachCommandButton.setEnabled(hasDebugger); debuggerReplaceTraceCommandButton.setEnabled(hasAbc && hasDebugger); - + } private boolean saveAs(SWF swf, SaveFileMode mode) { @@ -684,24 +678,24 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { @Override public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { - case ACTION_DEBUGGER_SWITCH: - if(debuggerSwitchGroup.getSelected()==null || View.showConfirmDialog(mainFrame, translate("message.debugger"), translate("dialog.message.title"),JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE, Configuration.displayDebuggerInfo,JOptionPane.OK_OPTION)==JOptionPane.OK_OPTION){ - Main.switchDebugger(); - mainFrame.panel.refreshDecompiled(); - }else{ - if(debuggerSwitchGroup.getSelected()==debuggerSwitchCommandButton){ + case ACTION_DEBUGGER_SWITCH: + if (debuggerSwitchGroup.getSelected() == null || View.showConfirmDialog(mainFrame, translate("message.debugger"), translate("dialog.message.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, Configuration.displayDebuggerInfo, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) { + Main.switchDebugger(); + mainFrame.panel.refreshDecompiled(); + } else { + if (debuggerSwitchGroup.getSelected() == debuggerSwitchCommandButton) { debuggerSwitchGroup.setSelected(debuggerSwitchCommandButton, false); } } - debuggerReplaceTraceCommandButton.setEnabled(debuggerSwitchGroup.getSelected()==debuggerSwitchCommandButton); - break; + debuggerReplaceTraceCommandButton.setEnabled(debuggerSwitchGroup.getSelected() == debuggerSwitchCommandButton); + break; case ACTION_DEBUGGER_LOG: Main.debuggerShowLog(); break; case ACTION_DEBUGGER_REPLACE_TRACE: - ReplaceTraceDialog rtd = new ReplaceTraceDialog(mainFrame,Configuration.lastDebuggerReplaceFunction.get()); + ReplaceTraceDialog rtd = new ReplaceTraceDialog(mainFrame, Configuration.lastDebuggerReplaceFunction.get()); rtd.setVisible(true); - if(rtd.getValue()!=null){ + if (rtd.getValue() != null) { Main.replaceTraceCalls(rtd.getValue()); mainFrame.panel.refreshDecompiled(); Configuration.lastDebuggerReplaceFunction.set(rtd.getValue()); @@ -862,14 +856,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { case ACTION_SAVE: { SWF swf = mainFrame.panel.getCurrentSwf(); if (swf != null) { - SWFNode snode = ((TagTreeModel) mainFrame.panel.tagTree.getModel()).getSwfNode(swf); boolean saved = false; - if (snode.binaryData != null) { + if (swf.binaryData != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { swf.saveTo(baos); - snode.binaryData.binaryData = baos.toByteArray(); - snode.binaryData.setModified(true); + swf.binaryData.binaryData = baos.toByteArray(); + swf.binaryData.setModified(true); saved = true; } catch (IOException ex) { Logger.getLogger(MainFrameRibbonMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 181fb46f0..7fe44190a 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFBundle; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.RenameType; import com.jpexs.decompiler.flash.abc.ScriptPack; @@ -45,6 +46,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode; import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode; import com.jpexs.decompiler.flash.exporters.modes.TextExportMode; +import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter; import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings; import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings; import com.jpexs.decompiler.flash.exporters.settings.FramesExportSettings; @@ -57,16 +59,14 @@ import com.jpexs.decompiler.flash.exporters.settings.TextExportSettings; import com.jpexs.decompiler.flash.gui.abc.ABCPanel; import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog; -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; import com.jpexs.decompiler.flash.gui.action.ActionPanel; import com.jpexs.decompiler.flash.gui.dumpview.DumpTree; import com.jpexs.decompiler.flash.gui.dumpview.DumpTreeModel; import com.jpexs.decompiler.flash.gui.dumpview.DumpViewPanel; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; +import com.jpexs.decompiler.flash.gui.tagtree.TagTree; +import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel; import com.jpexs.decompiler.flash.gui.timeline.TimelineViewPanel; -import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode; -import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; -import com.jpexs.decompiler.flash.gui.treenodes.StringNode; import com.jpexs.decompiler.flash.helpers.Freed; import com.jpexs.decompiler.flash.importers.BinaryDataImporter; import com.jpexs.decompiler.flash.importers.ImageImporter; @@ -116,17 +116,13 @@ import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.TagScript; import com.jpexs.decompiler.flash.timeline.Timeline; import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; +import com.jpexs.decompiler.flash.treeitems.FolderItem; +import com.jpexs.decompiler.flash.treeitems.HeaderItem; import com.jpexs.decompiler.flash.treeitems.SWFList; -import com.jpexs.decompiler.flash.treeitems.StringItem; 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.HeaderNode; -import com.jpexs.decompiler.flash.treenodes.TagNode; -import com.jpexs.decompiler.flash.treenodes.TreeNode; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.sound.SoundFormat; @@ -258,7 +254,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private TreePanelMode treePanelMode; private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); private CancellableWorker setSourceWorker; - public TreeNode oldNode; + public TreeItem oldItem; private SoundTagPlayer soundThread = null; @@ -600,7 +596,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec for (SWF swf : newSwfs) { - tagTree.setModel(new TagTreeModel(mainFrame, swfs)); + tagTree.setModel(new TagTreeModel(swfs)); dumpTree.setModel(new DumpTreeModel(swfs)); if (swf.isAS3) { @@ -695,7 +691,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public void closeAll() { swfs.clear(); - oldNode = null; + oldItem = null; previewPanel.clear(); if (abcPanel != null) { abcPanel.clearSwf(); @@ -719,7 +715,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (actionPanel != null) { actionPanel.clearSource(); } - oldNode = null; + oldItem = null; previewPanel.clear(); updateUi(); refreshTree(); @@ -748,11 +744,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } public void updateClassesList() { - List nodes = getASTreeNodes(tagTree); + List nodes = getASTreeNodes(tagTree); boolean updateNeeded = false; - for (TreeNode n : nodes) { - if (n.getItem() instanceof ClassesListTreeModel) { - ((ClassesListTreeModel) n.getItem()).update(); + for (TreeItem n : nodes) { + if (n instanceof ClassesListTreeModel) { + ((ClassesListTreeModel) n).update(); updateNeeded = true; } } @@ -770,11 +766,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } public void doFilter() { - List nodes = getASTreeNodes(tagTree); + List nodes = getASTreeNodes(tagTree); boolean updateNeeded = false; - for (TreeNode n : nodes) { - if (n.getItem() instanceof ClassesListTreeModel) { - ((ClassesListTreeModel) n.getItem()).setFilter(filterField.getText()); + for (TreeItem n : nodes) { + if (n instanceof ClassesListTreeModel) { + ((ClassesListTreeModel) n).setFilter(filterField.getText()); updateNeeded = true; } } @@ -954,30 +950,30 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } updateClassesList(); reload(true); - getABCPanel().hilightScript(getABCPanel().swf, getABCPanel().decompiledTextArea.getScriptLeaf().getPath().toString()); + getABCPanel().hilightScript(getABCPanel().swf, getABCPanel().decompiledTextArea.getScriptLeaf().getClassPath().toString()); } } } - public List getASTreeNodes(TagTree tree) { - List result = new ArrayList<>(); + public List getASTreeNodes(TagTree tree) { + List result = new ArrayList<>(); TagTreeModel tm = (TagTreeModel) tree.getModel(); if (tm == null) { return result; } - TreeNode root = tm.getRoot(); + TreeItem root = tm.getRoot(); for (int i = 0; i < tm.getChildCount(root); i++) { - // first level node can be SWFNode and SWFBundleNode - TreeNode node = tm.getChild(root, i); - if (node instanceof SWFBundleNode) { + // first level node can be SWF and SWFBundle + TreeItem node = tm.getChild(root, i); + if (node instanceof SWFBundle) { for (int j = 0; j < tm.getChildCount(node); j++) { - // child of SWFBundleNode should be SWFNode - SWFNode swfNode = (SWFNode) tm.getChild(node, j); - result.add(swfNode.scriptsNode); + // child of SWFBundle should be SWF + SWF swfNode = (SWF) tm.getChild(node, j); + result.add(tm.getScriptsNode(swfNode)); } - } else if (node instanceof SWFNode) { - SWFNode swfNode = (SWFNode) tm.getChild(root, i); - result.add(swfNode.scriptsNode); + } else if (node instanceof SWF) { + SWF swfNode = (SWF) tm.getChild(root, i); + result.add(tm.getScriptsNode(swfNode)); } } return result; @@ -991,7 +987,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException { List ret = new ArrayList<>(); - List sel = tagTree.getAllSelected(tagTree); + List sel = tagTree.getAllSelected(tagTree); List allSwfs = new ArrayList<>(); for (SWFList swfList : swfs) { @@ -1008,14 +1004,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec List movies = new ArrayList<>(); List sounds = new ArrayList<>(); List texts = new ArrayList<>(); - List as12scripts = new ArrayList<>(); + List as12scripts = new ArrayList<>(); List binaryData = new ArrayList<>(); Map> frames = new HashMap<>(); List fonts = new ArrayList<>(); SWF swf = allSwfs.get(j); - for (TreeNode d : sel) { - SWF selectedNodeSwf = d.getItem().getSwf(); + for (TreeItem d : sel) { + SWF selectedNodeSwf = d.getSwf(); if (!allSwfs.contains(selectedNodeSwf)) { allSwfs.add(selectedNodeSwf); } @@ -1023,59 +1019,52 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (selectedNodeSwf != swf) { continue; } - if (d instanceof ContainerNode) { - ContainerNode n = (ContainerNode) d; - TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem()); + if (d instanceof ContainerItem) { + ContainerItem n = (ContainerItem) d; + TreeNodeType nodeType = TagTree.getTreeNodeType(n); if (nodeType == TreeNodeType.IMAGE) { - images.add((Tag) n.getItem()); + images.add((Tag) n); } if (nodeType == TreeNodeType.SHAPE) { - shapes.add((Tag) n.getItem()); + shapes.add((Tag) n); } if (nodeType == TreeNodeType.MORPH_SHAPE) { - morphshapes.add((Tag) n.getItem()); + morphshapes.add((Tag) n); } if (nodeType == TreeNodeType.AS) { as12scripts.add(n); } if (nodeType == TreeNodeType.MOVIE) { - movies.add((Tag) n.getItem()); + movies.add((Tag) n); } if (nodeType == TreeNodeType.SOUND) { - sounds.add((Tag) n.getItem()); + sounds.add((Tag) n); } if (nodeType == TreeNodeType.BINARY_DATA) { - binaryData.add((Tag) n.getItem()); + binaryData.add((Tag) n); } if (nodeType == TreeNodeType.TEXT) { - texts.add((Tag) n.getItem()); + texts.add((Tag) n); } if (nodeType == TreeNodeType.FONT) { - fonts.add((Tag) n.getItem()); + fonts.add((Tag) n); } } - if (d instanceof FrameNode) { - FrameNode fn = (FrameNode) d; - if (!fn.scriptsNode) { - - FrameNodeItem fni = (FrameNodeItem) d.getItem(); - Timelined parent = fni.getParent(); - int frame = fni.getFrame(); - int parentId = 0; - if (parent instanceof CharacterTag) { - parentId = ((CharacterTag) parent).getCharacterId(); - } - if (!frames.containsKey(parentId)) { - frames.put(parentId, new ArrayList()); - } - frames.get(parentId).add(frame); + if (d instanceof Frame) { + Frame fn = (Frame) d; + Timelined parent = fn.timeline.timelined; + int frame = fn.frame; + int parentId = 0; + if (parent instanceof CharacterTag) { + parentId = ((CharacterTag) parent).getCharacterId(); } + if (!frames.containsKey(parentId)) { + frames.put(parentId, new ArrayList()); + } + frames.get(parentId).add(frame); } - if (d instanceof TreeElement) { - if (((TreeElement) d).isLeaf()) { - TreeElement treeElement = (TreeElement) d; - as3scripts.add((ScriptPack) treeElement.getItem()); - } + if (d instanceof ScriptPack) { + as3scripts.add((ScriptPack) d); } } @@ -1117,14 +1106,25 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } else { TagTreeModel ttm = (TagTreeModel) tagTree.getModel(); - List scriptNodeList = new ArrayList<>(1); - scriptNodeList.add(ttm.getSwfNode(swf).scriptsNode); - ret.addAll(TagNode.exportNodeAS(handler, scriptNodeList, as12scripts, selFile, scriptMode, null)); + List asmsToExport = new ArrayList<>(); + getASMs(ttm, ttm.getScriptsNode(swf), as12scripts, false, asmsToExport); + ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, selFile, asmsToExport, scriptMode, null)); } } return ret; } + private static void getASMs(TagTreeModel ttm, TreeItem node, List nodesToExport, boolean exportAll, List asmsToExport) throws IOException { + boolean exportNode = nodesToExport.contains(node); + if (node instanceof ASMSource && (exportAll || exportNode)) { + asmsToExport.add((ASMSource) node); + } + int childCount = ttm.getChildCount(node); + for (int i = 0; i < childCount; i++) { + getASMs(ttm, ttm.getChild(node, i), nodesToExport, exportAll || exportNode, asmsToExport); + } + } + public SWFList getCurrentSwfList() { SWF swf = getCurrentSwf(); if (swf == null) { @@ -1140,16 +1140,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } if (treePanelMode == TreePanelMode.TAG_TREE) { - TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); + TreeItem treeNode = (TreeItem) tagTree.getLastSelectedPathComponent(); if (treeNode == null) { return swfs.get(0).get(0); } - if (treeNode instanceof SWFBundleNode) { + if (treeNode instanceof SWFBundle) { return null; } - return treeNode.getItem().getSwf(); + return treeNode.getSwf(); } else if (treePanelMode == TreePanelMode.DUMP_TREE) { DumpInfo dumpInfo = (DumpInfo) dumpTree.getLastSelectedPathComponent(); @@ -1392,7 +1392,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec for (int i = FLAVersion.values().length - 1; i >= 0; i--) { final FLAVersion v = FLAVersion.values()[i]; if (!swf.isAS3 && v.minASVersion() > 2) { - //This version does not support AS1/2 + // This version does not support AS1/2 } else { versions.add(v); FileFilter f = new FileFilter() { @@ -1640,7 +1640,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public void export(final boolean onlySel) { final SWF swf = getCurrentSwf(); - List sel = tagTree.getSelection(swf); + List sel = tagTree.getSelection(swf); if (!onlySel) { sel = null; } else { @@ -1882,7 +1882,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec showCard(CARDEMPTYPANEL); TreeItem treeItem = tagTree.getCurrentTreeItem(); DumpInfo dumpInfo = (DumpInfo) dumpTree.getLastSelectedPathComponent(); - View.refreshTree(tagTree, new TagTreeModel(mainFrame, swfs)); + View.refreshTree(tagTree, new TagTreeModel(swfs)); View.refreshTree(dumpTree, new DumpTreeModel(swfs)); if (treeItem != null) { setTagTreeSelectedNode(treeItem); @@ -1890,14 +1890,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (dumpInfo != null) { setDumpTreeSelectedNode(dumpInfo); } + + reload(true); } - public void refreshDecompiled() { + public void refreshDecompiled() { clearCache(); if (abcPanel != null) { abcPanel.reload(); } - reload(true); + reload(true); updateClassesList(); } @@ -1909,7 +1911,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec String fontName = font.getSwf().sourceFontNamesMap.get(font.getFontId()); if (fontName == null) { fontName = font.getFontName(); - } + } Font f = FontTag.installedFontsByName.get(fontName); if (f == null || !f.canDisplay(character)) { View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); @@ -2113,8 +2115,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec reload(false); return; } - TreeNode treeNode = (TreeNode) e.getPath().getLastPathComponent(); - TreeItem treeItem = treeNode.getItem(); + TreeItem treeItem = (TreeItem) e.getPath().getLastPathComponent(); if (!(treeItem instanceof SWFList)) { SWF swf = treeItem.getSwf(); if (swfs.isEmpty()) { @@ -2214,7 +2215,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec showCard(CARDDUMPVIEW); } - public void loadFromBinaryTag(final TagNode node) { + public void loadFromBinaryTag(final DefineBinaryDataTag binaryDataTag) { if (Main.loadingDialog == null || Main.loadingDialog.getOwner() == null) { Main.loadingDialog = new LoadingDialog(mainFrame == null ? null : mainFrame.getWindow()); @@ -2226,7 +2227,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec @Override public void run() { try { - SWF bswf = new SWF(new ByteArrayInputStream(((DefineBinaryDataTag) node.getItem()).binaryData), new ProgressListener() { + SWF bswf = new SWF(new ByteArrayInputStream(binaryDataTag.binaryData), new ProgressListener() { @Override public void progress(int p) { @@ -2234,9 +2235,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } }, Configuration.parallelSpeedUp.get()); bswf.fileTitle = "(SWF Data)"; - SWFNode snode = ((TagTreeModel) tagTree.getModel()).createSwfNode(bswf); - snode.binaryData = (DefineBinaryDataTag) node.getItem(); - node.subNodes.add(snode); + binaryDataTag.innerSwf = bswf; } catch (IOException | InterruptedException ex) { //ignore } @@ -2254,18 +2253,22 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return; } - TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); - if (treeNode == null) { + TreeItem treeItem = (TreeItem) tagTree.getLastSelectedPathComponent(); + if (treeItem == null) { return; } - if (!forceReload && (treeNode == oldNode)) { + if (!forceReload && (treeItem == oldItem)) { return; } - oldNode = treeNode; + oldItem = treeItem; - TreeItem tagObj = treeNode.getItem(); + // show the preview of the tag when the user clicks to the tagname inside the scripts node, too + // this is a little bit inconsistent, beacuse the frames (FrameScript) are not shown + if (treeItem instanceof TagScript) { + treeItem = ((TagScript) treeItem).getTag(); + } if (flashPanel != null) { //flashPanel.specialPlayback = false; @@ -2275,8 +2278,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec soundThread.pause(); } stopFlashPlayer(); - if (tagObj instanceof ScriptPack) { - final ScriptPack scriptLeaf = (ScriptPack) tagObj; + if (treeItem instanceof ScriptPack) { + final ScriptPack scriptLeaf = (ScriptPack) treeItem; final List abcList = scriptLeaf.abc.swf.abcList; if (setSourceWorker != null) { setSourceWorker.cancel(true); @@ -2338,15 +2341,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.setImageReplaceButtonVisible(false); - if (treeNode instanceof HeaderNode) { + if (treeItem instanceof HeaderItem) { showCard(CARDHEADER); - headerPanel.load(((HeaderNode) treeNode).getItem().getSwf()); - } else if (treeNode instanceof StringNode) { + headerPanel.load(((HeaderItem) treeItem).getSwf()); + } else if (treeItem instanceof FolderItem) { showCard(CARDFOLDERPREVIEWPANEL); - showFolderPreview(treeNode); - } else if (treeNode instanceof SWFNode) { - SWFNode swfNode = (SWFNode) treeNode; - SWF swf = swfNode.getItem(); + showFolderPreview(treeItem); + } else if (treeItem instanceof SWF) { + SWF swf = (SWF) treeItem; showCard(CARDPREVIEWPANEL); if (isInternalFlashViewerSelected()) { previewPanel.showImagePanel(swf, swf, -1); @@ -2357,25 +2359,25 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.showSwf(swf); } } - } else if (tagObj instanceof DefineBinaryDataTag) { - DefineBinaryDataTag binaryTag = (DefineBinaryDataTag) tagObj; + } else if (treeItem instanceof DefineBinaryDataTag) { + DefineBinaryDataTag binaryTag = (DefineBinaryDataTag) treeItem; showCard(CARDPREVIEWPANEL); - previewPanel.showBinaryPanel(binaryTag.binaryData, (TagNode) treeNode); - } else if (tagObj instanceof ASMSource) { + previewPanel.showBinaryPanel(binaryTag.binaryData, binaryTag); + } else if (treeItem instanceof ASMSource) { ensureActionPanel(); showCard(CARDACTIONSCRIPTPANEL); - getActionPanel().setSource((ASMSource) tagObj, !forceReload); - } else if (tagObj instanceof ImageTag) { - ImageTag imageTag = (ImageTag) tagObj; + getActionPanel().setSource((ASMSource) treeItem, !forceReload); + } else if (treeItem instanceof ImageTag) { + ImageTag imageTag = (ImageTag) treeItem; previewPanel.setImageReplaceButtonVisible(imageTag.importSupported()); showCard(CARDPREVIEWPANEL); previewPanel.showImagePanel(imageTag.getImage()); - } else if ((tagObj instanceof DrawableTag) && (!(tagObj instanceof TextTag)) && (!(tagObj instanceof FontTag)) && (isInternalFlashViewerSelected())) { - final Tag tag = (Tag) tagObj; + } else if ((treeItem instanceof DrawableTag) && (!(treeItem instanceof TextTag)) && (!(treeItem instanceof FontTag)) && (isInternalFlashViewerSelected())) { + final Tag tag = (Tag) treeItem; showCard(CARDPREVIEWPANEL); DrawableTag d = (DrawableTag) tag; Timelined timelined; - if (tagObj instanceof Timelined && !(tagObj instanceof ButtonTag)) { + if (treeItem instanceof Timelined && !(treeItem instanceof ButtonTag)) { timelined = (Timelined) tag; } else { timelined = makeTimelined(tag); @@ -2383,56 +2385,56 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.setParametersPanelVisible(false); previewPanel.showImagePanel(timelined, tag.getSwf(), -1); - } else if ((tagObj instanceof FontTag) && (isInternalFlashViewerSelected())) { - FontTag fontTag = (FontTag) tagObj; + } else if ((treeItem instanceof FontTag) && (isInternalFlashViewerSelected())) { + FontTag fontTag = (FontTag) treeItem; showCard(CARDPREVIEWPANEL); showFontTag(fontTag); - } else if ((tagObj instanceof TextTag) && (isInternalFlashViewerSelected())) { - TextTag textTag = (TextTag) tagObj; + } else if ((treeItem instanceof TextTag) && (isInternalFlashViewerSelected())) { + TextTag textTag = (TextTag) treeItem; showCard(CARDPREVIEWPANEL); showTextTag(textTag); - } else if (tagObj instanceof FrameNodeItem && ((FrameNodeItem) tagObj).isDisplayed() && (isInternalFlashViewerSelected())) { + } else if (treeItem instanceof Frame && isInternalFlashViewerSelected()) { showCard(CARDPREVIEWPANEL); - FrameNodeItem fn = (FrameNodeItem) tagObj; + Frame fn = (Frame) treeItem; SWF swf = fn.getSwf(); List controlTags = swf.tags; int containerId = 0; RECT rect = swf.displayRect; int totalFrameCount = swf.frameCount; Timelined timelined = swf; - if (fn.getParent() instanceof DefineSpriteTag) { - DefineSpriteTag parentSprite = (DefineSpriteTag) fn.getParent(); + if (fn.timeline.timelined instanceof DefineSpriteTag) { + DefineSpriteTag parentSprite = (DefineSpriteTag) fn.timeline.timelined; controlTags = parentSprite.subTags; containerId = parentSprite.spriteId; rect = parentSprite.getRect(new HashSet()); totalFrameCount = parentSprite.frameCount; timelined = parentSprite; } - previewPanel.showImagePanel(timelined, swf, fn.getFrame()); - } else if ((tagObj instanceof SoundTag)) { //&& isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) { + previewPanel.showImagePanel(timelined, swf, fn.frame); + } else if ((treeItem instanceof SoundTag)) { //&& isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) { showCard(CARDPREVIEWPANEL); previewPanel.showImagePanel(new SerializableImage(View.loadImage("sound32"))); - previewPanel.setImageReplaceButtonVisible(tagObj instanceof DefineSoundTag); + previewPanel.setImageReplaceButtonVisible(treeItem instanceof DefineSoundTag); try { - soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE); + soundThread = new SoundTagPlayer((SoundTag) treeItem, Integer.MAX_VALUE); previewPanel.setMedia(soundThread); soundThread.play(); } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) { logger.log(Level.SEVERE, null, ex); } - } else if (((tagObj instanceof FrameNodeItem) && ((FrameNodeItem) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag) || (tagObj instanceof SoundStreamHeadTypeTag)) { + } else if ((treeItem instanceof Frame) || ((treeItem instanceof CharacterTag) || (treeItem instanceof FontTag)) && (treeItem instanceof Tag) || (treeItem instanceof SoundStreamHeadTypeTag)) { showCard(CARDPREVIEWPANEL); - previewPanel.createAndShowTempSwf(tagObj); + previewPanel.createAndShowTempSwf(treeItem); - if (tagObj instanceof TextTag) { - showTextTag((TextTag) tagObj); - } else if (tagObj instanceof FontTag) { - showFontTag((FontTag) tagObj); + if (treeItem instanceof TextTag) { + showTextTag((TextTag) treeItem); + } else if (treeItem instanceof FontTag) { + showFontTag((FontTag) treeItem); } else { previewPanel.setParametersPanelVisible(false); } - } else if (tagObj instanceof Tag) { - showGenericTag((Tag) tagObj); + } else if (treeItem instanceof Tag) { + showGenericTag((Tag) treeItem); } else { showCard(CARDEMPTYPANEL); } @@ -2454,10 +2456,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.showTextPanel(textTag); } - private void showFolderPreview(TreeNode treeNode) { + private void showFolderPreview(TreeItem treeNode) { folderPreviewPanel.removeAll(); - StringNode stringNode = (StringNode) treeNode; - StringItem item = stringNode.getItem(); + FolderItem item = (FolderItem) treeNode; String folderName = item.getName(); SWF swf = item.swf; JPanel panel = folderPreviewPanel; @@ -2513,10 +2514,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } break; case TagTreeModel.FOLDER_FRAMES: - for (TreeNode subNode : treeNode.subNodes) { - FrameNode frameNode = (FrameNode) subNode; - FrameNodeItem fn = frameNode.getItem(); - Component c = PreviewImage.createFolderPreviewImage(this, fn); + for (Frame frame : swf.getTimeline().getFrames()) { + Component c = PreviewImage.createFolderPreviewImage(this, frame); if (c != null) { panel.add(c); } @@ -2587,47 +2586,42 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (tim != null) { return tim; } - tim = new Timeline(tag.getSwf(), new ArrayList(), ((CharacterTag) tag).getCharacterId(), getRect(new HashSet())); + tim = new Timeline(tag.getSwf(), null, new ArrayList(), ((CharacterTag) tag).getCharacterId(), getRect(new HashSet())); if (tag instanceof MorphShapeTag) { tim.frameRate = MORPH_SHAPE_ANIMATION_FRAME_RATE; int framesCnt = tim.frameRate * MORPH_SHAPE_ANIMATION_LENGTH; for (int i = 0; i < framesCnt; i++) { - Frame f = new Frame(tim); + Frame f = new Frame(tim, i); DepthState ds = new DepthState(tag.getSwf(), f); ds.characterId = ((CharacterTag) tag).getCharacterId(); ds.matrix = new MATRIX(); ds.ratio = i * 65535 / framesCnt; f.layers.put(1, ds); - tim.frames.add(f); + tim.getFrames().add(f); } } else if (tag instanceof FontTag) { int pageCount = PreviewPanel.getFontPageCount((FontTag) tag); for (int i = 0; i < pageCount; i++) { - Frame f = new Frame(tim); + Frame f = new Frame(tim, i); DepthState ds = new DepthState(tag.getSwf(), f); ds.characterId = ((CharacterTag) tag).getCharacterId(); ds.matrix = new MATRIX(); ds.time = i; f.layers.put(1, ds); - tim.frames.add(f); + tim.getFrames().add(f); } } else { - Frame f = new Frame(tim); + Frame f = new Frame(tim, 0); DepthState ds = new DepthState(tag.getSwf(), f); ds.characterId = ((CharacterTag) tag).getCharacterId(); ds.matrix = new MATRIX(); f.layers.put(1, ds); - tim.frames.add(f); + tim.getFrames().add(f); } tim.displayRect = getRect(new HashSet()); return tim; } - @Override - public void resetTimeline() { - tim = null; - } - @Override public RECT getRect(Set added) { BoundedTag bt = (BoundedTag) tag; diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewImage.java b/src/com/jpexs/decompiler/flash/gui/PreviewImage.java index ad7cfcc46..5f34f9017 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewImage.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewImage.java @@ -24,7 +24,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; +import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.RECT; @@ -173,10 +173,10 @@ public class PreviewImage extends JPanel { int height = 0; SerializableImage imgSrc = null; Matrix m = new Matrix(); - if (treeItem instanceof FrameNodeItem) { - FrameNodeItem fn = (FrameNodeItem) treeItem; + if (treeItem instanceof Frame) { + Frame fn = (Frame) treeItem; RECT rect = swf.displayRect; - imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame(), 0, null, 0, rect, new Matrix(), new ColorTransform(), null, true, 1.0); + imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.frame, 0, null, 0, rect, new Matrix(), new ColorTransform(), null, true, 1.0); width = (imgSrc.getWidth()); height = (imgSrc.getHeight()); } else if (treeItem instanceof ImageTag) { diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index e83ee4d04..be1237aeb 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import com.jpexs.decompiler.flash.gui.player.MediaDisplay; import com.jpexs.decompiler.flash.gui.player.PlayerControls; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineBitsTag; import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; @@ -51,10 +52,9 @@ import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.TagNode; import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; @@ -427,9 +427,9 @@ public class PreviewPanel extends JSplitPane implements ActionListener { fontPanel.clear(); } - public void showBinaryPanel(byte[] data, TagNode node) { + public void showBinaryPanel(byte[] data, DefineBinaryDataTag binaryDataTag) { showCardLeft(BINARY_TAG_CARD); - binaryPanel.setBinaryData(data, node); + binaryPanel.setBinaryData(data, binaryDataTag); parametersPanel.setVisible(false); } @@ -470,10 +470,10 @@ public class PreviewPanel extends JSplitPane implements ActionListener { backgroundColor = View.DEFAULT_BACKGROUND_COLOR; } - if (tagObj instanceof FrameNodeItem) { - FrameNodeItem fn = (FrameNodeItem) tagObj; + if (tagObj instanceof Frame) { + Frame fn = (Frame) tagObj; swf = fn.getSwf(); - if (fn.getParent() == swf) { + if (fn.timeline.timelined == swf) { for (Tag t : swf.tags) { if (t instanceof SetBackgroundColorTag) { backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); @@ -525,10 +525,10 @@ public class PreviewPanel extends JSplitPane implements ActionListener { */ new SetBackgroundColorTag(swf, new RGB(backgroundColor)).writeTag(sos2); - if (tagObj instanceof FrameNodeItem) { - FrameNodeItem fn = (FrameNodeItem) tagObj; - Timelined parent = fn.getParent(); - List subs = parent.getTimeline().tags; + if (tagObj instanceof Frame) { + Frame fn = (Frame) tagObj; + Timelined parent = fn.timeline.timelined; + List subs = fn.timeline.tags; List doneCharacters = new ArrayList<>(); int frameCnt = 0; for (ContainerItem item : subs) { @@ -536,7 +536,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener { frameCnt++; continue; } - if (frameCnt > fn.getFrame()) { + if (frameCnt > fn.frame) { break; } @@ -878,7 +878,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener { SWF.clearImageCache(); Tag tag = genericTagPanel.getTag(); tag.getSwf().updateCharacters(); - tag.getTimelined().resetTimeline(); + tag.getTimelined().getTimeline().reset(); mainPanel.refreshTree(); mainPanel.setTagTreeSelectedNode(tag); editButton.setVisible(true); diff --git a/src/com/jpexs/decompiler/flash/gui/ReplaceTraceDialog.java b/src/com/jpexs/decompiler/flash/gui/ReplaceTraceDialog.java index 99c639e52..4287aa760 100644 --- a/src/com/jpexs/decompiler/flash/gui/ReplaceTraceDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ReplaceTraceDialog.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.gui; import java.awt.Container; @@ -22,7 +21,6 @@ import java.awt.FlowLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Arrays; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; @@ -34,19 +32,18 @@ import javax.swing.JRadioButton; * @author JPEXS */ public class ReplaceTraceDialog extends AppDialog { - + private JRadioButton debugAlertRadio; private JRadioButton debugConsoleRadio; private JRadioButton debugSocketRadio; private String value = null; - - private void setValue(String val){ - if(val == null){ + private void setValue(String val) { + if (val == null) { return; } - switch(val){ + switch (val) { case "debugAlert": debugAlertRadio.setSelected(true); break; @@ -56,17 +53,17 @@ public class ReplaceTraceDialog extends AppDialog { case "debugSocket": debugSocketRadio.setSelected(true); break; - } + } } - + public String getValue() { return value; } - - public ReplaceTraceDialog(Window owner,String defaultVal) { - super(owner); + + public ReplaceTraceDialog(Window owner, String defaultVal) { + super(owner); setTitle(translate("dialog.title")); - Container cnt=getContentPane(); + Container cnt = getContentPane(); cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS)); debugAlertRadio = new JRadioButton(translate("function.debugAlert")); debugAlertRadio.setAlignmentX(0); @@ -74,39 +71,37 @@ public class ReplaceTraceDialog extends AppDialog { debugConsoleRadio.setAlignmentX(0); debugSocketRadio = new JRadioButton(translate("function.debugSocket")); debugSocketRadio.setAlignmentX(0); - + debugAlertRadio.setSelected(true); - + ButtonGroup bg = new ButtonGroup(); bg.add(debugAlertRadio); bg.add(debugConsoleRadio); bg.add(debugSocketRadio); - - - + cnt.add(debugAlertRadio); cnt.add(debugConsoleRadio); cnt.add(debugSocketRadio); - + JPanel buttonsPanel = new JPanel(new FlowLayout()); - JButton okButton=new JButton(AppStrings.translate("button.ok")); + JButton okButton = new JButton(AppStrings.translate("button.ok")); okButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if(debugAlertRadio.isSelected()){ + if (debugAlertRadio.isSelected()) { value = "debugAlert"; } - if(debugConsoleRadio.isSelected()){ + if (debugConsoleRadio.isSelected()) { value = "debugConsole"; } - if(debugSocketRadio.isSelected()){ + if (debugSocketRadio.isSelected()) { value = "debugSocket"; } setVisible(false); } }); - JButton cancelButton=new JButton(AppStrings.translate("button.cancel")); + JButton cancelButton = new JButton(AppStrings.translate("button.cancel")); cancelButton.addActionListener(new ActionListener() { @Override @@ -116,7 +111,7 @@ public class ReplaceTraceDialog extends AppDialog { } }); buttonsPanel.add(okButton); - buttonsPanel.add(cancelButton); + buttonsPanel.add(cancelButton); buttonsPanel.setAlignmentX(0); add(buttonsPanel); setModalityType(DEFAULT_MODALITY_TYPE); @@ -125,5 +120,5 @@ public class ReplaceTraceDialog extends AppDialog { View.centerScreen(this); setValue(defaultVal); } - + } diff --git a/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java deleted file mode 100644 index 425a083c5..000000000 --- a/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; -import com.jpexs.decompiler.flash.gui.abc.treenodes.ClassesListNode; -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; -import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode; -import com.jpexs.decompiler.flash.gui.treenodes.SWFContainerNode; -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.ShowFrameTag; -import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; -import com.jpexs.decompiler.flash.timeline.Timeline; -import com.jpexs.decompiler.flash.timeline.Timelined; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; -import com.jpexs.decompiler.flash.treeitems.HeaderItem; -import com.jpexs.decompiler.flash.treeitems.SWFList; -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.FrameNode; -import com.jpexs.decompiler.flash.treenodes.HeaderNode; -import com.jpexs.decompiler.flash.treenodes.TagNode; -import com.jpexs.decompiler.flash.treenodes.TreeNode; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.swing.event.TreeModelListener; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; - -public class TagTreeModel implements TreeModel { - - public static final String FOLDER_TEXTS = "texts"; - public static final String FOLDER_IMAGES = "images"; - public static final String FOLDER_MOVIES = "movies"; - public static final String FOLDER_SOUNDS = "sounds"; - public static final String FOLDER_BINARY_DATA = "binaryData"; - public static final String FOLDER_FONTS = "fonts"; - public static final String FOLDER_SPRITES = "sprites"; - public static final String FOLDER_SHAPES = "shapes"; - public static final String FOLDER_MORPHSHAPES = "morphshapes"; - public static final String FOLDER_BUTTONS = "buttons"; - public static final String FOLDER_FRAMES = "frames"; - public static final String FOLDER_OTHERS = "others"; - public static final String FOLDER_SCRIPTS = "scripts"; - private final TagTreeRoot root = new TagTreeRoot(); - private final List swfs; - private final Map swfToSwfNode; - private final MainFrame mainFrame; - - public TagTreeModel(MainFrame mainFrame, List swfs) { - this.mainFrame = mainFrame; - this.swfs = new ArrayList<>(); - swfToSwfNode = new HashMap<>(); - for (SWFList swfList : swfs) { - if (swfList.isBundle) { - SWFBundleNode bundleNode = new SWFBundleNode(swfList, swfList.name); - for (SWF swf : swfList) { - bundleNode.swfs.add(createSwfNode(swf)); - } - this.swfs.add(bundleNode); - } else { - SWF swf = swfList.get(0); - this.swfs.add(createSwfNode(swf)); - } - } - } - - public SWFNode createSwfNode(SWF swf) { - SWFNode swfNode = createTagList(swf.tags, swf); - swfToSwfNode.put(swf, swfNode); - return swfNode; - } - - private String translate(String key) { - return mainFrame.translate(key); - } - - private List getSoundStreams(DefineSpriteTag sprite) { - List ret = new ArrayList<>(); - for (Tag t : sprite.subTags) { - if (t instanceof SoundStreamHeadTypeTag) { - ret.add(new TagNode(t)); - } - } - return ret; - } - - private SWFNode createTagList(List list, SWF swf) { - ClassesListTreeModel classTreeModel = new ClassesListTreeModel(swf); - SWFNode swfNode = new SWFNode(swf, swf.getShortFileName()); - - boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty(); - - List nodeList = new ArrayList<>(); - 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, swf); - List actionScriptTags = new ArrayList<>(); - SWF.getTagsFromTreeNodes(actionScript, actionScriptTags); - - for (Tag t : list) { - TreeNodeType ttype = TagTree.getTreeNodeType(t); - switch (ttype) { - case SHAPE: - shapes.add(new TagNode(t)); - break; - case MORPH_SHAPE: - morphShapes.add(new TagNode(t)); - break; - case SPRITE: - sprites.add(new TagNode(t)); - sounds.addAll(getSoundStreams((DefineSpriteTag) 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: - TagNode bt; - binaryData.add(bt = new TagNode(t)); - break; - default: - if (!actionScriptTags.contains(t) && t.getId() != ShowFrameTag.ID && !ShowFrameTag.isNestedTagType(t.getId())) { - others.add(new TagNode(t)); - } - break; - } - } - - Timeline timeline = swf.getTimeline(); - for (int i = 0; i < timeline.getFrameCount(); i++) { - frames.add(new FrameNode(new FrameNodeItem(swf, i, swf, true), timeline.frames.get(i).innerTags, false)); - } - - for (int i = 0; i < sounds.size(); i++) { - if (sounds.get(i).getItem() instanceof SoundStreamHeadTypeTag) { - List blocks = ((SoundStreamHeadTypeTag) sounds.get(i).getItem()).getBlocks(); - if (blocks.isEmpty()) { - sounds.remove(i); - i--; - } - } - } - - for (TreeNode n : sprites) { - Timelined timelined = n.getItem() instanceof Timelined ? (Timelined) n.getItem() : null; - n.subNodes = createSubTagList(((DefineSpriteTag) n.getItem()).subTags, timelined, swf, actionScriptTags); - } - - StringNode textsNode = new StringNode(new StringItem(translate("node.texts"), FOLDER_TEXTS, swf)); - textsNode.subNodes.addAll(texts); - - StringNode imagesNode = new StringNode(new StringItem(translate("node.images"), FOLDER_IMAGES, swf)); - imagesNode.subNodes.addAll(images); - - StringNode moviesNode = new StringNode(new StringItem(translate("node.movies"), FOLDER_MOVIES, swf)); - moviesNode.subNodes.addAll(movies); - - StringNode soundsNode = new StringNode(new StringItem(translate("node.sounds"), FOLDER_SOUNDS, swf)); - soundsNode.subNodes.addAll(sounds); - - StringNode binaryDataNode = new StringNode(new StringItem(translate("node.binaryData"), FOLDER_BINARY_DATA, swf)); - binaryDataNode.subNodes.addAll(binaryData); - - StringNode fontsNode = new StringNode(new StringItem(translate("node.fonts"), FOLDER_FONTS, swf)); - fontsNode.subNodes.addAll(fonts); - - StringNode spritesNode = new StringNode(new StringItem(translate("node.sprites"), FOLDER_SPRITES, swf)); - spritesNode.subNodes.addAll(sprites); - - StringNode shapesNode = new StringNode(new StringItem(translate("node.shapes"), FOLDER_SHAPES, swf)); - shapesNode.subNodes.addAll(shapes); - - StringNode morphShapesNode = new StringNode(new StringItem(translate("node.morphshapes"), FOLDER_MORPHSHAPES, swf)); - morphShapesNode.subNodes.addAll(morphShapes); - - StringNode buttonsNode = new StringNode(new StringItem(translate("node.buttons"), FOLDER_BUTTONS, swf)); - buttonsNode.subNodes.addAll(buttons); - - StringNode framesNode = new StringNode(new StringItem(translate("node.frames"), FOLDER_FRAMES, swf)); - framesNode.subNodes.addAll(frames); - - StringNode otherNode = new StringNode(new StringItem(translate("node.others"), FOLDER_OTHERS, swf)); - otherNode.subNodes.addAll(others); - - TreeNode actionScriptNode; - if (hasAbc) { - actionScriptNode = new ClassesListNode(classTreeModel); - } else { - actionScriptNode = new StringNode(new StringItem(translate("node.scripts"), FOLDER_SCRIPTS, swf)); - actionScriptNode.subNodes.addAll(actionScript); - } - swfNode.scriptsNode = actionScriptNode; - - nodeList.add(new HeaderNode(new HeaderItem(swf, AppStrings.translate("node.header")))); - - if (!shapesNode.subNodes.isEmpty()) { - nodeList.add(shapesNode); - } - if (!morphShapesNode.subNodes.isEmpty()) { - nodeList.add(morphShapesNode); - } - if (!spritesNode.subNodes.isEmpty()) { - nodeList.add(spritesNode); - } - if (!textsNode.subNodes.isEmpty()) { - nodeList.add(textsNode); - } - if (!imagesNode.subNodes.isEmpty()) { - nodeList.add(imagesNode); - } - if (!moviesNode.subNodes.isEmpty()) { - nodeList.add(moviesNode); - } - if (!soundsNode.subNodes.isEmpty()) { - nodeList.add(soundsNode); - } - if (!buttonsNode.subNodes.isEmpty()) { - nodeList.add(buttonsNode); - } - if (!fontsNode.subNodes.isEmpty()) { - nodeList.add(fontsNode); - } - if (!binaryDataNode.subNodes.isEmpty()) { - nodeList.add(binaryDataNode); - } - if (!framesNode.subNodes.isEmpty()) { - nodeList.add(framesNode); - } - if (!otherNode.subNodes.isEmpty()) { - nodeList.add(otherNode); - } - - if ((!actionScriptNode.subNodes.isEmpty()) || hasAbc) { - nodeList.add(actionScriptNode); - } - - swfNode.list = nodeList; - return swfNode; - } - - private List createSubTagList(List list, Timelined parent, SWF swf, List actionScriptTags) { - List ret = new ArrayList<>(); - List frames = new ArrayList<>(); - List others = new ArrayList<>(); - - for (Tag t : list) { - TreeNodeType ttype = TagTree.getTreeNodeType(t); - switch (ttype) { - default: - if (!actionScriptTags.contains(t) && t.getId() != ShowFrameTag.ID && !ShowFrameTag.isNestedTagType(t.getId())) { - if (!(t instanceof SoundStreamHeadTypeTag)) { - others.add(new TagNode(t)); - } - } - break; - } - } - - Timeline timeline = ((Timelined) parent).getTimeline(); - for (int i = 0; i < timeline.getFrameCount(); i++) { - frames.add(new FrameNode(new FrameNodeItem(swf, i, parent, true), timeline.frames.get(i).innerTags, false)); - } - - ret.addAll(frames); - - if (!others.isEmpty()) { - StringNode otherNode = new StringNode(new StringItem(translate("node.others"), FOLDER_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); - for (int i = 0; i < cnt; i++) { - TreeNode n = getChild(parent, i); - List newPath = new ArrayList<>(); - newPath.addAll(path); - newPath.add(n); - - if (n instanceof TreeElement) { - TreeElement te = (TreeElement) n; - TreeElementItem it = te.getItem(); - if (obj.equals(it)) { - return newPath; - } - } - - if (obj instanceof StringItem && n.getItem() instanceof StringItem) { - // StringItems are always recreated, so compare them by name - StringItem nds = (StringItem) n.getItem(); - StringItem objs = (StringItem) obj; - if (objs.getName().equals(nds.getName())) { - return newPath; - } - } else { - if (obj.equals(n.getItem())) { - return newPath; - } - } - - ret = searchTag(obj, n, newPath); - if (ret != null) { - return ret; - } - } - return ret; - } - - public SWFNode getSwfNode(SWF swf) { - return swfToSwfNode.get(swf); - } - - public TreePath getTagPath(TreeItem obj) { - List path = new ArrayList<>(); - path.add(getRoot()); - path = searchTag(obj, getRoot(), path); - if (path == null) { - return null; - } - TreePath tp = new TreePath(path.toArray(new Object[path.size()])); - return tp; - } - - @Override - public TreeNode getRoot() { - return root; - } - - @Override - public TreeNode getChild(Object parent, int index) { - TreeNode parentNode = (TreeNode) parent; - if (parent instanceof TreeElement) { - return ((TreeElement) parent).getChild(index); - } else { - if (parentNode.getItem() instanceof ClassesListTreeModel) { - ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem(); - return clt.getChild(clt.getRoot(), index); - } - } - if (parent == root) { - return swfs.get(index); - } else if (parent instanceof SWFBundleNode) { - return ((SWFBundleNode) parent).swfs.get(index); - } else if (parent instanceof SWFNode) { - return ((SWFNode) parent).list.get(index); - } - return parentNode.subNodes.get(index); - } - - @Override - public int getChildCount(Object parent) { - TreeNode parentNode = (TreeNode) parent; - if (parent == root) { - return swfs.size(); - } else if (parent instanceof TreeElement) { - return ((TreeElement) parent).getChildCount(); - } else if (parent instanceof SWFBundleNode) { - return ((SWFBundleNode) parent).swfs.size(); - } else if (parent instanceof SWFNode) { - return ((SWFNode) parent).list.size(); - } else { - if (parentNode.getItem() instanceof ClassesListTreeModel) { - ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem(); - return clt.getChildCount(clt.getRoot()); - } - return parentNode.subNodes.size(); - } - } - - @Override - public boolean isLeaf(Object node) { - return (getChildCount(node) == 0); - } - - @Override - public void valueForPathChanged(TreePath path, Object newValue) { - } - - @Override - public int getIndexOfChild(Object parent, Object child) { - TreeNode parentNode = (TreeNode) parent; - if (parent == root) { - return swfs.indexOf(child); - } else if (parent instanceof TreeElement) { - return ((TreeElement) parent).getIndexOfChild((TreeElement) child); - } else if (parent instanceof SWFBundleNode) { - return ((SWFBundleNode) parent).swfs.indexOf(child); - } else if (parent instanceof SWFNode) { - return ((SWFNode) parent).list.indexOf(child); - } else { - if (parentNode.getItem() instanceof ClassesListTreeModel) { - ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem(); - return clt.getIndexOfChild(clt.getRoot(), child); - } - return parentNode.subNodes.indexOf(child); - } - } - - @Override - public void addTreeModelListener(TreeModelListener l) { - } - - @Override - public void removeTreeModelListener(TreeModelListener l) { - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/TreeNodeType.java b/src/com/jpexs/decompiler/flash/gui/TreeNodeType.java index a3bdc59a9..e55094736 100644 --- a/src/com/jpexs/decompiler/flash/gui/TreeNodeType.java +++ b/src/com/jpexs/decompiler/flash/gui/TreeNodeType.java @@ -22,6 +22,7 @@ package com.jpexs.decompiler.flash.gui; */ public enum TreeNodeType { + UNKNOWN, FLASH, FONT, TEXT, @@ -43,5 +44,5 @@ public enum TreeNodeType { BUNDLE_ZIP, BUNDLE_SWC, BUNDLE_BINARY, - HEADER + HEADER, } diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java index 13ec09128..d78bc0e7b 100644 --- a/src/com/jpexs/decompiler/flash/gui/View.java +++ b/src/com/jpexs/decompiler/flash/gui/View.java @@ -376,7 +376,7 @@ public class View { public static int showConfirmDialog(final Component parentComponent, String message, final String title, final int optionType, final int messageTyp, ConfigurationItem showAgainConfig, int defaultOption) { - JLabel warLabel = new JLabel(""+message.replace("\r\n", "
")+""); + JLabel warLabel = new JLabel("" + message.replace("\r\n", "
") + ""); final JPanel warPanel = new JPanel(new BorderLayout()); warPanel.add(warLabel, BorderLayout.CENTER); JCheckBox donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain")); @@ -408,7 +408,7 @@ public class View { JCheckBox donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain")); if (showAgainConfig != null) { - JLabel warLabel = new JLabel(""+message.replace("\r\n", "
")+""); + JLabel warLabel = new JLabel("" + message.replace("\r\n", "
") + ""); final JPanel warPanel = new JPanel(new BorderLayout()); warPanel.add(warLabel, BorderLayout.CENTER); donotShowAgainCheckBox.setSelected(!showAgainConfig.get()); @@ -418,7 +418,7 @@ public class View { return; } } - final Object fmsg=msg; + final Object fmsg = msg; execInEventDispatch(new Runnable() { @Override diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 65b89c88a..c170dbe70 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -45,7 +45,6 @@ import com.jpexs.decompiler.flash.gui.MainPanel; import com.jpexs.decompiler.flash.gui.SearchListener; import com.jpexs.decompiler.flash.gui.SearchPanel; import com.jpexs.decompiler.flash.gui.SearchResultsDialog; -import com.jpexs.decompiler.flash.gui.TagTreeModel; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.abc.tablemodels.DecimalTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.DoubleTableModel; @@ -55,10 +54,11 @@ import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceSetTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.StringTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.UIntTableModel; +import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel; import com.jpexs.decompiler.flash.helpers.Freed; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.treenodes.TreeNode; +import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; @@ -156,10 +156,10 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se if ((txt != null) && (!txt.isEmpty())) { searchPanel.setOptions(ignoreCase, regexp); TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); - TreeNode scriptsNode = ttm.getSwfNode(mainPanel.getCurrentSwf()).scriptsNode; + TreeItem scriptsNode = ttm.getScriptsNode(mainPanel.getCurrentSwf()); final List found = new ArrayList<>(); - if (scriptsNode.getItem() instanceof ClassesListTreeModel) { - ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode.getItem(); + if (scriptsNode instanceof ClassesListTreeModel) { + ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode; List> allpacks = clModel.getList(); final Pattern pat = regexp ? Pattern.compile(txt, ignoreCase ? Pattern.CASE_INSENSITIVE : 0) @@ -320,11 +320,10 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se this.swf = swf; if (swf.abcList.size() > 0) { this.abc = swf.abcList.get(0).getABC(); - } - navigator.setABC(swf.abcList, abc); + } + navigator.setABC(swf.abcList, abc); } } - public void initSplits() { //splitPaneTreeVSNavigator.setDividerLocation(splitPaneTreeVSNavigator.getHeight() / 2); @@ -364,7 +363,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se setLayout(new BorderLayout()); decompiledTextArea = new DecompiledEditorPane(this); - + decompiledTextArea.setLinkHandler(new LinkHandler() { @Override @@ -478,7 +477,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se decompiledTextArea.addKeyListener(cch); decompiledTextArea.addMouseListener(cch); decompiledTextArea.addMouseMotionListener(cch); - + navigator = new TraitsList(this); navPanel = new JPanel(new BorderLayout()); @@ -561,13 +560,13 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se //more than one? display list if (!usages.isEmpty()) { return true; - } - }else{ - return decompiledTextArea.getLocalDeclarationOfPos(pos)!=-1; + } + } else { + return decompiledTextArea.getLocalDeclarationOfPos(pos) != -1; } return false; } - + private void gotoDeclaration(int pos) { int multinameIndex = decompiledTextArea.getMultinameAtPos(pos); if (multinameIndex > -1) { @@ -595,9 +594,9 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se } else if (!usages.isEmpty()) { //one UsageFrame.gotoUsage(ABCPanel.this, usages.get(0)); } - }else{ - int dpos=decompiledTextArea.getLocalDeclarationOfPos(pos); - if(dpos>-1){ + } else { + int dpos = decompiledTextArea.getLocalDeclarationOfPos(pos); + if (dpos > -1) { decompiledTextArea.setCaretPosition(dpos); } } @@ -673,7 +672,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se } @Override - public void itemStateChanged(ItemEvent e) { + public void itemStateChanged(ItemEvent e) { if (e.getSource() == constantTypeList) { int index = ((JComboBox) e.getSource()).getSelectedIndex(); if (index == -1) { @@ -689,9 +688,9 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se public void hilightScript(SWF swf, String name) { TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); - TreeNode scriptsNode = ttm.getSwfNode(swf).scriptsNode; - if (scriptsNode.getItem() instanceof ClassesListTreeModel) { - ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode.getItem(); + TreeItem scriptsNode = ttm.getScriptsNode(swf); + if (scriptsNode instanceof ClassesListTreeModel) { + ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode; ScriptPack pack = null; for (MyEntry item : clModel.getList()) { if (item.getKey().toString().equals(name)) { @@ -805,21 +804,20 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se ScriptPack pack = decompiledTextArea.getScriptLeaf(); int oldIndex = pack.scriptIndex; decompiledTextArea.uncache(pack); - - + try { String oldSp = null; List> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex); if (!packs.isEmpty()) { - oldSp = packs.get(0).getKey().toString(); + oldSp = packs.get(0).getKey().toString(); } - + String as = decompiledTextArea.getText(); abc.replaceSciptPack(pack, as); lastDecompiled = as; mainPanel.updateClassesList(); - - if(oldSp!=null){ + + if (oldSp != null) { hilightScript(swf, oldSp); } //decompiledTextArea.setClassIndex(-1); @@ -831,12 +829,12 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); - View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (CompilationException ex) { abc.script_info.get(oldIndex).delete(abc, false); decompiledTextArea.gotoLine((int) ex.line); decompiledTextArea.markError(); - View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } catch (IOException | InterruptedException ex) { //ignore } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 85de67079..3e88449e8 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -44,8 +44,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretListener { @@ -282,7 +280,6 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi setCaretPosition(lineStart); //requestFocus(); } - public Highlighting getSelectedSpecial() { return Highlighting.search(specialHilights, getCaretPosition()); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java b/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java index 4e78a8a7f..e92156ee9 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 JPEXS, Paolo Cancedda + * Copyright (C) 2010-2014 JPEXS, All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,70 +22,22 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.gui.AppStrings; -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; -import com.jpexs.decompiler.flash.treeitems.TreeElementItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; +import com.jpexs.decompiler.flash.timeline.AS3Package; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import java.util.ArrayList; import java.util.List; +import java.util.StringTokenizer; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; -class ClassIndexVisitor implements TreeVisitor { - - private TreeElement found = null; - private int classIndex = 0; - - public ClassIndexVisitor(int classIndex) { - this.classIndex = classIndex; - } - - @Override - public void onBranch(TreeElement branch) { - Object o = branch.getItem(); - if (o == null) { - return; - } - ScriptPack sc = (ScriptPack) o; - for (Trait t : sc.abc.script_info.get(sc.scriptIndex).traits.traits) { - if (t instanceof TraitClass) { - if (((TraitClass) t).class_info == classIndex) { - found = branch; - return; - } - } - } - } - - @Override - public void onLeaf(TreeElement leaf) { - Object o = leaf.getItem(); - if (o == null) { - return; - } - ScriptPack sc = (ScriptPack) o; - for (Trait t : sc.abc.script_info.get(sc.scriptIndex).traits.traits) { - if (t instanceof TraitClass) { - if (((TraitClass) t).class_info == classIndex) { - found = leaf; - return; - } - } - } - } - - public TreeElement getFound() { - return found; - } -} - -public class ClassesListTreeModel implements TreeModel, TreeElementItem { +public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel { private SWF swf; - private Tree classTree; private List> list; + private AS3Package root; private final List listeners = new ArrayList<>(); public List> getList() { @@ -97,6 +49,8 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { } public ClassesListTreeModel(SWF swf, String filter) { + super(null, null); + root = new AS3Package(null, swf); this.swf = swf; this.list = swf.getAS3Packs(); setFilter(filter); @@ -109,14 +63,16 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { public final void update() { this.list = swf.getAS3Packs(); - TreeModelEvent event = new TreeModelEvent(this, new TreePath(classTree.getRoot())); + TreeModelEvent event = new TreeModelEvent(this, new TreePath(root)); for (TreeModelListener listener : listeners) { listener.treeStructureChanged(event); } } public final void setFilter(String filter) { - classTree = new Tree(); + root.scripts.clear(); + root.subPackages.clear(); + filter = (filter == null || filter.isEmpty()) ? null : filter.toLowerCase(); for (MyEntry item : list) { if (filter != null) { @@ -124,40 +80,80 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { continue; } } - //String nsName = path.contains(".") ? path.substring(path.lastIndexOf(".") + 1) : path; - //String packageName = path.contains(".") ? path.substring(0, path.lastIndexOf(".")) : ""; - classTree.add(item.getKey().className, item.getKey().packageStr, item.getValue()); + + AS3Package pkg = ensurePackage(item.getKey().packageStr); + pkg.scripts.put(item.getKey().className, item.getValue()); } } - public TreeElement getElementByClassIndex(int classIndex) { - ClassIndexVisitor civ = new ClassIndexVisitor(classIndex); - classTree.visit(civ); - return civ.getFound(); + private AS3Package ensurePackage(String packageStr) { + StringTokenizer st = new StringTokenizer(packageStr, "."); + AS3Package parent = root; + while (st.hasMoreTokens()) { + String pathElement = st.nextToken(); + AS3Package pkg = parent.subPackages.get(pathElement); + if (pkg == null) { + pkg = new AS3Package(pathElement, swf); + parent.subPackages.put(pathElement, pkg); + } + + parent = pkg; + } + + return parent; + } + + public ScriptPack getElementByClassIndex(int classIndex) { + return getElementByClassIndexRecursive(root, classIndex); + } + + private ScriptPack getElementByClassIndexRecursive(AS3Package item, int classIndex) { + for (AS3Package pkg : item.subPackages.values()) { + ScriptPack result = getElementByClassIndexRecursive(pkg, classIndex); + if (result != null) { + return result; + } + } + + for (ScriptPack sc : item.scripts.values()) { + for (Trait t : sc.abc.script_info.get(sc.scriptIndex).traits.traits) { + if (t instanceof TraitClass) { + if (((TraitClass) t).class_info == classIndex) { + return sc; + } + } + } + } + + return null; } @Override - public TreeElement getRoot() { - return classTree.getRoot(); + public AS3ClassTreeItem getRoot() { + return root; } @Override - public TreeNode getChild(Object parent, int index) { - TreeElement pte = (TreeElement) parent; - TreeElement te = pte.getChild(index); - return te; + public AS3ClassTreeItem getChild(Object parent, int index) { + AS3Package pkg = (AS3Package) parent; + return pkg.getChild(index); } @Override public int getChildCount(Object parent) { - TreeElement te = (TreeElement) parent; - return te.getChildCount(); + AS3ClassTreeItem parentItem = (AS3ClassTreeItem) parent; + if (parentItem instanceof ScriptPack) { + return 0; + } + + AS3Package pkg = (AS3Package) parentItem; + return pkg.getChildCount(); } @Override public boolean isLeaf(Object node) { - TreeElement te = (TreeElement) node; - return te.isLeaf(); + AS3ClassTreeItem te = (AS3ClassTreeItem) node; + return te instanceof ScriptPack; } @Override @@ -166,9 +162,8 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { @Override public int getIndexOfChild(Object parent, Object child) { - TreeElement te1 = (TreeElement) parent; - TreeElement te2 = (TreeElement) child; - return te1.getIndexOfChild(te2); + AS3Package pkg = (AS3Package) parent; + return pkg.getIndexOfChild((AS3ClassTreeItem) child); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index c42203890..e074b73db 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -36,7 +36,6 @@ import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.helpers.Cache; import java.awt.Point; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; @@ -115,7 +114,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } List allh = new ArrayList<>(); - for (Highlighting h : traitHighlights) { + for (Highlighting h : traitHighlights) { if (h.getPropertyString("index").equals("" + lastTraitIndex)) { for (Highlighting sh : specialHighlights) { if (sh.startPos >= h.startPos && (sh.startPos + sh.len < h.startPos + h.len)) { @@ -223,59 +222,59 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL caretUpdate(null); reset = false; } - public int getMultinameUnderMouseCursor(Point pt) { - return getMultinameAtPos(viewToModel(pt)); + + public int getMultinameUnderMouseCursor(Point pt) { + return getMultinameAtPos(viewToModel(pt)); } - + public int getMultinameUnderCaret() { - return getMultinameAtPos(getCaretPosition()); + return getMultinameAtPos(getCaretPosition()); } - + public int getLocalDeclarationOfPos(int pos) { - Highlighting sh=Highlighting.search(specialHighlights,pos); - Highlighting h=Highlighting.search(highlights,pos); + Highlighting sh = Highlighting.search(specialHighlights, pos); + Highlighting h = Highlighting.search(highlights, pos); Highlighting tm = Highlighting.search(methodHighlights, pos); if (tm == null) { return -1; } - List tms= Highlighting.searchAll(methodHighlights, -1, "index", tm.getPropertyString("index"), -1, -1); - if(h==null){ + List tms = Highlighting.searchAll(methodHighlights, -1, "index", tm.getPropertyString("index"), -1, -1); + if (h == null) { return -1; } //is it already declaration? - if("true".equals(h.getPropertyString("declaration")) || (sh!=null && "true".equals(sh.getPropertyString("declaration")))){ + if ("true".equals(h.getPropertyString("declaration")) || (sh != null && "true".equals(sh.getPropertyString("declaration")))) { return -1; //no jump } - - Map search=h.getProperties(); + + Map search = h.getProperties(); search.remove("index"); search.remove("subtype"); search.remove("offset"); - if(search.isEmpty()){ + if (search.isEmpty()) { return -1; } - search.put("declaration", "true"); - - for(Highlighting tm1:tms) - { - Highlighting rh= Highlighting.search(highlights, search, tm1.startPos, tm1.startPos+tm1.len); - if(rh==null){ - rh=Highlighting.search(specialHighlights, search, tm1.startPos, tm1.startPos+tm1.len); + search.put("declaration", "true"); + + for (Highlighting tm1 : tms) { + Highlighting rh = Highlighting.search(highlights, search, tm1.startPos, tm1.startPos + tm1.len); + if (rh == null) { + rh = Highlighting.search(specialHighlights, search, tm1.startPos, tm1.startPos + tm1.len); } - if(rh!=null){ + if (rh != null) { return rh.startPos; } } - + return -1; } - - public int getMultinameAtPos(int pos) { + + public int getMultinameAtPos(int pos) { Highlighting tm = Highlighting.search(methodHighlights, pos); if (tm == null) { return -1; } - int mi = (int)(long)tm.getPropertyLong("index"); + int mi = (int) (long) tm.getPropertyLong("index"); int bi = abc.findBodyIndex(mi); Highlighting h = Highlighting.search(highlights, pos); if (h != null) { @@ -525,7 +524,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } public void setScript(ScriptPack scriptLeaf, List abcList) { - abcPanel.scriptNameLabel.setText(scriptLeaf.getPath().toString()); + abcPanel.scriptNameLabel.setText(scriptLeaf.getClassPath().toString()); int scriptIndex = scriptLeaf.scriptIndex; ScriptInfo script = null; ABC abc = scriptLeaf.abc; @@ -566,7 +565,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL public void reloadClass() { int ci = classIndex; - uncache(script); + uncache(script); if ((script != null) && (abc != null)) { setScript(script, abcList); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java index 2c929434a..75ffcdb32 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java @@ -169,7 +169,7 @@ public class DetailPanel extends JPanel implements ActionListener { if (trait == null) { traitNameLabel.setText("-"); } else { - if(abcPanel!=null){ + if (abcPanel != null) { traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList(), false)); } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/LineMarkedEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/LineMarkedEditorPane.java index 35ff92403..a7252e268 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/LineMarkedEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/LineMarkedEditorPane.java @@ -32,7 +32,6 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.regex.Pattern; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.plaf.TextUI; @@ -40,18 +39,13 @@ import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Document; import javax.swing.text.Element; -import javax.swing.text.Highlighter; import javax.swing.text.Highlighter.HighlightPainter; import javax.swing.text.JTextComponent; import javax.swing.text.Position; import javax.swing.text.View; -import javax.swing.text.html.HTMLEditorKit; import jsyntaxpane.SyntaxDocument; -import jsyntaxpane.SyntaxStyle; -import jsyntaxpane.SyntaxStyles; import jsyntaxpane.Token; import jsyntaxpane.actions.ActionUtils; -import jsyntaxpane.components.Markers; /** * @@ -210,14 +204,14 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan } repaint(); - } - }else { - lastUnderlined = null; - MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter); - setCursor(Cursor.getDefaultCursor()); - repaint(); } - + } else { + lastUnderlined = null; + MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter); + setCursor(Cursor.getDefaultCursor()); + repaint(); + } + } @Override @@ -297,7 +291,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan } @Override - public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) { + public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) { try { // --- determine locations --- TextUI mapper = c.getUI(); @@ -324,7 +318,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan @Override public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c, View view) { - + g.setColor(c.getSelectionColor()); Rectangle r; @@ -356,7 +350,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan r.width = Math.max(r.width, 1); paint(g, offs0, offs1, r, c); - + } return r; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java b/src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java index 461f2b49a..7c1b5a35a 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java @@ -24,7 +24,10 @@ import jsyntaxpane.Token; * @author JPEXS */ public interface LinkHandler { + public boolean isLink(Token token); + public void handleLink(Token token); + public Highlighter.HighlightPainter linkPainter(); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java b/src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java index a1420a33e..3fbc5e41b 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java @@ -47,12 +47,13 @@ public class MyMarkers { Highlighter.HighlightPainter hMarker = hilites[i].getPainter(); if (marker == null || hMarker.equals(marker)) { hilite.removeHighlight(hilites[i]); - } + } } } /** * Remove all the markers from an JEditorPane + * * @param editorPane */ public static void removeMarkers(JTextComponent editorPane) { @@ -61,6 +62,7 @@ public class MyMarkers { /** * add highlights for the given Token on the given pane + * * @param pane * @param token * @param marker @@ -71,6 +73,7 @@ public class MyMarkers { /** * add highlights for the given region on the given pane + * * @param pane * @param start * @param end @@ -82,45 +85,44 @@ public class MyMarkers { int selStart = pane.getSelectionStart(); int selEnd = pane.getSelectionEnd(); // if there is no selection or selection does not overlap - if(selStart == selEnd || end < selStart || start > selStart) { + if (selStart == selEnd || end < selStart || start > selStart) { hiliter.addHighlight(start, end, marker); return; } // selection starts within the highlight, highlight before slection - if(selStart > start && selStart < end ) { + if (selStart > start && selStart < end) { hiliter.addHighlight(start, selStart, marker); } // selection ends within the highlight, highlight remaining - if(selEnd > start && selEnd < end ) { + if (selEnd > start && selEnd < end) { hiliter.addHighlight(selEnd, end, marker); } } catch (BadLocationException ex) { - + } } /** * Mark all text in the document that matches the given pattern + * * @param pane control to use * @param pattern pattern to match * @param marker marker to use for highlighting */ public static void markAll(JTextComponent pane, Pattern pattern, Highlighter.HighlightPainter marker) { SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(pane); - if(sDoc == null || pattern == null) { + if (sDoc == null || pattern == null) { return; } Matcher matcher = sDoc.getMatcher(pattern); - // we may not have any matcher (due to undo or something, so don't do anything. - if(matcher==null) { - return; - } - while(matcher.find()) { + // we may not have any matcher (due to undo or something, so don't do anything. + if (matcher == null) { + return; + } + while (matcher.find()) { markText(pane, matcher.start(), matcher.end(), marker); } } - - } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/Tree.java b/src/com/jpexs/decompiler/flash/gui/abc/Tree.java deleted file mode 100644 index e700f5e55..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/Tree.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010-2014 Paolo Cancedda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc; - -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.gui.abc.treenodes.AS3PackageNode; -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; -import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; -import java.util.StringTokenizer; - -public class Tree { - - private final TreeElement ROOT = new AS3PackageNode("", "", new AS3PackageNodeItem(null, null), null); - - public void add(String name, String path, ScriptPack item) { - StringTokenizer st = new StringTokenizer(path, "."); - TreeElement parent = ROOT; - while (st.hasMoreTokens()) { - String pathElement = st.nextToken(); - parent = parent.getBranch(pathElement, item.getSwf()); - } - parent.addLeaf(name, item); - } - - public TreeElement getRoot() { - return ROOT; - } - - public void visit(TreeVisitor visitor) { - ROOT.visitLeafs(visitor); - ROOT.visitBranches(visitor); - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TreeVisitor.java b/src/com/jpexs/decompiler/flash/gui/abc/TreeVisitor.java deleted file mode 100644 index 8ed369fe2..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/TreeVisitor.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2010-2014 Paolo Cancedda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc; - -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; - -public interface TreeVisitor { - - public void onBranch(TreeElement branch); - - public void onLeaf(TreeElement leaf); -} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/AS3PackageNode.java b/src/com/jpexs/decompiler/flash/gui/abc/treenodes/AS3PackageNode.java deleted file mode 100644 index c7bad6021..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/AS3PackageNode.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc.treenodes; - -import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; - -/** - * - * @author JPEXS - */ -public class AS3PackageNode extends TreeElement { - - public AS3PackageNode(String name, String path, AS3PackageNodeItem item, TreeElement parent) { - super(name, path, item, parent); - } - - @Override - public AS3PackageNodeItem getItem() { - return (AS3PackageNodeItem) item; - } - -} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ClassesListNode.java b/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ClassesListNode.java deleted file mode 100644 index 15d6edac1..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ClassesListNode.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc.treenodes; - -import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; -import com.jpexs.decompiler.flash.treenodes.TreeNode; - -/** - * - * @author JPEXS - */ -public class ClassesListNode extends TreeNode { - - public ClassesListNode(ClassesListTreeModel item) { - super(item); - } - - @Override - public ClassesListTreeModel getItem() { - return (ClassesListTreeModel) item; - } - -} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ScriptPackNode.java b/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ScriptPackNode.java deleted file mode 100644 index 60d9c5350..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/ScriptPackNode.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc.treenodes; - -import com.jpexs.decompiler.flash.abc.ScriptPack; - -/** - * - * @author JPEXS - */ -public class ScriptPackNode extends TreeElement { - - public ScriptPackNode(String name, String path, ScriptPack item, TreeElement parent) { - super(name, path, item, parent); - } - - @Override - public ScriptPack getItem() { - return (ScriptPack) item; - } - -} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/TreeElement.java b/src/com/jpexs/decompiler/flash/gui/abc/treenodes/TreeElement.java deleted file mode 100644 index 831200cda..000000000 --- a/src/com/jpexs/decompiler/flash/gui/abc/treenodes/TreeElement.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2010-2014 Paolo Cancedda, JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.abc.treenodes; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.gui.abc.TreeVisitor; -import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; -import com.jpexs.decompiler.flash.treeitems.TreeElementItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; -import javax.swing.tree.TreePath; - -public abstract class TreeElement extends TreeNode { - - private final SortedMap branches; - private final SortedMap leafs; - private final String name; - private final String path; - private final TreeElement parent; - - public TreeElement(String name, String path, TreeElementItem item, TreeElement parent) { - super(item); - this.name = name; - this.path = path; - this.parent = parent; - branches = new TreeMap<>(); - leafs = new TreeMap<>(); - } - - @Override - public TreeElementItem getItem() { - return (TreeElementItem) item; - } - - public TreeElement getParent() { - return parent; - } - - public String getName() { - return name; - } - - public String getPath() { - return path; - } - - public TreePath getTreePath() { - List pathList = new ArrayList<>(); - TreeElement temp = this; - do { - pathList.add(0, temp); - } while ((temp = temp.getParent()) != null); - return new TreePath(pathList.toArray()); - } - - @Override - public String toString() { - return name; - } - - public TreeElement getBranch(String pathElement, SWF swf) { - TreeElement branch = branches.get(pathElement); - if (branch == null) { - branch = new AS3PackageNode(pathElement, path + "." + pathElement, new AS3PackageNodeItem(pathElement, swf), this); - branches.put(pathElement, branch); - } - return branch; - } - - public void addLeaf(String pathElement, ScriptPack item) { - ScriptPackNode child = new ScriptPackNode(pathElement, path + "." + pathElement, item, this); - leafs.put(pathElement, child); - } - - public TreeElement getChild(int index) { - Iterator iter; - int startingIndex; - if (index < branches.size()) { - iter = branches.values().iterator(); - startingIndex = 0; - } else { - iter = leafs.values().iterator(); - startingIndex = branches.size(); - } - int ii = startingIndex; - TreeElement child = null; - while (ii <= index && iter.hasNext()) { - child = iter.next(); - ii++; - } - return child; - } - - public int getChildCount() { - return branches.size() + leafs.size(); - } - - public boolean isLeaf() { - return getChildCount() == 0; - } - - public int getIndexOfChild(TreeElement child) { - if (getChildCount() < 1) { - return -1; - } - Iterator iter = branches.values().iterator(); - int ii = 0; - TreeElement aChild = null; - while (aChild != child && iter.hasNext()) { - aChild = iter.next(); - if (aChild == child) { - return ii; - } - ii++; - } - iter = leafs.values().iterator(); - while (aChild != child && iter.hasNext()) { - aChild = iter.next(); - if (aChild == child) { - return ii; - } - ii++; - } - return -1; - } - - public void visitBranches(TreeVisitor visitor) { - Iterator iter = branches.values().iterator(); - while (iter.hasNext()) { - TreeElement branch = iter.next(); - visitor.onBranch(branch); - branch.visitLeafs(visitor); - branch.visitBranches(visitor); - } - } - - public void visitLeafs(TreeVisitor visitor) { - Iterator iter = leafs.values().iterator(); - while (iter.hasNext()) { - TreeElement leaf = iter.next(); - visitor.onLeaf(leaf); - } - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 4c526c4a6..0cb4fbf03 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -39,9 +39,9 @@ import com.jpexs.decompiler.flash.gui.MainPanel; import com.jpexs.decompiler.flash.gui.SearchListener; import com.jpexs.decompiler.flash.gui.SearchPanel; import com.jpexs.decompiler.flash.gui.SearchResultsDialog; -import com.jpexs.decompiler.flash.gui.TagTreeModel; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane; +import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel; import com.jpexs.decompiler.flash.helpers.HilightedText; import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; @@ -714,7 +714,7 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene String newText = lastDecompiled; setDecompiledText(newText); if (lastLine > -1) { - decompiledEditor.gotoLine(lastLine + prefLines + 1); + decompiledEditor.gotoLine(lastLine + prefLines + 1); } decompiledEditor.setEditable(false); saveDecompiledButton.setVisible(false); @@ -777,7 +777,7 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene } catch (ActionParseException ex) { editor.gotoLine((int) ex.line); editor.markError(); - View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } break; case ACTION_EDIT_DECOMPILED: diff --git a/src/com/jpexs/decompiler/flash/gui/debugger/DebugListener.java b/src/com/jpexs/decompiler/flash/gui/debugger/DebugListener.java index 0627a7b58..3e797f022 100644 --- a/src/com/jpexs/decompiler/flash/gui/debugger/DebugListener.java +++ b/src/com/jpexs/decompiler/flash/gui/debugger/DebugListener.java @@ -5,6 +5,8 @@ package com.jpexs.decompiler.flash.gui.debugger; * @author JPEXS */ public interface DebugListener { - public void onMessage(String clientId,String msg); + + public void onMessage(String clientId, String msg); + public void onFinish(String clientId); } diff --git a/src/com/jpexs/decompiler/flash/gui/debugger/Debugger.java b/src/com/jpexs/decompiler/flash/gui/debugger/Debugger.java index b6dc83336..1c721d644 100644 --- a/src/com/jpexs/decompiler/flash/gui/debugger/Debugger.java +++ b/src/com/jpexs/decompiler/flash/gui/debugger/Debugger.java @@ -19,7 +19,7 @@ import java.util.WeakHashMap; */ public class Debugger { - private static Set listeners = new HashSet<>(); + private static final Set listeners = new HashSet<>(); public synchronized void addMessageListener(DebugListener l) { listeners.add(l); @@ -95,7 +95,7 @@ public class Debugger { } } else { String name = readString(is); - if (!name.equals("")) { + if (!name.isEmpty()) { clientName = name; } while (true) { @@ -152,7 +152,7 @@ public class Debugger { } - private int port; + private final int port; public Debugger(int port) { this.port = port; diff --git a/src/com/jpexs/decompiler/flash/gui/TagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java similarity index 84% rename from src/com/jpexs/decompiler/flash/gui/TagTree.java rename to src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java index 598572548..b56c66a83 100644 --- a/src/com/jpexs/decompiler/flash/gui/TagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java @@ -14,13 +14,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.gui; +package com.jpexs.decompiler.flash.gui.tagtree; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement; -import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; -import com.jpexs.decompiler.flash.gui.treenodes.TagTreeRoot; +import com.jpexs.decompiler.flash.gui.Main; +import com.jpexs.decompiler.flash.gui.MainFrameRibbonMenu; +import com.jpexs.decompiler.flash.gui.MainPanel; +import com.jpexs.decompiler.flash.gui.TreeNodeType; +import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; @@ -53,21 +55,19 @@ import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.timeline.AS2Package; +import com.jpexs.decompiler.flash.timeline.AS3Package; import com.jpexs.decompiler.flash.timeline.Frame; -import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem; -import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem; -import com.jpexs.decompiler.flash.treeitems.FrameNodeItem; +import com.jpexs.decompiler.flash.timeline.FrameScript; +import com.jpexs.decompiler.flash.timeline.TagScript; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; +import com.jpexs.decompiler.flash.treeitems.FolderItem; import com.jpexs.decompiler.flash.treeitems.HeaderItem; import com.jpexs.decompiler.flash.treeitems.SWFList; -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 com.jpexs.helpers.Helper; import com.jpexs.helpers.utf8.Utf8Helper; import java.awt.Color; @@ -127,8 +127,7 @@ public class TagTree extends JTree implements ActionListener { tree, value, sel, expanded, leaf, row, hasFocus); - TreeNode treeNode = (TreeNode) value; - TreeItem val = treeNode.getItem(); + TreeItem val = (TreeItem) value; TreeNodeType type = getTreeNodeType(val); if (type != null) { if (type == TreeNodeType.FOLDER && expanded) { @@ -136,8 +135,8 @@ public class TagTree extends JTree implements ActionListener { } String itemName = type.toString(); if (type == TreeNodeType.FOLDER || type == TreeNodeType.FOLDER_OPEN) { - if (val instanceof StringItem) { - StringItem si = (StringItem) val; + if (val instanceof FolderItem) { + FolderItem si = (FolderItem) val; if (!TagTreeRoot.FOLDER_ROOT.equals(si.getName())) { itemName = "folder" + si.getName(); } @@ -149,12 +148,10 @@ public class TagTree extends JTree implements ActionListener { Font font = getFont(); boolean isModified = false; - if (treeNode instanceof TreeNode) { - if (treeNode.getItem() instanceof Tag) { - Tag tag = (Tag) treeNode.getItem(); - if (tag.isModified()) { - isModified = true; - } + if (val instanceof Tag) { + Tag tag = (Tag) val; + if (tag.isModified()) { + isModified = true; } } @@ -175,7 +172,7 @@ public class TagTree extends JTree implements ActionListener { } } - TagTree(TagTreeModel treeModel, MainPanel mainPanel) { + public TagTree(TagTreeModel treeModel, MainPanel mainPanel) { super(treeModel); this.mainPanel = mainPanel; setCellRenderer(new TagTreeCellRenderer()); @@ -192,6 +189,10 @@ public class TagTree extends JTree implements ActionListener { public static TreeNodeType getTreeNodeType(TreeItem t) { + if (t instanceof TagScript) { + t = ((TagScript) t).getTag(); + } + if (t instanceof HeaderItem) { return TreeNodeType.HEADER; } @@ -240,13 +241,14 @@ public class TagTree extends JTree implements ActionListener { if (t instanceof ScriptPack) { return TreeNodeType.AS; } - if (t instanceof AS2PackageNodeItem) { + if (t instanceof AS2Package) { return TreeNodeType.PACKAGE; } - if (t instanceof AS3PackageNodeItem) { + if (t instanceof AS3Package) { return TreeNodeType.PACKAGE; } - if (t instanceof FrameNodeItem) { + if ((t instanceof Frame) + || (t instanceof FrameScript)) { return TreeNodeType.FRAME; } if (t instanceof ShowFrameTag) { @@ -287,6 +289,10 @@ public class TagTree extends JTree implements ActionListener { return TreeNodeType.OTHER_TAG; } + if (t instanceof FolderItem) { + return TreeNodeType.FOLDER; + } + return TreeNodeType.FOLDER; } @@ -360,10 +366,8 @@ public class TagTree extends JTree implements ActionListener { } boolean allSelectedIsTagOrFrame = true; for (TreePath treePath : paths) { - TreeNode treeNode = (TreeNode) treePath.getLastPathComponent(); - - TreeItem tag = treeNode.getItem(); - if (!(tag instanceof Tag) && !(tag instanceof FrameNodeItem)) { + TreeItem tag = (TreeItem) treePath.getLastPathComponent(); + if (!(tag instanceof Tag) && !(tag instanceof Frame)) { allSelectedIsTagOrFrame = false; break; } @@ -376,9 +380,7 @@ public class TagTree extends JTree implements ActionListener { openSWFInsideTagMenuItem.setVisible(false); if (paths.length == 1) { - TreeNode treeNode = (TreeNode) paths[0].getLastPathComponent(); - - TreeItem item = ((TreeNode) treeNode).getItem(); + TreeItem item = (TreeItem) paths[0].getLastPathComponent(); if (item instanceof ImageTag && ((ImageTag) item).importSupported()) { replaceSelectionMenuItem.setVisible(true); @@ -405,7 +407,7 @@ public class TagTree extends JTree implements ActionListener { replaceSelectionMenuItem.setVisible(true); } - if (treeNode instanceof SWFNode) { + if (item instanceof SWF) { closeSelectionMenuItem.setVisible(true); } @@ -434,7 +436,7 @@ public class TagTree extends JTree implements ActionListener { } TreeModel model = getModel(); - expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0); + expandRecursiveMenuItem.setVisible(model.getChildCount(item) > 0); jumpToCharacterMenuItem.setVisible(item instanceof CharacterIdTag && !(item instanceof CharacterTag)); @@ -457,8 +459,8 @@ public class TagTree extends JTree implements ActionListener { if (itemo == null) { return; } - if (itemo instanceof TagNode) { - mainPanel.loadFromBinaryTag((TagNode) itemo); + if (itemo instanceof DefineBinaryDataTag) { + mainPanel.loadFromBinaryTag((DefineBinaryDataTag) itemo); } break; case ACTION_RAW_EDIT: { @@ -490,16 +492,15 @@ public class TagTree extends JTree implements ActionListener { break; case ACTION_REMOVE_ITEM: case ACTION_REMOVE_ITEM_WITH_DEPENDENCIES: - List sel = getSelected(this); + List sel = getSelected(this); List tagsToRemove = new ArrayList<>(); - for (TreeNode o : sel) { - TreeItem tag = o.getItem(); + for (TreeItem tag : sel) { if (tag instanceof Tag) { tagsToRemove.add((Tag) tag); - } else if (tag instanceof FrameNodeItem) { - FrameNodeItem frameNode = (FrameNodeItem) tag; - Frame frame = frameNode.getParent().getTimeline().frames.get(frameNode.getFrame()); + } else if (tag instanceof Frame) { + Frame frameNode = (Frame) tag; + Frame frame = frameNode.timeline.getFrames().get(frameNode.frame); if (frame.showFrameTag != null) { tagsToRemove.add(frame.showFrameTag); } else { @@ -535,105 +536,99 @@ public class TagTree extends JTree implements ActionListener { return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); } - public List getAllSubs(JTree tree, TreeNode o) { + public List getAllSubs(JTree tree, TreeItem o) { TagTreeModel tm = (TagTreeModel) tree.getModel(); - List ret = new ArrayList<>(); + List ret = new ArrayList<>(); for (int i = 0; i < tm.getChildCount(o); i++) { - TreeNode c = tm.getChild(o, i); + TreeItem c = tm.getChild(o, i); ret.add(c); ret.addAll(getAllSubs(tree, c)); } return ret; } - public List getAllSelected(TagTree tree) { + public List getAllSelected(TagTree tree) { TreeSelectionModel tsm = tree.getSelectionModel(); TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); + List ret = new ArrayList<>(); if (tps == null) { return ret; } for (TreePath tp : tps) { - TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); + TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); ret.add(treeNode); ret.addAll(getAllSubs(tree, treeNode)); } return ret; } - public List getSelected(JTree tree) { + public List getSelected(JTree tree) { TreeSelectionModel tsm = tree.getSelectionModel(); TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); + List ret = new ArrayList<>(); if (tps == null) { return ret; } for (TreePath tp : tps) { - TreeNode treeNode = (TreeNode) tp.getLastPathComponent(); + TreeItem treeNode = (TreeItem) tp.getLastPathComponent(); ret.add(treeNode); } return ret; } - public List getSelection(SWF swf) { - List ret = new ArrayList<>(); - List sel = getAllSelected(this); - for (TreeNode d : sel) { - if (d.getItem().getSwf() != swf) { + public List getSelection(SWF swf) { + List ret = new ArrayList<>(); + List sel = getAllSelected(this); + for (TreeItem d : sel) { + if (d.getSwf() != swf) { continue; } - if (d instanceof ContainerNode) { - ContainerNode n = (ContainerNode) d; - TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem()); + if (d instanceof ContainerItem) { + ContainerItem n = (ContainerItem) d; + TreeNodeType nodeType = TagTree.getTreeNodeType(n); if (nodeType == TreeNodeType.IMAGE) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.SHAPE) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.MORPH_SHAPE) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.AS) { ret.add(n); } if (nodeType == TreeNodeType.MOVIE) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.SOUND) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.BINARY_DATA) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.TEXT) { - ret.add((Tag) n.getItem()); + ret.add(n); } if (nodeType == TreeNodeType.FONT) { - ret.add((Tag) n.getItem()); + ret.add(n); } } - if (d instanceof FrameNode) { - FrameNode fn = (FrameNode) d; - if (!fn.scriptsNode) { - ret.add(d.getItem()); - } + if (d instanceof Frame) { + ret.add(d); } - if (d instanceof TreeElement) { - if (((TreeElement) d).isLeaf()) { - TreeElement treeElement = (TreeElement) d; - ret.add((ScriptPack) treeElement.getItem()); - } + if (d instanceof ScriptPack) { + ret.add((ScriptPack) d); } } return ret; } - public List getTagsWithType(List list, TreeNodeType type) { - List ret = new ArrayList<>(); - for (TreeElementItem item : list) { + public List getTagsWithType(List list, TreeNodeType type) { + List ret = new ArrayList<>(); + for (AS3ClassTreeItem item : list) { TreeNodeType ttype = getTreeNodeType(item); if (type == ttype) { ret.add(item); @@ -643,10 +638,7 @@ public class TagTree extends JTree implements ActionListener { } public TreeItem getCurrentTreeItem() { - TreeNode treeNode = (TreeNode) getLastSelectedPathComponent(); - if (treeNode == null) { - return null; - } - return treeNode.getItem(); + TreeItem item = (TreeItem) getLastSelectedPathComponent(); + return item; } } diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java new file mode 100644 index 000000000..4e4e9f126 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.tagtree; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFBundle; +import com.jpexs.decompiler.flash.SWFContainerItem; +import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.gui.TreeNodeType; +import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.ShowFrameTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.Container; +import com.jpexs.decompiler.flash.tags.base.ContainerItem; +import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; +import com.jpexs.decompiler.flash.timeline.AS2Package; +import com.jpexs.decompiler.flash.timeline.AS3Package; +import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.FrameScript; +import com.jpexs.decompiler.flash.timeline.TagScript; +import com.jpexs.decompiler.flash.timeline.Timeline; +import com.jpexs.decompiler.flash.timeline.Timelined; +import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; +import com.jpexs.decompiler.flash.treeitems.FolderItem; +import com.jpexs.decompiler.flash.treeitems.HeaderItem; +import com.jpexs.decompiler.flash.treeitems.SWFList; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +public class TagTreeModel implements TreeModel { + + public static final String FOLDER_TEXTS = "texts"; + public static final String FOLDER_IMAGES = "images"; + public static final String FOLDER_MOVIES = "movies"; + public static final String FOLDER_SOUNDS = "sounds"; + public static final String FOLDER_BINARY_DATA = "binaryData"; + public static final String FOLDER_FONTS = "fonts"; + public static final String FOLDER_SPRITES = "sprites"; + public static final String FOLDER_SHAPES = "shapes"; + public static final String FOLDER_MORPHSHAPES = "morphshapes"; + public static final String FOLDER_BUTTONS = "buttons"; + public static final String FOLDER_FRAMES = "frames"; + public static final String FOLDER_OTHERS = "others"; + public static final String FOLDER_SCRIPTS = "scripts"; + private final TagTreeRoot root = new TagTreeRoot(); + private final List swfs; + private final Map> swfFolders; + + public TagTreeModel(List swfs) { + this.swfs = new ArrayList<>(); + this.swfFolders = new HashMap<>(); + for (SWFList swfList : swfs) { + if (swfList.isBundle) { + this.swfs.add(swfList); + for (SWF swf : swfList) { + createTagList(swf); + } + } else { + SWF swf = swfList.get(0); + this.swfs.add(swf); + createTagList(swf); + } + } + } + + private String translate(String key) { + return AppStrings.translate(key); + } + + private List getSoundStreams(DefineSpriteTag sprite) { + List ret = new ArrayList<>(); + for (Tag t : sprite.subTags) { + if (t instanceof SoundStreamHeadTypeTag) { + ret.add(t); + } + } + return ret; + } + + private void createTagList(SWF swf) { + List nodeList = new ArrayList<>(); + 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<>(); + + for (Tag t : swf.tags) { + TreeNodeType ttype = TagTree.getTreeNodeType(t); + switch (ttype) { + case SHAPE: + shapes.add(t); + break; + case MORPH_SHAPE: + morphShapes.add(t); + break; + case SPRITE: + sprites.add(t); + sounds.addAll(getSoundStreams((DefineSpriteTag) t)); + break; + case BUTTON: + buttons.add(t); + break; + case IMAGE: + images.add(t); + break; + case FONT: + fonts.add(t); + break; + case TEXT: + texts.add(t); + break; + case MOVIE: + movies.add(t); + break; + case SOUND: + sounds.add(t); + break; + case BINARY_DATA: + binaryData.add(t); + break; + case AS: + break; + default: + if (t.getId() != ShowFrameTag.ID && !ShowFrameTag.isNestedTagType(t.getId())) { + others.add(t); + } + break; + } + } + + Timeline timeline = swf.getTimeline(); + for (int i = 0; i < timeline.getFrameCount(); i++) { + frames.add(timeline.getFrames().get(i)); + } + + for (int i = 0; i < sounds.size(); i++) { + if (sounds.get(i) instanceof SoundStreamHeadTypeTag) { + List blocks = ((SoundStreamHeadTypeTag) sounds.get(i)).getBlocks(); + if (blocks.isEmpty()) { + sounds.remove(i); + i--; + } + } + } + + nodeList.add(new HeaderItem(swf, AppStrings.translate("node.header"))); + + if (!shapes.isEmpty()) { + FolderItem shapesNode = new FolderItem(translate("node.shapes"), FOLDER_SHAPES, swf, shapes); + nodeList.add(shapesNode); + } + if (!morphShapes.isEmpty()) { + FolderItem morphShapesNode = new FolderItem(translate("node.morphshapes"), FOLDER_MORPHSHAPES, swf, morphShapes); + nodeList.add(morphShapesNode); + } + if (!sprites.isEmpty()) { + FolderItem spritesNode = new FolderItem(translate("node.sprites"), FOLDER_SPRITES, swf, sprites); + nodeList.add(spritesNode); + } + if (!texts.isEmpty()) { + FolderItem textsNode = new FolderItem(translate("node.texts"), FOLDER_TEXTS, swf, texts); + nodeList.add(textsNode); + } + if (!images.isEmpty()) { + FolderItem imagesNode = new FolderItem(translate("node.images"), FOLDER_IMAGES, swf, images); + nodeList.add(imagesNode); + } + if (!movies.isEmpty()) { + FolderItem moviesNode = new FolderItem(translate("node.movies"), FOLDER_MOVIES, swf, movies); + nodeList.add(moviesNode); + } + if (!sounds.isEmpty()) { + FolderItem soundsNode = new FolderItem(translate("node.sounds"), FOLDER_SOUNDS, swf, sounds); + nodeList.add(soundsNode); + } + if (!buttons.isEmpty()) { + FolderItem buttonsNode = new FolderItem(translate("node.buttons"), FOLDER_BUTTONS, swf, buttons); + nodeList.add(buttonsNode); + } + if (!fonts.isEmpty()) { + FolderItem fontsNode = new FolderItem(translate("node.fonts"), FOLDER_FONTS, swf, fonts); + nodeList.add(fontsNode); + } + if (!binaryData.isEmpty()) { + FolderItem binaryDataNode = new FolderItem(translate("node.binaryData"), FOLDER_BINARY_DATA, swf, binaryData); + nodeList.add(binaryDataNode); + } + if (!frames.isEmpty()) { + FolderItem framesNode = new FolderItem(translate("node.frames"), FOLDER_FRAMES, swf, frames); + nodeList.add(framesNode); + } + if (!others.isEmpty()) { + FolderItem otherNode = new FolderItem(translate("node.others"), FOLDER_OTHERS, swf, others); + nodeList.add(otherNode); + } + + if (swf.isAS3) { + if (!swf.abcList.isEmpty()) { + nodeList.add(new ClassesListTreeModel(swf)); + } + } else { + List subNodes = new ArrayList<>(); + List subFrames = new ArrayList<>(); + subNodes.addAll(timeline.getAS2RootPackage().subPackages.values()); + subNodes.addAll(timeline.getAS2RootPackage().scripts.values()); + + for (Tag tag : swf.tags) { + if (tag instanceof Timelined) { + List tagSubNodes = new ArrayList<>(); + boolean hasInnerFrames = false; + for (Frame frame : ((Timelined) tag).getTimeline().getFrames()) { + if (!frame.actions.isEmpty()) { + FrameScript frameScript = new FrameScript(swf, frame); + tagSubNodes.add(frameScript); + hasInnerFrames = true; + } + } + + if (!hasInnerFrames) { + if (tag instanceof Container) { + for (ContainerItem item : ((Container) tag).getSubItems()) { + if (item instanceof ASMSource) { + tagSubNodes.add(item); + } + } + } + } + + if (!tagSubNodes.isEmpty()) { + TagScript ts = new TagScript(swf, tag, tagSubNodes); + if (hasInnerFrames) { + subFrames.add(ts); + } else { + subNodes.add(ts); + } + } + } + } + + subNodes.addAll(subFrames); + + for (Frame frame : timeline.getFrames()) { + if (!frame.actions.isEmpty()) { + FrameScript frameScript = new FrameScript(swf, frame); + subNodes.add(frameScript); + } + } + + if (subNodes.size() > 0) { + TreeItem actionScriptNode = new FolderItem(translate("node.scripts"), FOLDER_SCRIPTS, swf, subNodes); + nodeList.add(actionScriptNode); + } + } + + swfFolders.put(swf, nodeList); + } + + public TreeItem getScriptsNode(SWF swf) { + int childCount = getChildCount(swf); + for (int i = 0; i < childCount; i++) { + TreeItem child = getChild(swf, i); + if (child instanceof ClassesListTreeModel) { + return child; + } else if (child instanceof FolderItem) { + FolderItem folder = (FolderItem) child; + if (folder.getName().equals(FOLDER_SCRIPTS)) { + return folder; + } + } + } + + return null; + } + + private List searchTag(TreeItem obj, TreeItem parent, List path) { + List ret = null; + int cnt = getChildCount(parent); + for (int i = 0; i < cnt; i++) { + TreeItem n = getChild(parent, i); + List newPath = new ArrayList<>(); + newPath.addAll(path); + newPath.add(n); + + if (n instanceof AS3ClassTreeItem) { + AS3ClassTreeItem te = (AS3ClassTreeItem) n; + if (obj.equals(te)) { + return newPath; + } + } + + if (obj instanceof FolderItem && n instanceof FolderItem) { + // FolderItems are always recreated, so compare them by name + FolderItem nds = (FolderItem) n; + FolderItem objs = (FolderItem) obj; + if (objs.getName().equals(nds.getName())) { + return newPath; + } + } else { + if (obj.equals(n)) { + return newPath; + } + } + + ret = searchTag(obj, n, newPath); + if (ret != null) { + return ret; + } + } + return ret; + } + + public TreePath getTagPath(TreeItem obj) { + List path = new ArrayList<>(); + path.add(getRoot()); + path = searchTag(obj, getRoot(), path); + if (path == null) { + return null; + } + TreePath tp = new TreePath(path.toArray(new Object[path.size()])); + return tp; + } + + @Override + public TreeItem getRoot() { + return root; + } + + private List getSwfFolders(SWF swf) { + List ret = swfFolders.get(swf); + if (ret == null) { + createTagList(swf); + ret = swfFolders.get(swf); + } + + return ret; + } + + @Override + public TreeItem getChild(Object parent, int index) { + TreeItem parentNode = (TreeItem) parent; + if (parentNode == root) { + return swfs.get(index); + } else if (parentNode instanceof SWFBundle) { + return ((SWFList) parentNode).swfs.get(index); + } else if (parentNode instanceof SWF) { + return getSwfFolders((SWF) parentNode).get(index); + } else if (parentNode instanceof FolderItem) { + return ((FolderItem) parentNode).subItems.get(index); + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).innerTags.get(index); + } else if (parentNode instanceof DefineSpriteTag) { + return ((DefineSpriteTag) parentNode).getTimeline().getFrames().get(index); + } else if (parentNode instanceof DefineBinaryDataTag) { + return ((DefineBinaryDataTag) parentNode).innerSwf; + } else if (parentNode instanceof AS2Package) { + return ((AS2Package) parentNode).getChild(index); + } else if (parentNode instanceof FrameScript) { + return ((FrameScript) parentNode).getFrame().actions.get(index); + } else if (parentNode instanceof TagScript) { + return ((TagScript) parentNode).getFrames().get(index); + } else if (parentNode instanceof ClassesListTreeModel) { + ClassesListTreeModel clt = (ClassesListTreeModel) parentNode; + return clt.getChild(clt.getRoot(), index); + } else if (parentNode instanceof AS3ClassTreeItem) { + return ((AS3Package) parentNode).getChild(index); + } + + throw new Error("Unsupported parent type: " + parentNode.getClass().getName()); + } + + @Override + public int getChildCount(Object parent) { + TreeItem parentNode = (TreeItem) parent; + if (parentNode == root) { + return swfs.size(); + } else if (parentNode instanceof SWFBundle) { + return ((SWFList) parentNode).swfs.size(); + } else if (parentNode instanceof SWF) { + return getSwfFolders((SWF) parentNode).size(); + } else if (parentNode instanceof HeaderItem) { + return 0; + } else if (parentNode instanceof FolderItem) { + return ((FolderItem) parentNode).subItems.size(); + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).innerTags.size(); + } else if (parentNode instanceof DefineSpriteTag) { + return ((DefineSpriteTag) parentNode).getTimeline().getFrameCount(); + } else if (parentNode instanceof DefineBinaryDataTag) { + return ((DefineBinaryDataTag) parentNode).innerSwf == null ? 0 : 1; + } else if (parentNode instanceof AS2Package) { + return ((AS2Package) parentNode).getChildCount(); + } else if (parentNode instanceof FrameScript) { + return ((FrameScript) parentNode).getFrame().actions.size(); + } else if (parentNode instanceof TagScript) { + return ((TagScript) parentNode).getFrames().size(); + } else if (parentNode instanceof ClassesListTreeModel) { + ClassesListTreeModel clt = (ClassesListTreeModel) parentNode; + return clt.getChildCount(clt.getRoot()); + } else if (parentNode instanceof AS3Package) { + return ((AS3Package) parentNode).getChildCount(); + } + + return 0; + } + + @Override + public boolean isLeaf(Object node) { + return (getChildCount(node) == 0); + } + + @Override + public void valueForPathChanged(TreePath path, Object newValue) { + } + + @Override + public int getIndexOfChild(Object parent, Object child) { + TreeItem parentNode = (TreeItem) parent; + TreeItem childNode = (TreeItem) child; + if (parentNode == root) { + return swfs.indexOf(childNode); + } else if (parentNode instanceof SWFBundle) { + return ((SWFList) parentNode).swfs.indexOf(childNode); + } else if (parentNode instanceof SWF) { + return getSwfFolders((SWF) parentNode).indexOf(childNode); + } else if (parentNode instanceof FolderItem) { + return ((FolderItem) parentNode).subItems.indexOf(childNode); + } else if (parentNode instanceof Frame) { + return ((Frame) parentNode).innerTags.indexOf(childNode); + } else if (parentNode instanceof DefineSpriteTag) { + return ((Frame) parentNode).frame; + } else if (parentNode instanceof DefineBinaryDataTag) { + return 0; // binary data tag can have only 1 child + } else if (parentNode instanceof AS2Package) { + return ((AS2Package) parentNode).getIndexOfChild(childNode); + } else if (parentNode instanceof FrameScript) { + return ((FrameScript) parentNode).getFrame().actions.indexOf(childNode); + } else if (parentNode instanceof TagScript) { + return ((TagScript) parentNode).getFrames().indexOf(childNode); + } else if (parentNode instanceof ClassesListTreeModel) { + ClassesListTreeModel clt = (ClassesListTreeModel) parentNode; + return clt.getIndexOfChild(clt.getRoot(), childNode); + } else if (parentNode instanceof AS3ClassTreeItem) { + return ((AS3Package) parentNode).getIndexOfChild((AS3ClassTreeItem) childNode); + } + + throw new Error("Unsupported parent type: " + parentNode.getClass().getName()); + } + + @Override + public void addTreeModelListener(TreeModelListener l) { + } + + @Override + public void removeTreeModelListener(TreeModelListener l) { + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/treenodes/TagTreeRoot.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeRoot.java similarity index 73% rename from src/com/jpexs/decompiler/flash/gui/treenodes/TagTreeRoot.java rename to src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeRoot.java index d884a6af2..f3618211f 100644 --- a/src/com/jpexs/decompiler/flash/gui/treenodes/TagTreeRoot.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeRoot.java @@ -1,33 +1,32 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.treenodes; - -import com.jpexs.decompiler.flash.treeitems.StringItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; - -/** - * - * @author JPEXS - */ -public class TagTreeRoot extends TreeNode { - - public static final String FOLDER_ROOT = "root"; - - public TagTreeRoot() { - super(new StringItem("root", FOLDER_ROOT, null)); - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.tagtree; + +import com.jpexs.decompiler.flash.treeitems.FolderItem; + +/** + * + * @author JPEXS + */ +public class TagTreeRoot extends FolderItem { + + public static final String FOLDER_ROOT = "root"; + + public TagTreeRoot() { + super("root", FOLDER_ROOT, null, null); + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java index cb547cedb..d682a42fb 100644 --- a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java @@ -115,7 +115,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe for (int f = start_f; f <= end_f; f++) { for (int d = start_d; d <= end_d; d++) { - DepthState fl = timeLine.frames.get(f).layers.get(d); + DepthState fl = timeLine.getFrames().get(f).layers.get(d); if (fl == null) { if ((f + 1) % 5 == 0) { g.setColor(emptyFrameSecondColor); @@ -130,16 +130,16 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe } for (int f = start_f; f <= end_f; f++) { for (int d = start_d; d <= end_d; d++) { - DepthState fl = timeLine.frames.get(f).layers.get(d); + DepthState fl = timeLine.getFrames().get(f).layers.get(d); boolean motionTween = fl == null ? false : fl.motionTween; DepthState flNext = null; if (f < max_f) { - flNext = timeLine.frames.get(f + 1).layers.get(d); + flNext = timeLine.getFrames().get(f + 1).layers.get(d); } DepthState flPrev = null; if (f > 0) { - flPrev = timeLine.frames.get(f - 1).layers.get(d); + flPrev = timeLine.getFrames().get(f - 1).layers.get(d); } CharacterTag cht = fl == null ? null : timeLine.swf.characters.get(fl.characterId); @@ -167,18 +167,18 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe if (fl == null) { - if (timeLine.depthMaxFrame.containsKey(d) && f < timeLine.depthMaxFrame.get(d)) { + if (timeLine.getDepthMaxFrame().containsKey(d) && f < timeLine.getDepthMaxFrame().get(d)) { int draw_f = f; - DepthState prev_ds = f < 1 ? null : timeLine.frames.get(f - 1).layers.get(d); + DepthState prev_ds = f < 1 ? null : timeLine.getFrames().get(f - 1).layers.get(d); if (f == 0 || prev_ds != null) { draw_f = f; keyfound[d - start_d] = true; } else if (!keyfound[d - start_d]) { for (; draw_f >= 0; draw_f--) { - if (timeLine.frames.get(draw_f).layers.get(d) != null) { - if (timeLine.frames.get(draw_f).layers.get(d).characterId != -1) { + if (timeLine.getFrames().get(draw_f).layers.get(d) != null) { + if (timeLine.getFrames().get(draw_f).layers.get(d).characterId != -1) { break; } } @@ -187,9 +187,9 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe continue; } int num_frames = 1; - for (int i = draw_f + 1; i < timeLine.frames.size(); i++) { - if (timeLine.frames.get(i).layers.get(d) != null) { - if (timeLine.frames.get(i).layers.get(d).characterId != -1) { + for (int i = draw_f + 1; i < timeLine.getFrames().size(); i++) { + if (timeLine.getFrames().get(i).layers.get(d) != null) { + if (timeLine.getFrames().get(i).layers.get(d).characterId != -1) { break; } } @@ -228,7 +228,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe } if (d == 0) { - if (timeLine.frames.get(f).action != null) { + if (!timeLine.getFrames().get(f).actions.isEmpty()) { g.setColor(aColor); g.setFont(getFont().deriveFont(fontSize)); int awidth = g.getFontMetrics().stringWidth("a"); @@ -244,7 +244,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe keyfound[d - start_d] = true; } else if (!keyfound[d - start_d]) { for (int k = f - 1; k >= 0; k--) { - fl = timeLine.frames.get(k).layers.get(d); + fl = timeLine.getFrames().get(k).layers.get(d); if (fl == null) { break; } @@ -259,7 +259,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe } int num_frames = 1; for (int n = draw_f + 1; n < timeLine.getFrameCount(); n++) { - fl = timeLine.frames.get(n).layers.get(d); + fl = timeLine.getFrames().get(n).layers.get(d); if (fl == null) { break; } @@ -389,7 +389,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe } break; case 39: //right - if (cursor.x < timeLine.frames.size() - 1) { + if (cursor.x < timeLine.getFrames().size() - 1) { frameSelect(cursor.x + 1, cursor.y); } break; diff --git a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFBundleNode.java b/src/com/jpexs/decompiler/flash/gui/treenodes/SWFBundleNode.java deleted file mode 100644 index 325c3dd2d..000000000 --- a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFBundleNode.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.treenodes; - -import com.jpexs.decompiler.flash.treeitems.SWFList; -import java.util.ArrayList; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class SWFBundleNode extends SWFContainerNode { - - private final String name; - public List swfs = new ArrayList<>(); - - public SWFBundleNode(SWFList swfList, String name) { - super(swfList); - this.name = name; - } - - @Override - public String toString() { - return name; - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFContainerNode.java b/src/com/jpexs/decompiler/flash/gui/treenodes/SWFContainerNode.java deleted file mode 100644 index 4f528a1a4..000000000 --- a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFContainerNode.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.treenodes; - -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; - -/** - * - * @author JPEXS - */ -public abstract class SWFContainerNode extends TreeNode { - - public SWFContainerNode(TreeItem item) { - super(item); - } - -} diff --git a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFNode.java b/src/com/jpexs/decompiler/flash/gui/treenodes/SWFNode.java deleted file mode 100644 index a78a9b49e..000000000 --- a/src/com/jpexs/decompiler/flash/gui/treenodes/SWFNode.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.treenodes; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; -import com.jpexs.decompiler.flash.treenodes.TreeNode; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class SWFNode extends SWFContainerNode { - - private final String name; - public List list; - public TreeNode scriptsNode; - public DefineBinaryDataTag binaryData; - - public SWFNode(SWF swf, String name) { - super(swf); - this.name = name; - } - - @Override - public SWF getItem() { - return (SWF) item; - } - - @Override - public String toString() { - return name; - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/treenodes/StringNode.java b/src/com/jpexs/decompiler/flash/gui/treenodes/StringNode.java deleted file mode 100644 index eaf387b34..000000000 --- a/src/com/jpexs/decompiler/flash/gui/treenodes/StringNode.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.treenodes; - -import com.jpexs.decompiler.flash.treeitems.StringItem; -import com.jpexs.decompiler.flash.treenodes.TreeNode; - -/** - * - * @author JPEXS - */ -public class StringNode extends TreeNode { - - public StringNode(StringItem item) { - super(item); - } - - @Override - public StringItem getItem() { - return (StringItem) item; - } - -} diff --git a/src/com/sun/jna/platform/win32/WinNT.java b/src/com/sun/jna/platform/win32/WinNT.java index b508c7c12..95c1753a1 100644 --- a/src/com/sun/jna/platform/win32/WinNT.java +++ b/src/com/sun/jna/platform/win32/WinNT.java @@ -804,7 +804,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD { } @Override - public void setPointer(Pointer p) { + public final void setPointer(Pointer p) { if (immutable) { throw new UnsupportedOperationException("immutable reference"); }