diff --git a/lib/flashdebugger.jar b/lib/flashdebugger.jar index 7966868b1..8b7a7a60c 100644 Binary files a/lib/flashdebugger.jar and b/lib/flashdebugger.jar differ diff --git a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java index cef9729fb..5df50caed 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java @@ -26,11 +26,17 @@ import java.awt.Color; import java.awt.FlowLayout; 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.JButton; import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTable; @@ -84,9 +90,79 @@ public class DebugPanel extends JPanel { public DebugPanel() { super(new BorderLayout()); - debugRegistersTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>())); - debugLocalsTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>())); - debugScopeTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>())); + debugRegistersTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); + debugLocalsTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); + + //Add watch feature, commented out. I tried it, but without success. I can't add watch in Flash Pro or FDB either. :-( + /* + //locales + debug.watch.add = Add watch to %name% + debug.watch.add.read = Read + debug.watch.add.write = Write + debug.watch.add.readwrite = Read+Write + + error.debug.watch.add = Cannot add watch to this variable. + + + MouseAdapter watchHandler = new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + dopop(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + dopop(e); + } + } + + private void dopop(MouseEvent e) { + if (debugLocalsTable.getSelectedRow() == -1) { + return; + } + Variable v = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVars().get(debugLocalsTable.getSelectedRow()); + final long v_id = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVarIds().get(debugLocalsTable.getSelectedRow()); + + JPopupMenu pm = new JPopupMenu(); + JMenu addWatchMenu = new JMenu(AppStrings.translate("debug.watch.add").replace("%name%", v.name)); + JMenuItem watchReadMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.read")); + watchReadMenuItem.addActionListener((ActionEvent e1) -> { + if (!Main.addWatch(v, v_id, true, false)) { + View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + } + }); + JMenuItem watchWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.write")); + watchWriteMenuItem.addActionListener((ActionEvent e1) -> { + if (!Main.addWatch(v, v_id, false, true)) { + View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + } + }); + JMenuItem watchReadWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.readwrite")); + watchReadWriteMenuItem.addActionListener((ActionEvent e1) -> { + if (!Main.addWatch(v, v_id, true, true)) { + View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + } + }); + + addWatchMenu.add(watchReadMenuItem); + addWatchMenu.add(watchWriteMenuItem); + addWatchMenu.add(watchReadWriteMenuItem); + pm.add(addWatchMenu); + + pm.show(e.getComponent(), e.getX(), e.getY()); + } + }; + + debugLocalsTable.addMouseListener(watchHandler); + debugScopeTable.addMouseListener(watchHandler); + + */ + debugScopeTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); + callStackTable = new JTable(); stackTable = new JTable(); traceLogTextarea = new JTextArea(); @@ -190,12 +266,22 @@ public class DebugPanel extends JPanel { SelectedTab oldSel = selectedTab; InFrame f = Main.getDebugHandler().getFrame(); if (f != null) { - debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers)); + + List regVarIds = new ArrayList<>(); + for (int i = 0; i < f.registers.size(); i++) { + regVarIds.add(0L); + } + debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers, regVarIds)); List locals = new ArrayList<>(); locals.addAll(f.arguments); locals.addAll(f.variables); - debugLocalsTable.setModel(new ABCPanel.VariablesTableModel(locals)); - debugScopeTable.setModel(new ABCPanel.VariablesTableModel(f.scopeChain)); + + List localIds = new ArrayList<>(); + localIds.addAll(f.argumentIds); + localIds.addAll(f.variableIds); + + debugLocalsTable.setModel(new ABCPanel.VariablesTableModel(locals, localIds)); + debugScopeTable.setModel(new ABCPanel.VariablesTableModel(f.scopeChain, f.scopeChainIds)); } else { debugRegistersTable.setModel(new DefaultTableModel()); debugLocalsTable.setModel(new DefaultTableModel()); diff --git a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java index 84c913381..c951dd3ce 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java @@ -21,6 +21,7 @@ import com.jpexs.debugger.flash.DebugMessageListener; import com.jpexs.debugger.flash.Debugger; import com.jpexs.debugger.flash.DebuggerCommands; import com.jpexs.debugger.flash.DebuggerConnection; +import com.jpexs.debugger.flash.Variable; import com.jpexs.debugger.flash.messages.in.InAskBreakpoints; import com.jpexs.debugger.flash.messages.in.InBreakAt; import com.jpexs.debugger.flash.messages.in.InBreakAtExt; @@ -29,6 +30,7 @@ import com.jpexs.debugger.flash.messages.in.InContinue; import com.jpexs.debugger.flash.messages.in.InFrame; import com.jpexs.debugger.flash.messages.in.InGetSwd; import com.jpexs.debugger.flash.messages.in.InGetSwf; +import com.jpexs.debugger.flash.messages.in.InGetVariable; import com.jpexs.debugger.flash.messages.in.InNumScript; import com.jpexs.debugger.flash.messages.in.InProcessTag; import com.jpexs.debugger.flash.messages.in.InScript; @@ -36,6 +38,7 @@ import com.jpexs.debugger.flash.messages.in.InSetBreakpoint; import com.jpexs.debugger.flash.messages.in.InSwfInfo; import com.jpexs.debugger.flash.messages.in.InTrace; import com.jpexs.debugger.flash.messages.in.InVersion; +import com.jpexs.debugger.flash.messages.out.OutAddWatch2; import com.jpexs.debugger.flash.messages.out.OutGetBreakReason; import com.jpexs.debugger.flash.messages.out.OutGetSwd; import com.jpexs.debugger.flash.messages.out.OutGetSwf; @@ -131,6 +134,17 @@ public class DebuggerHandler implements DebugConnectionListener { } } + private int watchTag = 1; + + public synchronized com.jpexs.debugger.flash.DebuggerCommands.Watch addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) { + int tag = watchTag++; + try { + return commands.addWatch(v_id, v.name, (watchRead ? OutAddWatch2.FLAG_READ : 0) | (watchWrite ? OutAddWatch2.FLAG_WRITE : 0), tag); + } catch (IOException ex) { + return null; + } + } + public synchronized Set getBreakPoints(String scriptName, boolean onlyValid) { Set lines = new TreeSet<>(); if (confirmedPointMap.containsKey(scriptName)) { @@ -502,6 +516,7 @@ public class DebuggerHandler implements DebugConnectionListener { commands.setSetterTimeout(5000); boolean isAS3 = (Main.getMainFrame().getPanel().getCurrentSwf().isAS3()); + con.isAS3 = isAS3; //Widelines - only AS3, it hangs in AS1/2 and SWD does not support UI32 lines if (isAS3) { diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 3a9496c74..3809ce7ee 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -17,6 +17,8 @@ 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.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.SWF; @@ -195,6 +197,11 @@ public class Main { return runProcess != null && !runProcessDebug; } + public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) { + DebuggerCommands.Watch w = getDebugHandler().addWatch(v, v_id, watchRead, watchWrite); + return w != null; + } + public static void runPlayer(String title, final String exePath, String file, String flashVars) { if (flashVars != null && !flashVars.isEmpty()) { file += "?" + flashVars; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index f031d922e..4433e28d7 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -269,9 +269,19 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener tableListeners = new ArrayList<>(); private List vars; + private List varIds; - public VariablesTableModel(List vars) { + public List getVarIds() { + return varIds; + } + + public List getVars() { + return new ArrayList<>(vars); + } + + public VariablesTableModel(List vars, List varIds) { this.vars = vars; + this.varIds = varIds; } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 5c829ab73..617205e0e 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -694,4 +694,4 @@ debug.break.reason.step = (Step) debug.break.reason.halt = (Halt) debug.break.reason.scriptLoaded = (Script loaded) -menu.file.start.debugpcode = Debug P-code \ No newline at end of file +menu.file.start.debugpcode = Debug P-code