diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fba8f306..c4f5f6661 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
### Added
- Updated Flash player to SWF version map
- Harman AIR 51 float support compatibility
+- FlashDevelop project export - option to export AIR project (select correct type in the file save dialog)
### Fixed
- [#2266] StartSound/2 and VideoFrame tags, classNames not taken as dependencies (needed chars)
diff --git a/libsrc/ffdec_lib/build.xml b/libsrc/ffdec_lib/build.xml
index 90c1525a8..4dac3c4fc 100644
--- a/libsrc/ffdec_lib/build.xml
+++ b/libsrc/ffdec_lib/build.xml
@@ -34,7 +34,8 @@
-
+
+
diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FlashPlayerVersion.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FlashPlayerVersion.java
index b6faab155..285358eef 100644
--- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FlashPlayerVersion.java
+++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FlashPlayerVersion.java
@@ -25,7 +25,9 @@ import java.util.Map;
*/
public class FlashPlayerVersion {
private static final Map flashPlayerToSwfVersion = new HashMap<>();
+ private static final Map airToSwfVersion = new HashMap<>();
private static final Map swfVersionToFlashPlayer = new HashMap<>();
+ private static final Map swfVersionToAir = new HashMap<>();
static {
flashPlayerToSwfVersion.put("9.0", 9); //9.0.115.0
flashPlayerToSwfVersion.put("10.0", 10);
@@ -66,6 +68,47 @@ public class FlashPlayerVersion {
flashPlayerToSwfVersion.put("33.0", 44);
flashPlayerToSwfVersion.put("33.1", 44);
flashPlayerToSwfVersion.put("50.0", 50);
+ flashPlayerToSwfVersion.put("51.0", 51);
+
+ airToSwfVersion.put("1.5", 10);
+ airToSwfVersion.put("2.0", 10);
+ airToSwfVersion.put("2.6", 11);
+ airToSwfVersion.put("2.7", 12);
+ airToSwfVersion.put("3.0", 13);
+ airToSwfVersion.put("3.1", 14);
+ airToSwfVersion.put("3.2", 15);
+ airToSwfVersion.put("3.3", 16);
+ airToSwfVersion.put("3.4", 17);
+ airToSwfVersion.put("3.5", 18);
+ airToSwfVersion.put("3.6", 19);
+ airToSwfVersion.put("3.7", 20);
+ airToSwfVersion.put("3.8", 21);
+ airToSwfVersion.put("3.9", 22);
+ airToSwfVersion.put("4.0", 23);
+ airToSwfVersion.put("13.0", 24);
+ airToSwfVersion.put("14.0", 25);
+ airToSwfVersion.put("15.0", 26);
+ airToSwfVersion.put("16.0", 27);
+ airToSwfVersion.put("17.0", 28);
+ airToSwfVersion.put("18.0", 29);
+ airToSwfVersion.put("19.0", 30);
+ airToSwfVersion.put("20.0", 31);
+ airToSwfVersion.put("21.0", 32);
+ airToSwfVersion.put("22.0", 33);
+ airToSwfVersion.put("23.0", 34);
+ airToSwfVersion.put("24.0", 35);
+ airToSwfVersion.put("25.0", 36);
+ airToSwfVersion.put("26.0", 37);
+ airToSwfVersion.put("27.0", 38);
+ airToSwfVersion.put("28.0", 39);
+ airToSwfVersion.put("29.0", 40);
+ airToSwfVersion.put("30.0", 41);
+ airToSwfVersion.put("31.0", 42);
+ airToSwfVersion.put("32.0", 43);
+ airToSwfVersion.put("33.0", 44);
+ airToSwfVersion.put("33.1", 44);
+ airToSwfVersion.put("50.0", 50);
+ airToSwfVersion.put("51.0", 51);
for (String flashPlayer : flashPlayerToSwfVersion.keySet()) {
int swfVersion = flashPlayerToSwfVersion.get(flashPlayer);
@@ -73,6 +116,13 @@ public class FlashPlayerVersion {
swfVersionToFlashPlayer.put(swfVersion, flashPlayer);
}
}
+
+ for (String air : airToSwfVersion.keySet()) {
+ int swfVersion = airToSwfVersion.get(air);
+ if (!swfVersionToAir.containsKey(swfVersion)) {
+ swfVersionToAir.put(swfVersion, air);
+ }
+ }
}
/**
@@ -81,8 +131,8 @@ public class FlashPlayerVersion {
* @return Flash player version or null if not found
*/
public static String getFlashPlayerBySwfVersion(int swfVersion) {
- if (swfVersion > 50) {
- return "50.0"; //??
+ if (swfVersion > 51) {
+ return "51.0"; //??
}
return swfVersionToFlashPlayer.get(swfVersion);
}
@@ -98,4 +148,29 @@ public class FlashPlayerVersion {
}
return flashPlayerToSwfVersion.get(flashPlayerVersion);
}
+
+
+ /**
+ * Gets Air version by SWF version
+ * @param swfVersion SWF version
+ * @return Air version or null if not found
+ */
+ public static String getAirBySwfVersion(int swfVersion) {
+ if (swfVersion > 51) {
+ return "51.0"; //??
+ }
+ return swfVersionToFlashPlayer.get(swfVersion);
+ }
+
+ /**
+ * Gets SWF version by Air version.
+ * @param air Air version
+ * @return SWF version or -1 if not found
+ */
+ public static int getSwfVersionByAir(String air) {
+ if (!airToSwfVersion.containsKey(air)) {
+ return -1;
+ }
+ return airToSwfVersion.get(air);
+ }
}
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 ebfb516b8..37f61e230 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
@@ -31,10 +31,13 @@ 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.Helper;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
/**
* Exports SWF to FlashDevelop project.
@@ -49,19 +52,17 @@ public class SwfFlashDevelopExporter {
}
//Cannot export if it has something on main timeline
for (Tag t : swf.getTags()) {
- if (
- (t instanceof PlaceObjectTypeTag)
+ if ((t instanceof PlaceObjectTypeTag)
|| (t instanceof SoundStreamBlockTag)
|| (t instanceof VideoFrameTag)
|| (t instanceof StartSoundTag)
- || (t instanceof StartSound2Tag)
- ) {
+ || (t instanceof StartSound2Tag)) {
return false;
}
}
return true;
}
-
+
private static String doubleToString(double d) {
String ds = "" + d;
if (ds.endsWith(".0")) {
@@ -72,28 +73,32 @@ public class SwfFlashDevelopExporter {
/**
* Exports SWF to FlashDevelop project.
+ *
* @param swf SWF to export
* @param outFile Output file
+ * @param air
* @param handler Handler for abort, retry, ignore
* @throws IOException On I/O error
*/
- public void exportFlashDevelopProject(SWF swf, File outFile, AbortRetryIgnoreHandler handler) throws IOException {
- exportFlashDevelopProject(swf, outFile, handler, null);
+ public void exportFlashDevelopProject(SWF swf, File outFile, boolean air, AbortRetryIgnoreHandler handler) throws IOException {
+ exportFlashDevelopProject(swf, outFile, air, handler, null);
}
/**
* Exports SWF to FlashDevelop project.
+ *
* @param swf SWF to export
* @param outFile Output file
+ * @param air AIR
* @param handler Handler for abort, retry, ignore
* @param eventListener Event listener
* @throws IOException On I/O error
*/
- public void exportFlashDevelopProject(SWF swf, File outFile, AbortRetryIgnoreHandler handler, EventListener eventListener) throws IOException {
+ public void exportFlashDevelopProject(SWF swf, File outFile, boolean air, AbortRetryIgnoreHandler handler, EventListener eventListener) throws IOException {
if (!swf.isAS3()) {
throw new IllegalArgumentException("SWF must be AS3");
}
-
+
if (!canExportSwf(swf)) {
throw new IllegalArgumentException("SWF must not contain main timeline");
}
@@ -103,79 +108,240 @@ public class SwfFlashDevelopExporter {
simpleName = simpleName.substring(0, simpleName.lastIndexOf("."));
}
+ String simpleNameNoSpaces = simpleName.replace(" ", "");
+
SetBackgroundColorTag bgColorTag = swf.getBackgroundColor();
String documentClass = swf.getDocumentClass();
+ String srcPath = "src";
+ String project;
+
String flashPlayerVersion = FlashPlayerVersion.getFlashPlayerBySwfVersion(swf.version);
String[] flashPlayerVersions = flashPlayerVersion.split("\\.");
-
- String srcPath = "src";
- String project = "\n"
- + "\n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + (documentClass == null
- ? " \n"
- : "\n")
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + "";
+
+ String airVersion = FlashPlayerVersion.getAirBySwfVersion(swf.version);
+ String[] airVersions = airVersion.split("\\.");
+
+ if (air) {
+
+ project = "\n"
+ + "\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + (documentClass == null
+ ? " \n"
+ : "\n")
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + "";
+ } else {
+ project = "\n"
+ + "\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + (documentClass == null
+ ? " \n"
+ : "\n")
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + "";
+ }
try (FileOutputStream fos = new FileOutputStream(outFile)) {
fos.write(Utf8Helper.getBytes(project));
}
+ if (air) {
+ String applicationXml = " \n"
+ + "\n"
+ + " \n"
+ + " " + simpleNameNoSpaces + " \n"
+ + " 1.0 \n"
+ + " " + simpleNameNoSpaces + " \n"
+ + " \n"
+ + " " + simpleName + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " " + simpleName + " \n"
+ + " " + simpleNameNoSpaces + ".swf \n"
+ + " standard \n"
+ + " false \n"
+ + " true \n"
+ + " true \n"
+ + " true \n"
+ + " true \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + "";
+ try (FileOutputStream fos = new FileOutputStream(outFile.toPath().getParent().resolve("application.xml").toFile())) {
+ fos.write(Utf8Helper.getBytes(applicationXml));
+ }
+
+ Path batDirPath = outFile.toPath().getParent().resolve("bat");
+ batDirPath.toFile().mkdir();
+ String[] batFiles = new String[]{
+ "CreateCertificate.bat",
+ "PackageApp.bat",
+ "Packager.bat",
+ "RunApp.bat",
+ "SetupApp.bat",
+ "SetupSDK.bat"
+ };
+ for (String batFile : batFiles) {
+ InputStream is = SwfFlashDevelopExporter.class.getResourceAsStream("/com/jpexs/helpers/resource/fd_air/bat/" + batFile);
+ byte[] data = Helper.readStream(is);
+ String strData = Utf8Helper.decode(data);
+ strData = strData.replace("", simpleName);
+ strData = strData.replace("", simpleNameNoSpaces);
+ try (FileOutputStream fos = new FileOutputStream(batDirPath.resolve(batFile).toFile())) {
+ fos.write(Utf8Helper.getBytes(strData));
+ }
+ }
+ }
+
boolean parallel = Configuration.parallelSpeedUp.get();
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false);
swf.exportActionScript(handler, outFile.toPath().getParent().resolve(srcPath).toFile().getAbsolutePath(), scriptExportSettings, parallel, eventListener);
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/CreateCertificate.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/CreateCertificate.bat
new file mode 100644
index 000000000..f9a51a57f
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/CreateCertificate.bat
@@ -0,0 +1,34 @@
+@echo off
+
+:: Set working dir
+cd %~dp0 & cd ..
+
+set PAUSE_ERRORS=1
+call bat\SetupSDK.bat
+call bat\SetupApp.bat
+
+:: Generate
+echo.
+echo Generating a self-signed certificate...
+call adt -certificate -cn %CERT_NAME% 2048-RSA %CERT_FILE% %CERT_PASS%
+if errorlevel 1 goto failed
+
+:succeed
+echo.
+echo Certificate created: %CERT_FILE% with password "%CERT_PASS%"
+echo.
+if "%CERT_PASS%" == "fd" echo Note: You did not change the default password
+echo.
+echo HINTS:
+echo - you only need to generate this certificate once,
+echo - wait a minute before using this certificate to package your AIR application.
+echo.
+goto end
+
+:failed
+echo.
+echo Certificate creation FAILED.
+echo.
+
+:end
+pause
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/PackageApp.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/PackageApp.bat
new file mode 100644
index 000000000..59aed98b6
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/PackageApp.bat
@@ -0,0 +1,15 @@
+@echo off
+
+:: Set working dir
+cd %~dp0 & cd ..
+
+set PAUSE_ERRORS=1
+call bat\SetupSDK.bat
+call bat\SetupApp.bat
+
+set AIR_TARGET=
+::set AIR_TARGET=-captive-runtime
+set OPTIONS=-tsa none
+call bat\Packager.bat
+
+pause
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/Packager.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/Packager.bat
new file mode 100644
index 000000000..03a520e1a
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/Packager.bat
@@ -0,0 +1,39 @@
+@echo off
+
+:: Set working dir
+cd %~dp0 & cd ..
+
+if not exist %CERT_FILE% goto certificate
+
+:: AIR output
+if not exist %AIR_PATH% md %AIR_PATH%
+set OUTPUT=%AIR_PATH%\%AIR_NAME%%AIR_TARGET%.air
+
+:: Package
+echo.
+echo Packaging %AIR_NAME%%AIR_TARGET%.air using certificate %CERT_FILE%...
+call adt -package %OPTIONS% %SIGNING_OPTIONS% %OUTPUT% %APP_XML% %FILE_OR_DIR%
+if errorlevel 1 goto failed
+goto end
+
+:certificate
+echo.
+echo Certificate not found: %CERT_FILE%
+echo.
+echo Troubleshooting:
+echo - generate a default certificate using 'bat\CreateCertificate.bat'
+echo.
+if %PAUSE_ERRORS%==1 pause
+exit
+
+:failed
+echo AIR setup creation FAILED.
+echo.
+echo Troubleshooting:
+echo - verify AIR SDK target version in %APP_XML%
+echo.
+if %PAUSE_ERRORS%==1 pause
+exit
+
+:end
+echo.
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/RunApp.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/RunApp.bat
new file mode 100644
index 000000000..5b00357b4
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/RunApp.bat
@@ -0,0 +1,21 @@
+@echo off
+
+:: Set working dir
+cd %~dp0 & cd ..
+
+set PAUSE_ERRORS=1
+call bat\SetupSDK.bat
+call bat\SetupApp.bat
+
+echo.
+echo Starting AIR Debug Launcher...
+echo.
+
+adl "%APP_XML%" "%APP_DIR%"
+if errorlevel 1 goto error
+goto end
+
+:error
+pause
+
+:end
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupApp.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupApp.bat
new file mode 100644
index 000000000..21eecd47d
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupApp.bat
@@ -0,0 +1,47 @@
+:: Set working dir
+cd %~dp0 & cd ..
+
+:user_configuration
+
+:: About AIR application packaging
+:: http://livedocs.adobe.com/flex/3/html/help.html?content=CommandLineTools_5.html#1035959
+:: http://livedocs.adobe.com/flex/3/html/distributing_apps_4.html#1037515
+
+:: NOTICE: all paths are relative to project root
+
+:: Your certificate information
+set CERT_NAME=""
+set CERT_PASS=fd
+set CERT_FILE="bat\.p12"
+set SIGNING_OPTIONS=-storetype pkcs12 -keystore %CERT_FILE% -storepass %CERT_PASS%
+
+:: Application descriptor
+set APP_XML=application.xml
+
+:: Files to package
+set APP_DIR=bin
+set FILE_OR_DIR=-C %APP_DIR% .
+
+:: Your application ID (must match of Application descriptor) and remove spaces
+for /f "tokens=3 delims=<>" %%a in ('findstr /R /C:"^[ ]*" %APP_XML%') do set APP_ID=%%a
+set APP_ID=%APP_ID: =%
+
+:: Output
+set AIR_PATH=air
+set AIR_NAME=
+
+:validation
+findstr /C:"%APP_ID%" "%APP_XML%" > NUL
+if errorlevel 1 goto badid
+goto end
+
+:badid
+echo.
+echo ERROR:
+echo Application ID in 'bat\SetupApp.bat' (APP_ID)
+echo does NOT match Application descriptor '%APP_XML%' (id)
+echo.
+if %PAUSE_ERRORS%==1 pause
+exit
+
+:end
diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupSDK.bat b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupSDK.bat
new file mode 100644
index 000000000..9f9409f9f
--- /dev/null
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/resource/fd_air/bat/SetupSDK.bat
@@ -0,0 +1,26 @@
+:: Set working dir
+cd %~dp0 & cd ..
+
+:user_configuration
+
+:: Static path to Flex SDK
+set FLEX_SDK=C:\flex
+
+:: Use FD supplied SDK path if executed from FD
+if exist "%FD_CUR_SDK%" set FLEX_SDK=%FD_CUR_SDK%
+
+:validation
+if not exist "%FLEX_SDK%\bin" goto flexsdk
+goto succeed
+
+:flexsdk
+echo.
+echo ERROR: incorrect path to Flex SDK in 'bat\SetupSDK.bat'
+echo.
+echo Looking for: %FLEX_SDK%\bin
+echo.
+if %PAUSE_ERRORS%==1 pause
+exit
+
+:succeed
+set PATH=%FLEX_SDK%\bin;%PATH%
diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
index b6e155da7..8f59a9dbe 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
@@ -3328,7 +3328,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
fileName = swfShortName + ".as3proj";
}
- FileFilter f = new FileFilter() {
+ FileFilter as3Filter = new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".as3proj"));
@@ -3339,7 +3339,19 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return translate("filter.as3proj");
}
};
- fc.setFileFilter(f);
+ FileFilter airAs3Filter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return f.isDirectory() || (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".as3proj"));
+ }
+
+ @Override
+ public String getDescription() {
+ return translate("filter.air.as3proj");
+ }
+ };
+ fc.setFileFilter(as3Filter);
+ fc.addChoosableFileFilter(airAs3Filter);
fc.setAcceptAllFileFilterUsed(false);
fc.setSelectedFile(new File(selDir + fileName));
@@ -3380,7 +3392,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
EventListener evl = swf.getExportEventListener();
try {
AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler();
- exporter.exportFlashDevelopProject(swf, new File(fpath), errorHandler, evl);
+ exporter.exportFlashDevelopProject(swf, new File(fpath), fc.getFileFilter() == airAs3Filter, errorHandler, evl);
} catch (Exception ex) {
logger.log(Level.SEVERE, "FlashDevelop export error", ex);
ViewMessages.showMessageDialog(MainPanel.this, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE);
diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties
index ad6493554..1034bb0d3 100644
--- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties
+++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties
@@ -968,7 +968,7 @@ tagInfo.idType=Type of the id
contextmenu.configurePathResolving=Configure path resolving...
contextmenu.setAsLinkage=Set AS linkage
contextmenu.exportFlashDevelop=Export FlashDevelop project
-filter.as3proj=FlashDevelop AS3 projects (*.as3proj)
+filter.as3proj=FlashDevelop AS3 project (*.as3proj)
work.exporting.flashDevelop=Exporting FlashDevelop project
menu.file.export.flashDevelop=Export FD project
contextmenu.exportIdea=Export IDEA project
@@ -990,4 +990,7 @@ message.confirm.addfunction=This action creates a new MethodInfo object with \
which you can use as operand for newfunction instruction.\r\n\
For editation of body and parameters of such function, you must locate it then in ActionScript view.
addfunction.result=New method info id generated: %method_info_index%. Press OK to copy it to clipboard.
-addfunction.result.title=New method info
\ No newline at end of file
+addfunction.result.title=New method info
+
+#after 21.0.2
+filter.air.as3proj = FlashDevelop AIR AS3 project (*.as3proj)
\ No newline at end of file