diff --git a/CHANGELOG.md b/CHANGELOG.md index 39392cda5..10d0def09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,14 @@ All notable changes to this project will be documented in this file. - [#1414] Cancelling in-progress exportation - [#1755] Copy tags to tag clipboard and paste them elsewhere - [#1460] Bulk importing images +- Bulk importing scripts/text/images added to SWF context menu ### Fixed - FLA export printing xxx string on exporting character with id 320 - Copy to with dependencies does not refresh timeline - Copy to with dependencies does not set the timelined, that can result to missing dependencies (red tags in the tree) - Double warning/error when copy to / move to and same character id already exists +- [#1862] Exporting selection to subfolders by SWFname when multiple SWFs selected ## [16.1.0] - 2022-11-06 ### Added @@ -2516,6 +2518,7 @@ All notable changes to this project will be documented in this file. [#1414]: https://www.free-decompiler.com/flash/issues/1414 [#1755]: https://www.free-decompiler.com/flash/issues/1755 [#1460]: https://www.free-decompiler.com/flash/issues/1460 +[#1862]: https://www.free-decompiler.com/flash/issues/1862 [#1459]: https://www.free-decompiler.com/flash/issues/1459 [#1832]: https://www.free-decompiler.com/flash/issues/1832 [#1849]: https://www.free-decompiler.com/flash/issues/1849 diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java index a329ee7c3..c0191805f 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -28,6 +28,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.TreeItem; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.Helper; import com.jpexs.helpers.utf8.Utf8Helper; @@ -175,7 +176,7 @@ public abstract class MainFrameMenu implements MenuBuilder { protected void newActionPerformed(ActionEvent evt) { Main.newFile(); } - + protected boolean saveActionPerformed(ActionEvent evt) { if (Main.isWorking()) { return false; @@ -206,7 +207,7 @@ public abstract class MainFrameMenu implements MenuBuilder { private boolean isSwfReadOnly(SWF swf) { return swf.swfList != null && swf.swfList.bundle != null && swf.swfList.bundle.isReadOnly(); } - + private boolean saveAs(SWF swf, SaveFileMode mode) { View.checkAccess(); @@ -266,7 +267,7 @@ public abstract class MainFrameMenu implements MenuBuilder { mainFrame.getPanel().importScript(swf); } - + protected void importImagesActionPerformed(ActionEvent evt) { if (Main.isWorking()) { return; @@ -564,7 +565,7 @@ public abstract class MainFrameMenu implements MenuBuilder { 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); + mainFrame.getPanel().loadFromBinaryTag(swf.binaryData); } } else { Main.reloadFile(swf.swfList); @@ -740,6 +741,22 @@ public abstract class MainFrameMenu implements MenuBuilder { boolean swfLoaded = mainPanel != null ? !mainPanel.getSwfs().isEmpty() : false; boolean swfIsNew = swfSelected && swf.swfList != null && swf.swfList.sourceInfo.isEmpty(); + boolean allSameSwf = true; + if (mainPanel != null) { + List items = mainPanel.getCurrentTree().getSelected(); + SWF firstSwf = null; + for (TreeItem item : items) { + if (firstSwf == null) { + firstSwf = item.getSwf(); + } else { + if (item.getSwf() != firstSwf) { + allSameSwf = false; + break; + } + } + } + } + setMenuEnabled("_/open", !isWorking); setMenuEnabled("/file/open", !isWorking); setMenuEnabled("_/save", swfSelected && !isWorking); @@ -757,16 +774,16 @@ public abstract class MainFrameMenu implements MenuBuilder { setMenuEnabled("_/exportAll", swfSelected && !isWorking); setMenuEnabled("/file/export/exportAll", swfSelected && !isWorking); setMenuEnabled("_/exportFla", swfSelected && !isWorking); - setMenuEnabled("/file/export/exportFla", swfSelected && !isWorking); + setMenuEnabled("/file/export/exportFla", allSameSwf && swfSelected && !isWorking); setMenuEnabled("_/exportSelected", swfSelected && !isWorking); setMenuEnabled("/file/export/exportSelected", swfSelected && !isWorking); setMenuEnabled("/file/export/exportXml", swfSelected && !isWorking); setMenuEnabled("/file/import", swfSelected); - setMenuEnabled("/file/import/importText", swfSelected && !isWorking); - setMenuEnabled("/file/import/importScript", swfSelected && !isWorking); - setMenuEnabled("/file/import/importOther", swfSelected && !isWorking); - setMenuEnabled("/file/import/importXml", swfSelected && !isWorking); + 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/renameOneIdentifier", swfSelected && !isWorking); @@ -819,9 +836,9 @@ public abstract class MainFrameMenu implements MenuBuilder { titleBuilder.append(swf.getFileTitle()); } mainFrame.setTitle(titleBuilder.toString()); - + if (mainPanel != null) { - switch(mainPanel.getCurrentView()){ + switch (mainPanel.getCurrentView()) { case MainPanel.VIEW_RESOURCES: setGroupSelection("view", "/file/view/viewResources"); break; @@ -878,7 +895,7 @@ public abstract class MainFrameMenu implements MenuBuilder { addMenuItem("/file/reload", translate("menu.file.reload"), "reload16", this::reloadActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+R"), false); addMenuItem("/file/reloadAll", translate("menu.file.reloadAll"), "reload16", this::reloadAllActionPerformed, PRIORITY_MEDIUM, null, true, null, false); addMenuItem("/file/new", translate("menu.file.new"), "newswf32", this::newActionPerformed, PRIORITY_TOP, null, true, null, false); - + addSeparator("/file"); addMenuItem("/file/export", translate("menu.export"), null, null, 0, null, false, null, false); @@ -892,8 +909,8 @@ public abstract class MainFrameMenu implements MenuBuilder { addMenuItem("/file/import/importXml", translate("menu.file.import.xml"), "importxml32", this::importXmlActionPerformed, PRIORITY_TOP, null, true, null, false); addMenuItem("/file/import/importText", translate("menu.file.import.text"), "importtext32", this::importTextActionPerformed, PRIORITY_MEDIUM, null, true, null, false); addMenuItem("/file/import/importScript", translate("menu.file.import.script"), "importscript32", this::importScriptActionPerformed, PRIORITY_MEDIUM, null, true, null, false); - addMenuItem("/file/import/importOther", translate("menu.file.import.other"), "importother32", null, PRIORITY_MEDIUM, null, false, null, false); - addMenuItem("/file/import/importOther/importImages", translate("menu.file.import.images"), "importimage32", this::importImagesActionPerformed, PRIORITY_MEDIUM, null, true, null, false); + addMenuItem("/file/import/importOther", translate("menu.file.import.other"), "importother32", null, PRIORITY_MEDIUM, null, false, null, false); + addMenuItem("/file/import/importOther/importImages", translate("menu.file.import.image"), "importimage32", this::importImagesActionPerformed, PRIORITY_MEDIUM, null, true, null, false); addMenuItem("/file/import/importOther/importSymbolClass", translate("menu.file.import.symbolClass"), "importsymbolclass32", this::importSymbolClassActionPerformed, PRIORITY_MEDIUM, null, true, null, false); finishMenu("/file/import/importOther"); finishMenu("/file/import"); @@ -920,7 +937,7 @@ public abstract class MainFrameMenu implements MenuBuilder { addMenuItem("/file/exit", translate("menu.file.exit"), "exit32", this::exitActionPerformed, PRIORITY_TOP, null, true, null, false); } - finishMenu("/file"); + finishMenu("/file"); /* menu.file.start = Start @@ -1165,7 +1182,7 @@ public abstract class MainFrameMenu implements MenuBuilder { public void showTagListView() { viewTagListActionPerformed(null); } - + private void viewResourcesActionPerformed(ActionEvent evt) { Configuration.dumpView.set(false); mainFrame.getPanel().showView(MainPanel.VIEW_RESOURCES); @@ -1184,13 +1201,13 @@ public abstract class MainFrameMenu implements MenuBuilder { setGroupSelection("view", "/file/view/viewHex"); setMenuChecked("/tools/timeline", false); } - + private void viewTagListActionPerformed(ActionEvent evt) { - Configuration.dumpView.set(false); + Configuration.dumpView.set(false); MainPanel mainPanel = mainFrame.getPanel(); mainPanel.showView(MainPanel.VIEW_TAGLIST); setGroupSelection("view", "/file/view/viewTagList"); - setMenuChecked("/tools/timeline", false); + setMenuChecked("/tools/timeline", false); } private void debuggerSwitchActionPerformed(ActionEvent evt) { diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index e9d035e5a..8e54c51d0 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -1375,9 +1375,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private List getSelection(SWF swf) { if (currentView == MainPanel.VIEW_RESOURCES) { - return tagTree.getSelection(getCurrentSwf()); + return tagTree.getSelection(swf); } else if (currentView == MainPanel.VIEW_TAGLIST) { - return tagListTree.getSelection(getCurrentSwf()); + return tagListTree.getSelection(swf); } return new ArrayList<>(); } @@ -1385,7 +1385,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException, InterruptedException { List ret = new ArrayList<>(); - List sel = getSelection(getCurrentSwf()); + List sel = getSelection(null); Set usedSwfs = new HashSet<>(); for (TreeItem d : sel) { @@ -4708,6 +4708,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se this.missingNeededCharacters = missingNeededCharacters; tagTree.setMissingNeededCharacters(missingNeededCharacters); tagListTree.setMissingNeededCharacters(missingNeededCharacters); - } + } } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 561481439..143b433b1 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -927,7 +927,7 @@ contextmenu.pasteAfter = Paste after contextmenu.pasteInside = Paste inside menu.file.import.other = Import other... -menu.file.import.images = Import images +menu.file.import.image = Import images message.info.importImages = During importing images, you need to select a FOLDER.\r\n \ The folder must contain "images" subfolder and filenames inside must match existing images in current selected SWF.\r\n \ diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index 3bcf6c97f..f8b5e078e 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -898,7 +898,7 @@ contextmenu.pasteInside = Vlo\u017eit dovnit\u0159 menu.file.import.other = Importovat jin\u00e9... -menu.file.import.images = Importovat obr\u00e1zky +menu.file.import.image = Importovat obr\u00e1zky message.info.importImages = B\u011bhem importu text\u016f mus\u00edte vybrat SLO\u017dKU.\r\n \ Slo\u017eka mus\u00ed obsahovat podslo\u017eku "images" a n\u00e1zvy soubor\u016f v n\u00ed mus\u00ed souhlasit s existuj\u00edc\u00edmi obr\u00e1zky v pr\u00e1v\u011b vybran\u00e9m SWF.\r\n \ diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java index 875483a99..2c66c36aa 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java @@ -466,7 +466,7 @@ public abstract class AbstractTagTree extends JTree { if (d instanceof SWFList) { continue; } - if (d.getSwf() != swf) { + if (swf != null && d.getSwf() != swf) { continue; } diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index fa563faac..36c7eddce 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -145,6 +145,15 @@ public class TagTreeContextMenu extends JPopupMenu { private JMenuItem exportSwfXmlMenuItem; private JMenuItem importSwfXmlMenuItem; + + private JMenuItem importScriptsMenuItem; + + private JMenuItem importTextsMenuItem; + + private JMenuItem importImagesMenuItem; + + private JMenuItem importSymbolClassMenuItem; + private JMenuItem closeMenuItem; @@ -276,6 +285,26 @@ public class TagTreeContextMenu extends JPopupMenu { importSwfXmlMenuItem.addActionListener(mainPanel::importSwfXmlActionPerformed); importSwfXmlMenuItem.setIcon(View.getIcon("importxml16")); add(importSwfXmlMenuItem); + + importScriptsMenuItem = new JMenuItem(mainPanel.translate("menu.file.import.script")); + importScriptsMenuItem.addActionListener(this::importScriptsActionPerformed); + importScriptsMenuItem.setIcon(View.getIcon("importscript16")); + add(importScriptsMenuItem); + + importTextsMenuItem = new JMenuItem(mainPanel.translate("menu.file.import.text")); + importTextsMenuItem.addActionListener(this::importTextsActionPerformed); + importTextsMenuItem.setIcon(View.getIcon("importtext16")); + add(importTextsMenuItem); + + importImagesMenuItem = new JMenuItem(mainPanel.translate("menu.file.import.image")); + importImagesMenuItem.addActionListener(this::importImagesActionPerformed); + importImagesMenuItem.setIcon(View.getIcon("importimage16")); + add(importImagesMenuItem); + + importSymbolClassMenuItem = new JMenuItem(mainPanel.translate("menu.file.import.symbolClass")); + importSymbolClassMenuItem.addActionListener(this::importSymbolClassActionPerformed); + importSymbolClassMenuItem.setIcon(View.getIcon("importsymbolclass16")); + add(importSymbolClassMenuItem); showInResourcesViewTagMenuItem = new JMenuItem(mainPanel.translate("contextmenu.showInResources")); showInResourcesViewTagMenuItem.addActionListener(this::showInResourcesViewActionPerformed); @@ -623,7 +652,13 @@ public class TagTreeContextMenu extends JPopupMenu { jumpToCharacterMenuItem.setVisible(false); exportJavaSourceMenuItem.setVisible(allSelectedIsSwf); exportSwfXmlMenuItem.setVisible(allSelectedIsSwf); - importSwfXmlMenuItem.setVisible(allSelectedIsSwf); + + importImagesMenuItem.setVisible(false); + importScriptsMenuItem.setVisible(false); + importSymbolClassMenuItem.setVisible(false); + importTextsMenuItem.setVisible(false); + importSwfXmlMenuItem.setVisible(false); + closeMenuItem.setVisible(allSelectedIsSwf); addTagInsideMenu.setVisible(false); attachTagMenu.setVisible(false); @@ -793,6 +828,14 @@ public class TagTreeContextMenu extends JPopupMenu { if (firstItem instanceof Tag) { showInHexDumpViewTagMenuItem.setVisible(true); } + + if (firstItem instanceof SWF) { + importImagesMenuItem.setVisible(true); + importScriptsMenuItem.setVisible(true); + importSymbolClassMenuItem.setVisible(true); + importTextsMenuItem.setVisible(true); + importSwfXmlMenuItem.setVisible(true); + } if (!mainPanel.clipboardEmpty()) { if ((firstItem instanceof SWF) || (firstItem instanceof DefineSpriteTag) || (firstItem instanceof Frame)) { @@ -861,7 +904,7 @@ public class TagTreeContextMenu extends JPopupMenu { openSWFInsideTagMenuItem.setVisible(anyInnerSwf); } - + for (TreeItem item : items) { if (item instanceof Tag) { if (((Tag) item).isReadOnly()) { @@ -2809,4 +2852,25 @@ public class TagTreeContextMenu extends JPopupMenu { Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, null, ex); } } + + public void importScriptsActionPerformed(ActionEvent evt) { + SWF swf = getTree().getCurrentTreeItem().getSwf(); + mainPanel.importScript(swf); + } + + public void importTextsActionPerformed(ActionEvent evt) { + SWF swf = getTree().getCurrentTreeItem().getSwf(); + mainPanel.importText(swf); + } + + public void importImagesActionPerformed(ActionEvent evt) { + SWF swf = getTree().getCurrentTreeItem().getSwf(); + mainPanel.importImage(swf); + } + + public void importSymbolClassActionPerformed(ActionEvent evt) { + SWF swf = getTree().getCurrentTreeItem().getSwf(); + mainPanel.importSymbolClass(swf); + } + }