From 8fefb0b1f32ae3443648c9de48deb3390938d688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 29 Sep 2024 10:53:44 +0200 Subject: [PATCH] Added: #2328 Searching/replacing in texts now supports selection / all files scope --- CHANGELOG.md | 2 + .../jpexs/decompiler/flash/gui/MainPanel.java | 125 +++++++++++++++--- .../decompiler/flash/gui/SearchDialog.java | 26 +--- 3 files changed, 107 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d973d0b0d..72111a88a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. - [#2321] Commandline option to generate HTML docs for AS1/2 Actions - Chinese translation update - [#2305] Saving recent colors in the color selection dialog +- [#2328] Searching/replacing in texts now supports selection / all files scope ### Fixed - [#2319] AS3 Compound assignments problems in some cases @@ -3590,6 +3591,7 @@ Major version of SWF to XML export changed to 2. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#2321]: https://www.free-decompiler.com/flash/issues/2321 [#2305]: https://www.free-decompiler.com/flash/issues/2305 +[#2328]: https://www.free-decompiler.com/flash/issues/2328 [#2319]: https://www.free-decompiler.com/flash/issues/2319 [#2320]: https://www.free-decompiler.com/flash/issues/2320 [#2272]: https://www.free-decompiler.com/flash/issues/2272 diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index c7343827e..c63828117 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -221,6 +221,7 @@ import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.LinkedIdentityHashSet; import com.jpexs.helpers.Path; import com.jpexs.helpers.ProgressListener; import com.jpexs.helpers.Reference; @@ -2847,11 +2848,30 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se Map> scopeAs3 = new LinkedHashMap<>(); Map> swfToAllASMSourceMap = new HashMap<>(); Map> scopeAs12 = new LinkedHashMap<>(); + Set scopeTextTags = new LinkedIdentityHashSet<>(); Set openablesUsed = new LinkedHashSet<>(); List allItems = getAllSelected(); for (TreeItem t : allItems) { + if (t instanceof SWF) { + for (Tag g : ((SWF) t).getTags()) { + if (g instanceof TextTag) { + scopeTextTags.add((TextTag) g); + } + } + } + if (t instanceof FolderItem) { + FolderItem f = (FolderItem) t; + for (TreeItem t2 : f.subItems) { + if (t2 instanceof TextTag) { + scopeTextTags.add((TextTag) t2); + } + } + } + if (t instanceof TextTag) { + scopeTextTags.add((TextTag) t); + } if (t instanceof ScriptPack) { ScriptPack sp = (ScriptPack) t; Openable s = sp.getOpenable(); //Fixme for ABCs @@ -2897,7 +2917,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se List items = getSelected(); String selected; - if (scopeAs12.isEmpty() && scopeAs3.isEmpty()) { + if (scopeAs12.isEmpty() && scopeAs3.isEmpty() && scopeTextTags.isEmpty()) { selected = null; } else if (items.size() == 1) { selected = items.get(0).toString(); @@ -3037,7 +3057,25 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se List textResult; SearchPanel textSearchPanel = previewPanel.getTextPanel().getSearchPanel(); textSearchPanel.setOptions(ignoreCase, regexp); - textResult = searchText(txt, ignoreCase, regexp, swf); + List scope = new ArrayList<>(); + if (searchDialog.getCurrentScope() == SearchDialog.SCOPE_CURRENT_FILE) { + for (Tag t : swf.getTags()) { + if (t instanceof TextTag) { + scope.add((TextTag) t); + } + } + } else if (searchDialog.getCurrentScope() == SearchDialog.SCOPE_ALL_FILES) { + for (SWF s : getAllSwfs()) { + for (Tag t : s.getTags()) { + if (t instanceof TextTag) { + scope.add((TextTag) t); + } + } + } + } else if (searchDialog.getCurrentScope() == SearchDialog.SCOPE_SELECTION) { + scope.addAll(scopeTextTags); + } + textResult = searchText(txt, ignoreCase, regexp, scope); List fTextResult = textResult; View.execInEventDispatch(() -> { @@ -3067,7 +3105,42 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } public void replaceText() { - SearchDialog replaceDialog = new SearchDialog(getMainFrame().getWindow(), true, null, false, false); + Set scopeTextTags = new LinkedIdentityHashSet<>(); + + List allItems = getAllSelected(); + for (TreeItem t : allItems) { + if (t instanceof SWF) { + for (Tag g : ((SWF) t).getTags()) { + if (g instanceof TextTag) { + scopeTextTags.add((TextTag) g); + } + } + } + if (t instanceof FolderItem) { + FolderItem f = (FolderItem) t; + for (TreeItem t2 : f.subItems) { + if (t2 instanceof TextTag) { + scopeTextTags.add((TextTag) t2); + } + } + } + if (t instanceof TextTag) { + scopeTextTags.add((TextTag) t); + } + } + List items = getSelected(); + + String selected; + if (scopeTextTags.isEmpty()) { + selected = null; + } else if (items.size() == 1) { + selected = items.get(0).toString(); + } else if (items.isEmpty()) { + selected = null; + } else { + selected = AppDialog.translateForDialog("scope.selection.items", SearchDialog.class).replace("%count%", "" + items.size()); + } + SearchDialog replaceDialog = new SearchDialog(getMainFrame().getWindow(), true, selected, false, false); if (replaceDialog.showDialog() == AppDialog.OK_OPTION) { final String txt = replaceDialog.searchField.getText(); if (!txt.isEmpty()) { @@ -3089,13 +3162,26 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else { pat = Pattern.compile(Pattern.quote(txt), ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0); } - List textTags = new ArrayList<>(); - for (Tag tag : swf.getTags()) { - if (tag instanceof TextTag) { - textTags.add((TextTag) tag); + + List scope = new ArrayList<>(); + if (replaceDialog.getCurrentScope() == SearchDialog.SCOPE_CURRENT_FILE) { + for (Tag t : swf.getTags()) { + if (t instanceof TextTag) { + scope.add((TextTag) t); + } } + } else if (replaceDialog.getCurrentScope() == SearchDialog.SCOPE_ALL_FILES) { + for (SWF s : getAllSwfs()) { + for (Tag t : s.getTags()) { + if (t instanceof TextTag) { + scope.add((TextTag) t); + } + } + } + } else if (replaceDialog.getCurrentScope() == SearchDialog.SCOPE_SELECTION) { + scope.addAll(scopeTextTags); } - for (TextTag textTag : textTags) { + for (TextTag textTag : scope) { if (!replaceDialog.replaceInParametersCheckBox.isSelected()) { List texts = textTag.getTexts(); boolean found = false; @@ -3132,7 +3218,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } - private List searchText(String txt, boolean ignoreCase, boolean regexp, SWF swf) { + private List searchText(String txt, boolean ignoreCase, boolean regexp, List scope) { if (txt != null && !txt.isEmpty()) { List found = new ArrayList<>(); Pattern pat; @@ -3141,12 +3227,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else { pat = Pattern.compile(Pattern.quote(txt), ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0); } - for (Tag tag : swf.getTags()) { - if (tag instanceof TextTag) { - TextTag textTag = (TextTag) tag; - if (pat.matcher(textTag.getFormattedText(true).text).find()) { - found.add(textTag); - } + for (TextTag textTag : scope) { + if (pat.matcher(textTag.getFormattedText(true).text).find()) { + found.add(textTag); } } @@ -3500,7 +3583,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } }.execute(); } - + public void exportVsCode(final SWF swf) { if (swf == null) { return; @@ -3603,7 +3686,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se boolean isAS3 = swf.isAS3(); Map filterToVersion = new HashMap<>(); Map filterToCompressed = new HashMap<>(); - + Map filterToFlaVersion = new HashMap<>(); FLAVersion lastVersion = FLAVersion.fromString(Configuration.lastFlaExportVersion.get("CS6")); @@ -3631,12 +3714,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else { fc.addChoosableFileFilter(f); } - filterToFlaVersion.put(f, v); + filterToFlaVersion.put(f, v); filterToVersion.put(f, "" + v); filterToCompressed.put(f, true); flaFilters.add(f); - - if (v.xflVersion() != null) { + + if (v.xflVersion() != null) { f = new FileFilter() { @Override public boolean accept(File f) { @@ -5387,7 +5470,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se updateUi(); } - clearEditingStatus(); + clearEditingStatus(); reload(false, false); if (source == dumpTree) { diff --git a/src/com/jpexs/decompiler/flash/gui/SearchDialog.java b/src/com/jpexs/decompiler/flash/gui/SearchDialog.java index 4a70e3705..e38c23c91 100644 --- a/src/com/jpexs/decompiler/flash/gui/SearchDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/SearchDialog.java @@ -120,13 +120,6 @@ public class SearchDialog extends AppDialog { scopeComboBox.setSelectedIndex(1); } - if (replace) { - if (selection != null) { - scopeComboBox.setSelectedIndex(1); - } - scopeComboBox.setEnabled(false); - } - cnt.add(panField); JPanel checkPanel = new JPanel(new FlowLayout()); @@ -152,10 +145,6 @@ public class SearchDialog extends AppDialog { rbPanel.add(searchInPCodeRadioButton); rbPanel.add(searchInTextsRadioButton); cnt.add(rbPanel); - - searchInASRadioButton.addActionListener(this::searchTypeActionPerformed); - searchInPCodeRadioButton.addActionListener(this::searchTypeActionPerformed); - searchInTextsRadioButton.addActionListener(this::searchTypeActionPerformed); } cnt.add(panButtons); @@ -170,20 +159,7 @@ public class SearchDialog extends AppDialog { images.add(View.loadImage(replace ? "replace32" : "search32")); setIconImages(images); } - - private void searchTypeActionPerformed(ActionEvent e) { - if (searchInTextsRadioButton.isSelected()) { - if (scopeComboBox.getModel().getSize() == 3) { - scopeComboBox.setSelectedIndex(1); - } else { - scopeComboBox.setSelectedIndex(0); - } - scopeComboBox.setEnabled(false); - } else { - scopeComboBox.setEnabled(true); - } - } - + @Override public void setVisible(boolean b) { if (b) {