From 1e4d2511a243187e921bc5d0c94044d993010811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 27 Jul 2024 10:31:32 +0200 Subject: [PATCH] Added #2189 Search bar in replace character (+ replace references) window --- CHANGELOG.md | 2 + .../flash/gui/ReplaceCharacterDialog.java | 120 +++++++++++++++--- 2 files changed, 107 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74958364d..740d41ee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. - Updated Dutch translation - [#2259] Optional resampling sound to 44kHz on playback and on export - Set class to character mapping tool (via SymbolClass) context menu on characters +- [#2189] Search bar in replace character (+ replace references) window ### Fixed - Debugger - getting children of top level variables @@ -3408,6 +3409,7 @@ Major version of SWF to XML export changed to 2. [#2179]: https://www.free-decompiler.com/flash/issues/2179 [#2185]: https://www.free-decompiler.com/flash/issues/2185 [#2259]: https://www.free-decompiler.com/flash/issues/2259 +[#2189]: https://www.free-decompiler.com/flash/issues/2189 [#2149]: https://www.free-decompiler.com/flash/issues/2149 [#2172]: https://www.free-decompiler.com/flash/issues/2172 [#2174]: https://www.free-decompiler.com/flash/issues/2174 diff --git a/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java b/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java index e5e74a397..f23164feb 100644 --- a/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ReplaceCharacterDialog.java @@ -20,19 +20,28 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.util.Map; import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; import javax.swing.JButton; -import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; /** * @@ -44,7 +53,13 @@ public class ReplaceCharacterDialog extends AppDialog { private final JButton cancelButton = new JButton(translate("button.cancel")); - private final JComboBox> charactersComboBox = new JComboBox<>(); + //private final JComboBox> charactersComboBox = new JComboBox<>(); + + private final JList> charactersListBox = new JList<>(); + + private final JTextField searchTextField = new JTextField(10); + + private DefaultListModel> fullModel = new DefaultListModel<>(); private int result = ERROR_OPTION; @@ -52,13 +67,45 @@ public class ReplaceCharacterDialog extends AppDialog { super(owner); setSize(400, 150); setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); - setLayout(new BorderLayout()); - add(new JLabel(translate("replace.with")), BorderLayout.NORTH); + Container cnt = getContentPane(); + cnt.setLayout(new BorderLayout()); + + JPanel topPanel = new JPanel(new BorderLayout()); + topPanel.add(new JLabel(translate("replace.with")), BorderLayout.WEST); + + JPanel searchPanel = new JPanel(new FlowLayout()); + JLabel iconSearchLabel = new JLabel(View.getIcon("search16")); + searchPanel.add(iconSearchLabel); + searchPanel.add(searchTextField); + topPanel.add(searchPanel, BorderLayout.EAST); + + cnt.add(topPanel, BorderLayout.NORTH); - charactersComboBox.setPreferredSize(new Dimension(400, charactersComboBox.getPreferredSize().height)); - add(charactersComboBox, BorderLayout.CENTER); + charactersListBox.setModel(new DefaultListModel<>()); + if (View.isOceanic()) { + charactersListBox.setBackground(Color.white); + } + charactersListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + charactersListBox.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + okButton.setEnabled(charactersListBox.getSelectedIndex() > -1); + if (okButton.isEnabled()) { + getRootPane().setDefaultButton(okButton); + } else { + getRootPane().setDefaultButton(null); + } + } + }); + + okButton.setEnabled(false); - charactersComboBox.setRenderer(new CharacterTagListCellRenderer()); + JScrollPane sc = new JScrollPane(charactersListBox); + sc.setPreferredSize(new Dimension(400,300)); + + cnt.add(sc, BorderLayout.CENTER); + + charactersListBox.setCellRenderer(new CharacterTagListCellRenderer()); JPanel panButtons = new JPanel(new FlowLayout()); okButton.addActionListener(this::okButtonActionPerformed); @@ -66,12 +113,50 @@ public class ReplaceCharacterDialog extends AppDialog { panButtons.add(okButton); panButtons.add(cancelButton); - add(panButtons, BorderLayout.SOUTH); + cnt.add(panButtons, BorderLayout.SOUTH); + + searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + update(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + update(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + update(); + } + + private void update() { + String searchedText = searchTextField.getText(); + ComboBoxItem selectedValue = charactersListBox.getSelectedValue(); + DefaultListModel> filteredModel = new DefaultListModel<>(); + int newSelectedIndex = -1; + boolean isEmpty = searchedText.trim().isEmpty(); + for (int i = 0; i < fullModel.getSize(); i++) { + ComboBoxItem element = fullModel.getElementAt(i); + if (isEmpty || element.toString().toLowerCase().contains(searchedText.toLowerCase())) { + filteredModel.addElement(element); + if (selectedValue == element) { + newSelectedIndex = filteredModel.size() - 1; + } + } + } + charactersListBox.setModel(filteredModel); + if (newSelectedIndex != -1) { + charactersListBox.setSelectedIndex(newSelectedIndex); + } + } + }); + setModalityType(ModalityType.APPLICATION_MODAL); View.setWindowIcon(this); - setTitle(translate("dialog.title")); - getRootPane().setDefaultButton(okButton); + setTitle(translate("dialog.title")); pack(); View.centerScreen(this); } @@ -91,20 +176,25 @@ public class ReplaceCharacterDialog extends AppDialog { return null; } - @SuppressWarnings("unchecked") - ComboBoxItem item = (ComboBoxItem) charactersComboBox.getSelectedItem(); + ComboBoxItem item = charactersListBox.getSelectedValue(); + if (item == null) { + return null; + } return item.getValue().getCharacterId(); } public int showDialog(SWF swf, int selectedCharacterId) { - Map characters = swf.getCharacters(); + Map characters = swf.getCharacters(); + fullModel = new DefaultListModel<>(); + fullModel.clear(); for (Integer key : characters.keySet()) { CharacterTag character = characters.get(key); int characterId = character.getCharacterId(); - if (characterId != selectedCharacterId) { - charactersComboBox.addItem(new ComboBoxItem<>(character.getName(), character)); + if (characterId != selectedCharacterId) { + fullModel.addElement(new ComboBoxItem<>(character.getName(), character)); } } + charactersListBox.setModel(fullModel); setVisible(true); return result;