mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 20:38:08 +00:00
Merge origin/master
Conflicts: libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
@@ -41,5 +41,4 @@ public class HeaderItem implements TreeItem {
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -284,5 +284,4 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S
|
||||
public Tag getSourceTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
488
src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java
Normal file
488
src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user