From d3eb321ddcc8622e2bb379189814c1ef6c58c12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 27 Feb 2026 22:10:49 +0100 Subject: [PATCH] Added: #2644 Debugger - Button to sort variables alphabetically --- CHANGELOG.md | 2 + .../flash/configuration/Configuration.java | 5 ++ .../decompiler/flash/gui/DebugPanel.java | 69 +++++++++++++++---- .../decompiler/flash/gui/abc/ABCPanel.java | 49 ++++++++++--- .../locales/AdvancedSettingsDialog.properties | 3 + .../AdvancedSettingsDialog_cs.properties | 4 ++ .../AdvancedSettingsDialog_de.properties | 4 ++ .../AdvancedSettingsDialog_sk.properties | 4 ++ .../flash/gui/locales/MainFrame.properties | 1 + .../flash/gui/locales/MainFrame_cs.properties | 4 +- .../flash/gui/locales/MainFrame_de.properties | 4 +- .../flash/gui/locales/MainFrame_sk.properties | 4 +- 12 files changed, 127 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc0d31d7f..3b018254c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - Debugger - Button to disconnect current session (stay listening) +- [#2644] Debugger - Button to sort variables alphabetically ### Fixed - [#2643] APNG export - images containing multiple IDAT chunks @@ -4174,6 +4175,7 @@ Major version of SWF to XML export changed to 2. [alpha 9]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha8...alpha9 [alpha 8]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha7...alpha8 [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 +[#2644]: https://www.free-decompiler.com/flash/issues/2644 [#2643]: https://www.free-decompiler.com/flash/issues/2643 [#2645]: https://www.free-decompiler.com/flash/issues/2645 [#2639]: https://www.free-decompiler.com/flash/issues/2639 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index b2688b681..80ccc35fa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -1201,6 +1201,11 @@ public final class Configuration { @ConfigurationCategory("script") public static ConfigurationItem as3QNameObfuscatedPropsInSquareBrackets = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("ui") + public static ConfigurationItem sortDebugVariablesAlphabetically = null; + + private static Map configurationDescriptions = new LinkedHashMap<>(); private static Map configurationTitles = new LinkedHashMap<>(); diff --git a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java index 7a5e9b9c9..b7cd82258 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.gui; -import com.jpexs.debugger.flash.Debugger; import com.jpexs.debugger.flash.DebuggerCommands; import com.jpexs.debugger.flash.Variable; import com.jpexs.debugger.flash.messages.in.InConstantPool; @@ -24,6 +23,7 @@ import com.jpexs.debugger.flash.messages.in.InFrame; import com.jpexs.debugger.flash.messages.in.InGetVariable; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener; import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener; import com.jpexs.decompiler.flash.gui.abc.ABCPanel; import com.jpexs.helpers.Helper; @@ -57,6 +57,7 @@ import javax.swing.JPopupMenu; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextArea; +import javax.swing.JToggleButton; import javax.swing.JTree; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -97,6 +98,8 @@ public class DebugPanel extends JPanel { public ABCPanel.VariablesTableModel localsTable; private WeakReference currentSessionRef = null; + + private JToggleButton sortToggleButton; private boolean as3; @@ -169,9 +172,12 @@ public class DebugPanel extends JPanel { public DebugPanel(boolean as3) { super(new BorderLayout()); this.as3 = as3; - debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>()), false); - debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>()), false); - debugWatchesTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>()), false); + + sortToggleButton = new JToggleButton(View.getIcon("sort16")); + + debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>(), false), false); + debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>(), false), false); + debugWatchesTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>(), false), false); MouseAdapter watchHandler = new MouseAdapter() { @@ -409,7 +415,7 @@ public class DebugPanel extends JPanel { debugWatchesTable.addMouseListener(watchHandler); //debugScopeTable.addMouseListener(watchHandler); - debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>()), false); + debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>(), false), false); constantPoolTable = new JTable(new DefaultTableModel(new Object[2][0], new Object[]{ AppStrings.translate("constantpool.header.id"), @@ -497,6 +503,30 @@ public class DebugPanel extends JPanel { //reacts to frameChanged instead } }); + + sortToggleButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + refresh(); + } + }); + sortToggleButton.setToolTipText(AppStrings.translate("sort.alphabetically")); + sortToggleButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Configuration.sortDebugVariablesAlphabetically.set(sortToggleButton.isSelected()); + } + }); + Configuration.sortDebugVariablesAlphabetically.addListener(new ConfigurationItemChangeListener() { + @Override + public void configurationItemChanged(Boolean newValue) { + sortToggleButton.setSelected(newValue); + refresh(); + } + }); + JPanel bottomButtonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + bottomButtonsPanel.add(sortToggleButton); + varTabs = new JTabbedPane(); varTabs.addChangeListener(new ChangeListener() { @@ -511,6 +541,11 @@ public class DebugPanel extends JPanel { int si = varTabs.getSelectedIndex(); if (si > -1 && si < tabTypes.size()) { selectedTab = tabTypes.get(si); + + bottomButtonsPanel.setVisible( + selectedTab == SelectedTab.LOCALS + || selectedTab == SelectedTab.WATCHES + ); } } } @@ -519,6 +554,10 @@ public class DebugPanel extends JPanel { add(new HeaderLabel(AppStrings.translate("debugpanel.header")), BorderLayout.NORTH); add(varTabs, BorderLayout.CENTER); + + + + add(bottomButtonsPanel, BorderLayout.SOUTH); } /* private void getVariableList() { @@ -571,6 +610,8 @@ public class DebugPanel extends JPanel { try { setLoading(true); + boolean sort = sortToggleButton.isSelected(); + int sessionId = -1; if (session != null) { @@ -583,10 +624,10 @@ public class DebugPanel extends JPanel { localsTable = null; InFrame f = session == null ? null : session.getFrame(); - ABCPanel.VariablesTableModel registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>()); - ABCPanel.VariablesTableModel localsTableModel = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>()); - ABCPanel.VariablesTableModel scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>()); - ABCPanel.VariablesTableModel watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>()); + ABCPanel.VariablesTableModel registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>(), sort); + ABCPanel.VariablesTableModel localsTableModel = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>(), sort); + ABCPanel.VariablesTableModel scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>(), sort); + ABCPanel.VariablesTableModel watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>(), sort); ABCPanel.VariablesTableModel fRegistersTableModel; ABCPanel.VariablesTableModel fLocalsTableModel; ABCPanel.VariablesTableModel fScopeTableModel; @@ -621,8 +662,8 @@ public class DebugPanel extends JPanel { locals.addAll(f.arguments); locals.addAll(f.variables); - - localsTable = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, locals, null); + + localsTable = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, locals, null, sort); List watchedVars = new ArrayList<>(); List watchedParentIds = new ArrayList<>(); @@ -663,10 +704,10 @@ public class DebugPanel extends JPanel { } }; - registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, f.registers, null); + registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, f.registers, null, sort); localsTableModel = localsTable; - scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, f.scopeChain, null); - watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, watchedVars, watchedParentIds); + scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, f.scopeChain, null, sort); + watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, watchedVars, watchedParentIds, sort); localsTableModel.addTreeModelListener(refreshListener); scopeTableModel.addTreeModelListener(refreshListener); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index d287d3220..0e73bc079 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -123,6 +123,7 @@ import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; @@ -344,6 +345,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener(); - traits = new ArrayList<>(); + List newChilds = new ArrayList<>(); + List newTraits = new ArrayList<>(); if ("".equals(var.name)) { return; @@ -447,12 +449,24 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener() { + @Override + public int compare(VariableNode o1, VariableNode o2) { + return o1.var.name.compareTo(o2.var.name); + } + }); + } + + this.childs = newChilds; + this.traits = newTraits; } private void ensureLoaded() { @@ -578,7 +592,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener parentPath, int level, Variable var, Long parentObjectId, Variable trait) { + public VariableNode(DebuggerSession session, MyTreeTable treeTable, boolean as3, List parentPath, int level, Variable var, Long parentObjectId, Variable trait, boolean sort) { this.var = var; this.varInsideGetter = var; this.parentObjectId = parentObjectId; @@ -590,9 +604,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener parentPath, int level, Variable var, Long parentObjectId, Variable trait, List subvars) { + public VariableNode(DebuggerSession session, MyTreeTable treeTable, boolean as3, List parentPath, int level, Variable var, Long parentObjectId, Variable trait, List subvars, boolean sort) { this.var = var; this.varInsideGetter = var; this.parentObjectId = parentObjectId; @@ -611,6 +626,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener vars, List parentIds) { + public VariablesTableModel(DebuggerSession session, boolean as3, MyTreeTable treeTable, List vars, List parentIds, boolean sort) { this.treeTable = treeTable; List childs = new ArrayList<>(); for (int i = 0; i < vars.size(); i++) { - childs.add(new VariableNode(session, treeTable, as3, new ArrayList<>(), 1, vars.get(i), parentIds == null ? 0L : parentIds.get(i), null)); + childs.add(new VariableNode(session, treeTable, as3, new ArrayList<>(), 1, vars.get(i), parentIds == null ? 0L : parentIds.get(i), null, sort)); } - root = new VariableNode(session, treeTable, as3, new ArrayList<>(), 0, null, 0L, null, childs); + + if (sort) { + childs.sort(new Comparator() { + @Override + public int compare(VariableNode o1, VariableNode o2) { + return o1.var.name.compareTo(o2.var.name); + } + }); + } + + + root = new VariableNode(session, treeTable, as3, new ArrayList<>(), 0, null, 0L, null, childs, sort); root.loaded = true; + this.sort = sort; } @Override @@ -1646,6 +1676,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener