diff --git a/CHANGELOG.md b/CHANGELOG.md index b2a3ab777..267c5f74a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file. ### Changed - Compound script has slot/const traits inside main script initializer +- Export to FlashDevelop and IntelliJ IDEA is available only for SWFs without main timeline ## [21.0.2] - 2024-08-12 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfFlashDevelopExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfFlashDevelopExporter.java index 993c3499f..5cb6596d4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfFlashDevelopExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfFlashDevelopExporter.java @@ -24,7 +24,14 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; +import static com.jpexs.decompiler.flash.exporters.swf.SwfIntelliJIdeaExporter.canExportSwf; import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.StartSound2Tag; +import com.jpexs.decompiler.flash.tags.StartSoundTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.File; import java.io.FileOutputStream; @@ -37,6 +44,25 @@ import java.io.IOException; */ public class SwfFlashDevelopExporter { + public static boolean canExportSwf(SWF swf) { + if (!swf.isAS3()) { + return false; + } + //Cannot export if it has something on main timeline + for (Tag t : swf.getTags()) { + if ( + (t instanceof PlaceObjectTypeTag) + || (t instanceof SoundStreamBlockTag) + || (t instanceof VideoFrameTag) + || (t instanceof StartSoundTag) + || (t instanceof StartSound2Tag) + ) { + return false; + } + } + return true; + } + private static String doubleToString(double d) { String ds = "" + d; if (ds.endsWith(".0")) { @@ -68,6 +94,10 @@ public class SwfFlashDevelopExporter { if (!swf.isAS3()) { throw new IllegalArgumentException("SWF must be AS3"); } + + if (!canExportSwf(swf)) { + throw new IllegalArgumentException("SWF must not contain main timeline"); + } String simpleName = outFile.getName(); if (simpleName.contains(".")) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfIntelliJIdeaExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfIntelliJIdeaExporter.java index 238b4d5ac..ec2085464 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfIntelliJIdeaExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/swf/SwfIntelliJIdeaExporter.java @@ -23,6 +23,12 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.StartSound2Tag; +import com.jpexs.decompiler.flash.tags.StartSoundTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.File; import java.io.FileOutputStream; @@ -52,14 +58,26 @@ public class SwfIntelliJIdeaExporter { return sb.toString(); } - private static String doubleToString(double d) { - String ds = "" + d; - if (ds.endsWith(".0")) { - ds = ds.substring(0, ds.length() - 2); + public static boolean canExportSwf(SWF swf) { + if (!swf.isAS3()) { + return false; } - return ds; + + //Cannot export if it has something on main timeline + for (Tag t : swf.getTags()) { + if ( + (t instanceof PlaceObjectTypeTag) + || (t instanceof SoundStreamBlockTag) + || (t instanceof VideoFrameTag) + || (t instanceof StartSoundTag) + || (t instanceof StartSound2Tag) + ) { + return false; + } + } + return true; } - + /** * Exports SWF to IntelliJ IDEA project. * @param swf SWF to export @@ -83,6 +101,10 @@ public class SwfIntelliJIdeaExporter { if (!swf.isAS3()) { throw new IllegalArgumentException("SWF must be AS3"); } + + if (!canExportSwf(swf)) { + throw new IllegalArgumentException("SWF must not contain main timeline"); + } if (!outDir.exists()) { if (!outDir.mkdirs()) { diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java index 77e058f9f..09b2a5c0e 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -25,6 +25,8 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener; import com.jpexs.decompiler.flash.console.ContextMenuTools; +import com.jpexs.decompiler.flash.exporters.swf.SwfFlashDevelopExporter; +import com.jpexs.decompiler.flash.exporters.swf.SwfIntelliJIdeaExporter; import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools; import com.jpexs.decompiler.flash.gui.helpers.CheckResources; import com.jpexs.decompiler.flash.search.ScriptSearchResult; @@ -1001,8 +1003,12 @@ public abstract class MainFrameMenu implements MenuBuilder { boolean swfSelected = openable instanceof SWF; boolean abcSelected = openable instanceof ABC; boolean isAs3 = false; + boolean canExportFlashDevelop = false; + boolean canExportIdea = false; if (swf != null) { isAs3 = swf.isAS3(); + canExportFlashDevelop = SwfFlashDevelopExporter.canExportSwf(swf); + canExportIdea = SwfIntelliJIdeaExporter.canExportSwf(swf); } if (abcSelected) { isAs3 = true; @@ -1075,10 +1081,10 @@ public abstract class MainFrameMenu implements MenuBuilder { setMenuEnabled("/file/export/exportAll", openableSelected && !isWorking); setMenuEnabled("_/exportFla", swfSelected && !isWorking); setMenuEnabled("/file/export/exportFla", allSameSwf && openableSelected && !isWorking); - setMenuEnabled("_/exportFlashDevelop", swfSelected && !isWorking); - setMenuEnabled("/file/export/exportFlashDevelop", allSameSwf && openableSelected && isAs3 && !isWorking); - setMenuEnabled("_/exportIdea", swfSelected && !isWorking); - setMenuEnabled("/file/export/exportIdea", allSameSwf && openableSelected && isAs3 && !isWorking); + setMenuEnabled("_/exportFlashDevelop", swfSelected && !isWorking && canExportFlashDevelop); + setMenuEnabled("/file/export/exportFlashDevelop", allSameSwf && openableSelected && isAs3 && !isWorking && canExportFlashDevelop); + setMenuEnabled("_/exportIdea", swfSelected && !isWorking && canExportIdea); + setMenuEnabled("/file/export/exportIdea", allSameSwf && openableSelected && isAs3 && !isWorking && canExportIdea); setMenuEnabled("_/exportSelected", openableSelected && !isWorking); setMenuEnabled("/file/export/exportSelected", openableSelected && !isWorking); setMenuEnabled("/file/export/exportXml", swfSelected && !isWorking);