Merge origin/master

Conflicts:
	libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java
This commit is contained in:
Jindra Petřík
2014-11-04 20:58:15 +01:00
90 changed files with 1977 additions and 2502 deletions

View File

@@ -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;

View File

@@ -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<Tag> 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<ABCContainerTag> 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<ABCContainerTag> 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<ScriptPack> 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<MyEntry<ClassPath, ScriptPack>> getAS3Packs() {
List<MyEntry<ClassPath, ScriptPack>> 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<File> exportActionScript2(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException {
private List<File> exportActionScript2(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException {
List<File> ret = new ArrayList<>();
List<ContainerItem> list2 = new ArrayList<>();
list2.addAll(tags);
List<TreeNode> list = createASTagList(list2, this);
Map<String, ASMSource> 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<File> exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel) {
private List<File> exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel) {
final AtomicInteger cnt = new AtomicInteger(1);
final List<ABCContainerTag> abcTags = new ArrayList<>();
for (Tag t : tags) {
if (t instanceof ABCContainerTag) {
abcTags.add((ABCContainerTag) t);
}
}
final List<File> ret = new ArrayList<>();
final List<MyEntry<ClassPath, ScriptPack>> packs = getAS3Packs();
@@ -964,7 +931,7 @@ public final class SWF implements TreeItem, Timelined {
@Override
public Void call() throws Exception {
for (MyEntry<ClassPath, ScriptPack> 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<Future<File>> futureResults = new ArrayList<>();
for (MyEntry<ClassPath, ScriptPack> item : packs) {
Future<File> future = executor.submit(new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, abcTags, exportMode, parallel));
Future<File> 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<File> exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel) throws Exception {
boolean asV3Found = false;
List<File> 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<TreeNode> createASTagList(List<? extends ContainerItem> list, Timelined parent) {
List<TreeNode> ret = new ArrayList<>();
int frame = 0;
List<TreeNode> 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<ContainerItem> 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<TreeNode> 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<String, ASMSource> getASMs() {
List<TreeNode> list = createASTagList(tags, this);
Map<String, ASMSource> asms = new HashMap<>();
getASMs("", list, asms);
return asms;
Map<String, ASMSource> asms2 = new HashMap<>();
getASMs("", tags, asms2);
return asms2;
}
private static void getASMs(String path, List<TreeNode> nodes, Map<String, ASMSource> 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<? extends ContainerItem> items, Map<String, ASMSource> 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<TreeNode> treeNodes, List<Tag> result) {
for (TreeNode treeNode : treeNodes) {
TreeItem treeItem = treeNode.getItem();
if (treeItem instanceof Tag) {
result.add((Tag) treeItem);
}
getTagsFromTreeNodes(treeNode.subNodes, result);
}
}
private final HashSet<EventListener> 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<Integer> 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<SvgClip> clips = new ArrayList<>();
List<String> 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<SerializableImage> ret, int startFrame, int stopFrame, DepthState stateUnderCursor, int mouseButton, RECT displayRect, int totalFrameCount, Stack<Integer> 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();
}
}

View File

@@ -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;

View File

@@ -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 {
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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<Integer> 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<ABCContainerTag> 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()) {

View File

@@ -44,7 +44,7 @@ public class Multiname {
public List<Integer> 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) {

View File

@@ -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<File> exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Collection<ASMSource> asms, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
try {
List<File> result = CancellableWorker.call(new Callable<List<File>>() {
@Override
public List<File> 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<File> exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Collection<ASMSource> asms, ScriptExportMode exportMode, EventListener ev) throws IOException {
List<File> ret = new ArrayList<>();
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
outdir += "scripts" + File.separator;
Map<String, List<String>> 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<String> 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<Action> 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());
}
}
}

View File

@@ -54,6 +54,12 @@ public class FileTextWriter extends GraphTextWriter implements AutoCloseable {
return this;
}
@Override
public GraphTextWriter hilightSpecial(String text, String type, int index, Map<String, String> data) {
writeToFile(text);
return this;
}
@Override
public FileTextWriter append(String str) {
writeToFile(str);

View File

@@ -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
*

View File

@@ -255,13 +255,13 @@ public class DefineButton2Tag extends ButtonTag implements Container {
if (timeline != null) {
return timeline;
}
timeline = new Timeline(swf, new ArrayList<Tag>(), buttonId, getRect(new HashSet<BoundedTag>()));
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect(new HashSet<BoundedTag>()));
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;
}
}

View File

@@ -326,7 +326,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
if (timeline != null) {
return timeline;
}
timeline = new Timeline(swf, new ArrayList<Tag>(), buttonId, getRect(new HashSet<BoundedTag>()));
timeline = new Timeline(swf, this, new ArrayList<Tag>(), buttonId, getRect(new HashSet<BoundedTag>()));
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;

View File

@@ -263,7 +263,7 @@ public class DefineFont2Tag extends FontTag {
fontBoundsTable.add(sis.readRECT("rect"));
}
int kerningCount = sis.readUI16("kerningCount");
fontKerningTable = new ArrayList<KERNINGRECORD>();
fontKerningTable = new ArrayList<>();
for (int i = 0; i < kerningCount; i++) {
fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record"));
}

View File

@@ -168,7 +168,7 @@ public class DefineFont3Tag extends FontTag {
fontBoundsTable.add(sis.readRECT("rect"));
}
int kerningCount = sis.readUI16("kerningCount");
fontKerningTable = new ArrayList<KERNINGRECORD>();
fontKerningTable = new ArrayList<>();
for (int i = 0; i < kerningCount; i++) {
fontKerningTable.add(sis.readKERNINGRECORD(fontFlagsWideCodes, "record"));
}

View File

@@ -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<BoundedTag>()));
timeline = new Timeline(swf, this, subTags, spriteId, getRect(new HashSet<BoundedTag>()));
}
return timeline;
}
@Override
public void resetTimeline() {
timeline = null;
}
@Override
public int getCharacterId() {
return spriteId;

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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.tags.Tag;
import java.util.List;
/**
@@ -29,7 +29,7 @@ import java.util.List;
*
* @author JPEXS
*/
*/
public interface ASMSource extends Exportable {
/**
* Converts actions to ASM source

View File

@@ -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 extends TreeItem {
public String getExportFileName();
}

View File

@@ -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<String, AS2Package> subPackages = new TreeMap<>();
public Map<String, ASMSource> 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;
}
}

View File

@@ -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<String, AS3Package> subPackages = new TreeMap<>();
public Map<String, ScriptPack> 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;
}
}

View File

@@ -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 implements TreeItem {
public final int frame;
public TreeMap<Integer, DepthState> layers = new TreeMap<>();
public TreeMap<Integer, DepthState> layers = new TreeMap<>();
public RGB backgroundColor = new RGBA(0, 0, 0, 0);
public Timeline timeline;
public List<Integer> sounds = new ArrayList<>();
public List<String> soundClasses = new ArrayList<>();
public List<DoActionTag> actions = new ArrayList<>();
public List<Tag> innerTags = new ArrayList<>();
public ShowFrameTag showFrameTag = null; // can be null for the last frame
public Frame(Timeline timeline, int frame) {
this.timeline = timeline;
this.frame = frame;
}
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);
}
}

View File

@@ -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();
}
}

View File

@@ -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<TreeItem> frames;
public TagScript(SWF swf, Tag tag, List<TreeItem> 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<TreeItem> 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();
}
}

View File

@@ -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<Frame> frames = new ArrayList<>();
public int id;
public SWF swf;
public RECT displayRect;
public int frameRate;
public Timelined timelined;
public Tag parentTag;
public List<Tag> tags;
public Map<Integer, Integer> depthMaxFrame = new HashMap<>();
public int getMaxDepth() {
private final List<Frame> frames = new ArrayList<>();
private final Map<Integer, Integer> depthMaxFrame = new HashMap<>();
private final List<ASMSource> asmSources = new ArrayList<>();
private final Map<ASMSource, Integer> actionFrames = new HashMap<>();
private AS2Package as2RootPackage;
private final List<Tag> otherTags = new ArrayList<>();
private boolean initialized = false;
private void ensureInitialized() {
if (!initialized) {
initialize();
}
}
public List<Frame> getFrames() {
ensureInitialized();
return frames;
}
public AS2Package getAS2RootPackage() {
ensureInitialized();
return as2RootPackage;
}
public Map<Integer, Integer> 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<Tag> tags, int id, RECT displayRect) {
public Timeline(SWF swf, Tag parentTag, List<Tag> 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<Integer> usedCharacters) {
for (int i = 0; i < getFrameCount(); i++) {
getNeededCharacters(i, usedCharacters);
@@ -244,13 +331,13 @@ public class Timeline {
}
public void getNeededCharacters(List<Integer> frames, Set<Integer> 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<Integer> 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<Integer> sounds, List<String> 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<DepthState> objs, List<Shape> outlines) {
Frame fr = this.frames.get(frame);
Frame fr = getFrames().get(frame);
Stack<Clip> 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<Clip> 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;

View File

@@ -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 Timeline getTimeline();
}

View File

@@ -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;
}
}

View File

@@ -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<TreeItem> subItems;
public StringItem(String str, String name, SWF swf) {
public FolderItem(String str, String name, SWF swf, List<TreeItem> subItems) {
this.swf = swf;
this.str = str;
this.name = name;
this.subItems = subItems;
}
public String getName() {

View File

@@ -41,5 +41,4 @@ public class HeaderItem implements TreeItem {
public String toString() {
return name;
}
}

View File

@@ -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<SWF>, SWFContainerItem {
public String name;
public boolean isBundle;
@@ -39,6 +41,11 @@ public class SWFList implements List<SWF>, TreeItem {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
return name;
}
@Override
public Iterator<SWF> iterator() {
return swfs.iterator();

View File

@@ -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<String, TreeItem> getInnerScripts();
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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<Tag> 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;
}

View File

@@ -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;
}
}

View File

@@ -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<TreeNode> 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<File> exportNodeAS(final AbortRetryIgnoreHandler handler, final List<TreeNode> nodesList, final List<TreeNode> nodesToExport, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
try {
List<File> result = CancellableWorker.call(new Callable<List<File>>() {
@Override
public List<File> 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<File> exportNodeAS(AbortRetryIgnoreHandler handler, List<TreeNode> nodesList, List<TreeNode> nodesToExport, boolean exportAll, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException {
File dir = new File(outdir);
List<File> ret = new ArrayList<>();
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
List<String> 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<Action> 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;
}
}

View File

@@ -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<TreeNode> 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();
}
}

View File

@@ -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;

View File

@@ -284,5 +284,4 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S
public Tag getSourceTag() {
return tag;
}
}

View File

@@ -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;

View File

@@ -59,7 +59,7 @@ public abstract class GraphTargetItem implements Serializable {
public List<GraphSourceItemPos> moreSrc = new ArrayList<>();
public GraphPart firstPart;
public GraphTargetItem value;
protected Map<String,String> srcData = new HashMap<String, String>();
protected Map<String,String> srcData = new HashMap<>();
public GraphPart getFirstPart() {
if (value == null) {

View File

@@ -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<TreeNode> 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<ABC> 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<ContainerItem> list2 = new ArrayList<>();
list2.addAll(swf.tags);
List<TreeNode> list = SWF.createASTagList(list2, null);
Map<String, ASMSource> 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");

View File

@@ -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

View File

@@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
}
}
}

View File

@@ -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<Object> exportables) {
public ExportDialog(List<TreeItem> 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;

View File

@@ -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();

View File

@@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<FontFace>{
public Font font;
public FontFace(Font font) {
this.font = font;
}
public class FontFace implements Comparable<FontFace> {
@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) {

View File

@@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<FontFamily>{
public String familyEn;
public String family;
public class FontFamily implements Comparable<FontFamily> {
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) {

View File

@@ -77,21 +77,21 @@ public class FontPanel extends javax.swing.JPanel {
}
public static ComboBoxModel<FontFamily> getFamilyModel() {
Set<FontFamily> famSet=new TreeSet<>();
for(Font f:FontTag.installedFontsByName.values()){
Set<FontFamily> famSet = new TreeSet<>();
for (Font f : FontTag.installedFontsByName.values()) {
famSet.add(new FontFamily(f));
}
return new DefaultComboBoxModel<>(new Vector<FontFamily>(famSet));
return new DefaultComboBoxModel<>(new Vector<>(famSet));
}
public static ComboBoxModel<FontFace> getFaceModel(FontFamily family) {
Set<FontFace> faceSet=new TreeSet<>();
for(Font f:FontTag.installedFontsByFamily.get(family.familyEn).values()){
public static ComboBoxModel<FontFace> getFaceModel(FontFamily family) {
Set<FontFace> faceSet = new TreeSet<>();
for (Font f : FontTag.installedFontsByFamily.get(family.familyEn).values()) {
faceSet.add(new FontFace(f));
}
return new DefaultComboBoxModel<>(new Vector<FontFace>(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<Integer> 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;
}

View File

@@ -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<DepthState>(), new ArrayList<Shape>());
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<DepthState> dss = new ArrayList<>();
List<Shape> 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

View File

@@ -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
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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<TreeNode> nodes = getASTreeNodes(tagTree);
List<TreeItem> 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<TreeNode> nodes = getASTreeNodes(tagTree);
List<TreeItem> 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<TreeNode> getASTreeNodes(TagTree tree) {
List<TreeNode> result = new ArrayList<>();
public List<TreeItem> getASTreeNodes(TagTree tree) {
List<TreeItem> 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<File> exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException {
List<File> ret = new ArrayList<>();
List<TreeNode> sel = tagTree.getAllSelected(tagTree);
List<TreeItem> sel = tagTree.getAllSelected(tagTree);
List<SWF> allSwfs = new ArrayList<>();
for (SWFList swfList : swfs) {
@@ -1008,14 +1004,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
List<Tag> movies = new ArrayList<>();
List<Tag> sounds = new ArrayList<>();
List<Tag> texts = new ArrayList<>();
List<TreeNode> as12scripts = new ArrayList<>();
List<TreeItem> as12scripts = new ArrayList<>();
List<Tag> binaryData = new ArrayList<>();
Map<Integer, List<Integer>> frames = new HashMap<>();
List<Tag> 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<Integer>());
}
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<Integer>());
}
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<TreeNode> scriptNodeList = new ArrayList<>(1);
scriptNodeList.add(ttm.getSwfNode(swf).scriptsNode);
ret.addAll(TagNode.exportNodeAS(handler, scriptNodeList, as12scripts, selFile, scriptMode, null));
List<ASMSource> 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<TreeItem> nodesToExport, boolean exportAll, List<ASMSource> 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<Object> sel = tagTree.getSelection(swf);
List<TreeItem> 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<ABCContainerTag> 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<Tag> 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<BoundedTag>());
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<Tag>(), ((CharacterTag) tag).getCharacterId(), getRect(new HashSet<BoundedTag>()));
tim = new Timeline(tag.getSwf(), null, new ArrayList<Tag>(), ((CharacterTag) tag).getCharacterId(), getRect(new HashSet<BoundedTag>()));
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<BoundedTag>());
return tim;
}
@Override
public void resetTimeline() {
tim = null;
}
@Override
public RECT getRect(Set<BoundedTag> added) {
BoundedTag bt = (BoundedTag) tag;

View File

@@ -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) {

View File

@@ -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<Tag> subs = parent.getTimeline().tags;
if (tagObj instanceof Frame) {
Frame fn = (Frame) tagObj;
Timelined parent = fn.timeline.timelined;
List<Tag> subs = fn.timeline.tags;
List<Integer> 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);

View File

@@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<SWFContainerNode> swfs;
private final Map<SWF, SWFNode> swfToSwfNode;
private final MainFrame mainFrame;
public TagTreeModel(MainFrame mainFrame, List<SWFList> 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<TreeNode> getSoundStreams(DefineSpriteTag sprite) {
List<TreeNode> ret = new ArrayList<>();
for (Tag t : sprite.subTags) {
if (t instanceof SoundStreamHeadTypeTag) {
ret.add(new TagNode(t));
}
}
return ret;
}
private SWFNode createTagList(List<Tag> list, SWF swf) {
ClassesListTreeModel classTreeModel = new ClassesListTreeModel(swf);
SWFNode swfNode = new SWFNode(swf, swf.getShortFileName());
boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty();
List<TreeNode> nodeList = new ArrayList<>();
List<TreeNode> frames = new ArrayList<>();
List<TreeNode> shapes = new ArrayList<>();
List<TreeNode> morphShapes = new ArrayList<>();
List<TreeNode> sprites = new ArrayList<>();
List<TreeNode> buttons = new ArrayList<>();
List<TreeNode> images = new ArrayList<>();
List<TreeNode> fonts = new ArrayList<>();
List<TreeNode> texts = new ArrayList<>();
List<TreeNode> movies = new ArrayList<>();
List<TreeNode> sounds = new ArrayList<>();
List<TreeNode> binaryData = new ArrayList<>();
List<TreeNode> others = new ArrayList<>();
List<TreeNode> actionScript = SWF.createASTagList(list, swf);
List<Tag> 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<SoundStreamBlockTag> 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<TreeNode> createSubTagList(List<Tag> list, Timelined parent, SWF swf, List<Tag> actionScriptTags) {
List<TreeNode> ret = new ArrayList<>();
List<TreeNode> frames = new ArrayList<>();
List<TreeNode> 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<TreeNode> searchTag(TreeItem obj, TreeNode parent, List<TreeNode> path) {
List<TreeNode> ret = null;
int cnt = getChildCount(parent);
for (int i = 0; i < cnt; i++) {
TreeNode n = getChild(parent, i);
List<TreeNode> 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<TreeNode> 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) {
}
}

View File

@@ -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,
}

View File

@@ -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<Boolean> showAgainConfig, int defaultOption) {
JLabel warLabel = new JLabel("<html>"+message.replace("\r\n", "<br>")+"</html>");
JLabel warLabel = new JLabel("<html>" + message.replace("\r\n", "<br>") + "</html>");
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("<html>"+message.replace("\r\n", "<br>")+"</html>");
JLabel warLabel = new JLabel("<html>" + message.replace("\r\n", "<br>") + "</html>");
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

View File

@@ -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<ABCPanelSearchResult> found = new ArrayList<>();
if (scriptsNode.getItem() instanceof ClassesListTreeModel) {
ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode.getItem();
if (scriptsNode instanceof ClassesListTreeModel) {
ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode;
List<MyEntry<ClassPath, ScriptPack>> 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<ClassPath, ScriptPack> 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<MyEntry<ClassPath, ScriptPack>> 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
}

View File

@@ -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());

View File

@@ -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<MyEntry<ClassPath, ScriptPack>> list;
private AS3Package root;
private final List<TreeModelListener> listeners = new ArrayList<>();
public List<MyEntry<ClassPath, ScriptPack>> 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<ClassPath, ScriptPack> 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

View File

@@ -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<Highlighting> 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<Highlighting> tms= Highlighting.searchAll(methodHighlights, -1, "index", tm.getPropertyString("index"), -1, -1);
if(h==null){
List<Highlighting> 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<String,String> search=h.getProperties();
Map<String, String> 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<ABCContainerTag> 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);
}

View File

@@ -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<String>(), false));
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<String, TreeElement> branches;
private final SortedMap<String, TreeElement> 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<TreeElement> 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<TreeElement> 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<TreeElement> 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<TreeElement> 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<TreeElement> iter = leafs.values().iterator();
while (iter.hasNext()) {
TreeElement leaf = iter.next();
visitor.onLeaf(leaf);
}
}
}

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -19,7 +19,7 @@ import java.util.WeakHashMap;
*/
public class Debugger {
private static Set<DebugListener> listeners = new HashSet<>();
private static final Set<DebugListener> 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;

View File

@@ -14,13 +14,15 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<TreeNode> sel = getSelected(this);
List<TreeItem> sel = getSelected(this);
List<Tag> 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<TreeNode> getAllSubs(JTree tree, TreeNode o) {
public List<TreeItem> getAllSubs(JTree tree, TreeItem o) {
TagTreeModel tm = (TagTreeModel) tree.getModel();
List<TreeNode> ret = new ArrayList<>();
List<TreeItem> 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<TreeNode> getAllSelected(TagTree tree) {
public List<TreeItem> getAllSelected(TagTree tree) {
TreeSelectionModel tsm = tree.getSelectionModel();
TreePath[] tps = tsm.getSelectionPaths();
List<TreeNode> ret = new ArrayList<>();
List<TreeItem> 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<TreeNode> getSelected(JTree tree) {
public List<TreeItem> getSelected(JTree tree) {
TreeSelectionModel tsm = tree.getSelectionModel();
TreePath[] tps = tsm.getSelectionPaths();
List<TreeNode> ret = new ArrayList<>();
List<TreeItem> 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<Object> getSelection(SWF swf) {
List<Object> ret = new ArrayList<>();
List<TreeNode> sel = getAllSelected(this);
for (TreeNode d : sel) {
if (d.getItem().getSwf() != swf) {
public List<TreeItem> getSelection(SWF swf) {
List<TreeItem> ret = new ArrayList<>();
List<TreeItem> 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<TreeElementItem> getTagsWithType(List<TreeElementItem> list, TreeNodeType type) {
List<TreeElementItem> ret = new ArrayList<>();
for (TreeElementItem item : list) {
public List<AS3ClassTreeItem> getTagsWithType(List<AS3ClassTreeItem> list, TreeNodeType type) {
List<AS3ClassTreeItem> 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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<SWFContainerItem> swfs;
private final Map<SWF, List<TreeItem>> swfFolders;
public TagTreeModel(List<SWFList> 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<TreeItem> getSoundStreams(DefineSpriteTag sprite) {
List<TreeItem> ret = new ArrayList<>();
for (Tag t : sprite.subTags) {
if (t instanceof SoundStreamHeadTypeTag) {
ret.add(t);
}
}
return ret;
}
private void createTagList(SWF swf) {
List<TreeItem> nodeList = new ArrayList<>();
List<TreeItem> frames = new ArrayList<>();
List<TreeItem> shapes = new ArrayList<>();
List<TreeItem> morphShapes = new ArrayList<>();
List<TreeItem> sprites = new ArrayList<>();
List<TreeItem> buttons = new ArrayList<>();
List<TreeItem> images = new ArrayList<>();
List<TreeItem> fonts = new ArrayList<>();
List<TreeItem> texts = new ArrayList<>();
List<TreeItem> movies = new ArrayList<>();
List<TreeItem> sounds = new ArrayList<>();
List<TreeItem> binaryData = new ArrayList<>();
List<TreeItem> 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<SoundStreamBlockTag> 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<TreeItem> subNodes = new ArrayList<>();
List<TreeItem> 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<TreeItem> 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<TreeItem> searchTag(TreeItem obj, TreeItem parent, List<TreeItem> path) {
List<TreeItem> ret = null;
int cnt = getChildCount(parent);
for (int i = 0; i < cnt; i++) {
TreeItem n = getChild(parent, i);
List<TreeItem> 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<TreeItem> 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<TreeItem> getSwfFolders(SWF swf) {
List<TreeItem> 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) {
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<SWFContainerNode> swfs = new ArrayList<>();
public SWFBundleNode(SWFList swfList, String name) {
super(swfList);
this.name = name;
}
@Override
public String toString() {
return name;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<TreeNode> 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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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");
}