Added Opening ABC file format (*.abc)

This commit is contained in:
Jindra Petřík
2022-11-20 22:12:19 +01:00
parent dd63487dd8
commit 344bdfa6ea
70 changed files with 1576 additions and 906 deletions
@@ -22,9 +22,8 @@ import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFCompression;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import com.jpexs.decompiler.flash.OpenableSourceInfo;
import com.jpexs.decompiler.flash.SearchMode;
import com.jpexs.decompiler.flash.SwfOpenException;
import com.jpexs.decompiler.flash.ValueTooLargeException;
@@ -147,7 +146,7 @@ import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.tags.base.TextImportErrorHandler;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
@@ -216,6 +215,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jpexs.decompiler.flash.Bundle;
/**
*
@@ -2009,11 +2009,11 @@ public class CommandLineArgumentParser {
File[] files = new File(folder).listFiles(getSwfFilter());
for (File file : files) {
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, file.getAbsolutePath(), file.getName());
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, file.getAbsolutePath(), file.getName());
try {
SWF swf = new SWF(new FileInputStream(file), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get(), charset);
swf.swfList = new SWFList();
swf.swfList.sourceInfo = sourceInfo;
swf.openableList = new OpenableList();
swf.openableList.sourceInfo = sourceInfo;
boolean found = false;
for (Tag tag : swf.getTags()) {
if (tag.getId() == tagId) {
@@ -2051,11 +2051,11 @@ public class CommandLineArgumentParser {
File[] files = new File(folder).listFiles(getSwfFilter());
for (File file : files) {
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, file.getAbsolutePath(), file.getName());
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, file.getAbsolutePath(), file.getName());
try {
SWF swf = new SWF(new FileInputStream(file), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get(), charset);
swf.swfList = new SWFList();
swf.swfList.sourceInfo = sourceInfo;
swf.openableList = new OpenableList();
swf.openableList.sourceInfo = sourceInfo;
boolean found = false;
for (Tag tag : swf.getTags()) {
if (tag instanceof JPEGTablesTag) {
@@ -2231,7 +2231,7 @@ public class CommandLineArgumentParser {
System.out.println("Start exporting " + inFile.getName());
}
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, inFile.getAbsolutePath(), inFile.getName());
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, inFile.getAbsolutePath(), inFile.getName());
SWF swf;
try {
swf = new SWF(new StdInAwareFileInputStream(inFile), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get(), charset);
@@ -2241,8 +2241,8 @@ public class CommandLineArgumentParser {
continue;
}
swf.swfList = new SWFList();
swf.swfList.sourceInfo = sourceInfo;
swf.openableList = new OpenableList();
swf.openableList.sourceInfo = sourceInfo;
String outDir = outDirBase.getAbsolutePath();
if (!singleFile) {
outDir = Path.combine(outDir, inFile.getName());
@@ -2705,12 +2705,12 @@ public class CommandLineArgumentParser {
}
try {
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, fileName, null);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, fileName, null);
if (!sourceInfo.isBundle()) {
System.err.println("Error: <infile> should be a bundle. (ZIP or non SWF binary file)");
System.exit(1);
}
SWFBundle bundle = sourceInfo.getBundle(noCheck, mode);
Bundle bundle = sourceInfo.getBundle(noCheck, mode);
List<Map.Entry<String, SeekableInputStream>> streamsToExtract = new ArrayList<>();
for (Map.Entry<String, SeekableInputStream> streamEntry : bundle.getAll().entrySet()) {
InputStream stream = streamEntry.getValue();
@@ -3652,8 +3652,8 @@ public class CommandLineArgumentParser {
boolean result = true;
for (String fileName : fileNames) {
try {
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, fileName, null);
Main.parseSWF(sourceInfo);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, fileName, null);
Main.parseOpenable(sourceInfo);
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
result = false;
@@ -3816,12 +3816,12 @@ public class CommandLineArgumentParser {
detectBundle = false;
break;
default:
SWFBundle bundle;
Bundle bundle;
String sfile = a;
File file = new File(sfile);
try {
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, sfile, sfile, detectBundle);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, sfile, sfile, detectBundle);
bundle = sourceInfo.getBundle(false, SearchMode.ALL);
logger.log(Level.INFO, "Load file: {0}", sourceInfo.getFile());
@@ -3977,8 +3977,8 @@ public class CommandLineArgumentParser {
try {
Configuration.dumpTags.set(true);
Configuration.parallelSpeedUp.set(false);
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, args.pop(), null);
Main.parseSWF(sourceInfo);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, args.pop(), null);
Main.parseOpenable(sourceInfo);
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
System.exit(1);
@@ -266,7 +266,7 @@ public class FolderPreviewPanel extends JPanel {
private synchronized void renderImageTask(final int index, final TreeItem treeItem) {
executor.submit(() -> {
cachedPreviews.put(index, renderImage(treeItem.getSwf(), treeItem));
cachedPreviews.put(index, renderImage((SWF)treeItem.getOpenable(), treeItem));
if (!repaintQueued) {
repaintQueued = true;
View.execInEventDispatchLater(() -> {
@@ -19,7 +19,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.browsers.cache.CacheEntry;
import com.jpexs.browsers.cache.CacheImplementation;
import com.jpexs.browsers.cache.CacheReader;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import com.jpexs.decompiler.flash.OpenableSourceInfo;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReReadableInputStream;
@@ -226,7 +226,7 @@ public class LoadFromCacheFrame extends AppFrame {
CacheEntry en = list.getSelectedValue();
if (en != null) {
ReReadableInputStream str = new ReReadableInputStream(en.getResponseDataStream());
SWFSourceInfo sourceInfo = new SWFSourceInfo(str, null, entryToFileName(en));
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(str, null, entryToFileName(en));
Main.openFile(sourceInfo);
}
}
@@ -16,7 +16,7 @@
*/
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import com.jpexs.decompiler.flash.OpenableSourceInfo;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReReadableInputStream;
@@ -164,7 +164,7 @@ public class LoadFromMemoryFrame extends AppFrame {
return;
}
str.mark(Integer.MAX_VALUE);
SWFSourceInfo sourceInfo = new SWFSourceInfo(str, null, swf.process + " [" + (index + 1) + "]");
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(str, null, swf.process + " [" + (index + 1) + "]");
Main.openFile(sourceInfo);
}
}
@@ -45,7 +45,7 @@ public class LoadingDialog extends AppDialog {
private final JProgressBar progressBar = new JProgressBar(0, 100);
public void setWroker(CancellableWorker<?> worker) {
public void setWorker(CancellableWorker<?> worker) {
this.worker = worker;
}
+333 -257
View File
@@ -28,8 +28,7 @@ import com.jpexs.debugger.flash.messages.in.InCallFunction;
import com.jpexs.decompiler.flash.ApplicationInfo;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import com.jpexs.decompiler.flash.OpenableSourceInfo;
import com.jpexs.decompiler.flash.SearchMode;
import com.jpexs.decompiler.flash.SwfOpenException;
import com.jpexs.decompiler.flash.UrlResolver;
@@ -54,7 +53,7 @@ import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImportTag;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.helpers.Cache;
@@ -133,6 +132,13 @@ import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import com.jpexs.decompiler.flash.Bundle;
import com.jpexs.decompiler.flash.OpenableSourceKind;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ABCInputStream;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.helpers.MemoryInputStream;
/**
* Main executable class
@@ -143,7 +149,7 @@ public class Main {
protected static ProxyFrame proxyFrame;
private static List<SWFSourceInfo> sourceInfos = new ArrayList<>();
private static List<OpenableSourceInfo> sourceInfos = new ArrayList<>();
public static LoadingDialog loadingDialog;
@@ -202,11 +208,10 @@ public class Main {
public static CancellableWorker importWorker = null;
public static CancellableWorker deobfuscatePCodeWorker = null;
public static CancellableWorker swfPrepareWorker = null;
public static final int LIBRARY_AIR = 0;
public static final int LIBRARY_FLASH = 1;
public static boolean isSwfAir(SWF swf) {
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(swf.getShortPathTitle());
if (conf != null) {
@@ -216,7 +221,7 @@ public class Main {
}
return false;
}
//This method makes file watcher to shut up during our own file saving
public static void startSaving(File savedFile) {
savedFiles.add(savedFile);
@@ -845,11 +850,11 @@ public class Main {
}
}
public static SWFList parseSWF(SWFSourceInfo sourceInfo) throws Exception {
SWFList result = new SWFList();
public static OpenableList parseOpenable(OpenableSourceInfo sourceInfo) throws Exception {
OpenableList result = new OpenableList();
InputStream inputStream = sourceInfo.getInputStream();
SWFBundle bundle = null;
Bundle bundle = null;
FileInputStream fis = null;
if (inputStream == null) {
inputStream = new BufferedInputStream(fis = new FileInputStream(sourceInfo.getFile()));
@@ -887,7 +892,7 @@ public class Main {
final CancellableWorker worker = this;
String fileKey = fname + "/" + streamEntry.getKey();
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(fileKey);
String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(CustomConfigurationKeys.KEY_CHARSET, Charset.defaultCharset().name());
SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() {
@Override
@@ -898,7 +903,7 @@ public class Main {
return swf;
}
};
loadingDialog.setWroker(worker);
loadingDialog.setWorker(worker);
worker.execute();
try {
@@ -910,163 +915,197 @@ public class Main {
} else {
InputStream fInputStream = inputStream;
final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
CancellableWorker<? extends Openable> worker = null;
if (sourceInfo.getKind() == OpenableSourceKind.ABC) {
CancellableWorker<ABC> abcWorker = new CancellableWorker<ABC>() {
private ABC open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
SWF dummySwf = new SWF();
dummySwf.setFileTitle(fileTitle != null ? fileTitle : file);
FileAttributesTag fileAttributes = new FileAttributesTag(dummySwf);
fileAttributes.actionScript3 = true;
dummySwf.addTag(fileAttributes);
fileAttributes.setTimelined(dummySwf);
DoABC2Tag doABC2Tag = new DoABC2Tag(dummySwf);
dummySwf.addTag(doABC2Tag);
doABC2Tag.setTimelined(dummySwf);
dummySwf.clearModified();
startWork(AppStrings.translate("work.reading.abc"), this);
return new ABC(new ABCInputStream(new MemoryInputStream(Helper.readFile(file))), dummySwf, doABC2Tag, file, fileTitle);
}
@Override
protected ABC doInBackground() throws Exception {
return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
}
CancellableWorker<SWF> worker = new CancellableWorker<SWF>() {
private boolean yestoall = false;
@Override
protected void done() {
stopWork();
}
};
worker = abcWorker;
} else if (sourceInfo.getKind() == OpenableSourceKind.SWF) {
final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
private boolean notoall = false;
CancellableWorker<SWF> swfWorker = new CancellableWorker<SWF>() {
private boolean yestoall = false;
private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
final CancellableWorker worker = this;
String shortName = fileTitle != null ? fileTitle : file;
String fileKey = shortName == null ? "" : new File(shortName).getName();
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(fileKey);
String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(CustomConfigurationKeys.KEY_CHARSET, Charset.defaultCharset().name());
private boolean notoall = false;
SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
@Override
public void progress(int p) {
startWork(AppStrings.translate("work.reading.swf"), p, worker);
}
}, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
@Override
public SWF resolveUrl(final String url) {
int opt = -1;
if (!(yestoall || notoall)) {
opt = ViewMessages.showOptionDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
if (opt == 2) {
yestoall = true;
}
if (opt == 3) {
notoall = true;
}
private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
final CancellableWorker worker = this;
String shortName = fileTitle != null ? fileTitle : file;
String fileKey = shortName == null ? "" : new File(shortName).getName();
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(fileKey);
String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(CustomConfigurationKeys.KEY_CHARSET, Charset.defaultCharset().name());
SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
@Override
public void progress(int p) {
startWork(AppStrings.translate("work.reading.swf"), p, worker);
}
if (yestoall) {
opt = 0; // yes
} else if (notoall) {
opt = 1; // no
}
if (opt == 1) //no
{
return null;
}
if (url.startsWith("http://") || url.startsWith("https://")) {
try {
URL u = new URL(url);
return open(u.openStream(), null, url); //?
} catch (Exception ex) {
//ignore
}, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
@Override
public SWF resolveUrl(final String url) {
int opt = -1;
if (!(yestoall || notoall)) {
opt = ViewMessages.showOptionDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
if (opt == 2) {
yestoall = true;
}
if (opt == 3) {
notoall = true;
}
}
} else {
File swf = new File(new File(file).getParentFile(), url);
if (swf.exists()) {
if (yestoall) {
opt = 0; // yes
} else if (notoall) {
opt = 1; // no
}
if (opt == 1) //no
{
return null;
}
if (url.startsWith("http://") || url.startsWith("https://")) {
try {
return open(new FileInputStream(swf), swf.getAbsolutePath(), swf.getName());
URL u = new URL(url);
return open(u.openStream(), null, url); //?
} catch (Exception ex) {
//ignore
}
}
// try .gfx if .swf failed
if (url.endsWith(".swf")) {
File gfx = new File(new File(file).getParentFile(), url.substring(0, url.length() - 4) + ".gfx");
if (gfx.exists()) {
} else {
File swf = new File(new File(file).getParentFile(), url);
if (swf.exists()) {
try {
return open(new FileInputStream(gfx), gfx.getAbsolutePath(), gfx.getName());
return open(new FileInputStream(swf), swf.getAbsolutePath(), swf.getName());
} catch (Exception ex) {
//ignore
}
}
}
}
Reference<SWF> ret = new Reference<>(null);
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
while (JOptionPane.YES_OPTION == ViewMessages.showConfirmDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
FileFilter allSupportedFilter = new FileFilter() {
private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
@Override
public boolean accept(File f) {
String name = f.getName().toLowerCase(Locale.ENGLISH);
for (String ext : supportedExtensions) {
if (name.endsWith(ext)) {
return true;
}
}
return f.isDirectory();
}
@Override
public String getDescription() {
String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
return AppStrings.translate("filter.supported") + " (" + exts + ")";
}
};
fc.setFileFilter(allSupportedFilter);
FileFilter swfFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".swf")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.swf");
}
};
fc.addChoosableFileFilter(swfFilter);
FileFilter gfxFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".gfx")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.gfx");
}
};
fc.addChoosableFileFilter(gfxFilter);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(getDefaultMessagesComponent());
if (returnVal == JFileChooser.APPROVE_OPTION) {
Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
File selFile = Helper.fixDialogFile(fc.getSelectedFile());
// try .gfx if .swf failed
if (url.endsWith(".swf")) {
File gfx = new File(new File(file).getParentFile(), url.substring(0, url.length() - 4) + ".gfx");
if (gfx.exists()) {
try {
ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
break;
return open(new FileInputStream(gfx), gfx.getAbsolutePath(), gfx.getName());
} catch (Exception ex) {
//ignore;
//ignore
}
} else {
break;
}
}
}
});
return ret.getVal();
}
}, charset);
return swf;
}
Reference<SWF> ret = new Reference<>(null);
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
@Override
public SWF doInBackground() throws Exception {
return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
}
};
while (JOptionPane.YES_OPTION == ViewMessages.showConfirmDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
FileFilter allSupportedFilter = new FileFilter() {
private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
@Override
public boolean accept(File f) {
String name = f.getName().toLowerCase(Locale.ENGLISH);
for (String ext : supportedExtensions) {
if (name.endsWith(ext)) {
return true;
}
}
return f.isDirectory();
}
@Override
public String getDescription() {
String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
return AppStrings.translate("filter.supported") + " (" + exts + ")";
}
};
fc.setFileFilter(allSupportedFilter);
FileFilter swfFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".swf")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.swf");
}
};
fc.addChoosableFileFilter(swfFilter);
FileFilter gfxFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".gfx")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.gfx");
}
};
fc.addChoosableFileFilter(gfxFilter);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(getDefaultMessagesComponent());
if (returnVal == JFileChooser.APPROVE_OPTION) {
Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
File selFile = Helper.fixDialogFile(fc.getSelectedFile());
try {
ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
break;
} catch (Exception ex) {
//ignore;
}
} else {
break;
}
}
}
});
return ret.getVal();
}
}, charset);
return swf;
}
@Override
public SWF doInBackground() throws Exception {
return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
}
};
worker = swfWorker;
}
if (loadingDialog != null) {
loadingDialog.setWroker(worker);
loadingDialog.setWorker(worker);
}
worker.execute();
@@ -1087,67 +1126,72 @@ public class Main {
}
result.sourceInfo = sourceInfo;
for (SWF swf : result) {
logger.log(Level.INFO, "");
logger.log(Level.INFO, "== File information ==");
logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
logger.log(Level.INFO, "Flash version: {0}", swf.version);
int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
logger.log(Level.INFO, "Width: {0}", width);
logger.log(Level.INFO, "Height: {0}", height);
for (Openable openable : result) {
swf.swfList = result;
swf.addEventListener(new EventListener() {
@Override
public void handleExportingEvent(String type, int index, int count, Object data) {
String text = AppStrings.translate("work.exporting");
if (type != null && type.length() > 0) {
text += " " + type;
openable.setOpenableList(result);
if (openable instanceof SWF) {
SWF swf = (SWF) openable;
logger.log(Level.INFO, "");
logger.log(Level.INFO, "== File information ==");
logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
logger.log(Level.INFO, "Flash version: {0}", swf.version);
int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
logger.log(Level.INFO, "Width: {0}", width);
logger.log(Level.INFO, "Height: {0}", height);
swf.addEventListener(new EventListener() {
@Override
public void handleExportingEvent(String type, int index, int count, Object data) {
String text = AppStrings.translate("work.exporting");
if (type != null && type.length() > 0) {
text += " " + type;
}
continueWork(text + " " + index + "/" + count + " " + data);
}
continueWork(text + " " + index + "/" + count + " " + data);
}
@Override
public void handleExportedEvent(String type, int index, int count, Object data) {
String text = AppStrings.translate("work.exported");
if (type != null && type.length() > 0) {
text += " " + type;
}
@Override
public void handleExportedEvent(String type, int index, int count, Object data) {
String text = AppStrings.translate("work.exported");
if (type != null && type.length() > 0) {
text += " " + type;
continueWork(text + " " + index + "/" + count + " " + data);
}
continueWork(text + " " + index + "/" + count + " " + data);
}
@Override
public void handleEvent(String event, Object data) {
if (event.equals("exporting") || event.equals("exported")) {
throw new Error("Event is not supported by this handler.");
@Override
public void handleEvent(String event, Object data) {
if (event.equals("exporting") || event.equals("exported")) {
throw new Error("Event is not supported by this handler.");
}
if (event.equals("getVariables")) {
continueWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data);
}
if (event.equals("deobfuscate")) {
continueWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data);
}
if (event.equals("deobfuscate_pcode")) {
startWork(AppStrings.translate("work.deobfuscating_pcode") + "..." + (String) data, deobfuscatePCodeWorker);
}
if (event.equals("rename")) {
continueWork(AppStrings.translate("work.renaming") + "..." + (String) data);
}
if (event.equals("importing_as")) {
startWork(AppStrings.translate("work.importing_as") + "..." + (String) data, importWorker);
}
}
if (event.equals("getVariables")) {
continueWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data);
}
if (event.equals("deobfuscate")) {
continueWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data);
}
if (event.equals("deobfuscate_pcode")) {
startWork(AppStrings.translate("work.deobfuscating_pcode") + "..." + (String) data, deobfuscatePCodeWorker);
}
if (event.equals("rename")) {
continueWork(AppStrings.translate("work.renaming") + "..." + (String) data);
}
if (event.equals("importing_as")) {
startWork(AppStrings.translate("work.importing_as") + "..." + (String) data, importWorker);
}
}
});
});
}
}
return result;
}
public static void saveFile(SWF swf, String outfile) throws IOException {
saveFile(swf, outfile, SaveFileMode.SAVE, null);
public static void saveFile(Openable openable, String outfile) throws IOException {
saveFile(openable, outfile, SaveFileMode.SAVE, null);
}
public static void saveFileToExe(SWF swf, ExeExportMode exeExportMode, File tmpFile) throws IOException {
@@ -1206,22 +1250,22 @@ public class Main {
}
}
public static void saveFile(SWF swf, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
public static void saveFile(Openable openable, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
File savedFile = new File(outfile);
startSaving(savedFile);
if (mode == SaveFileMode.SAVEAS && swf.swfList != null /*SWF in binarydata has null*/ && !swf.swfList.isBundle()) {
swf.setFile(outfile);
swf.swfList.sourceInfo.setFile(outfile);
if (mode == SaveFileMode.SAVEAS && openable.getOpenableList() != null /*SWF in binarydata has null*/ && !openable.getOpenableList().isBundle()) {
openable.setFile(outfile);
openable.getOpenableList().sourceInfo.setFile(outfile);
}
File outfileF = new File(outfile);
File tmpFile = new File(outfile + ".tmp");
try {
if (mode == SaveFileMode.EXE) {
saveFileToExe(swf, exeExportMode, tmpFile);
saveFileToExe((SWF)openable, exeExportMode, tmpFile);
} else {
try ( FileOutputStream fos = new FileOutputStream(tmpFile); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
swf.saveTo(bos);
openable.saveTo(bos);
}
}
} catch (Throwable t) {
@@ -1249,39 +1293,39 @@ public class Main {
private static class OpenFileWorker extends SwingWorker {
private final SWFSourceInfo[] sourceInfos;
private final OpenableSourceInfo[] sourceInfos;
private final Runnable executeAfterOpen;
private final int[] reloadIndices;
public OpenFileWorker(SWFSourceInfo sourceInfo) {
public OpenFileWorker(OpenableSourceInfo sourceInfo) {
this(sourceInfo, -1);
}
public OpenFileWorker(SWFSourceInfo sourceInfo, int reloadIndex) {
public OpenFileWorker(OpenableSourceInfo sourceInfo, int reloadIndex) {
this(sourceInfo, null, reloadIndex);
}
public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
public OpenFileWorker(OpenableSourceInfo sourceInfo, Runnable executeAfterOpen) {
this(sourceInfo, executeAfterOpen, -1);
}
public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
this.sourceInfos = new SWFSourceInfo[]{sourceInfo};
public OpenFileWorker(OpenableSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
this.sourceInfos = new OpenableSourceInfo[]{sourceInfo};
this.executeAfterOpen = executeAfterOpen;
this.reloadIndices = new int[]{reloadIndex};
}
public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
public OpenFileWorker(OpenableSourceInfo[] sourceInfos) {
this(sourceInfos, null, null);
}
public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
public OpenFileWorker(OpenableSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
this(sourceInfos, executeAfterOpen, null);
}
public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
public OpenFileWorker(OpenableSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
this.sourceInfos = sourceInfos;
this.executeAfterOpen = executeAfterOpen;
int[] indices = new int[sourceInfos.length];
@@ -1295,13 +1339,14 @@ public class Main {
protected Object doInBackground() throws Exception {
boolean first = true;
SWF firstSWF = null;
Openable firstOpenable = null;
for (int index = 0; index < sourceInfos.length; index++) {
SWFSourceInfo sourceInfo = sourceInfos[index];
SWFList swfs = null;
OpenableSourceInfo sourceInfo = sourceInfos[index];
OpenableList openables = null;
try {
Main.startWork(AppStrings.translate("work.reading.swf") + "...", null);
try {
swfs = parseSWF(sourceInfo);
openables = parseOpenable(sourceInfo);
} catch (ExecutionException ex) {
Throwable cause = ex.getCause();
if (cause instanceof SwfOpenException) {
@@ -1324,11 +1369,14 @@ public class Main {
continue;
}
final SWFList swfs1 = swfs;
final OpenableList openables1 = openables;
final boolean first1 = first;
first = false;
if (firstSWF == null && swfs1.size() > 0) {
firstSWF = swfs1.get(0);
if (firstOpenable == null && openables1.size() > 0) {
firstOpenable = openables1.get(0);
}
if (firstSWF == null && openables1.size() > 0 && (openables1.get(0) instanceof SWF)) {
firstSWF = (SWF) openables1.get(0);
}
final int findex = index;
@@ -1337,9 +1385,9 @@ public class Main {
Main.startWork(AppStrings.translate("work.creatingwindow") + "...", null);
ensureMainFrame();
if (reloadIndices[findex] > -1) {
mainFrame.getPanel().loadSwfAtPos(swfs1, reloadIndices[findex]);
mainFrame.getPanel().loadSwfAtPos(openables1, reloadIndices[findex]);
} else {
mainFrame.getPanel().load(swfs1, first1);
mainFrame.getPanel().load(openables1, first1);
}
});
} catch (Exception ex) {
@@ -1351,6 +1399,7 @@ public class Main {
shouldCloseWhenClosingLoadingDialog = false;
final SWF fswf = firstSWF;
final Openable fopenable = firstOpenable;
View.execInEventDispatch(() -> {
if (mainFrame != null) {
mainFrame.setVisible(true);
@@ -1358,18 +1407,18 @@ public class Main {
Main.stopWork();
if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) {
if (mainFrame != null && Configuration.gotoMainClassOnStartup.get() && fswf != null) {
mainFrame.getPanel().gotoDocumentClass(fswf);
}
if (mainFrame != null && fswf != null) {
SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortPathTitle());
if (mainFrame != null && fopenable != null) {
SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fopenable.getShortPathTitle());
String resourcesPathStr = null;
String tagListPathStr = null;
if (swfConf != null) {
resourcesPathStr = swfConf.lastSelectedPath;
}
SwfSpecificCustomConfiguration swfCustomConf = Configuration.getSwfSpecificCustomConfiguration(fswf.getShortPathTitle());
SwfSpecificCustomConfiguration swfCustomConf = Configuration.getSwfSpecificCustomConfiguration(fopenable.getShortPathTitle());
if (swfCustomConf != null) {
resourcesPathStr = swfCustomConf.getCustomData(CustomConfigurationKeys.KEY_LAST_SELECTED_PATH_RESOURCES, resourcesPathStr);
tagListPathStr = swfCustomConf.getCustomData(CustomConfigurationKeys.KEY_LAST_SELECTED_PATH_TAGLIST, null);
@@ -1406,7 +1455,7 @@ public class Main {
sourceInfos.remove(i);
}
}
SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
OpenableSourceInfo[] sourceInfosCopy = new OpenableSourceInfo[sourceInfos.size()];
sourceInfos.toArray(sourceInfosCopy);
sourceInfos.clear();
openFile(sourceInfosCopy);
@@ -1472,7 +1521,7 @@ public class Main {
return OpenFileResult.NOT_FOUND;
}
swfFile = file.getCanonicalPath();
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(null, swfFile, fileTitle);
OpenFileResult openResult = openFile(sourceInfo);
return openResult;
} catch (IOException ex) {
@@ -1481,31 +1530,31 @@ public class Main {
}
}
public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
public static OpenFileResult openFile(OpenableSourceInfo sourceInfo) {
View.checkAccess();
return openFile(new SWFSourceInfo[]{sourceInfo});
return openFile(new OpenableSourceInfo[]{sourceInfo});
}
public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
public static OpenFileResult openFile(OpenableSourceInfo sourceInfo, Runnable executeAfterOpen) {
View.checkAccess();
return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen);
return openFile(new OpenableSourceInfo[]{sourceInfo}, executeAfterOpen);
}
public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
public static OpenFileResult openFile(OpenableSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
View.checkAccess();
return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
return openFile(new OpenableSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
}
public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
public static OpenFileResult openFile(OpenableSourceInfo[] newSourceInfos) {
View.checkAccess();
return openFile(newSourceInfos, null);
}
public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
public static OpenFileResult openFile(OpenableSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
View.checkAccess();
return openFile(newSourceInfos, executeAfterOpen, null);
@@ -1524,9 +1573,9 @@ public class Main {
}
String ext = newFileDialog.isGfx() ? "gfx" : "swf";
String fileTitle = AppStrings.translate("new.filename") + "." + ext;
SWFSourceInfo sourceInfo = new SWFSourceInfo(fileTitle);
OpenableSourceInfo sourceInfo = new OpenableSourceInfo(fileTitle);
sourceInfos.add(sourceInfo);
SWFList list = new SWFList();
OpenableList list = new OpenableList();
list.sourceInfo = sourceInfo;
SWF swf = new SWF();
swf.setFile(null);
@@ -1559,7 +1608,7 @@ public class Main {
swf.frameCount = 1;
swf.hasEndTag = true;
list.add(swf);
swf.swfList = list;
swf.openableList = list;
mainFrame.getPanel().load(list, true);
//select first frame
@@ -1567,7 +1616,7 @@ public class Main {
}
}
public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
public static OpenFileResult openFile(OpenableSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
View.checkAccess();
if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
@@ -1581,7 +1630,7 @@ public class Main {
loadingDialog.setVisible(true);
for (int i = 0; i < newSourceInfos.length; i++) {
SWFSourceInfo si = newSourceInfos[i];
OpenableSourceInfo si = newSourceInfos[i];
String fileName = si.getFile();
if (fileName != null) {
Configuration.addRecentFile(fileName);
@@ -1614,14 +1663,14 @@ public class Main {
return OpenFileResult.OK;
}
public static void closeFile(SWFList swf) {
public static void closeFile(OpenableList openableList) {
View.checkAccess();
sourceInfos.remove(swf.sourceInfo);
mainFrame.getPanel().close(swf);
sourceInfos.remove(openableList.sourceInfo);
mainFrame.getPanel().close(openableList);
}
public static void reloadFile(SWFList swf) {
public static void reloadFile(OpenableList swf) {
View.checkAccess();
openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
@@ -1629,7 +1678,7 @@ public class Main {
public static void reloadFile(File file) {
for (int i = 0; i < sourceInfos.size(); i++) {
SWFSourceInfo info = sourceInfos.get(i);
OpenableSourceInfo info = sourceInfos.get(i);
if (info.getFile() == null) {
continue;
}
@@ -1655,15 +1704,15 @@ public class Main {
return closeResult;
}
public static boolean saveFileDialog(SWF swf, final SaveFileMode mode) {
public static boolean saveFileDialog(Openable openable, final SaveFileMode mode) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
String ext = ".swf";
switch (mode) {
case SAVE:
case SAVEAS:
if (swf.getFile() != null) {
ext = Path.getExtension(swf.getFile());
if (openable.getFile() != null) {
ext = Path.getExtension(openable.getFile());
}
break;
case EXE:
@@ -1695,6 +1744,18 @@ public class Main {
}
};
FileFilter abcFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".abc")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.abc");
}
};
ExeExportMode exeExportMode = null;
if (mode == SaveFileMode.EXE) {
exeExportMode = Configuration.exeExportMode.get();
@@ -1734,12 +1795,14 @@ public class Main {
}
};
fc.setFileFilter(exeFilter);
} else if (swf.gfx) {
} else if ((openable instanceof SWF) && ((SWF)openable).gfx) {
fc.addChoosableFileFilter(swfFilter);
fc.setFileFilter(gfxFilter);
} else {
} else if (openable instanceof SWF) {
fc.setFileFilter(swfFilter);
fc.addChoosableFileFilter(gfxFilter);
} else if (openable instanceof ABC) {
fc.setFileFilter(abcFilter);
}
final String extension = ext;
fc.setAcceptAllFileFilterUsed(false);
@@ -1752,15 +1815,15 @@ public class Main {
if (!fileName.toLowerCase(Locale.ENGLISH).endsWith(extension)) {
fileName += extension;
}
swf.gfx = false;
((SWF)openable).gfx = false;
}
if (selFilter == gfxFilter) {
if (!fileName.toLowerCase(Locale.ENGLISH).endsWith(".gfx")) {
fileName += ".gfx";
}
swf.gfx = true;
((SWF)openable).gfx = true;
}
Main.saveFile(swf, fileName, mode, exeExportMode);
Main.saveFile(openable, fileName, mode, exeExportMode);
Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
return true;
} catch (Exception | OutOfMemoryError | StackOverflowError ex) {
@@ -1814,7 +1877,7 @@ public class Main {
}
fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
FileFilter allSupportedFilter = new FileFilter() {
private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip", ".iggy"};
private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip", ".iggy", ".abc"};
@Override
public boolean accept(File f) {
@@ -1885,6 +1948,19 @@ public class Main {
}
};
fc.addChoosableFileFilter(iggyFilter);
FileFilter abcFilter = new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".abc")) || (f.isDirectory());
}
@Override
public String getDescription() {
return AppStrings.translate("filter.abc");
}
};
fc.addChoosableFileFilter(abcFilter);
FileFilter zipFilter = new FileFilter() {
@Override
@@ -2031,7 +2107,7 @@ public class Main {
continue;
}
for (SWFSourceInfo info : sourceInfos) {
for (OpenableSourceInfo info : sourceInfos) {
final String infoFile = info.getFile();
if (infoFile != null && new File(infoFile).equals(fullPath)) {
View.execInEventDispatchLater(new Runnable() {
@@ -2074,7 +2150,7 @@ public class Main {
@Override
public void onLoaderBytes(String clientId, byte[] data) {
String hash = md5(data);
for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
for (OpenableList sl : Main.getMainFrame().getPanel().getSwfs()) {
for (int s = 0; s < sl.size(); s++) {
String t = sl.get(s).getFileTitle();
if (t == null) {
@@ -2095,7 +2171,7 @@ public class Main {
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
openFile(new SWFSourceInfo(null, tfile, titleWithHash));
openFile(new OpenableSourceInfo(null, tfile, titleWithHash));
}
});
} catch (IOException ex) {
@@ -2445,10 +2521,10 @@ public class Main {
}
}
}
SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()];
OpenableSourceInfo[] sourceInfos = new OpenableSourceInfo[exfiles.size()];
for (int i = 0; i < exfiles.size(); i++) {
String extitle = extitles.get(i);
sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
sourceInfos[i] = new OpenableSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
}
if (sourceInfos.length > 0) {
openingFiles = true;
@@ -2559,7 +2635,7 @@ public class Main {
searchResultsStorage.save();
} catch (IOException ex) {
//ignore
}
}
Configuration.saveConfig();
if (mainFrame != null && mainFrame.getPanel() != null) {
mainFrame.getPanel().unloadFlashPlayer();
@@ -19,8 +19,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.debugger.flash.DebuggerCommands;
import com.jpexs.decompiler.flash.ApplicationInfo;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import com.jpexs.decompiler.flash.OpenableSourceInfo;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener;
import com.jpexs.decompiler.flash.console.ContextMenuTools;
@@ -28,7 +27,7 @@ import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
import com.jpexs.decompiler.flash.gui.helpers.CheckResources;
import com.jpexs.decompiler.flash.search.ScriptSearchResult;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Cache;
@@ -65,6 +64,8 @@ import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import com.jpexs.decompiler.flash.Bundle;
import com.jpexs.decompiler.flash.treeitems.Openable;
/**
*
@@ -76,7 +77,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
private KeyEventDispatcher keyEventDispatcher;
private SWF swf;
private Openable openable;
private ConfigurationItemChangeListener<Boolean> configListenerAutoDeobfuscate;
@@ -131,18 +132,18 @@ public abstract class MainFrameMenu implements MenuBuilder {
return true;
}
private boolean saveSwf(SWF swf) {
private boolean saveOpenable(Openable openable) {
boolean saved = false;
if (swf != null) {
if (swf.swfList != null && swf.swfList.isBundle()) {
File savedFile = new File(swf.swfList.sourceInfo.getFile());
if (openable != null) {
if (openable.getOpenableList() != null && openable.getOpenableList().isBundle()) {
File savedFile = new File(openable.getOpenableList().sourceInfo.getFile());
Main.startSaving(savedFile);
SWFBundle bundle = swf.swfList.bundle;
Bundle bundle = openable.getOpenableList().bundle;
if (!bundle.isReadOnly()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
swf.saveTo(baos);
saved = bundle.putSWF(swf.getFileTitle(), new ByteArrayInputStream(baos.toByteArray()));
openable.saveTo(baos);
saved = bundle.putOpenable(openable.getFileTitle(), new ByteArrayInputStream(baos.toByteArray()));
} catch (IOException ex) {
Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
}
@@ -150,29 +151,30 @@ public abstract class MainFrameMenu implements MenuBuilder {
ViewMessages.showMessageDialog(mainFrame.getWindow(), translate("error.readonly.cannotSave"), translate("error"), JOptionPane.ERROR_MESSAGE);
}
Main.stopSaving(savedFile);
} else if (swf.binaryData != null) {
} else if ((openable instanceof SWF) && ((SWF)openable).binaryData != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
swf.saveTo(baos);
openable.saveTo(baos);
SWF swf = (SWF) openable;
swf.binaryData.binaryData = new ByteArrayRange(baos.toByteArray());
swf.binaryData.setModified(true);
saved = saveSwf(swf.binaryData.getSwf()); //save parent swf
saved = saveOpenable(swf.binaryData.getSwf()); //save parent swf
} catch (IOException ex) {
Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
}
} else if (swf.getFile() == null) {
saved = saveAs(swf, SaveFileMode.SAVEAS);
} else if (openable.getFile() == null) {
saved = saveAs(openable, SaveFileMode.SAVEAS);
} else {
try {
Main.saveFile(swf, swf.getFile());
Main.saveFile(openable, openable.getFile());
saved = true;
} catch (Exception | OutOfMemoryError | StackOverflowError ex) {
Main.handleSaveError(ex);
}
}
if (saved) {
swf.clearModified();
mainFrame.getPanel().refreshTree(swf);
openable.clearModified();
mainFrame.getPanel().refreshTree(openable);
}
}
return saved;
@@ -186,7 +188,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
if (Main.isWorking()) {
return false;
}
return saveSwf(swf);
return saveOpenable(openable);
}
protected boolean saveAsActionPerformed(ActionEvent evt) {
@@ -194,11 +196,11 @@ public abstract class MainFrameMenu implements MenuBuilder {
return false;
}
if (swf != null) {
if (saveAs(swf, SaveFileMode.SAVEAS)) {
if (swf.swfList != null) { //binarydata won't clear modified on saveas
if (!isSwfReadOnly(swf)) {
swf.clearModified();
if (openable != null) {
if (saveAs(openable, SaveFileMode.SAVEAS)) {
if (openable.getOpenableList() != null) { //binarydata won't clear modified on saveas
if (!isSwfReadOnly(openable)) {
openable.clearModified();
}
}
}
@@ -209,15 +211,15 @@ public abstract class MainFrameMenu implements MenuBuilder {
return false;
}
private boolean isSwfReadOnly(SWF swf) {
return swf.swfList != null && swf.swfList.bundle != null && swf.swfList.bundle.isReadOnly();
private boolean isSwfReadOnly(Openable openable) {
return openable.getOpenableList() != null && openable.getOpenableList().bundle != null && openable.getOpenableList().bundle.isReadOnly();
}
private boolean saveAs(SWF swf, SaveFileMode mode) {
private boolean saveAs(Openable openable, SaveFileMode mode) {
View.checkAccess();
if (Main.saveFileDialog(swf, mode)) {
updateComponents(swf);
if (Main.saveFileDialog(openable, mode)) {
updateComponents(openable);
return true;
}
return false;
@@ -228,8 +230,8 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
if (swf != null) {
saveAs(swf, SaveFileMode.EXE);
if (openable != null) {
saveAs(openable, SaveFileMode.EXE);
}
}
@@ -238,11 +240,11 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
if (swf == null) {
if (openable == null) {
return;
}
Main.closeFile(swf.swfList);
swf = null;
Main.closeFile(openable.getOpenableList());
openable = null;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
@@ -257,10 +259,10 @@ public abstract class MainFrameMenu implements MenuBuilder {
return false;
}
if (swf != null) {
if (openable != null) {
boolean result = Main.closeAll();
if (result) {
swf = null;
openable = null;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
@@ -280,7 +282,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().importText(swf);
mainFrame.getPanel().importText((SWF) openable);
}
protected void importScriptActionPerformed(ActionEvent evt) {
@@ -288,28 +290,28 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().importScript(swf);
mainFrame.getPanel().importScript((SWF) openable);
}
protected void importImagesActionPerformed(ActionEvent evt) {
if (Main.isWorking()) {
return;
}
mainFrame.getPanel().importImage(swf);
mainFrame.getPanel().importImage((SWF) openable);
}
protected void importShapesActionPerformed(ActionEvent evt) {
if (Main.isWorking()) {
return;
}
mainFrame.getPanel().importShape(swf, false);
mainFrame.getPanel().importShape((SWF) openable, false);
}
protected void importShapesNoFillActionPerformed(ActionEvent evt) {
if (Main.isWorking()) {
return;
}
mainFrame.getPanel().importShape(swf, true);
mainFrame.getPanel().importShape((SWF) openable, true);
}
protected void importSymbolClassActionPerformed(ActionEvent evt) {
@@ -317,7 +319,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().importSymbolClass(swf);
mainFrame.getPanel().importSymbolClass((SWF) openable);
}
protected boolean exportAllActionPerformed(ActionEvent evt) {
@@ -339,7 +341,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
protected boolean export(boolean onlySelected) {
View.checkAccess();
if (swf != null) {
if (openable != null) {
mainFrame.getPanel().export(onlySelected);
return true;
}
@@ -352,7 +354,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().exportFla(swf);
mainFrame.getPanel().exportFla((SWF) openable);
}
protected void importXmlActionPerformed(ActionEvent evt) {
@@ -386,8 +388,8 @@ public abstract class MainFrameMenu implements MenuBuilder {
protected boolean search(ActionEvent evt, Boolean searchInText) {
View.checkAccess();
if (swf != null) {
mainFrame.getPanel().searchInActionScriptOrText(searchInText, swf, false);
if (openable != null) {
mainFrame.getPanel().searchInActionScriptOrText(searchInText, openable, false);
return true;
}
@@ -395,7 +397,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected boolean replaceActionPerformed(ActionEvent evt) {
if (swf != null) {
if (openable != null) {
mainFrame.getPanel().replaceText();
return true;
}
@@ -421,7 +423,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().renameOneIdentifier(swf);
mainFrame.getPanel().renameOneIdentifier((SWF) openable);
}
protected void renameColliding(ActionEvent evt) {
@@ -431,7 +433,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().renameColliding(swf);
mainFrame.getPanel().renameColliding(openable);
}
protected void renameInvalidIdentifiers(ActionEvent evt) {
@@ -441,7 +443,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
return;
}
mainFrame.getPanel().renameIdentifiers(swf);
mainFrame.getPanel().renameIdentifiers(openable);
}
protected void deobfuscationActionPerformed(ActionEvent evt) {
@@ -463,7 +465,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected void switchDebugger() {
DebuggerTools.switchDebugger(swf);
DebuggerTools.switchDebugger((SWF) openable);
}
protected void debuggerShowLogActionPerformed(ActionEvent evt) {
@@ -471,7 +473,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected void debuggerInjectLoader(ActionEvent evt) {
DebuggerTools.injectDebugLoader(swf);
DebuggerTools.injectDebugLoader((SWF) openable);
refreshDecompiled();
}
@@ -480,7 +482,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
rtd.setVisible(true);
if (rtd.getValue() != null) {
String fname = rtd.getValue();
DebuggerTools.replaceTraceCalls(swf, fname);
DebuggerTools.replaceTraceCalls((SWF) openable, fname);
mainFrame.getPanel().refreshDecompiled();
Configuration.lastDebuggerReplaceFunction.set(rtd.getValue());
}
@@ -499,11 +501,17 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected void removeNonScripts() {
mainFrame.getPanel().removeNonScripts(swf);
if (openable instanceof SWF) {
return;
}
mainFrame.getPanel().removeNonScripts((SWF) openable);
}
protected void removeExceptSelected() {
mainFrame.getPanel().removeExceptSelected(swf);
if (openable instanceof SWF) {
return;
}
mainFrame.getPanel().removeExceptSelected((SWF) openable);
}
protected void refreshDecompiled() {
@@ -602,14 +610,17 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected boolean reloadActionPerformed(ActionEvent evt) {
if (swf != null) {
if (openable != null) {
if (!Configuration.showCloseConfirmation.get() || ViewMessages.showConfirmDialog(Main.getDefaultMessagesComponent(), translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
if (swf.swfList == null) {
if (swf.binaryData != null) {
mainFrame.getPanel().loadFromBinaryTag(swf.binaryData);
if (openable.getOpenableList() == null) {
if (openable instanceof SWF) {
SWF swf = (SWF) openable;
if (swf.binaryData != null) {
mainFrame.getPanel().loadFromBinaryTag(swf.binaryData);
}
}
} else {
Main.reloadFile(swf.swfList);
Main.reloadFile(openable.getOpenableList());
}
}
}
@@ -617,7 +628,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
protected boolean reloadAllActionPerformed(ActionEvent evt) {
if (swf != null) {
if (openable != null) {
if (!Configuration.showCloseConfirmation.get() || ViewMessages.showConfirmDialog(Main.getDefaultMessagesComponent(), translate("message.confirm.reloadAll"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
Main.reloadApp();
}
@@ -769,39 +780,47 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
public void updateComponents() {
updateComponents(swf);
updateComponents(openable);
}
public void updateComponents(SWF swf) {
this.swf = swf;
public void updateComponents(Openable openable) {
this.openable = openable;
boolean isRunning = Main.isRunning();
boolean isDebugRunning = Main.isDebugRunning();
boolean isDebugPaused = Main.isDebugPaused();
boolean isRunningOrDebugging = isRunning || isDebugRunning;
boolean swfSelected = swf != null;
SWF swf = (openable instanceof SWF) ? (SWF) openable : null;
boolean openableSelected = openable != null;
boolean swfSelected = openable instanceof SWF;
boolean isWorking = Main.isWorking();
List<ABCContainerTag> abcList = swf != null ? swf.getAbcList() : null;
boolean hasAbc = swfSelected && abcList != null && !abcList.isEmpty();
boolean hasAbc = openableSelected && abcList != null && !abcList.isEmpty();
boolean hasDebugger = hasAbc && DebuggerTools.hasDebugger(swf);
MainPanel mainPanel = mainFrame.getPanel();
boolean swfLoaded = mainPanel != null ? !mainPanel.getSwfs().isEmpty() : false;
boolean swfIsNew = swfSelected && swf.swfList != null && swf.swfList.sourceInfo.isEmpty();
boolean swfIsNew = openableSelected && openable.getOpenableList() != null && openable.getOpenableList().sourceInfo.isEmpty();
boolean allSameSwf = true;
if (mainPanel != null) {
List<TreeItem> items = mainPanel.getCurrentTree().getSelected();
SWF firstSwf = null;
for (TreeItem item : items) {
if (item instanceof SWFList) {
if (item instanceof OpenableList) {
allSameSwf = false;
break;
}
if (firstSwf == null) {
firstSwf = item.getSwf();
Openable fopenable = item.getOpenable();
if (fopenable instanceof SWF) {
firstSwf = (SWF) fopenable;
} else {
allSameSwf = false;
break;
}
} else {
if (item.getSwf() != firstSwf) {
if (item.getOpenable() != firstSwf) {
allSameSwf = false;
break;
}
@@ -811,39 +830,39 @@ public abstract class MainFrameMenu implements MenuBuilder {
setMenuEnabled("_/open", !isWorking);
setMenuEnabled("/file/open", !isWorking);
setMenuEnabled("_/save", swfSelected && !isWorking);
setMenuEnabled("/file/save", swfSelected && !isWorking);
setMenuEnabled("_/saveAs", swfSelected && !isWorking);
setMenuEnabled("/file/saveAs", swfSelected && !isWorking);
setMenuEnabled("_/save", openableSelected && !isWorking);
setMenuEnabled("/file/save", openableSelected && !isWorking);
setMenuEnabled("_/saveAs", openableSelected && !isWorking);
setMenuEnabled("/file/saveAs", openableSelected && !isWorking);
setMenuEnabled("/file/saveAsExe", swfSelected && !isWorking);
setMenuEnabled("_/close", swfSelected && !isWorking);
setMenuEnabled("/file/close", swfSelected && !isWorking);
setMenuEnabled("_/close", openableSelected && !isWorking);
setMenuEnabled("/file/close", openableSelected && !isWorking);
setMenuEnabled("_/closeAll", swfLoaded && !isWorking);
setMenuEnabled("/file/closeAll", swfLoaded && !isWorking);
setMenuEnabled("/file/reload", swfSelected && !swfIsNew && !isWorking);
setMenuEnabled("/file/reload", openableSelected && !swfIsNew && !isWorking);
setMenuEnabled("/file/export", swfSelected);
setMenuEnabled("_/exportAll", swfSelected && !isWorking);
setMenuEnabled("/file/export/exportAll", swfSelected && !isWorking);
setMenuEnabled("/file/export", openableSelected);
setMenuEnabled("_/exportAll", openableSelected && !isWorking);
setMenuEnabled("/file/export/exportAll", openableSelected && !isWorking);
setMenuEnabled("_/exportFla", swfSelected && !isWorking);
setMenuEnabled("/file/export/exportFla", allSameSwf && swfSelected && !isWorking);
setMenuEnabled("_/exportSelected", swfSelected && !isWorking);
setMenuEnabled("/file/export/exportSelected", swfSelected && !isWorking);
setMenuEnabled("/file/export/exportFla", allSameSwf && openableSelected && !isWorking);
setMenuEnabled("_/exportSelected", openableSelected && !isWorking);
setMenuEnabled("/file/export/exportSelected", openableSelected && !isWorking);
setMenuEnabled("/file/export/exportXml", swfSelected && !isWorking);
setMenuEnabled("/file/import", swfSelected);
setMenuEnabled("/file/import", openableSelected);
setMenuEnabled("/file/import/importText", allSameSwf && swfSelected && !isWorking);
setMenuEnabled("/file/import/importScript", allSameSwf && swfSelected && !isWorking);
setMenuEnabled("/file/import/importOther", allSameSwf && swfSelected && !isWorking);
setMenuEnabled("/file/import/importXml", allSameSwf && swfSelected && !isWorking);
setMenuEnabled("/tools/deobfuscation", swfSelected);
setMenuEnabled("/tools/deobfuscation", openableSelected);
setMenuEnabled("/tools/deobfuscation/renameOneIdentifier", swfSelected && !isWorking);
setMenuEnabled("/tools/deobfuscation/renameInvalidIdentifiers", swfSelected && !isWorking);
setMenuEnabled("/tools/deobfuscation/renameColliding", swfSelected && !isWorking);
setMenuEnabled("/tools/deobfuscation/deobfuscation", hasAbc);
setMenuEnabled("/tools/search", swfSelected);
setMenuEnabled("/tools/search", openableSelected);
setMenuEnabled("/tools/replace", swfSelected);
setMenuEnabled("/tools/timeline", swfSelected);
setMenuEnabled("/tools/showProxy", !isWorking);
@@ -880,9 +899,9 @@ public abstract class MainFrameMenu implements MenuBuilder {
StringBuilder titleBuilder = new StringBuilder();
titleBuilder.append(ApplicationInfo.applicationVerName);
if (Configuration.displayFileName.get() && swf != null) {
if (Configuration.displayFileName.get() && openable != null) {
titleBuilder.append(" - ");
titleBuilder.append(swf.getFullPathTitle());
titleBuilder.append(openable.getFullPathTitle());
}
mainFrame.setTitle(titleBuilder.toString());
@@ -1212,12 +1231,12 @@ public abstract class MainFrameMenu implements MenuBuilder {
addMenuItem("/debug/openTestSwfs", "Open test SWFs", "continue16", e -> {
String path;
SWFSourceInfo[] sourceInfos = new SWFSourceInfo[2];
OpenableSourceInfo[] sourceInfos = new OpenableSourceInfo[2];
String mainPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as2\\as2.swf";
sourceInfos[0] = new SWFSourceInfo(null, path, null);
sourceInfos[0] = new OpenableSourceInfo(null, path, null);
path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as3\\as3.swf";
sourceInfos[1] = new SWFSourceInfo(null, path, null);
sourceInfos[1] = new OpenableSourceInfo(null, path, null);
Main.openFile(sourceInfos);
}, PRIORITY_MEDIUM, null, true, null, false);
addMenuItem("/debug/createNewSwf", "Create new SWF", "continue16", e -> {
@@ -1229,7 +1248,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
}
Main.openFile(new SWFSourceInfo(new ByteArrayInputStream(baos.toByteArray()), "new.swf", "New SWF"));
Main.openFile(new OpenableSourceInfo(new ByteArrayInputStream(baos.toByteArray()), "new.swf", "New SWF"));
}, PRIORITY_MEDIUM, null, true, null, false);
finishMenu("/debug");
}
@@ -1303,7 +1322,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
if (swf != null) {
List<Integer> indices = Main.searchResultsStorage.getIndicesForSwf(swf);
List<Integer> indices = Main.searchResultsStorage.getIndicesForOpenable(swf);
int j = 0;
for (int i = 0; i < indices.size(); i++) {
final int fi = indices.get(i);
@@ -1320,7 +1339,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
} else {
sr = new SearchResultsDialog<>(Main.getDefaultDialogsOwner(), searched, Main.searchResultsStorage.isIgnoreCaseAt(fi), Main.searchResultsStorage.isRegExpAt(fi), listeners);
}
sr.setResults(Main.searchResultsStorage.getSearchResultsAt(mainFrame.getPanel().getAllSwfs(), fi));
sr.setResults(Main.searchResultsStorage.getSearchResultsAt(mainFrame.getPanel().getAllOpenablesAndSwfs(), fi));
sr.setVisible(true);
Main.getMainFrame().getPanel().searchResultsDialogs.add(sr);
};
@@ -1337,7 +1356,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
protected void clearRecentSearchesForCurrentSwfActionPerformed(ActionEvent evt) {
if (ViewMessages.showConfirmDialog(Main.getDefaultMessagesComponent(), translate("message.confirm.recentSearches.clear"), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
Main.searchResultsStorage.clearForSwf(swf);
Main.searchResultsStorage.clearForOpenable(openable);
}
}
@@ -1381,17 +1400,17 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
public boolean runActionPerformed(ActionEvent evt) {
Main.run(swf);
Main.run((SWF) openable);
return true;
}
public boolean debugActionPerformed(ActionEvent evt) {
Main.runDebug(swf, false);
Main.runDebug((SWF) openable, false);
return true;
}
public boolean debugPCodeActionPerformed(ActionEvent evt) {
Main.runDebug(swf, true);
Main.runDebug((SWF) openable, true);
return true;
}
@@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.helpers.Helper;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -129,7 +129,7 @@ public final class MainFrameRibbon extends AppRibbonFrame {
StringBuilder sbt = new StringBuilder();
boolean first = true;
for (SWFList swf : panel.getSwfs()) {
for (OpenableList swf : panel.getSwfs()) {
if (!first) {
sb.append(File.pathSeparator);
sbt.append(File.pathSeparator);
@@ -17,8 +17,10 @@
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.search.ScriptSearchResult;
import com.jpexs.decompiler.flash.treeitems.Openable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
@@ -170,8 +172,9 @@ public class MainFrameRibbonMenu extends MainFrameMenu {
String groupName = translate("menu.recentSearches");
searchHistoryPanel.addButtonGroup(groupName);
SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
List<Integer> indices = Main.searchResultsStorage.getIndicesForSwf(swf);
Openable openable = Main.getMainFrame().getPanel().getCurrentOpenable();
SWF swf = (openable instanceof SWF) ? (SWF) openable : ((ABC)openable).getSwf();
List<Integer> indices = Main.searchResultsStorage.getIndicesForOpenable(openable);
int height = 0;
height = searchHistoryPanel.getInsets().top + searchHistoryPanel.getInsets().bottom + 6/*groupInset top*/ + new JLabel(groupName).getPreferredSize().height + 4 /*layoutGap*/;
@@ -196,7 +199,7 @@ public class MainFrameRibbonMenu extends MainFrameMenu {
} else {
sr = new SearchResultsDialog<>(Main.getDefaultDialogsOwner(), searched, Main.searchResultsStorage.isIgnoreCaseAt(fi), Main.searchResultsStorage.isRegExpAt(fi), listeners);
}
sr.setResults(Main.searchResultsStorage.getSearchResultsAt(Main.getMainFrame().getPanel().getAllSwfs(), fi));
sr.setResults(Main.searchResultsStorage.getSearchResultsAt(Main.getMainFrame().getPanel().getAllOpenablesAndSwfs(), fi));
sr.setVisible(true);
Main.getMainFrame().getPanel().searchResultsDialogs.add(sr);
});
File diff suppressed because it is too large Load Diff
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.tagtree.TreeRoot;
import com.jpexs.decompiler.flash.timeline.TagScript;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -355,11 +356,11 @@ public class PinsPanel extends JPanel {
rebuild();
}
public void removeSwf(SWF swf) {
public void removeOpenable(Openable openable) {
for (int i = 0; i < items.size(); i++) {
TreeItem item = items.get(i);
SWF itemSwf = item.getSwf();
if (itemSwf == swf || itemSwf == null) {
Openable itemOpenable = item.getOpenable();
if (itemOpenable == openable || itemOpenable == null) {
String tagTreePath = mainPanel.tagTree.getItemPathString(item);
if (tagTreePath == null) {
@@ -787,7 +787,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
}
} else if (treeItem instanceof Frame) {
Frame fn = (Frame) treeItem;
SWF sourceSwf = fn.getSwf();
SWF sourceSwf = (SWF) fn.getOpenable();
if (fn.timeline.timelined == sourceSwf) {
SetBackgroundColorTag setBgColorTag = sourceSwf.getBackgroundColor();
if (setBgColorTag != null) {
@@ -825,7 +825,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
}
} else if (treeItem instanceof Frame) {
Frame fn = (Frame) treeItem;
SWF sourceSwf = fn.getSwf();
SWF sourceSwf = (SWF) fn.getOpenable();
if (fn.timeline.timelined == sourceSwf) {
SetBackgroundColorTag setBgColorTag = sourceSwf.getBackgroundColor();
if (setBgColorTag != null) {
@@ -78,7 +78,7 @@ public class SearchDialog extends AppDialog {
}
}
public SearchDialog(Window owner, boolean replace, String selection, boolean selectionFirst) {
public SearchDialog(Window owner, boolean replace, String selection, boolean selectionFirst, boolean currentAbc) {
super(owner);
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
ignoreCaseCheckBox.setSelected(true);
@@ -111,7 +111,7 @@ public class SearchDialog extends AppDialog {
if (selection != null) {
scopeItems.add(translate("scope.selection").replace("%selection%", selection));
}
scopeItems.add(translate("scope.currentFile"));
scopeItems.add(translate(currentAbc ? "scope.currentFile.abc" : "scope.currentFile"));
scopeItems.add(translate("scope.allFiles"));
panField.add(new JLabel(translate("label.scope")));
scopeComboBox = new JComboBox<>(scopeItems.toArray(new String[scopeItems.size()]));
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.search.SearchResult;
import com.jpexs.decompiler.flash.treeitems.Openable;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
@@ -86,7 +87,7 @@ public class SearchResultsDialog<E extends SearchResult> extends AppDialog {
private String text;
private final boolean ignoreCase;
private Map<SWF, List<SearchResult>> swfToResults = new LinkedHashMap<>();
private Map<Openable, List<SearchResult>> openableToResults = new LinkedHashMap<>();
public SearchResultsDialog(Window owner, String text, boolean ignoreCase, boolean regExp, List<SearchListener<E>> listeners) {
super(owner);
@@ -388,30 +389,30 @@ public class SearchResultsDialog<E extends SearchResult> extends AppDialog {
}
public void setResults(List<E> results) {
swfToResults.clear();
openableToResults.clear();
for (E e : results) {
if (!swfToResults.containsKey(e.getSWF())) {
swfToResults.put(e.getSWF(), new ArrayList<>());
if (!openableToResults.containsKey(e.getOpenable())) {
openableToResults.put(e.getOpenable(), new ArrayList<>());
}
swfToResults.get(e.getSWF()).add(e);
openableToResults.get(e.getOpenable()).add(e);
}
updateModel();
}
private void updateModel() {
boolean showSwfTitles = swfToResults.size() > 1;
boolean showSwfTitles = openableToResults.size() > 1;
if (showSwfTitles) {
BasicTreeNode rootNode = new BasicTreeNode("root");
List<BasicTreeNode> swfNodes = new ArrayList<>();
for (SWF s : swfToResults.keySet()) {
for (Openable s : openableToResults.keySet()) {
BasicTreeNode swfNode = new BasicTreeNode(s);
if (showSwfTitles) {
rootNode.addChild(swfNode);
swfNode.setParent(rootNode);
swfNodes.add(swfNode);
}
for (SearchResult r : swfToResults.get(s)) {
for (SearchResult r : openableToResults.get(s)) {
BasicTreeNode rNode = new BasicTreeNode(r);
if (showSwfTitles) {
swfNode.addChild(rNode);
@@ -430,8 +431,8 @@ public class SearchResultsDialog<E extends SearchResult> extends AppDialog {
} else {
DefaultListModel<SearchResult> model = (DefaultListModel<SearchResult>) resultsList.getModel();
model.clear();
if (!swfToResults.isEmpty()) {
List<SearchResult> elements = swfToResults.get(swfToResults.keySet().iterator().next());
if (!openableToResults.isEmpty()) {
List<SearchResult> elements = openableToResults.get(openableToResults.keySet().iterator().next());
for (SearchResult e : elements) {
model.addElement(e);
}
@@ -442,12 +443,12 @@ public class SearchResultsDialog<E extends SearchResult> extends AppDialog {
}
public void removeSwf(SWF swf) {
swfToResults.remove(swf);
openableToResults.remove(swf);
updateModel();
}
public boolean isEmpty() {
return swfToResults.isEmpty();
return openableToResults.isEmpty();
}
private void gotoButtonActionPerformed(ActionEvent evt) {
@@ -460,7 +461,7 @@ public class SearchResultsDialog<E extends SearchResult> extends AppDialog {
@SuppressWarnings("unchecked")
private void gotoElement() {
if (swfToResults.size() > 1) {
if (openableToResults.size() > 1) {
BasicTreeNode selection = (BasicTreeNode) resultsTree.getLastSelectedPathComponent();
if (selection.getData() instanceof SearchResult) {
for (SearchListener<E> listener : listeners) {
@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.search.ABCSearchResult;
import com.jpexs.decompiler.flash.search.ActionSearchResult;
import com.jpexs.decompiler.flash.search.ScriptNotFoundException;
import com.jpexs.decompiler.flash.search.ScriptSearchResult;
import com.jpexs.decompiler.flash.treeitems.Openable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -57,7 +58,7 @@ public class SearchResultsStorage {
return Configuration.getFFDecHome() + SEARCH_RESULTS_FILE;
}
List<String> swfIds = new ArrayList<>();
List<String> openableIds = new ArrayList<>();
List<String> searchedValues = new ArrayList<>();
List<Boolean> isRegExp = new ArrayList<>();
List<Boolean> isIgnoreCase = new ArrayList<>();
@@ -71,28 +72,28 @@ public class SearchResultsStorage {
currentGroupId++;
}
public static String getSwfId(SWF swf) {
public static String getOpenableId(Openable swf) {
SWF s = swf;
Openable s = swf;
String binaryDataSuffix = "";
while (s.binaryData != null) {
binaryDataSuffix += "|binaryData[" + s.binaryData.getCharacterId() + "]";
s = s.binaryData.getSwf();
while ((s instanceof SWF) && ((SWF)s).binaryData != null) {
binaryDataSuffix += "|binaryData[" + ((SWF)s).binaryData.getCharacterId() + "]";
s = ((SWF)s).binaryData.getSwf();
}
if (s.swfList != null) {
if (s.getOpenableList() != null) {
String fileInsideTitle = s.getFile() == null ? s.getFileTitle() : "";
if (fileInsideTitle != null && !"".equals(fileInsideTitle)) {
fileInsideTitle = "|" + fileInsideTitle;
}
return s.swfList.sourceInfo.getFile() + fileInsideTitle + binaryDataSuffix;
return s.getOpenableList().sourceInfo.getFile() + fileInsideTitle + binaryDataSuffix;
}
return "**NONE**";
}
public int getCount() {
return swfIds.size();
return openableIds.size();
}
public String getSearchedValueAt(int index) {
@@ -122,12 +123,12 @@ public class SearchResultsStorage {
return false;
}
public List<Integer> getIndicesForSwf(SWF swf) {
String swfId = getSwfId(swf);
public List<Integer> getIndicesForOpenable(Openable swf) {
String swfId = getOpenableId(swf);
List<Integer> res = new ArrayList<>();
Set<Integer> foundGroups = new LinkedHashSet<>();
for (int i = 0; i < swfIds.size(); i++) {
if (swfIds.get(i).equals(swfId)) {
for (int i = 0; i < openableIds.size(); i++) {
if (openableIds.get(i).equals(swfId)) {
foundGroups.add(groups.get(i));
}
}
@@ -135,29 +136,29 @@ public class SearchResultsStorage {
}
@SuppressWarnings("unchecked")
public List<ScriptSearchResult> getSearchResultsAt(Set<SWF> allSwfs, int index) {
public List<ScriptSearchResult> getSearchResultsAt(Set<Openable> allOpenables, int index) {
List<ScriptSearchResult> result = new ArrayList<>();
Map<String, SWF> swfIdToSwf = new HashMap<>();
for (SWF s : allSwfs) {
swfIdToSwf.put(getSwfId(s), s);
Map<String, Openable> openableIdToOpenable = new HashMap<>();
for (Openable o : allOpenables) {
openableIdToOpenable.put(getOpenableId(o), o);
}
for (int j = 0; j < data.size(); j++) {
if (groups.get(j) == index) {
if (!swfIdToSwf.containsKey(swfIds.get(j))) {
if (!openableIdToOpenable.containsKey(openableIds.get(j))) {
continue;
}
if (unpackedData.get(j) != null) {
List<ScriptSearchResult> unpacked = unpackedData.get(j);
for (ScriptSearchResult sr : unpacked) {
if (allSwfs.contains(sr.getSWF())) {
if (allOpenables.contains(sr.getOpenable())) {
result.add(sr);
}
}
continue;
}
SWF swf = swfIdToSwf.get(swfIds.get(j));
Openable openable = openableIdToOpenable.get(openableIds.get(j));
byte[] itemData = data.get(j);
List<ScriptSearchResult> currentResults = new ArrayList<>();
try {
@@ -170,10 +171,10 @@ public class SearchResultsStorage {
ByteArrayInputStream bais = new ByteArrayInputStream(resultData.get(i));
if (kind == DATA_ABC) {
currentResults.add(new ABCSearchResult(swf, bais));
currentResults.add(new ABCSearchResult(openable, bais));
}
if (kind == DATA_ACTION) {
currentResults.add(new ActionSearchResult(swf, bais));
currentResults.add(new ActionSearchResult((SWF) openable, bais));
}
} catch (ScriptNotFoundException | IOException ex) {
ex.printStackTrace();
@@ -201,7 +202,7 @@ public class SearchResultsStorage {
if (major != SERIAL_VERSION_MAJOR) { //incompatible version
return;
}
swfIds = (List<String>) ois.readObject();
openableIds = (List<String>) ois.readObject();
searchedValues = (List<String>) ois.readObject();
isIgnoreCase = (List<Boolean>) ois.readObject();
isRegExp = (List<Boolean>) ois.readObject();
@@ -231,7 +232,7 @@ public class SearchResultsStorage {
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.write(SERIAL_VERSION_MAJOR);
oos.write(SERIAL_VERSION_MINOR);
oos.writeObject(swfIds);
oos.writeObject(openableIds);
oos.writeObject(searchedValues);
oos.writeObject(isIgnoreCase);
oos.writeObject(isRegExp);
@@ -240,8 +241,8 @@ public class SearchResultsStorage {
}
}
public void addABCResults(SWF swf, String searchedString, boolean ignoreCase, boolean regExp, List<ABCSearchResult> results) {
swfIds.add(getSwfId(swf));
public void addABCResults(Openable openable, String searchedString, boolean ignoreCase, boolean regExp, List<ABCSearchResult> results) {
openableIds.add(getOpenableId(openable));
searchedValues.add(searchedString);
isIgnoreCase.add(ignoreCase);
isRegExp.add(regExp);
@@ -268,7 +269,7 @@ public class SearchResultsStorage {
}
public void addActionResults(SWF swf, String searchedString, boolean ignoreCase, boolean regExp, List<ActionSearchResult> results) {
swfIds.add(getSwfId(swf));
openableIds.add(getOpenableId(swf));
searchedValues.add(searchedString);
isIgnoreCase.add(ignoreCase);
isRegExp.add(regExp);
@@ -293,7 +294,7 @@ public class SearchResultsStorage {
}
public void clear() {
swfIds.clear();
openableIds.clear();
searchedValues.clear();
isIgnoreCase.clear();
isRegExp.clear();
@@ -302,11 +303,11 @@ public class SearchResultsStorage {
unpackedData.clear();
}
public void clearForSwf(SWF swf) {
String swfId = getSwfId(swf);
for (int i = 0; i < swfIds.size(); i++) {
if (swfIds.get(i).equals(swfId)) {
swfIds.remove(i);
public void clearForOpenable(Openable openable) {
String swfId = getOpenableId(openable);
for (int i = 0; i < openableIds.size(); i++) {
if (openableIds.get(i).equals(swfId)) {
openableIds.remove(i);
searchedValues.remove(i);
isIgnoreCase.remove(i);
isRegExp.remove(i);
@@ -339,9 +340,9 @@ public class SearchResultsStorage {
}
public void destroySwf(SWF swf) {
String swfId = getSwfId(swf);
for (int i = 0; i < swfIds.size(); i++) {
if (swfIds.get(i).equals(swfId)) {
String swfId = getOpenableId(swf);
for (int i = 0; i < openableIds.size(); i++) {
if (openableIds.get(i).equals(swfId)) {
unpackedData.set(i, null);
}
}
@@ -63,5 +63,6 @@ public enum TreeNodeType {
REMOVE_OBJECT,
SCALING_GRID,
END,
ERROR
ERROR,
ABC
}
@@ -84,6 +84,7 @@ import com.jpexs.decompiler.flash.search.ScriptSearchListener;
import com.jpexs.decompiler.flash.search.ScriptSearchResult;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
@@ -208,13 +209,13 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
return mainPanel;
}
public List<ABCSearchResult> search(final SWF swf, final String txt, boolean ignoreCase, boolean regexp, boolean pcode, CancellableWorker<Void> worker, List<ScriptPack> scope) {
public List<ABCSearchResult> search(final Openable openable, final String txt, boolean ignoreCase, boolean regexp, boolean pcode, CancellableWorker<Void> worker, List<ScriptPack> scope) {
if (txt != null && !txt.isEmpty()) {
searchPanel.setOptions(ignoreCase, regexp);
String workText = AppStrings.translate("work.searching");
String decAdd = AppStrings.translate("work.decompiling");
return new ActionScriptSearch().searchAs3(swf, txt, ignoreCase, regexp, pcode, new ScriptSearchListener() {
return new ActionScriptSearch().searchAs3(openable, txt, ignoreCase, regexp, pcode, new ScriptSearchListener() {
@Override
public void onDecompile(int pos, int total, String name) {
Main.startWork(workText + " \"" + txt + "\", " + decAdd + " - (" + pos + "/" + total + ") " + name + "... ", worker);
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.abc;
import com.jpexs.decompiler.flash.AppResources;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
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;
@@ -25,6 +26,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.timeline.AS3Package;
import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.graph.DottedChain;
import java.util.ArrayList;
import java.util.List;
@@ -40,7 +42,7 @@ import javax.swing.tree.TreePath;
*/
public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel {
private final SWF swf;
private final Openable openable;
private List<ScriptPack> list;
@@ -58,18 +60,36 @@ public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel
super(null, null, null);
this.flat = flat;
root = new AS3Package(null, swf, flat, false);
this.swf = swf;
this.openable = swf;
this.list = swf.getAS3Packs();
setFilter(null);
}
public ClassesListTreeModel(ABC abc, boolean flat) {
super(null, null, null);
this.flat = flat;
root = new AS3Package(null, abc, flat, false);
this.openable = abc;
List<ABC> allAbcs = new ArrayList<>();
allAbcs.add(abc);
this.list = abc.getScriptPacks(null, allAbcs);
setFilter(null);
}
@Override
public SWF getSwf() {
return swf;
public Openable getOpenable() {
return openable;
}
public final void update() {
this.list = swf.getAS3Packs();
if (openable instanceof SWF) {
this.list = ((SWF)openable).getAS3Packs();
} else if (openable instanceof ABC) {
ABC abc = (ABC) openable;
List<ABC> allAbcs = new ArrayList<>();
allAbcs.add(abc);
this.list = abc.getScriptPacks(null, allAbcs);
}
TreeModelEvent event = new TreeModelEvent(this, new TreePath(root));
for (TreeModelListener listener : listeners) {
listener.treeStructureChanged(event);
@@ -81,8 +101,10 @@ public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel
List<String> ignoredClasses = new ArrayList<>();
List<String> ignoredNss = new ArrayList<>();
if (Configuration._ignoreAdditionalFlexClasses.get()) {
getSwf().getFlexMainClass(ignoredClasses, ignoredNss);
if (Configuration._ignoreAdditionalFlexClasses.get()) {
if (openable instanceof SWF) {
((SWF)openable).getFlexMainClass(ignoredClasses, ignoredNss);
}
}
filter = (filter == null || filter.isEmpty()) ? null : filter.toLowerCase(Locale.ENGLISH);
@@ -124,7 +146,7 @@ public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel
}
AS3Package pkg = root.getSubPackage(fullName);
if (pkg == null) {
pkg = new AS3Package(fullName, swf, true, defaultPackage);
pkg = new AS3Package(fullName, openable, true, defaultPackage);
root.addSubPackage(pkg);
}
return pkg;
@@ -134,7 +156,7 @@ public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel
String pathElement = packageStr.get(i);
AS3Package pkg = parent.getSubPackage(pathElement);
if (pkg == null) {
pkg = new AS3Package(pathElement, swf, false, false);
pkg = new AS3Package(pathElement, openable, false, false);
parent.addSubPackage(pkg);
}
@@ -238,11 +260,11 @@ public class ClassesListTreeModel extends AS3ClassTreeItem implements TreeModel
return false;
}
return swf.equals(((ClassesListTreeModel) obj).swf);
return openable.equals(((ClassesListTreeModel) obj).openable);
}
@Override
public int hashCode() {
return ClassesListTreeModel.class.hashCode() ^ swf.hashCode();
return ClassesListTreeModel.class.hashCode() ^ openable.hashCode();
}
}
@@ -626,7 +626,7 @@ public class DumpTree extends JTree {
return null;
}
long address = range.getPos();
return searchTimelinedForTag(item.getSwf(), address);
return searchTimelinedForTag((SWF) item.getOpenable(), address);
}
public Timelined getTimelinedForItem(TreeItem item) {
@@ -674,7 +674,7 @@ public class DumpTree extends JTree {
for (DumpInfo sd : d.getChildInfos()) {
if (sd instanceof DumpInfoSwfNode) {
DumpInfoSwfNode si = (DumpInfoSwfNode) sd;
if (si.getSwf() == item.getSwf()) {
if (si.getSwf() == item.getOpenable()) {
DumpInfo di = si;
while (model.getChildCount(di) > 0) {
boolean found = false;
@@ -18,7 +18,8 @@ package com.jpexs.decompiler.flash.gui.dumpview;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TreeModelEvent;
@@ -36,20 +37,23 @@ public final class DumpTreeModel implements TreeModel {
private final List<TreeModelListener> listeners = new ArrayList<>();
private final List<SWFList> swfs;
private final List<OpenableList> openables;
public DumpTreeModel(List<SWFList> swfs) {
this.swfs = swfs;
public DumpTreeModel(List<OpenableList> openables) {
this.openables = openables;
root = new DumpInfo("root", "", null, 0, 0);
updateSwfs();
}
public void updateSwfs() {
root.getChildInfos().clear();
for (SWFList swfList : swfs) {
for (SWF swf : swfList) {
swf.dumpInfo.name = swf.getFileTitle();
root.getChildInfos().add(swf.dumpInfo);
for (OpenableList openableList : openables) {
for (Openable openable : openableList) {
if (openable instanceof SWF) {
SWF swf = (SWF) openable;
swf.dumpInfo.name = swf.getFileTitle();
root.getChildInfos().add(swf.dumpInfo);
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

@@ -978,4 +978,8 @@ contextmenu.unpin.others = Unpin others
menu.tools.otherTools.clearPinnedItems = Clear pinned items
menu.settings.flattenASPackages = Flatten ActionScript packages
menu.settings.flattenASPackages = Flatten ActionScript packages
work.reading.abc = Reading ABC
filter.abc = ActionScript 3 bytecode files (*.abc)
@@ -950,4 +950,8 @@ contextmenu.unpin.others = Odepnout ostatn\u00ed
menu.tools.otherTools.clearPinnedItems = Vymazat p\u0159ipnut\u00e9 polo\u017eky
menu.settings.flattenASPackages = Zplo\u0161tit bal\u00ed\u010dky ActionScriptu
menu.settings.flattenASPackages = Zplo\u0161tit bal\u00ed\u010dky ActionScriptu
work.reading.abc = \u010cten\u00ed ABC
filter.abc = ActionScript 3 bytecode soubory (*.abc)
@@ -36,4 +36,7 @@ label.scope = Scope:
scope.currentFile = Current SWF
scope.selection = Selection (%selection%)
scope.allFiles = All opened SWFs
scope.selection.items = %count% items
scope.selection.items = %count% items
#after 16.3.1
scope.currentFile.abc = Current ABC
@@ -35,4 +35,7 @@ label.scope = Rozsah:
scope.currentFile = Aktu\u00e1ln\u00ed SWF
scope.selection = V\u00fdb\u011br (%selection%)
scope.allFiles = V\u0161echny otev\u0159en\u00e9 SWF
scope.selection.items = %count% polo\u017eek
scope.selection.items = %count% polo\u017eek
#after 16.3.1
scope.currentFile.abc = Nyn\u011bj\u0161\u00ed ABC
@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
@@ -58,8 +59,8 @@ public class TagListTree extends AbstractTagTree {
}
@Override
public List<TreeItem> getSelection(SWF swf) {
return getSelection(swf, getAllSelected());
public List<TreeItem> getSelection(Openable openable) {
return getSelection(openable, getAllSelected());
}
@Override
@@ -23,7 +23,7 @@ import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel;
import com.jpexs.decompiler.flash.gui.tagtree.TagTree;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.AlphaComposite;
import java.awt.Color;
@@ -84,7 +84,7 @@ public class TagListTreeCellRenderer extends DefaultTreeCellRenderer {
val = (TreeItem) value;
}
if (val != null && !(val instanceof SWFList) && val.getSwf() == null) {
if (val != null && !(val instanceof OpenableList) && val.getOpenable()== null) {
// SWF was closed
value = null;
}
@@ -28,7 +28,8 @@ import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.treeitems.HeaderItem;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.ArrayList;
import java.util.HashMap;
@@ -46,11 +47,11 @@ public class TagListTreeModel extends AbstractTagTreeModel {
private final TagListTreeRoot root = new TagListTreeRoot();
private List<SWFList> swfs;
private List<OpenableList> swfs;
private Map<SWF, HeaderItem> swfHeaders = new HashMap<>();
public TagListTreeModel(List<SWFList> swfs) {
public TagListTreeModel(List<OpenableList> swfs) {
this.swfs = swfs;
}
@@ -80,13 +81,13 @@ public class TagListTreeModel extends AbstractTagTreeModel {
TreeItem parentNode = (TreeItem) parent;
if (parentNode == root) {
SWFList swfList = swfs.get(index);
OpenableList swfList = swfs.get(index);
if (!swfList.isBundle()) {
return swfList.get(0);
}
return swfList;
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs.get(index);
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items.get(index);
} else if (parentNode instanceof SWF) {
if (index == 0) {
return getSwfHeader((SWF) parentNode);
@@ -118,8 +119,8 @@ public class TagListTreeModel extends AbstractTagTreeModel {
TreeItem parentNode = (TreeItem) parent;
if (parentNode == root) {
return swfs.size();
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs.size();
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items.size();
} else if (parentNode instanceof SWF) {
return ((SWF) parentNode).getTimeline().getFrameCount() + 1;
} else if (parentNode instanceof HeaderItem) {
@@ -156,12 +157,12 @@ public class TagListTreeModel extends AbstractTagTreeModel {
TreeItem parentNode = (TreeItem) parent;
if (parentNode == root) {
SWFList swfList = child instanceof SWFList
? (SWFList) child
: ((SWF) child).swfList;
return swfs.indexOf(swfList);
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs.indexOf(child);
OpenableList openableListswfList = child instanceof OpenableList
? (OpenableList) child
: ((Openable) child).getOpenableList();
return swfs.indexOf(openableListswfList);
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items.indexOf(child);
} else if (parentNode instanceof SWF) {
HeaderItem header = getSwfHeader((SWF) parentNode);
@@ -210,7 +211,7 @@ public class TagListTreeModel extends AbstractTagTreeModel {
List<SWF> toRemove = new ArrayList<>();
for (SWF swf : swfHeaders.keySet()) {
SWF swf2 = swf.getRootSwf();
if (swf2 != null && !swfs.contains(swf2.swfList)) {
if (swf2 != null && !swfs.contains(swf2.openableList)) {
toRemove.add(swf);
}
}
@@ -274,15 +275,15 @@ public class TagListTreeModel extends AbstractTagTreeModel {
TreeItem parentNode = (TreeItem) parent;
if (parentNode == root) {
List<TreeItem> result = new ArrayList<>(swfs.size());
for (SWFList swfList : swfs) {
for (OpenableList swfList : swfs) {
if (!swfList.isBundle()) {
result.add(swfList.get(0));
}
result.add(swfList);
}
return result;
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs;
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items;
} else if (parentNode instanceof SWF) {
List<TreeItem> ret = new ArrayList<>();
ret.add(getSwfHeader((SWF)parentNode));
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.taglistview;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.gui.tagtree.TreeRoot;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
/**
@@ -27,7 +28,7 @@ import com.jpexs.decompiler.flash.treeitems.TreeItem;
public class TagListTreeRoot implements TreeItem, TreeRoot{
@Override
public SWF getSwf() {
public Openable getOpenable() {
return null;
}
@@ -18,7 +18,8 @@ package com.jpexs.decompiler.flash.gui.tagtree;
import com.jpexs.decompiler.flash.SWC;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.ZippedSWFBundle;
import com.jpexs.decompiler.flash.ZippedBundle;
import com.jpexs.decompiler.flash.abc.ABC;
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;
@@ -88,7 +89,8 @@ import com.jpexs.decompiler.flash.timeline.FrameScript;
import com.jpexs.decompiler.flash.timeline.TagScript;
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.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
@@ -332,10 +334,10 @@ public abstract class AbstractTagTree extends JTree {
return TreeNodeType.FLASH;
}
if (t instanceof SWFList) {
SWFList slist = (SWFList) t;
if (t instanceof OpenableList) {
OpenableList slist = (OpenableList) t;
if (slist.isBundle()) {
if (slist.bundle.getClass() == ZippedSWFBundle.class) {
if (slist.bundle.getClass() == ZippedBundle.class) {
return TreeNodeType.BUNDLE_ZIP;
} else if (slist.bundle.getClass() == SWC.class) {
return TreeNodeType.BUNDLE_SWC;
@@ -382,6 +384,10 @@ public abstract class AbstractTagTree extends JTree {
if (t instanceof FolderItem) {
return TreeNodeType.FOLDER;
}
if (t instanceof ABC) {
return TreeNodeType.ABC;
}
return TreeNodeType.FOLDER;
}
@@ -493,15 +499,15 @@ public abstract class AbstractTagTree extends JTree {
return !getSelection(mainPanel.getCurrentSwf()).isEmpty();
}
public abstract List<TreeItem> getSelection(SWF swf);
public abstract List<TreeItem> getSelection(Openable openable);
public static List<TreeItem> getSelection(SWF swf, List<TreeItem> sel) {
public static List<TreeItem> getSelection(Openable openable, List<TreeItem> sel) {
List<TreeItem> ret = new ArrayList<>();
for (TreeItem d : sel) {
if (d instanceof SWFList) {
if (d instanceof OpenableList) {
continue;
}
if (swf != null && d.getSwf() != swf) {
if (openable != null && d.getOpenable() != openable) {
continue;
}
@@ -574,7 +580,7 @@ public abstract class AbstractTagTree extends JTree {
return ret;
}
public void updateSwfs(SWF[] swfs) {
public void updateSwfs(Openable[] openables) {
AbstractTagTreeModel ttm = getModel();
if (ttm != null) {
List<List<String>> expandedNodes = View.getExpandedNodes(this);
@@ -88,7 +88,8 @@ import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage2;
import com.jpexs.decompiler.flash.tags.gfx.DefineSubImage;
import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem;
import com.jpexs.decompiler.flash.treeitems.FolderItem;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.AlphaComposite;
import java.awt.Color;
@@ -154,7 +155,7 @@ public class TagTree extends AbstractTagTree {
boolean hasFocus) {
TreeItem val = (TreeItem) value;
if (val != null && !(val instanceof SWFList) && val.getSwf() == null) {
if (val != null && !(val instanceof OpenableList) && val.getOpenable() == null) {
// SWF was closed
value = null;
}
@@ -307,7 +308,7 @@ public class TagTree extends AbstractTagTree {
}
@Override
public List<TreeItem> getSelection(SWF swf) {
public List<TreeItem> getSelection(Openable openable) {
List<TreeItem> sel;
if (mainPanel.folderPreviewPanel.selectedItems.isEmpty()) {
sel = getAllSelected();
@@ -319,7 +320,7 @@ public class TagTree extends AbstractTagTree {
getAllSubs(treeItem, sel);
}
}
return getSelection(swf, sel);
return getSelection(openable, sel);
}
public List<AS3ClassTreeItem> getTagsWithType(List<AS3ClassTreeItem> list, TreeNodeType type) {
@@ -76,7 +76,8 @@ 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.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
@@ -529,7 +530,7 @@ public class TagTreeContextMenu extends JPopupMenu {
AbstractTagTree tree = getTree();
final List<SWFList> swfs = mainPanel.getSwfs();
final List<OpenableList> swfs = mainPanel.getSwfs();
boolean canRemove = true;
boolean allDoNotHaveDependencies = true;
@@ -659,13 +660,13 @@ public class TagTreeContextMenu extends JPopupMenu {
boolean allSelectedIsSwf = true;
for (TreeItem item : items) {
if (!(item instanceof SWF) && !(item instanceof SWFList)) {
if (!(item instanceof SWF) && !(item instanceof OpenableList)) {
allSelectedIsSwf = false;
break;
} else if (item instanceof SWF) {
SWF swf = (SWF) item;
// Do not allow to close SWF in bundle
if (swf.swfList != null && swf.swfList.isBundle()) {
if (swf.openableList != null && swf.openableList.isBundle()) {
allSelectedIsSwf = false;
}
}
@@ -674,13 +675,19 @@ public class TagTreeContextMenu extends JPopupMenu {
boolean allSelectedIsInTheSameSwf = true;
SWF singleSwf = null;
for (TreeItem item : items) {
if (item instanceof SWFList) {
if (item instanceof OpenableList) {
allSelectedIsInTheSameSwf = false;
break;
}
if (singleSwf == null) {
singleSwf = item.getSwf();
} else if (singleSwf != item.getSwf()) {
Openable singleOpenable = item.getOpenable();
if (singleOpenable instanceof SWF) {
singleSwf = (SWF) singleOpenable;
} else {
allSelectedIsInTheSameSwf = false;
break;
}
} else if (singleSwf != item.getOpenable()) {
allSelectedIsInTheSameSwf = false;
break;
}
@@ -933,12 +940,12 @@ public class TagTreeContextMenu extends JPopupMenu {
}
if (firstItem instanceof SWF) {
SWF firstSwf = (SWF) firstItem;
if (firstSwf.swfList != null && !firstSwf.swfList.isBundle() && firstSwf.swfList.size() == 1) {
if (firstSwf.openableList != null && !firstSwf.openableList.isBundle() && firstSwf.openableList.size() == 1) {
moveUpMenuItem.setVisible(true);
moveDownMenuItem.setVisible(true);
}
}
if (firstItem instanceof SWFList) {
if (firstItem instanceof OpenableList) {
moveUpMenuItem.setVisible(true);
moveDownMenuItem.setVisible(true);
}
@@ -993,7 +1000,7 @@ public class TagTreeContextMenu extends JPopupMenu {
copyTagToWithDependenciesMenu.setVisible(true);
}
if (allSelectedIsInTheSameSwf && allSelectedIsTag && swfs.size() > 1) {
for (SWFList targetSwfList : swfs) {
for (OpenableList targetSwfList : swfs) {
if ((targetSwfList.size() == 1) && (targetSwfList.get(0) == singleSwf)) {
continue;
}
@@ -1238,7 +1245,7 @@ public class TagTreeContextMenu extends JPopupMenu {
Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, null, ex);
}
SWF swf = item.getSwf();
SWF swf = (SWF) item.getOpenable();
Timelined selectedTimelined = null;
Tag selectedTag = null;
boolean selectNext = false;
@@ -1251,7 +1258,7 @@ public class TagTreeContextMenu extends JPopupMenu {
selectedTag = frame.allInnerTags.get(frame.allInnerTags.size() - 1);
}
} else if (item instanceof FolderItem) {
selectedTimelined = item.getSwf();
selectedTimelined = (SWF) item.getOpenable();
} else if (item instanceof SWF) {
selectedTimelined = (SWF) item;
}
@@ -1280,7 +1287,7 @@ public class TagTreeContextMenu extends JPopupMenu {
private void addTagBeforeActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
try {
SWF swf = item.getSwf();
SWF swf = (SWF) item.getOpenable();
Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf});
Timelined timelined = null;
@@ -1319,7 +1326,7 @@ public class TagTreeContextMenu extends JPopupMenu {
private void addTagAfterActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
try {
SWF swf = item.getSwf();
SWF swf = (SWF) item.getOpenable();
Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf});
Timelined timelined = null;
@@ -1438,7 +1445,7 @@ public class TagTreeContextMenu extends JPopupMenu {
return;
}
SWF swf = itemr.getSwf();
SWF swf = (SWF) itemr.getOpenable();
CharacterTag characterTag = (CharacterTag) itemr;
int characterId = characterTag.getCharacterId();
ReplaceCharacterDialog replaceCharacterDialog = new ReplaceCharacterDialog(Main.getDefaultDialogsOwner());
@@ -1455,7 +1462,7 @@ public class TagTreeContextMenu extends JPopupMenu {
return;
}
SWF swf = itemr.getSwf();
SWF swf = (SWF) itemr.getOpenable();
CharacterTag characterTag = (CharacterTag) itemr;
int characterId = characterTag.getCharacterId();
ReplaceCharacterDialog replaceCharacterDialog = new ReplaceCharacterDialog(Main.getDefaultDialogsOwner());
@@ -1515,7 +1522,7 @@ public class TagTreeContextMenu extends JPopupMenu {
}
HasCharacterId hasCharacterId = (HasCharacterId) itemj;
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), itemj.getSwf().getCharacter(hasCharacterId.getCharacterId()));
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), ((SWF) itemj.getOpenable()).getCharacter(hasCharacterId.getCharacterId()));
}
private void expandRecursiveActionPerformed(ActionEvent evt) {
@@ -1540,11 +1547,21 @@ public class TagTreeContextMenu extends JPopupMenu {
String preselected = "";
if (sel.get(0) instanceof ClassesListTreeModel) {
ClassesListTreeModel cl = (ClassesListTreeModel) sel.get(0);
swf = cl.getSwf();
Openable openable = cl.getOpenable();
if (openable instanceof SWF) {
swf = (SWF) openable;
} else {
swf = ((ABC)openable).getSwf();
}
}
if (sel.get(0) instanceof AS3Package) {
AS3Package pkg = (AS3Package) sel.get(0);
swf = pkg.getSwf();
Openable openable = pkg.getOpenable();
if (openable instanceof SWF) {
swf = (SWF) openable;
} else {
swf = ((ABC)openable).getSwf();
}
TreePath tp = tree.getSelectionPaths()[0];
Object[] path = tp.getPath();
for (int p = path.length - 1; p >= 0; p--) {
@@ -1649,7 +1666,7 @@ public class TagTreeContextMenu extends JPopupMenu {
if (sel.get(0) instanceof FolderItem) {
FolderItem folder = (FolderItem) sel.get(0);
SWF swf = folder.getSwf();
SWF swf = (SWF) folder.getOpenable();
AddScriptDialog addScriptDialog = new AddScriptDialog(Main.getDefaultDialogsOwner(), swf);
if (addScriptDialog.showDialog() == JOptionPane.OK_OPTION) {
@@ -2275,8 +2292,10 @@ public class TagTreeContextMenu extends JPopupMenu {
ScriptPack sp = (ScriptPack) item;
sp.delete(sp.abc, true);
abcsToPack.add(sp.abc);
swfsToClearCache.add(sp.getSwf());
for (ABCContainerTag ct : sp.getSwf().getAbcList()) {
Openable openable = sp.getOpenable();
SWF swf = (openable instanceof SWF) ? (SWF) openable : ((ABC)openable).getSwf();
swfsToClearCache.add(swf);
for (ABCContainerTag ct : swf.getAbcList()) {
if (ct.getABC() == sp.abc) {
((Tag) ct).setModified(true);
break;
@@ -2377,10 +2396,10 @@ public class TagTreeContextMenu extends JPopupMenu {
swf.clearTagSwfs();
mainPanel.refreshTree();
} else {
Main.closeFile(swf.swfList);
Main.closeFile(swf.openableList);
}
} else if (item instanceof SWFList) {
Main.closeFile((SWFList) item);
} else if (item instanceof OpenableList) {
Main.closeFile((OpenableList) item);
}
}
}
@@ -2394,7 +2413,7 @@ public class TagTreeContextMenu extends JPopupMenu {
try {
for (TreeItem item : items) {
SWF swf = item.getSwf();
SWF swf = (SWF)item.getOpenable();
swfs.add(swf);
if (item instanceof Tag) {
@@ -2591,7 +2610,7 @@ public class TagTreeContextMenu extends JPopupMenu {
frame = (Frame) item;
timelined = frame.timeline.timelined;
} else if (item instanceof FolderItem) { //frames folder
timelined = item.getSwf();
timelined = (SWF) item.getOpenable();
} else {
timelined = (Timelined) item;
}
@@ -2646,16 +2665,18 @@ public class TagTreeContextMenu extends JPopupMenu {
addFrames(false); //this works because timeline is selected, no frame
}
private void addCopyMoveToMenusSwfList(int kind, SWF singleSwf, SWFList targetSwfList, JMenuItem menu, List<TreeItem> items) {
private void addCopyMoveToMenusSwfList(int kind, SWF singleSwf, OpenableList targetSwfList, JMenuItem menu, List<TreeItem> items) {
if (targetSwfList.isBundle()) {
JMenu bundleMenu = new JMenu(targetSwfList.name);
bundleMenu.setIcon(AbstractTagTree.getIconForType(AbstractTagTree.getTreeNodeType(targetSwfList)));
menu.add(bundleMenu);
menu = bundleMenu;
}
for (final SWF targetSwf : targetSwfList) {
if (targetSwf != singleSwf) {
addCopyMoveToMenus(kind, menu, items, targetSwf.getShortFileName(), targetSwf);
for (final Openable targetOpenable : targetSwfList) {
if (targetOpenable instanceof SWF) {
if (targetOpenable != singleSwf) {
addCopyMoveToMenus(kind, menu, items, targetOpenable.getShortFileName(), (SWF) targetOpenable);
}
}
}
}
@@ -2728,7 +2749,11 @@ public class TagTreeContextMenu extends JPopupMenu {
}
private Set<TreeItem> getDependenciesSet(List<TreeItem> items) {
SWF sourceSwf = items.get(0).getSwf();
Openable sourceOpenable = items.get(0).getOpenable();
if (sourceOpenable instanceof ABC) {
return new LinkedHashSet<>();
}
SWF sourceSwf = (SWF) items.get(0).getOpenable();
Set<TreeItem> newItems = new LinkedHashSet<>();
for (TreeItem item : items) {
Set<Integer> needed = new LinkedHashSet<>();
@@ -2966,32 +2991,33 @@ public class TagTreeContextMenu extends JPopupMenu {
}
public void importScriptsActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
Openable openable = getTree().getCurrentTreeItem().getOpenable();
SWF swf = (openable instanceof SWF) ? (SWF) openable : ((ABC)openable).getSwf();
mainPanel.importScript(swf);
}
public void importTextsActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
SWF swf = (SWF) getTree().getCurrentTreeItem().getOpenable();
mainPanel.importText(swf);
}
public void importImagesActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
SWF swf = (SWF) getTree().getCurrentTreeItem().getOpenable();
mainPanel.importImage(swf);
}
public void importShapesActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
SWF swf = (SWF) getTree().getCurrentTreeItem().getOpenable();
mainPanel.importShape(swf, false);
}
public void importShapesNoFillActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
SWF swf = (SWF) getTree().getCurrentTreeItem().getOpenable();
mainPanel.importShape(swf, true);
}
public void importSymbolClassActionPerformed(ActionEvent evt) {
SWF swf = getTree().getCurrentTreeItem().getSwf();
SWF swf = (SWF) getTree().getCurrentTreeItem().getOpenable();
mainPanel.importSymbolClass(swf);
}
@@ -3004,7 +3030,7 @@ public class TagTreeContextMenu extends JPopupMenu {
}
public void moveUpDown(TreeItem item, boolean up) {
if ((item instanceof SWF) || (item instanceof SWFList)) {
if ((item instanceof SWF) || (item instanceof OpenableList)) {
mainPanel.moveSwfListUpDown(item, up);
return;
}
@@ -3080,6 +3106,6 @@ public class TagTreeContextMenu extends JPopupMenu {
while (item.binaryData != null) {
item = item.binaryData.getSwf();
}
Main.reloadFile(item.swfList);
Main.reloadFile(item.openableList);
}
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.gui.tagtree;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.TreeNodeType;
@@ -45,12 +46,14 @@ 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.Openable;
import com.jpexs.decompiler.flash.treeitems.OpenableList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreePath;
@@ -91,15 +94,17 @@ public class TagTreeModel extends AbstractTagTreeModel {
private final TagTreeRoot root = new TagTreeRoot();
private final List<SWFList> swfs;
private final List<OpenableList> swfs;
private final Map<SWF, TagTreeSwfInfo> swfInfos = new HashMap<>();
private final boolean addAllFolders;
private final Map<TreeItem, TreePath> pathCache = new HashMap<>();
private final Map<ABC, ClassesListTreeModel> abcClassesTree = new WeakHashMap<>();
public TagTreeModel(List<SWFList> swfs, boolean addAllFolders) {
public TagTreeModel(List<OpenableList> swfs, boolean addAllFolders) {
this.swfs = swfs;
this.addAllFolders = addAllFolders;
//Main.startWork(AppStrings.translate("work.buildingscripttree") + "...");
@@ -116,7 +121,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
List<SWF> toRemove = new ArrayList<>();
for (SWF swf : swfInfos.keySet()) {
SWF swf2 = swf.getRootSwf();
if (swf2 != null && !swfs.contains(swf2.swfList)) {
if (swf2 != null && !swfs.contains(swf2.openableList)) {
toRemove.add(swf);
}
}
@@ -499,15 +504,15 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
if (parentNode == root) {
for (SWFList swfList : swfs) {
for (OpenableList swfList : swfs) {
if (!swfList.isBundle()) {
result.add(swfList.get(0));
}
result.add(swfList);
}
return result;
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs;
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items;
} else if (parentNode instanceof SWF) {
return getSwfFolders((SWF) parentNode);
} else if (parentNode instanceof FolderItem) {
@@ -535,7 +540,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
TreeItem item = result.get(i);
if (item instanceof Tag) {
Tag resultTag = (Tag) item;
Map<Tag, TagScript> currentTagScriptCache = getTagScriptCache(item.getSwf());
Map<Tag, TagScript> currentTagScriptCache = getTagScriptCache((SWF) item.getOpenable());
TagScript tagScript = currentTagScriptCache.get(resultTag);
if (tagScript == null) {
List<TreeItem> subNodes = new ArrayList<>();
@@ -544,7 +549,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
subNodes.add(item2);
}
}
tagScript = new TagScript(item.getSwf(), resultTag, subNodes);
tagScript = new TagScript((SWF) item.getOpenable(), resultTag, subNodes);
currentTagScriptCache.put(resultTag, tagScript);
}
result.set(i, tagScript);
@@ -564,6 +569,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
} else if (parentNode instanceof ButtonTag) {
return ((ButtonTag) parentNode).getRecords();
} else if (parentNode instanceof ABC) {
ClassesListTreeModel classesTreeModel = getClassesListTreeModel((ABC) parentNode);
return classesTreeModel.getAllChildren(classesTreeModel.getRoot());
}
return result;
@@ -585,13 +593,13 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
if (parentNode == root) {
SWFList swfList = swfs.get(index);
if (!swfList.isBundle()) {
return swfList.get(0);
OpenableList openableList = swfs.get(index);
if (!openableList.isBundle()) {
return openableList.get(0);
}
return swfList;
} else if (parentNode instanceof SWFList) {
return ((SWFList) parentNode).swfs.get(index);
return openableList;
} else if (parentNode instanceof OpenableList) {
return ((OpenableList) parentNode).items.get(index);
} else if (parentNode instanceof SWF) {
return getSwfFolders((SWF) parentNode).get(index);
} else if (parentNode instanceof FolderItem) {
@@ -615,7 +623,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
if (result instanceof Tag) {
Tag resultTag = (Tag) result;
Map<Tag, TagScript> currentTagScriptCache = getTagScriptCache(result.getSwf());
Map<Tag, TagScript> currentTagScriptCache = getTagScriptCache((SWF) result.getOpenable());
TagScript tagScript = currentTagScriptCache.get(resultTag);
if (tagScript == null) {
List<TreeItem> subNodes = new ArrayList<>();
@@ -624,7 +632,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
subNodes.add(item);
}
}
tagScript = new TagScript(result.getSwf(), resultTag, subNodes);
tagScript = new TagScript((SWF) result.getOpenable(), resultTag, subNodes);
currentTagScriptCache.put(resultTag, tagScript);
}
result = tagScript;
@@ -639,6 +647,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
return ((AS3Package) parentNode).getChild(index);
} else if (parentNode instanceof ButtonTag) {
return ((ButtonTag) parentNode).getRecords().get(index);
} else if (parentNode instanceof ABC) {
ClassesListTreeModel classesTreeModel = getClassesListTreeModel((ABC) parentNode);
return classesTreeModel.getChild(classesTreeModel.getRoot(), index);
}
throw new Error("Unsupported parent type: " + parentNode.getClass().getName());
@@ -653,8 +664,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
}
if (parentNode == root) {
return mappedSize + swfs.size();
} else if (parentNode instanceof SWFList) {
return mappedSize + ((SWFList) parentNode).swfs.size();
} else if (parentNode instanceof OpenableList) {
return mappedSize + ((OpenableList) parentNode).items.size();
} else if (parentNode instanceof SWF) {
return mappedSize + getSwfFolders((SWF) parentNode).size();
} else if (parentNode instanceof HeaderItem) {
@@ -683,6 +694,9 @@ public class TagTreeModel extends AbstractTagTreeModel {
return mappedSize + ((ButtonTag) parentNode).getRecords().size();
} else if (parentNode instanceof CharacterTag) {
return mappedSize;
} else if (parentNode instanceof ABC) {
ClassesListTreeModel classesTreeModel = getClassesListTreeModel((ABC) parentNode);
return classesTreeModel.getChildCount(classesTreeModel.getRoot());
}
return 0;
@@ -715,12 +729,12 @@ public class TagTreeModel extends AbstractTagTreeModel {
baseIndex = mapped.size();
}
if (parentNode == root) {
SWFList swfList = child instanceof SWFList
? (SWFList) child
: ((SWF) child).swfList;
return indexOfAdd(baseIndex, swfs.indexOf(swfList));
} else if (parentNode instanceof SWFList) {
return indexOfAdd(baseIndex, ((SWFList) parentNode).swfs.indexOf(childNode));
OpenableList openableList = child instanceof OpenableList
? (OpenableList) child
: ((Openable) child).getOpenableList();
return indexOfAdd(baseIndex, swfs.indexOf(openableList));
} else if (parentNode instanceof OpenableList) {
return indexOfAdd(baseIndex, ((OpenableList) parentNode).items.indexOf(childNode));
} else if (parentNode instanceof SWF) {
return indexOfAdd(baseIndex, getSwfFolders((SWF) parentNode).indexOf(childNode));
} else if (parentNode instanceof FolderItem) {
@@ -754,8 +768,21 @@ public class TagTreeModel extends AbstractTagTreeModel {
return indexOfAdd(baseIndex, ((ButtonTag) parentNode).getRecords().indexOf(childNode));
} else if (parentNode instanceof CharacterTag) {
return indexOfAdd(baseIndex, getMappedCharacters(((CharacterTag) parentNode).getSwf(), (CharacterTag) parentNode).indexOf(childNode));
} else if (parentNode instanceof ABC) {
ClassesListTreeModel classesTreeModel = getClassesListTreeModel((ABC) parentNode);
return indexOfAdd(baseIndex, classesTreeModel.getIndexOfChild(classesTreeModel.getRoot(), childNode));
}
return -1;
}
private ClassesListTreeModel getClassesListTreeModel(ABC abc) {
if (abcClassesTree.containsKey(abc)) {
return abcClassesTree.get(abc);
}
ClassesListTreeModel model = new ClassesListTreeModel(abc, Configuration.flattenASPackages.get());
abcClassesTree.put(abc, model);
return model;
}
}