From 5909a0de071b6d105760ed2483d4f91d0cdd5eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 22 Dec 2022 11:09:35 +0100 Subject: [PATCH] Added #1912 Persist selected item in the tree upon quick search (Ctrl+F) --- CHANGELOG.md | 2 ++ .../jpexs/decompiler/flash/gui/MainPanel.java | 4 ++- .../flash/gui/tagtree/FilteredTreeModel.java | 29 ++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 356157f0e..c72c556fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - [#1909] Export/import DefineBitsJPEG3/4s alpha channel to/from separate file ("PNG/GIF/JPEG+alpha" option in GUI, "-format image:png_gif_jpeg_alpha" for commandline) - [#1910] Copy/paste transform matrix to/from the clipboard +- [#1912] Persist selected item in the tree upon quick search (Ctrl+F) ### Fixed - [#1904] NullPointerException when renaming invalid identifiers in AS1/2 files caused by missing charset @@ -2783,6 +2784,7 @@ All notable changes to this project will be documented in this file. [#1904]: https://www.free-decompiler.com/flash/issues/1904 [#595]: https://www.free-decompiler.com/flash/issues/595 [#1908]: https://www.free-decompiler.com/flash/issues/1908 +[#1912]: https://www.free-decompiler.com/flash/issues/1912 [#1898]: https://www.free-decompiler.com/flash/issues/1898 [#1511]: https://www.free-decompiler.com/flash/issues/1511 [#1765]: https://www.free-decompiler.com/flash/issues/1765 diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index a53ddbb1a..d5b7d0427 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -1639,7 +1639,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return; } - tree.setModel(new FilteredTreeModel(newFilter, tree.getFullModel())); + TreePath selectionPaths[] = tree.getSelectionPaths(); + tree.setModel(new FilteredTreeModel(newFilter, tree.getFullModel(), tree)); if (!isFilterEmpty(newFilter)) { for (int i = 0; i < tree.getRowCount(); i++) { tree.expandRow(i); @@ -1648,6 +1649,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se tree.setModel(tree.getFullModel()); View.expandTreeNodes(tree, unfilteredExpandedNodes); } + tree.setSelectionPaths(selectionPaths); } public void doFilter() { diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/FilteredTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/FilteredTreeModel.java index b252c75b2..d2463d9c7 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/FilteredTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/FilteredTreeModel.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.WeakHashMap; +import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; @@ -36,14 +37,17 @@ public class FilteredTreeModel implements TreeModel { private TreeItem root; private Map> subItems = new WeakHashMap<>(); - private final List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); + + private final JTree tree; public String getFilter() { return filter; } - public FilteredTreeModel(String filter, AbstractTagTreeModel fullModel) { + public FilteredTreeModel(String filter, AbstractTagTreeModel fullModel, JTree tree) { this.filter = filter; + this.tree = tree; fullModel.addTreeModelListener(new TreeModelListener() { @Override @@ -72,11 +76,22 @@ public class FilteredTreeModel implements TreeModel { private void rebuildTree(AbstractTagTreeModel fullModel) { subItems.clear(); this.root = fullModel.getRoot(); - buildTree(fullModel, this.root, "root"); + List selectionPathsList = new ArrayList<>(); + TreePath selectionPaths[] = tree.getSelectionPaths(); + if (selectionPaths != null) { + List currentPathItems = new ArrayList<>(); + for (TreePath tp:selectionPaths) { + for (int i = 0; i < tp.getPathCount(); i++) { + currentPathItems.add(tp.getPathComponent(i).toString()); + } + } + selectionPathsList.add(String.join(".", currentPathItems)); + } + buildTree(fullModel, this.root, "root", selectionPathsList); fireTreeStructureChanged(new TreeModelEvent(this, new Object[]{root})); } - private void buildTree(AbstractTagTreeModel fullModel, TreeItem item, String path) { + private void buildTree(AbstractTagTreeModel fullModel, TreeItem item, String path, List selectionPaths) { List items = fullModel.getAllChildren(item); List newSubItems = new ArrayList<>(); if (filter.trim().isEmpty()) { @@ -86,7 +101,7 @@ public class FilteredTreeModel implements TreeModel { String subPath = path + "." + ti.toString(); boolean matches = subPath.toLowerCase().contains(filter.toLowerCase()); if (fullModel.isLeaf(ti)) { - if (matches) { + if (matches || selectionPaths.contains(subPath)) { newSubItems.add(ti); } } else { @@ -98,8 +113,8 @@ public class FilteredTreeModel implements TreeModel { for (int i = 0; i < newSubItems.size(); i++) { TreeItem ti = newSubItems.get(i); String subPath = path + "." + ti.toString(); - buildTree(fullModel, ti, subPath); - if (!fullModel.isLeaf(ti) && (!this.subItems.containsKey(ti) || this.subItems.get(ti).isEmpty())) { + buildTree(fullModel, ti, subPath, selectionPaths); + if (!selectionPaths.contains(subPath) && !fullModel.isLeaf(ti) && (!this.subItems.containsKey(ti) || this.subItems.get(ti).isEmpty())) { newSubItems.remove(i); i--; }