diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f2212be..77d5db055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - [#1898] Keyboard shortcut to remove tags (DEL, SHIFT+DEL) -- [#1765] Quick search tree for everything, not just AS3 classes +- [#1765] Quick search tree (Ctrl+F) for everything, not just AS3 classes +- Quick search (Ctrl+F) for tag list view ### Fixed - [#1897] Close menu button without selecting specific item diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 6e2f79fde..779de7401 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -283,6 +283,7 @@ import jsyntaxpane.DefaultSyntaxKit; import com.jpexs.decompiler.flash.Bundle; import com.jpexs.decompiler.flash.gui.tagtree.FilteredTreeModel; import com.jpexs.decompiler.flash.treeitems.Openable; +import java.awt.event.ActionListener; import javax.swing.tree.TreeModel; /** @@ -368,11 +369,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private final JPersistentSplitPane splitPane2; - private JPanel detailPanel; + private JPanel detailPanel; - private JTextField filterField = new MyTextField(""); - - private JPanel searchPanel; + private QuickTreeFindPanel quickTreeFindPanel; + + private QuickTreeFindPanel quickTagListFindPanel; private ABCPanel abcPanel; @@ -414,7 +415,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private PinsPanel pinsPanel; - private List> unfilteredExpandedNodes = new ArrayList<>(); + private List> unfilteredTreeExpandedNodes = new ArrayList<>(); + private List> unfilteredTagListExpandedNodes = new ArrayList<>(); public void savePins() { pinsPanel.save(); @@ -512,9 +514,22 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se getCurrentTree().scrollPathToVisible(path); repaintTree(); } + + public void hideQuickTreeFind() { + quickTreeFindPanel.setVisible(false); + quickTagListFindPanel.setVisible(false); + } private void handleTreeKeyPressed(KeyEvent e) { AbstractTagTree tree = (AbstractTagTree) e.getSource(); + if ((e.getKeyCode() == 'F') && (e.isControlDown())) { + if (tree == tagTree) { + quickTreeFindPanel.setVisible(true); + } + if (tree == tagListTree) { + quickTagListFindPanel.setVisible(true); + } + } if ((e.getKeyCode() == KeyEvent.VK_DELETE) && !e.isControlDown() && !e.isAltDown()) { TreePath[] paths = tree.getSelectionPaths(); if (paths == null || paths.length == 0) { @@ -1011,22 +1026,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se displayPanel.add(headerPanel, CARDHEADER); displayPanel.add(new JPanel(), CARDEMPTYPANEL); - showCard(CARDEMPTYPANEL); - - searchPanel = new JPanel(); - searchPanel.setLayout(new BorderLayout()); - searchPanel.add(filterField, BorderLayout.CENTER); - searchPanel.add(new JLabel(View.getIcon("search16")), BorderLayout.WEST); - JLabel closeSearchButton = new JLabel(View.getIcon("cancel16")); - closeSearchButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - closeTagTreeSearch(); - } - }); - closeSearchButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - searchPanel.add(closeSearchButton, BorderLayout.EAST); - searchPanel.setVisible(false); + showCard(CARDEMPTYPANEL); LazyCardLayout treePanelLayout = new LazyCardLayout(); treePanelLayout.registerLayout(createResourcesViewCard(), RESOURCES_VIEW); @@ -1036,26 +1036,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se //treePanel.add(searchPanel, BorderLayout.SOUTH); //searchPanel.setVisible(false); - filterField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void changedUpdate(DocumentEvent e) { - warn(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - warn(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - warn(); - } - - public void warn() { - doFilter(); - } - }); + JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(displayPanel, BorderLayout.CENTER); @@ -1095,11 +1076,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } @Override - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == 'F') && (e.isControlDown())) { - searchPanel.setVisible(true); - filterField.requestFocusInWindow(); - } + public void keyPressed(KeyEvent e) { handleTreeKeyPressed(e); if ((e.getKeyCode() == 'G') && (e.isControlDown())) { SWF swf = getCurrentSwf(); @@ -1244,15 +1221,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se refreshTree(); } }); - } - - public void closeTagTreeSearch() { - View.checkAccess(); - - filterField.setText(""); - doFilter(); - searchPanel.setVisible(false); - } + } public void resetAllTimelines() { List openableLists = new ArrayList<>(openables); @@ -1398,8 +1367,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (!isWelcomeScreen && openables.isEmpty()) { showContentPanelCard(WELCOME_PANEL); - isWelcomeScreen = true; - closeTagTreeSearch(); + isWelcomeScreen = true; + quickTagListFindPanel.setVisible(false); + quickTreeFindPanel.setVisible(false); + doFilter(); } mainFrame.setTitle(ApplicationInfo.applicationVerName); @@ -1591,35 +1562,40 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se return filter.trim().length() < 3; } - public void doFilter() { - View.checkAccess(); - - TreeModel model = tagTree.getModel(); + private void doFilter(AbstractTagTree tree, QuickTreeFindPanel findPanel, List> unfilteredExpandedNodes) { + TreeModel model = tree.getModel(); String oldFilter = ""; if (model instanceof FilteredTreeModel) { oldFilter = ((FilteredTreeModel)model).getFilter(); } - String newFilter = filterField.getText(); + String newFilter = findPanel.getFilter(); if (isFilterEmpty(oldFilter)) { - unfilteredExpandedNodes = View.getExpandedNodes(tagTree); + unfilteredExpandedNodes.clear();; + unfilteredExpandedNodes.addAll(View.getExpandedNodes(tree)); } if (oldFilter.trim().equals(newFilter.trim())) { return; } - tagTree.setModel(new FilteredTreeModel(newFilter, tagTree.getFullModel())); + tree.setModel(new FilteredTreeModel(newFilter, tree.getFullModel())); if (!isFilterEmpty(newFilter)) { - for (int i = 0; i < tagTree.getRowCount(); i++) { - tagTree.expandRow(i); + for (int i = 0; i < tree.getRowCount(); i++) { + tree.expandRow(i); } } else { - tagTree.setModel(tagTree.getFullModel()); - View.expandTreeNodes(tagTree, unfilteredExpandedNodes); + tree.setModel(tree.getFullModel()); + View.expandTreeNodes(tree, unfilteredExpandedNodes); } } + + public void doFilter() { + View.checkAccess(); + doFilter(tagTree, quickTreeFindPanel, unfilteredTreeExpandedNodes); + doFilter(tagListTree, quickTagListFindPanel, unfilteredTagListExpandedNodes); + } public void renameIdentifier(SWF swf, String identifier) throws InterruptedException { String oldName = identifier; @@ -4440,6 +4416,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se JPanel r = new JPanel(new BorderLayout()); r.add(tagListClipboardPanel, BorderLayout.NORTH); r.add(new FasterScrollPane(tagListTree), BorderLayout.CENTER); + quickTagListFindPanel = new QuickTreeFindPanel(); + quickTagListFindPanel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + doFilter(); + } + }); + r.add(quickTagListFindPanel, BorderLayout.SOUTH); return r; } @@ -4448,7 +4432,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se JPanel r = new JPanel(new BorderLayout()); r.add(resourcesClipboardPanel, BorderLayout.NORTH); r.add(tagTreeScrollPanel = new FasterScrollPane(tagTree), BorderLayout.CENTER); - r.add(searchPanel, BorderLayout.SOUTH); + quickTreeFindPanel = new QuickTreeFindPanel(); + quickTreeFindPanel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + doFilter(); + } + }); + r.add(quickTreeFindPanel, BorderLayout.SOUTH); return r; } diff --git a/src/com/jpexs/decompiler/flash/gui/QuickTreeFindPanel.java b/src/com/jpexs/decompiler/flash/gui/QuickTreeFindPanel.java new file mode 100644 index 000000000..1f4d0e90f --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/QuickTreeFindPanel.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2022 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import java.awt.BorderLayout; +import java.awt.Cursor; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * + * @author JPEXS + */ +public class QuickTreeFindPanel extends JPanel { + + private List listeners = new ArrayList<>(); + + private JTextField filterField = new MyTextField(""); + + public QuickTreeFindPanel() { + + filterField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + warn(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + warn(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + warn(); + } + + public void warn() { + fireAction(); + } + }); + + setLayout(new BorderLayout()); + add(filterField, BorderLayout.CENTER); + add(new JLabel(View.getIcon("search16")), BorderLayout.WEST); + JLabel closeSearchButton = new JLabel(View.getIcon("cancel16")); + closeSearchButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + filterField.setText(""); + setVisible(false); + fireAction(); + } + }); + closeSearchButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + add(closeSearchButton, BorderLayout.EAST); + setVisible(false); + } + + private void fireAction() { + for (ActionListener listener:listeners) { + listener.actionPerformed(new ActionEvent(this, 0, "")); + } + } + + public void addActionListener(ActionListener listener) { + listeners.add(listener); + } + + public void removeActionListener(ActionListener listener) { + listeners.remove(listener); + } + + + public String getFilter() { + return filterField.getText().trim(); + } + + @Override + public void setVisible(boolean aFlag) { + super.setVisible(aFlag); + if (aFlag) { + filterField.requestFocusInWindow(); + } else { + filterField.setText(""); + } + } + + +} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 87570eaa8..ad46aca77 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -1447,7 +1447,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener