diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index f7315c384..546fcc5e1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -290,7 +290,7 @@ public final class SWF implements SWFContainerItem, Timelined { private final IdentifiersDeobfuscation deobfuscation = new IdentifiersDeobfuscation(); @Internal - private static Cache frameCache = Cache.getInstance(false, false, "frame"); + private Cache frameCache = Cache.getInstance(false, false, "frame"); @Internal private final Cache as2Cache = Cache.getInstance(true, false, "as2"); @@ -337,6 +337,7 @@ public final class SWF implements SWFContainerItem, Timelined { as2Cache.clear(); as3Cache.clear(); + frameCache.clear(); timeline = null; clearDumpInfo(dumpInfo); @@ -2176,14 +2177,14 @@ public final class SWF implements SWFContainerItem, Timelined { mat.translateX, mat.translateY); } - public static SerializableImage getFromCache(String key) { + public SerializableImage getFromCache(String key) { if (frameCache.contains(key)) { - return SWF.frameCache.get(key); + return frameCache.get(key); } return null; } - public static void putToCache(String key, SerializableImage img) { + public void putToCache(String key, SerializableImage img) { if (Configuration.useFrameCache.get()) { frameCache.put(key, img); } @@ -2405,10 +2406,11 @@ public final class SWF implements SWFContainerItem, Timelined { } public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, boolean useCache, double zoom) { - String key = "frame_" + frame + "_" + timeline.id + "_" + timeline.swf.hashCode() + "_" + zoom; + SWF swf = timeline.swf; + String key = "frame_" + frame + "_" + timeline.id + "_" + swf.hashCode() + "_" + zoom; SerializableImage image; if (useCache) { - image = getFromCache(key); + image = swf.getFromCache(key); if (image != null) { return image; } @@ -2429,6 +2431,7 @@ public final class SWF implements SWFContainerItem, Timelined { g.setColor(backGroundColor); g.fill(new Rectangle(image.getWidth(), image.getHeight())); } + Matrix m = transformation.clone(); m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom); m.scale(zoom); @@ -2437,8 +2440,9 @@ public final class SWF implements SWFContainerItem, Timelined { renderContext.mouseButton = mouseButton; frameToImage(timeline, frame, time, renderContext, image, m, colorTransform); if (useCache) { - putToCache(key, image); + swf.putToCache(key, image); } + return image; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java index f3d19ab9a..89c61d4c2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -1060,6 +1060,10 @@ public class SWFInputStream implements AutoCloseable { * @throws java.lang.InterruptedException */ public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean lazy) throws IOException, InterruptedException { + if (Thread.currentThread().interrupted()) { + throw new InterruptedException(); + } + boolean parallel1 = level == 0 && parallel; ExecutorService executor = null; List> futureResults = new ArrayList<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 89fa5f584..15010ac41 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -196,7 +196,7 @@ public class ScriptPack extends AS3ClassTreeItem { String packageName = getPathPackage(); File outDir = new File(directory + File.separatorChar + makeDirPath(packageName)); Path.createDirectorySafe(outDir); - String fileName = outDir.toString() + File.separator + Helper.makeFileName(scriptName) + ".as"; + String fileName = outDir.toString() + File.separator + Helper.makeFileName(scriptName) + exportSettings.getFileExtension(); file = new File(fileName); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index da3d61b4f..4e97c4458 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -297,7 +297,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -745,7 +744,6 @@ public class AVM2Code implements Cloneable { public AVM2Code(ABCInputStream ais) throws IOException { Map codeMap = new TreeMap<>(); - Map endOffsets = new HashMap<>(); DumpInfo diParent = ais.dumpInfo; List addresses = new ArrayList<>(); long startPos = ais.getPosition(); @@ -810,8 +808,6 @@ public class AVM2Code implements Cloneable { } codeMap.put(startOffset, new AVM2Instruction(startOffset, instr, actualOperands)); ais.endDumpLevel(instr.instructionCode); - long endOffset = ais.getPosition(); - endOffsets.put(startOffset, endOffset); if (instr.isExitInstruction()) { //do not process jumps if there is return/throw instruction afterExit = true; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java index e555cf3f1..a0fa961b1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/AS2ScriptExporter.java @@ -117,7 +117,7 @@ public class AS2ScriptExporter { Path.createDirectorySafe(new File(outdir)); } - String f = outdir + name + ".as"; + String f = outdir + name + exportSettings.getFileExtension(); if (evl != null) { evl.handleExportingEvent("script", currentIndex, count, f); } @@ -153,7 +153,7 @@ public class AS2ScriptExporter { return file; } catch (InterruptedException ex) { } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { - Logger.getLogger(AS2ScriptExporter.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); + Logger.getLogger(AS2ScriptExporter.class.getName()).log(Level.SEVERE, "Decompilation error in script: " + name, ex); if (handler != null) { int action = handler.getNewInstance().handle(ex); switch (action) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/settings/ScriptExportSettings.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/settings/ScriptExportSettings.java index b5b99ca9c..d3b5c7bd7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/settings/ScriptExportSettings.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/settings/ScriptExportSettings.java @@ -35,4 +35,18 @@ public class ScriptExportSettings { this.mode = mode; this.singleFile = singleFile; } + + public String getFileExtension() { + switch (mode) { + case AS: + return ".as"; + case PCODE: + case PCODE_HEX: + return ".pcode"; + case HEX: + return ".hex"; + default: + throw new Error("Unsupported script export mode: " + mode); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java index 1c7f26954..f146545ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java @@ -830,6 +830,10 @@ public class Helper { } public static boolean contains(int[] array, int value) { + if (array == null) { + return false; + } + for (int i : array) { if (i == value) { return true; diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 0fee44ed2..2613a2314 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -1075,7 +1075,7 @@ public class CommandLineArgumentParser { as3classes = parseSelectClassOld(args); } - String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + ".as"); + String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; if (!as3classes.isEmpty()) { diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index efe4f390b..75efb4802 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -676,7 +676,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis drawFrame(counter); synchronized (ImagePanel.class) { if (timelined != null && counter == this.counter) { - int newframe = (frame + 1) % timelined.getTimeline().getFrameCount(); + int frameCount = timelined.getTimeline().getFrameCount(); + int newframe = frameCount > 0 ? (frame + 1) % frameCount : frame; if (stillFrame) { newframe = frame; } @@ -697,9 +698,10 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton, int selectedDepth, double zoom) { String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_depth" + selectedDepth + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode()) + "_" + zoom; - SerializableImage img = SWF.getFromCache(key); + SerializableImage img = swf.getFromCache(key); if (img == null) { Timeline timeline = drawable.getTimeline(); + boolean shouldCache = timeline.isSingleFrame(frame); if (drawable instanceof BoundedTag) { BoundedTag bounded = (BoundedTag) drawable; RECT rect = bounded.getRect(); @@ -760,8 +762,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis img = image; } - if (timeline.isSingleFrame(frame)) { - SWF.putToCache(key, img); + if (shouldCache) { + swf.putToCache(key, img); } } return img; @@ -796,38 +798,46 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis if (timelined == null) { return; } - Timeline timeline = timelined.getTimeline(); - if (frame >= timeline.getFrameCount()) { - return; - } - double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value; - getOutlines(timelined, frame, time, zoomDouble, stateUnderCursor, mouseButton, counter); - updatePos(timelined, lastMouseEvent, counter); + SerializableImage img; + try { + Timeline timeline = timelined.getTimeline(); + if (frame >= timeline.getFrameCount()) { + return; + } - Matrix mat = new Matrix(); - mat.translateX = swf.displayRect.Xmin; - mat.translateY = swf.displayRect.Ymin; - SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton, selectedDepth, zoomDouble); + double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value; + getOutlines(timelined, frame, time, zoomDouble, stateUnderCursor, mouseButton, counter); + updatePos(timelined, lastMouseEvent, counter); - List sounds = new ArrayList<>(); - List soundClasses = new ArrayList<>(); - timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses); - for (int cid : swf.getCharacters().keySet()) { - CharacterTag c = swf.getCharacter(cid); - for (String cls : soundClasses) { - if (cls.equals(c.getClassName())) { - sounds.add(cid); + Matrix mat = new Matrix(); + mat.translateX = swf.displayRect.Xmin; + mat.translateY = swf.displayRect.Ymin; + + img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton, selectedDepth, zoomDouble); + + List sounds = new ArrayList<>(); + List soundClasses = new ArrayList<>(); + timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses); + for (int cid : swf.getCharacters().keySet()) { + CharacterTag c = swf.getCharacter(cid); + for (String cls : soundClasses) { + if (cls.equals(c.getClassName())) { + sounds.add(cid); + } } } - } - for (int sndId : sounds) { - CharacterTag c = swf.getCharacter(sndId); - if (c instanceof SoundTag) { - SoundTag st = (SoundTag) c; - playSound(st, counter); + for (int sndId : sounds) { + CharacterTag c = swf.getCharacter(sndId); + if (c instanceof SoundTag) { + SoundTag st = (SoundTag) c; + playSound(st, counter); + } } + } catch (Throwable ex) { + // swf was closed during the rendering probably + return; } synchronized (ImagePanel.class) { diff --git a/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java b/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java index 4aaf9457b..7e7cd59c2 100644 --- a/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java +++ b/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java @@ -146,7 +146,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener { try { PosMarkedInputStream pmi = new PosMarkedInputStream(ret.get(addr)); ReReadableInputStream is = new ReReadableInputStream(pmi); - SWF swf = new SWF(is, null, null, null, false, true, true); + SWF swf = new SWF(is, null, null, null, false, true, false); long limit = pmi.getPos(); is.seek(0); is = new ReReadableInputStream(new LimitedInputStream(is, limit)); diff --git a/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java b/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java index 73b086586..49fe4523b 100644 --- a/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java @@ -17,12 +17,12 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.ApplicationInfo; +import com.jpexs.helpers.CancellableWorker; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.awt.image.ImageObserver; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JPanel; @@ -34,11 +34,17 @@ import javax.swing.SwingConstants; * * @author JPEXS */ -public class LoadingDialog extends AppDialog implements ImageObserver { +public class LoadingDialog extends AppDialog { private final JLabel detailLabel; - JProgressBar progressBar = new JProgressBar(0, 100); + private CancellableWorker worker; + + private final JProgressBar progressBar = new JProgressBar(0, 100); + + public void setWroker(CancellableWorker worker) { + this.worker = worker; + } public void setDetail(String d) { detailLabel.setText(d); @@ -46,17 +52,14 @@ public class LoadingDialog extends AppDialog implements ImageObserver { } public void setPercent(final int percent) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - if (percent == -1) { - progressBar.setIndeterminate(true); - progressBar.setStringPainted(false); - } else { - progressBar.setIndeterminate(false); - progressBar.setValue(percent); - progressBar.setStringPainted(true); - } + View.execInEventDispatch(() -> { + if (percent == -1) { + progressBar.setIndeterminate(true); + progressBar.setStringPainted(false); + } else { + progressBar.setIndeterminate(false); + progressBar.setValue(percent); + progressBar.setStringPainted(true); } }); } @@ -95,6 +98,10 @@ public class LoadingDialog extends AppDialog implements ImageObserver { public void windowClosing(WindowEvent e) { if (Main.shouldCloseWhenClosingLoadingDialog) { System.exit(0); + } else { + if (worker != null) { + worker.cancel(true); + } } } }); diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 12997cc3c..4d6bccd27 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -77,6 +77,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map.Entry; +import java.util.concurrent.CancellationException; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Formatter; @@ -213,27 +214,23 @@ public class Main { public static void startWork(final String name, final int percent, final CancellableWorker worker) { working = true; - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - if (mainFrame != null) { - mainFrame.getPanel().setWorkStatus(name, worker); - if (percent == -1) { - mainFrame.getPanel().hidePercent(); - } else { - mainFrame.getPanel().setPercent(percent); - } - } - if (loadingDialog != null) { - loadingDialog.setDetail(name); - loadingDialog.setPercent(percent); - } - if (CommandLineArgumentParser.isCommandLineMode()) { - System.out.println(name); + View.execInEventDispatchLater(() -> { + if (mainFrame != null) { + mainFrame.getPanel().setWorkStatus(name, worker); + if (percent == -1) { + mainFrame.getPanel().hidePercent(); + } else { + mainFrame.getPanel().setPercent(percent); } } + if (loadingDialog != null) { + loadingDialog.setDetail(name); + loadingDialog.setPercent(percent); + } + if (CommandLineArgumentParser.isCommandLineMode()) { + System.out.println(name); + } }); - } public static void stopWork() { @@ -278,22 +275,49 @@ public class Main { for (Entry streamEntry : bundle.getAll().entrySet()) { InputStream stream = streamEntry.getValue(); stream.reset(); - SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() { + CancellableWorker worker = new CancellableWorker() { @Override - public void progress(int p) { - startWork(AppStrings.translate("work.reading.swf"), p); + public SWF doInBackground() throws Exception { + SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() { + @Override + public void progress(int p) { + startWork(AppStrings.translate("work.reading.swf"), p); + } + }, Configuration.parallelSpeedUp.get()); + return swf; } - }, Configuration.parallelSpeedUp.get()); - result.add(swf); + }; + loadingDialog.setWroker(worker); + worker.execute(); + + try { + result.add(worker.get()); + } catch (CancellationException ex) { + Logger.getLogger(Main.class.getName()).log(Level.WARNING, "Loading SWF {0} was cancelled.", streamEntry.getKey()); + } } } else { - SWF swf = new SWF(inputStream, sourceInfo.getFile(), sourceInfo.getFileTitle(), new ProgressListener() { + InputStream fInputStream = inputStream; + CancellableWorker worker = new CancellableWorker() { @Override - public void progress(int p) { - startWork(AppStrings.translate("work.reading.swf"), p); + public SWF doInBackground() throws Exception { + SWF swf = new SWF(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle(), new ProgressListener() { + @Override + public void progress(int p) { + startWork(AppStrings.translate("work.reading.swf"), p); + } + }, Configuration.parallelSpeedUp.get()); + return swf; } - }, Configuration.parallelSpeedUp.get()); - result.add(swf); + }; + loadingDialog.setWroker(worker); + worker.execute(); + + try { + result.add(worker.get()); + } catch (CancellationException ex) { + Logger.getLogger(Main.class.getName()).log(Level.WARNING, "Loading SWF {0} was cancelled.", sourceInfo.getFileTitleOrName()); + } } if (fis != null) { @@ -472,17 +496,19 @@ public class Main { final SWF fswf = firstSWF; View.execInEventDispatch(() -> { - if (executeAfterOpen != null) { - executeAfterOpen.run(); - } - if (mainFrame != null) { mainFrame.setVisible(true); } + Main.stopWork(); + if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) { mainFrame.getPanel().gotoDocumentClass(fswf); } + + if (executeAfterOpen != null) { + executeAfterOpen.run(); + } }); return true; diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 0a54d40e2..fdbdc5cf6 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -775,18 +775,19 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } - for (SWFList swfList : swfs) { + List swfsLists = new ArrayList<>(swfs); + swfs.clear(); + oldItem = null; + clear(); + updateUi(); + + for (SWFList swfList : swfsLists) { List swfs2 = new ArrayList<>(swfList); for (SWF swf : swfs2) { swf.clearTagSwfs(); } } - swfs.clear(); - oldItem = null; - clear(); - updateUi(); - return true; } @@ -805,15 +806,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } + swfs.remove(swfList); + oldItem = null; + clear(); + updateUi(); + List swfs2 = new ArrayList<>(swfList); for (SWF swf : swfs2) { swf.clearTagSwfs(); } - swfs.remove(swfList); - oldItem = null; - clear(); - updateUi(); return true; } @@ -1130,7 +1132,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec String scriptsFolder = Path.combine(selFile, "scripts"); Path.createDirectorySafe(new File(scriptsFolder)); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), !parallel && Configuration.scriptExportSingleFile.get()); - String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + ".as"); + String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); if (swf.isAS3()) { try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; @@ -1184,7 +1186,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec String scriptsFolder = Path.combine(selFile, "scripts"); Path.createDirectorySafe(new File(scriptsFolder)); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), !parallel && Configuration.scriptExportSingleFile.get()); - String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + ".as"); + String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { scriptExportSettings.singleFileWriter = writer; swf.exportActionScript(handler, scriptsFolder, scriptExportSettings, parallel, evl); @@ -1766,12 +1768,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec long timeAfter = System.currentTimeMillis(); final long timeMs = timeAfter - timeBefore; - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - setStatus(translate("export.finishedin").replace("%time%", Helper.formatTimeSec(timeMs))); - } + View.execInEventDispatchLater(() -> { + setStatus(translate("export.finishedin").replace("%time%", Helper.formatTimeSec(timeMs))); }); } }.execute(); @@ -1874,13 +1872,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec Main.stopWork(); View.showMessageDialog(null, translate("work.restoringControlFlow.complete")); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - getABCPanel().reload(); - updateClassesList(); - } + View.execInEventDispatch(() -> { + getABCPanel().reload(); + updateClassesList(); }); } }.execute(); @@ -1904,26 +1898,22 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec @Override protected void done() { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - try { - int cnt = get(); - Main.stopWork(); - View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", Integer.toString(cnt))); - swf.assignClassesToSymbols(); - swf.clearScriptCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - updateClassesList(); - reload(true); - } catch (Exception ex) { - logger.log(Level.SEVERE, "Error during renaming identifiers", ex); - Main.stopWork(); - View.showMessageDialog(null, translate("error.occured").replace("%error%", ex.getClass().getSimpleName())); + View.execInEventDispatch(() -> { + try { + int cnt = get(); + Main.stopWork(); + View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", Integer.toString(cnt))); + swf.assignClassesToSymbols(); + swf.clearScriptCache(); + if (abcPanel != null) { + abcPanel.reload(); } + updateClassesList(); + reload(true); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error during renaming identifiers", ex); + Main.stopWork(); + View.showMessageDialog(null, translate("error.occured").replace("%error%", ex.getClass().getSimpleName())); } }); } @@ -2596,18 +2586,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec protected void done() { Main.stopWork(); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - setSourceWorker = null; - try { - get(); - } catch (CancellationException ex) { - getABCPanel().decompiledTextArea.setText("// " + AppStrings.translate("work.canceled")); - } catch (Exception ex) { - getABCPanel().decompiledTextArea.setText("// " + AppStrings.translate("decompilationError") + ": " + ex); - } + View.execInEventDispatch(() -> { + setSourceWorker = null; + try { + get(); + } catch (CancellationException ex) { + getABCPanel().decompiledTextArea.setText("// " + AppStrings.translate("work.canceled")); + } catch (Exception ex) { + getABCPanel().decompiledTextArea.setText("// " + AppStrings.translate("decompilationError") + ": " + ex); } }); } diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 9283e1d74..d2262f873 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -404,7 +404,7 @@ public class TagTreeContextMenu extends JPopupMenu implements ActionListener { rawEditMenuItem.setVisible(firstItem instanceof Tag); } } - + if (allSelectedIsInTheSameSwf && allSelectedIsTag && swfs.size() > 1) { moveTagMenu.removeAll(); copyTagMenu.removeAll(); @@ -424,7 +424,7 @@ public class TagTreeContextMenu extends JPopupMenu implements ActionListener { targetSwf.tags.add(tag); tag.setModified(true); } - + sourceSwf.assignExportNamesToSymbols(); targetSwf.assignExportNamesToSymbols(); sourceSwf.assignClassesToSymbols(); @@ -451,7 +451,7 @@ public class TagTreeContextMenu extends JPopupMenu implements ActionListener { targetSwf.tags.add(copyTag); copyTag.setModified(true); } - + targetSwf.assignExportNamesToSymbols(); targetSwf.assignClassesToSymbols(); targetSwf.clearImageCache();