mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-24 19:01:01 +00:00
Changed: SWF to XML export in GUI dialog selects a XML file instead of directory
(and directory when multiple SWFs are selected)
This commit is contained in:
@@ -44,6 +44,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
This may break backwards compatibility. For importing scripts from older
|
This may break backwards compatibility. For importing scripts from older
|
||||||
versions of FFDec, you should move the scripts from `<default package>`
|
versions of FFDec, you should move the scripts from `<default package>`
|
||||||
to main scripts folder.
|
to main scripts folder.
|
||||||
|
- SWF to XML export in GUI dialog selects a XML file instead of directory
|
||||||
|
(and directory when multiple SWFs are selected)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- [#2456] FLA export - NullPointer exception while exporting to CS4 or lower via commandline
|
- [#2456] FLA export - NullPointer exception while exporting to CS4 or lower via commandline
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import java.io.Writer;
|
|||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -70,12 +69,12 @@ public class SwfXmlExporter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports SWF to XML.
|
* Exports SWF to XML.
|
||||||
|
*
|
||||||
* @param swf SWF to export
|
* @param swf SWF to export
|
||||||
* @param outFile Target file to save to
|
* @param outFile Target file to save to
|
||||||
* @return List of exported files
|
|
||||||
* @throws IOException On I/O error
|
* @throws IOException On I/O error
|
||||||
*/
|
*/
|
||||||
public List<File> exportXml(SWF swf, File outFile) throws IOException {
|
public void exportXml(SWF swf, File outFile) throws IOException {
|
||||||
try {
|
try {
|
||||||
File tmp = File.createTempFile("FFDEC", "XML");
|
File tmp = File.createTempFile("FFDEC", "XML");
|
||||||
|
|
||||||
@@ -92,21 +91,23 @@ public class SwfXmlExporter {
|
|||||||
xmlWriter.close();
|
xmlWriter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Test write to raise IOException
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(outFile)) {
|
||||||
|
fos.write(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!new XmlPrettyFormat().prettyFormat(tmp, outFile, 2, true)) {
|
if (!new XmlPrettyFormat().prettyFormat(tmp, outFile, 2, true)) {
|
||||||
logger.log(Level.SEVERE, "Cannot prettyformat XML");
|
logger.log(Level.SEVERE, "Cannot prettyformat XML");
|
||||||
}
|
}
|
||||||
tmp.delete();
|
tmp.delete();
|
||||||
} catch (Exception ex) {
|
} catch (XMLStreamException ex) {
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<File> ret = new ArrayList<>();
|
|
||||||
ret.add(outFile);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports SWF to XML.
|
* Exports SWF to XML.
|
||||||
|
*
|
||||||
* @param swf SWF to export
|
* @param swf SWF to export
|
||||||
* @param writer XML writer
|
* @param writer XML writer
|
||||||
* @throws IOException On I/O error
|
* @throws IOException On I/O error
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.DecompilerPool;
|
|||||||
import com.jpexs.decompiler.flash.EventListener;
|
import com.jpexs.decompiler.flash.EventListener;
|
||||||
import com.jpexs.decompiler.flash.OpenableSourceInfo;
|
import com.jpexs.decompiler.flash.OpenableSourceInfo;
|
||||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||||
|
import com.jpexs.decompiler.flash.RetryTask;
|
||||||
import com.jpexs.decompiler.flash.SWF;
|
import com.jpexs.decompiler.flash.SWF;
|
||||||
import com.jpexs.decompiler.flash.abc.ABC;
|
import com.jpexs.decompiler.flash.abc.ABC;
|
||||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||||
@@ -4538,38 +4539,114 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
|||||||
public void exportSwfXml(List<TreeItem> items) {
|
public void exportSwfXml(List<TreeItem> items) {
|
||||||
View.checkAccess();
|
View.checkAccess();
|
||||||
|
|
||||||
Set<SWF> swfs = new LinkedHashSet<>();
|
Set<SWF> usedOpenables = new LinkedHashSet<>();
|
||||||
|
Set<OpenableList> usedOpenableLists = new HashSet<>();
|
||||||
|
|
||||||
for (TreeItem item : items) {
|
for (TreeItem item : items) {
|
||||||
if (item instanceof OpenableList) {
|
if (item instanceof OpenableList) {
|
||||||
OpenableList list = (OpenableList) item;
|
OpenableList list = (OpenableList) item;
|
||||||
|
usedOpenableLists.add(list);
|
||||||
for (Openable openable : list) {
|
for (Openable openable : list) {
|
||||||
if (openable instanceof SWF) {
|
if (openable instanceof SWF) {
|
||||||
swfs.add((SWF) openable);
|
usedOpenables.add((SWF) openable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Openable openable = item.getOpenable();
|
Openable openable = item.getOpenable();
|
||||||
if (openable instanceof SWF) {
|
if (openable instanceof SWF) {
|
||||||
swfs.add((SWF) openable);
|
usedOpenables.add((SWF) openable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SWF swf : swfs) {
|
Map<OpenableList, Map<String, Integer>> usedSwfIdsInBundles = new HashMap<>();
|
||||||
final String selFile = selectExportDir("exportxml");
|
Map<String, Integer> usedSwfsIds = new HashMap<>();
|
||||||
|
|
||||||
|
String selFile;
|
||||||
|
if (usedOpenables.size() > 1) {
|
||||||
|
selFile = selectExportDir("exportxml");
|
||||||
|
if (selFile == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JFileChooser fc = View.getFileChooserWithIcon("exportxml");
|
||||||
|
fc.setDialogTitle(AppStrings.translate("menu.file.export.xml"));
|
||||||
|
String selDir = Configuration.lastExportDir.get();
|
||||||
|
fc.setCurrentDirectory(new File(selDir));
|
||||||
|
if (!selDir.endsWith(File.separator)) {
|
||||||
|
selDir += File.separator;
|
||||||
|
}
|
||||||
|
SWF swf = usedOpenables.iterator().next();
|
||||||
|
String swfFileName = swf.getTitleOrShortFileName();
|
||||||
|
String xmlFileName = swfFileName + ".xml";
|
||||||
|
if (swfFileName.toLowerCase(Locale.ENGLISH).endsWith(".swf")
|
||||||
|
|| swfFileName.toLowerCase(Locale.ENGLISH).endsWith(".gfx")) {
|
||||||
|
xmlFileName = swfFileName.substring(0, swfFileName.lastIndexOf(".")) + ".xml";
|
||||||
|
}
|
||||||
|
fc.setSelectedFile(new File(selDir + xmlFileName));
|
||||||
|
fc.setFileFilter(new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File f) {
|
||||||
|
return f.isDirectory() || f.getName().toLowerCase(Locale.ENGLISH).endsWith(".xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return AppStrings.translate("filter.xml");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (fc.showSaveDialog(Main.getDefaultMessagesComponent()) != JFileChooser.APPROVE_OPTION) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selFile = Helper.fixDialogFile(fc.getSelectedFile()).getAbsolutePath();
|
||||||
|
if (!selFile.toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
|
||||||
|
selFile = selFile + ".xml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbortRetryIgnoreHandler handler = new GuiAbortRetryIgnoreHandler();
|
||||||
|
for (SWF openable : usedOpenables) {
|
||||||
if (selFile != null) {
|
if (selFile != null) {
|
||||||
Main.startWork(translate("work.exporting") + "...", null);
|
Main.startWork(translate("work.exporting") + "...", null);
|
||||||
|
|
||||||
|
String selFile2;
|
||||||
|
if (usedOpenables.size() > 1) {
|
||||||
|
String swfFileName = openable.getTitleOrShortFileName();
|
||||||
|
String fileNameNoExt = swfFileName;
|
||||||
|
if (swfFileName.toLowerCase(Locale.ENGLISH).endsWith(".swf")
|
||||||
|
|| swfFileName.toLowerCase(Locale.ENGLISH).endsWith(".gfx")) {
|
||||||
|
fileNameNoExt = swfFileName.substring(0, swfFileName.lastIndexOf("."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedOpenableLists.size() > 1 && openable.getOpenableList() != null && openable.getOpenableList().isBundle()) {
|
||||||
|
if (!usedSwfIdsInBundles.containsKey(openable.getOpenableList())) {
|
||||||
|
usedSwfIdsInBundles.put(openable.getOpenableList(), new HashMap<>());
|
||||||
|
}
|
||||||
|
File parentDir = new File(selFile + File.separator + openable.getOpenableList().name);
|
||||||
|
parentDir.mkdirs();
|
||||||
|
selFile2 = selFile + File.separator + openable.getOpenableList().name + File.separator + Helper.getNextId(fileNameNoExt, usedSwfIdsInBundles.get(openable.getOpenableList())) + ".xml";
|
||||||
|
} else {
|
||||||
|
selFile2 = selFile + File.separator + Helper.getNextId(fileNameNoExt, usedSwfsIds) + ".xml";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selFile2 = selFile;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File outFile = new File(selFile + File.separator + Helper.makeFileName("swf.xml"));
|
new RetryTask(() -> {
|
||||||
new SwfXmlExporter().exportXml(swf, outFile);
|
File outFile = new File(selFile2);
|
||||||
Main.stopWork();
|
new SwfXmlExporter().exportXml(openable, outFile);
|
||||||
|
}, handler).run();
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
|
break;
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Main.stopWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importSwfXml(List<TreeItem> items) {
|
public void importSwfXml(List<TreeItem> items) {
|
||||||
|
|||||||
Reference in New Issue
Block a user