From 59e106091ec436fd954c15fefb9ff50cf6bf1fc6 Mon Sep 17 00:00:00 2001 From: Honfika Date: Tue, 3 Sep 2013 21:40:06 +0200 Subject: [PATCH] tag tree context menu deselected the selected nodes earlier. Now it preserves the selection, and applies the command for all selected nodes => removing multiple items. --- .../flash/action/ActionListReader.java | 5 +- .../jpexs/decompiler/flash/gui/MainFrame.java | 72 +++++++++++++++---- .../flash/gui/locales/MainFrame.properties | 4 +- .../flash/gui/locales/MainFrame_hu.properties | 9 ++- trunk/src/com/jpexs/helpers/Helper.java | 10 ++- .../jpexs/decompiler/flash/ExportTest.java | 16 ++++- 6 files changed, 92 insertions(+), 24 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java index c03de1b56..ac13fc6df 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -86,7 +86,7 @@ public class ActionListReader { SWFInputStream sis = new SWFInputStream(rri, version); - // List of the actions. Item 0 contains the first (entry) action + // List of the actions. N. item contains the action which starts in offset N. List actionMap = new ArrayList<>(); List nextOffsets = new ArrayList<>(); Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool, @@ -248,7 +248,7 @@ public class ActionListReader { Map map = new HashMap<>(actions.size()); for (Action a : actions) { long address = a.getAddress(); - // There are multiple action in the same address (2nd action is a jump for deobfuscated code) + // There are multiple actions in the same address (2nd action is a jump for obfuscated code) // So this check is required if (!map.containsKey(address)) { map.put(a.getAddress(), a); @@ -319,7 +319,6 @@ public class ActionListReader { Action a = actions.get(i); a.setAddress(address, version); int length = a.getBytes(version).length; - //a.actionLength = length - 1 - ((a.actionCode >= 0x80) ? 2 : 0); if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { // placeholder for jump action length = getTotalActionLength(new ActionJump(0)); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 6d23988c0..134c8f57c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -960,16 +960,29 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel if (SwingUtilities.isRightMouseButton(e)) { int row = tagTree.getClosestRowForLocation(e.getX(), e.getY()); - tagTree.setSelectionRow(row); - Object tagObj = tagTree.getLastSelectedPathComponent(); - if (tagObj == null) { + int[] selectionRows = tagTree.getSelectionRows(); + if (!Helper.contains(selectionRows, row)) { + tagTree.setSelectionRow(row); + } + + TreePath[] paths = tagTree.getSelectionPaths(); + if (paths == null || paths.length == 0) { return; } + boolean allSelectedIsTag = true; + for (TreePath treePath : paths) { + Object tagObj = treePath.getLastPathComponent(); - if (tagObj instanceof TagNode) { - tagObj = ((TagNode) tagObj).tag; + if (tagObj instanceof TagNode) { + Object tag = ((TagNode) tagObj).tag; + if (!(tag instanceof Tag)) { + allSelectedIsTag = false; + break; + } + } } - removeMenuItem.setVisible(tagObj instanceof Tag); + + removeMenuItem.setVisible(allSelectedIsTag); contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); } } @@ -1923,6 +1936,21 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } } + public List getSelected(JTree tree) { + TreeSelectionModel tsm = tree.getSelectionModel(); + TreePath tps[] = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + Object o = tp.getLastPathComponent(); + ret.add(o); + } + return ret; + } + public List getAllSubs(JTree tree, Object o) { TreeModel tm = tree.getModel(); List ret = new ArrayList<>(); @@ -2424,17 +2452,31 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } break; case "REMOVEITEM": - tagObj = tagTree.getLastSelectedPathComponent(); - if (tagObj == null) { - return; - } + List sel = getSelected(tagTree); - if (tagObj instanceof TagNode) { - tagObj = ((TagNode) tagObj).tag; + List tagsToRemove = new ArrayList<>(); + for (Object o : sel) { + Object tag = o; + if (o instanceof TagNode) { + tag = ((TagNode) o).tag; + } + if (tag instanceof Tag) { + tagsToRemove.add((Tag) tag); + } } - if (tagObj instanceof Tag) { - if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tagObj.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { - swf.removeTag((Tag) tagObj); + + if (tagsToRemove.size() == 1) { + Tag tag = tagsToRemove.get(0); + if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tag.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + swf.removeTag(tag); + showCard(CARDEMPTYPANEL); + refreshTree(); + } + } else if (tagsToRemove.size() > 1) { + if (View.showConfirmDialog(this, translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + for (Tag tag : tagsToRemove) { + swf.removeTag(tag); + } showCard(CARDEMPTYPANEL); refreshTree(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index fd21bd090..1fd735e50 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -350,4 +350,6 @@ ColorChooser.sampleText=Sample Text Sample Text #after version 1.7.1: preview.play = Play preview.pause = Pause -preview.stop = Stop \ No newline at end of file +preview.stop = Stop + +message.confirm.removemultiple = Are you sure you want to remove %count% items\n and all objects which depend on it? diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties index 6526d098c..33c1305a8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties +++ b/trunk/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties @@ -350,4 +350,11 @@ ColorChooser.resetText = Alaphelyzet ColorChooser.previewText = El\u0151n\u00e9zet ColorChooser.swatchesNameText = Mint\u00e1k ColorChooser.swatchesRecentText = El\u0151zm\u00e9nyek: -ColorChooser.sampleText=Minta Sz\u00f6veg Minta Sz\u00f6veg \ No newline at end of file +ColorChooser.sampleText=Minta Sz\u00f6veg Minta Sz\u00f6veg + +#after version 1.7.1: +preview.play = Lej\u00e1tsz\u00e1s +preview.pause = Sz\u00fcnet +preview.stop = Meg\u00e1ll\u00edt\u00e1s + +message.confirm.removemultiple = Biztos benne, hogy t\u00f6r\u00f6lni k\u00edv\u00e1nja a %count% elemet\n \u00e9s az \u00f6sszes t\u0151le f\u00fcgg\u0151 objektumot ? diff --git a/trunk/src/com/jpexs/helpers/Helper.java b/trunk/src/com/jpexs/helpers/Helper.java index ed6c8a20e..5e96d7345 100644 --- a/trunk/src/com/jpexs/helpers/Helper.java +++ b/trunk/src/com/jpexs/helpers/Helper.java @@ -17,7 +17,6 @@ package com.jpexs.helpers; import com.jpexs.decompiler.flash.gui.Freed; -import com.jpexs.decompiler.flash.helpers.Highlighting; import com.jpexs.decompiler.graph.GraphTargetItem; import java.awt.Component; import java.io.ByteArrayInputStream; @@ -552,4 +551,13 @@ public class Helper { THREAD_POOL.execute(task); return task.get(timeout, timeUnit); } + + public static boolean contains(int[] array, int value) { + for (int i : array) { + if (i == value) { + return true; + } + } + return false; + } } diff --git a/trunk/test/com/jpexs/decompiler/flash/ExportTest.java b/trunk/test/com/jpexs/decompiler/flash/ExportTest.java index 083c9c82a..1e21eafef 100644 --- a/trunk/test/com/jpexs/decompiler/flash/ExportTest.java +++ b/trunk/test/com/jpexs/decompiler/flash/ExportTest.java @@ -78,11 +78,21 @@ public class ExportTest { } @Test(dataProvider = "swfFiles") - public void testDecompile(File f) { + public void testDecompileAS(File f) { + testDecompile(f, false); + } + + @Test(dataProvider = "swfFiles") + public void testDecompilePcode(File f) { + testDecompile(f, true); + } + + public void testDecompile(File f, boolean isPcode) { try { SWF swf = new SWF(new FileInputStream(f), false); Configuration.DEBUG_COPY = true; - File fdir = new File(TESTDATADIR + File.separator + "output" + File.separator + f.getName()); + String folderName = isPcode ? "outputp" : "output"; + File fdir = new File(TESTDATADIR + File.separator + folderName + File.separator + f.getName()); fdir.mkdirs(); swf.exportActionScript(new AbortRetryIgnoreHandler() { @@ -96,7 +106,7 @@ public class ExportTest { return this; } - }, fdir.getAbsolutePath(), false, false); + }, fdir.getAbsolutePath(), isPcode, false); } catch (Exception ex) { fail(); }