mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 15:51:33 +00:00
Debugger - display variables in the tree structure
Set variables while debugging
This commit is contained in:
@@ -21,6 +21,11 @@ import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
|
||||
import de.hameister.treetable.MyAbstractTreeTableModel;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
import de.hameister.treetable.MyTreeTableModel;
|
||||
import de.hameister.treetable.MyTreeTableModelAdapter;
|
||||
import de.hameister.treetable.MyTreeTableSelectionModel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
@@ -43,7 +48,15 @@ import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -51,11 +64,11 @@ import javax.swing.table.DefaultTableModel;
|
||||
*/
|
||||
public class DebugPanel extends JPanel {
|
||||
|
||||
private JTable debugRegistersTable;
|
||||
private MyTreeTable debugRegistersTable;
|
||||
|
||||
private JTable debugLocalsTable;
|
||||
private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
|
||||
|
||||
private JTable debugScopeTable;
|
||||
private MyTreeTable debugScopeTable;
|
||||
|
||||
private JTable callStackTable;
|
||||
|
||||
@@ -88,10 +101,34 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
private SelectedTab selectedTab = null;
|
||||
|
||||
private void safeSetTreeModel(MyTreeTable tt, MyTreeTableModel tmodel) {
|
||||
List<List<String>> expanded = View.getExpandedNodes(tt.getTree());
|
||||
|
||||
int selRows[] = tt.getSelectedRows();
|
||||
|
||||
TreePath selPaths[] = new TreePath[selRows.length];
|
||||
for (int i = 0; i < selRows.length; i++) {
|
||||
selPaths[i] = tt.getTree().getPathForRow(selRows[i]);
|
||||
}
|
||||
tt.setTreeModel(tmodel);
|
||||
//tt.getTree().setRootVisible(false);
|
||||
|
||||
View.expandTreeNodes(tt.getTree(), expanded);
|
||||
for (int i = 0; i < selRows.length; i++) {
|
||||
selRows[i] = tt.getTree().getRowForPath(selPaths[i]);
|
||||
if (i == 0) {
|
||||
tt.setRowSelectionInterval(selRows[i], selRows[i]);
|
||||
} else {
|
||||
tt.addRowSelectionInterval(selRows[i], selRows[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DebugPanel() {
|
||||
super(new BorderLayout());
|
||||
debugRegistersTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, 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. :-(
|
||||
/*
|
||||
@@ -161,7 +198,7 @@ public class DebugPanel extends JPanel {
|
||||
debugScopeTable.addMouseListener(watchHandler);
|
||||
|
||||
*/
|
||||
debugScopeTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>()));
|
||||
debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
|
||||
|
||||
callStackTable = new JTable();
|
||||
stackTable = new JTable();
|
||||
@@ -271,21 +308,56 @@ public class DebugPanel extends JPanel {
|
||||
for (int i = 0; i < f.registers.size(); i++) {
|
||||
regVarIds.add(0L);
|
||||
}
|
||||
debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers, regVarIds));
|
||||
safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers, regVarIds));
|
||||
List<Variable> locals = new ArrayList<>();
|
||||
locals.addAll(f.arguments);
|
||||
locals.addAll(f.variables);
|
||||
|
||||
List<Long> localIds = new ArrayList<>();
|
||||
localIds.addAll(f.argumentIds);
|
||||
localIds.addAll(f.variableIds);
|
||||
localIds.addAll(f.argumentFrameIds);
|
||||
localIds.addAll(f.frameIds);
|
||||
|
||||
debugLocalsTable.setModel(new ABCPanel.VariablesTableModel(locals, localIds));
|
||||
debugScopeTable.setModel(new ABCPanel.VariablesTableModel(f.scopeChain, f.scopeChainIds));
|
||||
safeSetTreeModel(debugLocalsTable, new ABCPanel.VariablesTableModel(debugLocalsTable, locals, localIds));
|
||||
safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain, f.scopeChainFrameIds));
|
||||
|
||||
/*TableModelListener refreshListener = new TableModelListener() {
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
};*/
|
||||
TreeModelListener refreshListener = new TreeModelListener() {
|
||||
@Override
|
||||
public void treeNodesChanged(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesInserted(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesRemoved(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeStructureChanged(TreeModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
} else {
|
||||
debugRegistersTable.setModel(new DefaultTableModel());
|
||||
debugLocalsTable.setModel(new DefaultTableModel());
|
||||
debugScopeTable.setModel(new DefaultTableModel());
|
||||
debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()));
|
||||
debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
|
||||
}
|
||||
InBreakAtExt info = Main.getDebugHandler().getBreakInfo();
|
||||
if (info != null) {
|
||||
@@ -325,13 +397,13 @@ public class DebugPanel extends JPanel {
|
||||
varTabs.removeAll();
|
||||
tabTypes.clear();
|
||||
JPanel pa;
|
||||
if (debugRegistersTable.getRowCount() > 0) {
|
||||
if (debugRegistersTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.REGISTERS);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new JScrollPane(debugRegistersTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
|
||||
}
|
||||
if (debugLocalsTable.getRowCount() > 0) {
|
||||
if (debugLocalsTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.LOCALS);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
@@ -339,7 +411,7 @@ public class DebugPanel extends JPanel {
|
||||
varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
|
||||
}
|
||||
|
||||
if (debugScopeTable.getRowCount() > 0) {
|
||||
if (debugScopeTable.getRowCount() > 1 /*root*/) {
|
||||
tabTypes.add(SelectedTab.SCOPECHAIN);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
|
||||
@@ -22,6 +22,7 @@ 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.VariableType;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
@@ -108,6 +109,40 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
return breakScriptName;
|
||||
}
|
||||
|
||||
public InGetVariable getVariable(long parentId, String varName, boolean children) {
|
||||
try {
|
||||
return commands.getVariable(parentId, varName, true, children);
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVariable(long parentId, String varName, int valueType, Object value) {
|
||||
try {
|
||||
String svalue = "";
|
||||
switch (valueType) {
|
||||
case VariableType.STRING:
|
||||
svalue = "" + value;
|
||||
break;
|
||||
case VariableType.NUMBER:
|
||||
svalue = "" + value;
|
||||
break;
|
||||
case VariableType.BOOLEAN:
|
||||
svalue = ((Boolean) value) ? "true" : "false";
|
||||
break;
|
||||
case VariableType.UNDEFINED:
|
||||
svalue = "undefined";
|
||||
break;
|
||||
case VariableType.NULL:
|
||||
svalue = "undefined";
|
||||
break;
|
||||
}
|
||||
commands.setVariable(parentId, varName, valueType, svalue);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeBreakPoint(String scriptName, int line) {
|
||||
if (isBreakpointInvalid(scriptName, line)) {
|
||||
invalidBreakPointMap.get(scriptName).remove(line);
|
||||
@@ -332,6 +367,17 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
clisteners.remove(l);
|
||||
}
|
||||
|
||||
public synchronized void refreshFrame() {
|
||||
if (!paused) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
frame = commands.getFrame(0);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized InFrame getFrame() {
|
||||
if (!paused) {
|
||||
return null;
|
||||
|
||||
@@ -519,6 +519,10 @@ public class Main {
|
||||
loadFromMemoryFrame.setVisible(true);
|
||||
}
|
||||
|
||||
public static void setVariable(long parentId, String varName, int valueType, Object value) {
|
||||
getDebugHandler().setVariable(parentId, varName, valueType, value);
|
||||
}
|
||||
|
||||
public static void setSubLimiter(boolean value) {
|
||||
if (value) {
|
||||
AVM2Code.toSourceLimit = Configuration.sublimiter.get();
|
||||
@@ -1394,7 +1398,9 @@ public class Main {
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
Main.mainFrame.getPanel().refreshBreakPoints();
|
||||
if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
|
||||
Main.mainFrame.getPanel().refreshBreakPoints();
|
||||
}
|
||||
}
|
||||
});
|
||||
flashDebugger.addConnectionListener(debugHandler);
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.VariableType;
|
||||
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.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
@@ -38,6 +41,13 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TraitMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.SymbolType;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
@@ -66,6 +76,9 @@ import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
import de.hameister.treetable.MyTreeTableModel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FlowLayout;
|
||||
@@ -82,8 +95,13 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -101,7 +119,11 @@ import javax.swing.JTable;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.text.Highlighter;
|
||||
@@ -263,30 +285,167 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
decompiledTextArea.clearScript();
|
||||
}
|
||||
|
||||
public static class VariablesTableModel implements TableModel {
|
||||
public static class VariableNode {
|
||||
|
||||
// DebuggerHandler.VariableChangedListener varChangeListener;
|
||||
List<TableModelListener> tableListeners = new ArrayList<>();
|
||||
public List<VariableNode> path = new ArrayList<>();
|
||||
|
||||
private List<Variable> vars;
|
||||
private List<Long> varIds;
|
||||
public Long parentId;
|
||||
public int level;
|
||||
|
||||
public List<Long> getVarIds() {
|
||||
return varIds;
|
||||
}
|
||||
public Variable thisVar;
|
||||
public Variable thisTrait;
|
||||
public long thisTraitId;
|
||||
|
||||
public List<Variable> getVars() {
|
||||
return new ArrayList<>(vars);
|
||||
}
|
||||
private List<Variable> childs;
|
||||
private List<Variable> childTraits;
|
||||
|
||||
public VariablesTableModel(List<Variable> vars, List<Long> varIds) {
|
||||
this.vars = vars;
|
||||
this.varIds = varIds;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 53 * hash + Objects.hashCode(this.parentId);
|
||||
hash = 53 * hash + (this.thisVar == null ? 0 : Objects.hashCode(this.thisVar.name));
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return vars.size();
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final VariableNode other = (VariableNode) obj;
|
||||
if (!Objects.equals(this.parentId, other.parentId)) {
|
||||
return false;
|
||||
}
|
||||
if (this.thisVar == null && other.thisVar == null) {
|
||||
return true;
|
||||
}
|
||||
if (this.thisVar == null) {
|
||||
return false;
|
||||
}
|
||||
if (other.thisVar == null) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.thisVar.name, other.thisVar.name);
|
||||
}
|
||||
|
||||
public boolean loaded = false;
|
||||
|
||||
private static boolean isTraits(Variable v) {
|
||||
return (v.vType == VariableType.UNKNOWN && "traits".equals(v.typeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (level == 0) {
|
||||
return "root"; //TODO: localize?
|
||||
}
|
||||
return thisVar.name;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (path.size() > 1) {
|
||||
path.get(path.size() - 2).reloadChildren();
|
||||
} else {
|
||||
//Main.getDebugHandler().refreshFrame();
|
||||
//InFrame fr = Main.getDebugHandler().getFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadChildren() {
|
||||
InGetVariable igv = Main.getDebugHandler().getVariable(parentId, thisVar.name, true);
|
||||
childs = new ArrayList<>();
|
||||
childTraits = new ArrayList<>();
|
||||
|
||||
Variable curTrait = null;
|
||||
|
||||
for (int i = 0; i < igv.childs.size(); i++) {
|
||||
if (!isTraits(igv.childs.get(i))) {
|
||||
childs.add(igv.childs.get(i));
|
||||
childTraits.add(curTrait);
|
||||
} else {
|
||||
curTrait = igv.childs.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureLoaded() {
|
||||
if (!loaded) {
|
||||
reloadChildren();
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public VariableNode getChildAt(int index) {
|
||||
ensureLoaded();
|
||||
Long parId = 0L;
|
||||
if (thisVar != null && thisVar.vType == VariableType.OBJECT) {
|
||||
parId = (Long) thisVar.value;
|
||||
}
|
||||
VariableNode vn = new VariableNode(level + 1, childs.get(index), parId, childTraits.get(index));
|
||||
vn.path.addAll(path);
|
||||
vn.path.add(vn);
|
||||
return vn;
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
ensureLoaded();
|
||||
return childs.size();
|
||||
}
|
||||
|
||||
public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait) {
|
||||
this.parentId = parentId;
|
||||
this.thisVar = thisVar;
|
||||
this.level = level;
|
||||
this.thisTrait = thisTrait;
|
||||
}
|
||||
|
||||
public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait, Long thisTraitId, List<Variable> vars, List<Variable> varTraits) {
|
||||
this.parentId = parentId;
|
||||
|
||||
this.thisVar = thisVar;
|
||||
|
||||
this.level = level;
|
||||
this.childs = vars;
|
||||
|
||||
this.thisTrait = thisTrait;
|
||||
|
||||
this.childTraits = varTraits;
|
||||
this.path.add(this);
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VariablesTableModel implements MyTreeTableModel {
|
||||
|
||||
List<TableModelListener> tableListeners = new ArrayList<>();
|
||||
|
||||
VariableNode root;
|
||||
private Map<VariableNode, List<VariableNode>> nodeCache = new HashMap<>();
|
||||
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private static final int CHANGED = 0;
|
||||
private static final int INSERTED = 1;
|
||||
private static final int REMOVED = 2;
|
||||
private static final int STRUCTURE_CHANGED = 3;
|
||||
|
||||
private MyTreeTable ttable;
|
||||
|
||||
public VariablesTableModel(MyTreeTable ttable, List<Variable> vars, List<Long> parentIds) {
|
||||
this.ttable = ttable;
|
||||
List<Variable> varTraits = new ArrayList<>();
|
||||
for (int i = 0; i < vars.size(); i++) {
|
||||
varTraits.add(null);
|
||||
}
|
||||
root = new VariableNode(0, null, 0L, null, 0L, vars, varTraits);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,17 +469,21 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
return MyTreeTableModel.class;
|
||||
}
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false; //columnIndex == 2; //TODO: edit variables
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
Variable v = vars.get(rowIndex);
|
||||
public Object getValueAt(Object node, int columnIndex) {
|
||||
if (node == root) {
|
||||
if (columnIndex == 0) {
|
||||
return "root";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
Variable v = ((VariableNode) node).thisVar;
|
||||
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
@@ -335,24 +498,157 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
}
|
||||
return typeStr;
|
||||
case 2:
|
||||
return v.getValueAsStr();
|
||||
switch (v.vType) {
|
||||
case VariableType.OBJECT:
|
||||
case VariableType.MOVIECLIP:
|
||||
case VariableType.FUNCTION:
|
||||
return v.getTypeAsStr() + "(" + v.value + ")";
|
||||
case VariableType.STRING:
|
||||
return "\"" + Helper.escapeActionScriptString("" + v.value) + "\"";
|
||||
default:
|
||||
return "" + v.value;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
//Main.getDebugHandler().setVariableValue(rowIndex, "" + aValue);
|
||||
public boolean isCellEditable(Object node, int column) {
|
||||
return column == 0 || (column == 2 && node != root && ((VariableNode) node).thisVar.isPrimitive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableModelListener(TableModelListener l) {
|
||||
tableListeners.add(l);
|
||||
public void setValueAt(Object aValue, Object node, int column) {
|
||||
ActionScriptLexer lexer = new ActionScriptLexer(new StringReader("" + aValue));
|
||||
ParsedSymbol symb;
|
||||
try {
|
||||
symb = lexer.lex();
|
||||
ParsedSymbol f = lexer.yylex();
|
||||
if (f.type != SymbolType.EOF) {
|
||||
return;
|
||||
}
|
||||
} catch (IOException | ActionParseException ex) {
|
||||
return;
|
||||
}
|
||||
int valType;
|
||||
switch (symb.type) {
|
||||
case DOUBLE:
|
||||
valType = VariableType.NUMBER;
|
||||
break;
|
||||
case INTEGER:
|
||||
valType = VariableType.NUMBER;
|
||||
break;
|
||||
case NULL:
|
||||
valType = VariableType.NULL;
|
||||
break;
|
||||
case STRING:
|
||||
valType = VariableType.STRING;
|
||||
break;
|
||||
case UNDEFINED:
|
||||
valType = VariableType.UNDEFINED;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
Main.getDebugHandler().setVariable(((VariableNode) node).parentId, ((VariableNode) node).thisVar.name, valType, symb.value);
|
||||
//((VariableNode) node).refresh();
|
||||
Object path[] = new Object[((VariableNode) node).path.size()];
|
||||
for (int i = 0; i < path.length; i++) {
|
||||
path[i] = ((VariableNode) node).path.get(i);
|
||||
}
|
||||
valueForPathChanged(new TreePath(path), aValue);
|
||||
//fireTreeNodesChanged(this, path, new int[0]/*removed*/, new Object[]{node});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTableModelListener(TableModelListener l) {
|
||||
tableListeners.remove(l);
|
||||
public Object getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
return ((VariableNode) parent).getChildAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
int cnt = ((VariableNode) parent).getChildCount();
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
return getChildCount(node) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
fireTreeNodesChanged(ttable, path.getParentPath().getPath(), new int[0], new Object[]{path.getLastPathComponent()});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
int cnt = getChildCount(parent);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (getChild(parent, i) == child) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
listenerList.add(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
listenerList.remove(TreeModelListener.class, l);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(INSERTED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(REMOVED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
fireTreeNode(STRUCTURE_CHANGED, source, path, childIndices, children);
|
||||
}
|
||||
|
||||
private void fireTreeNode(int changeType, Object source, Object[] path, int[] childIndices, Object[] children) {
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == TreeModelListener.class) {
|
||||
|
||||
switch (changeType) {
|
||||
case CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);
|
||||
break;
|
||||
case INSERTED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);
|
||||
break;
|
||||
case REMOVED:
|
||||
((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);
|
||||
break;
|
||||
case STRUCTURE_CHANGED:
|
||||
((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,6 +946,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
int dpos = decompiledTextArea.getLocalDeclarationOfPos(pos, new Reference<>(null));
|
||||
if (dpos > -1) {
|
||||
decompiledTextArea.setCaretPosition(dpos);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -872,8 +1169,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
decompiledTextArea.markError();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
Logger.getLogger(ABCPanel.class
|
||||
.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user