mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 09:10:48 +00:00
Added ActionScript Debugger - Call stack frames switching - view variables around call stack
Added ActionScript Debugger - Highlight lines of callstack Changed Basic tag info panel always visible even when nothing to display (to avoid flickering)
This commit is contained in:
@@ -61,18 +61,16 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
|
||||
|
||||
private MyTreeTable debugScopeTable;
|
||||
|
||||
private JTable callStackTable;
|
||||
|
||||
private JTable stackTable;
|
||||
private MyTreeTable debugScopeTable;
|
||||
|
||||
private JTable constantPoolTable;
|
||||
|
||||
private JTabbedPane varTabs;
|
||||
|
||||
private BreakListener listener;
|
||||
private BreakListener breakListener;
|
||||
|
||||
private DebuggerHandler.FrameChangeListener frameChangeListener;
|
||||
|
||||
private JTextArea traceLogTextarea;
|
||||
|
||||
private int logLength = 0;
|
||||
@@ -215,8 +213,6 @@ public class DebugPanel extends JPanel {
|
||||
//debugScopeTable.addMouseListener(watchHandler);
|
||||
debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()), false);
|
||||
|
||||
callStackTable = new JTable();
|
||||
stackTable = new JTable();
|
||||
constantPoolTable = new JTable();
|
||||
traceLogTextarea = new JTextArea();
|
||||
traceLogTextarea.setEditable(false);
|
||||
@@ -258,30 +254,33 @@ public class DebugPanel extends JPanel {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addFrameChangeListener(frameChangeListener = new DebuggerHandler.FrameChangeListener() {
|
||||
@Override
|
||||
public void frameChanged() {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addBreakListener(listener = new DebuggerHandler.BreakListener() {
|
||||
Main.getDebugHandler().addBreakListener(breakListener = new DebuggerHandler.BreakListener() {
|
||||
|
||||
@Override
|
||||
public void doContinue() {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakAt(String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
public void breakAt(String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -406,52 +405,6 @@ public class DebugPanel extends JPanel {
|
||||
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) {
|
||||
//InBreakReason reason = Main.getDebugHandler().getBreakReason();
|
||||
List<String> callStackFiles = new ArrayList<>();
|
||||
List<Integer> callStackLines = new ArrayList<>();
|
||||
|
||||
callStackFiles.add(Main.getDebugHandler().moduleToString(info.file));
|
||||
callStackLines.add(info.line);
|
||||
|
||||
for (int i = 0; i < info.files.size(); i++) {
|
||||
callStackFiles.add(Main.getDebugHandler().moduleToString(info.files.get(i)));
|
||||
callStackLines.add(info.lines.get(i));
|
||||
}
|
||||
Object[][] data = new Object[callStackFiles.size()][2];
|
||||
for (int i = 0; i < callStackFiles.size(); i++) {
|
||||
data[i][0] = callStackFiles.get(i);
|
||||
data[i][1] = callStackLines.get(i);
|
||||
}
|
||||
|
||||
DefaultTableModel tm = new DefaultTableModel(data, new Object[]{
|
||||
AppStrings.translate("callStack.header.file"),
|
||||
AppStrings.translate("callStack.header.line")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
callStackTable.setModel(tm);
|
||||
|
||||
Object[][] data2 = new Object[info.stacks.size()][1];
|
||||
for (int i = 0; i < info.stacks.size(); i++) {
|
||||
data2[i][0] = info.stacks.get(i);
|
||||
}
|
||||
stackTable.setModel(new DefaultTableModel(data2, new Object[]{AppStrings.translate("stack.header.item")}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
callStackTable.setModel(new DefaultTableModel());
|
||||
stackTable.setModel(new DefaultTableModel());
|
||||
}
|
||||
InConstantPool cpool = Main.getDebugHandler().getConstantPool();
|
||||
if (cpool != null) {
|
||||
Object[][] data2 = new Object[cpool.vars.size()][2];
|
||||
@@ -469,6 +422,8 @@ public class DebugPanel extends JPanel {
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
constantPoolTable.setModel(new DefaultTableModel());
|
||||
}
|
||||
|
||||
varTabs.removeAll();
|
||||
@@ -503,21 +458,7 @@ public class DebugPanel extends JPanel {
|
||||
pa.add(new FasterScrollPane(constantPoolTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("constantpool.header"), pa);
|
||||
}
|
||||
|
||||
if (callStackTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.CALLSTACK);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(callStackTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("callStack.header"), pa);
|
||||
}
|
||||
if (stackTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.STACK);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(stackTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("stack.header"), pa);
|
||||
}
|
||||
|
||||
if (logLength > 0) {
|
||||
tabTypes.add(SelectedTab.LOG);
|
||||
|
||||
@@ -560,6 +501,7 @@ public class DebugPanel extends JPanel {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
Main.getDebugHandler().removeBreakListener(listener);
|
||||
Main.getDebugHandler().removeBreakListener(breakListener);
|
||||
Main.getDebugHandler().removeFrameChangeListener(frameChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DebugStackPanel extends JPanel {
|
||||
|
||||
private JTable stackTable;
|
||||
|
||||
private boolean active = false;
|
||||
|
||||
private int depth = 0;
|
||||
|
||||
public DebugStackPanel() {
|
||||
stackTable = new JTable();
|
||||
Main.getDebugHandler().addFrameChangeListener(new DebuggerHandler.FrameChangeListener() {
|
||||
@Override
|
||||
public void frameChanged() {
|
||||
depth = Main.getDebugHandler().getDepth();
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
Main.getDebugHandler().addBreakListener(new DebuggerHandler.BreakListener() {
|
||||
@Override
|
||||
public void breakAt(String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doContinue() {
|
||||
clear();
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addConnectionListener(new DebuggerHandler.ConnectionListener() {
|
||||
@Override
|
||||
public void connected() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
clear();
|
||||
}
|
||||
});
|
||||
|
||||
//JLabel titleLabel = new JLabel(AppStrings.translate("callStack.header"), JLabel.CENTER);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
//add(titleLabel, BorderLayout.NORTH);
|
||||
add(new FasterScrollPane(stackTable), BorderLayout.CENTER);
|
||||
|
||||
stackTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
|
||||
int row = stackTable.rowAtPoint(e.getPoint());
|
||||
if (row >= 0) {
|
||||
String scriptName = (String) stackTable.getModel().getValueAt(row, 0);
|
||||
int line = (int)(Integer) stackTable.getModel().getValueAt(row, 1);
|
||||
Main.getMainFrame().getPanel().gotoScriptLine(Main.getMainFrame().getPanel().getCurrentSwf(),
|
||||
scriptName, line, -1, -1, -1);
|
||||
Main.getDebugHandler().setDepth(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
stackTable.setModel(new DefaultTableModel());
|
||||
active = false;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
InBreakAtExt info = Main.getDebugHandler().getBreakInfo();
|
||||
if (info == null) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
Object[][] data = new Object[info.files.size()][3];
|
||||
for (int i = 0; i < info.files.size(); i++) {
|
||||
data[i][0] = Main.getDebugHandler().moduleToString(info.files.get(i));
|
||||
data[i][1] = info.lines.get(i);
|
||||
data[i][2] = info.stacks.get(i);
|
||||
}
|
||||
|
||||
DefaultTableModel tm = new DefaultTableModel(data, new Object[]{
|
||||
AppStrings.translate("callStack.header.file"),
|
||||
AppStrings.translate("callStack.header.line"),
|
||||
AppStrings.translate("stack.header.item")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
stackTable.setModel(tm);
|
||||
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TableCellRenderer renderer = new DefaultTableCellRenderer() {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
if (row == depth) {
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
};
|
||||
stackTable.getColumnModel().getColumn(0).setCellRenderer(renderer);
|
||||
stackTable.getColumnModel().getColumn(1).setCellRenderer(renderer);
|
||||
stackTable.getColumnModel().getColumn(2).setCellRenderer(renderer);
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public void setDepth(int depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,10 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
private int breakIp = -1;
|
||||
|
||||
private String breakScriptName = null;
|
||||
|
||||
private List<String> stackScriptNames = new ArrayList<>();
|
||||
|
||||
private List<Integer> stackLines = new ArrayList<>();
|
||||
|
||||
public static class ActionScriptException extends Exception {
|
||||
|
||||
@@ -129,12 +133,30 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
return breakIp;
|
||||
}
|
||||
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public String getBreakScriptName() {
|
||||
if (!isPaused()) {
|
||||
return "-";
|
||||
}
|
||||
return breakScriptName;
|
||||
}
|
||||
|
||||
public synchronized List<String> getStackScripts() {
|
||||
if (!isPaused()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return stackScriptNames;
|
||||
}
|
||||
|
||||
public synchronized List<Integer> getStackLines() {
|
||||
if (!isPaused()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return stackLines;
|
||||
}
|
||||
|
||||
public InGetVariable getVariable(long parentId, String varName, boolean children) {
|
||||
try {
|
||||
@@ -324,6 +346,8 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
|
||||
private InFrame frame;
|
||||
|
||||
private int depth;
|
||||
|
||||
private InConstantPool pool;
|
||||
|
||||
@@ -334,9 +358,16 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
private final List<BreakListener> breakListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final List<TraceListener> traceListeners = new ArrayList<>();
|
||||
|
||||
private final List<FrameChangeListener> frameChangeListeners = new ArrayList<>();
|
||||
|
||||
private final List<ConnectionListener> clisteners = new ArrayList<>();
|
||||
|
||||
public void setDepth(int depth) {
|
||||
this.depth = depth;
|
||||
refreshFrame();
|
||||
}
|
||||
|
||||
public String moduleToString(int file) {
|
||||
if (!modulePaths.containsKey(file)) {
|
||||
return "unknown";
|
||||
@@ -369,6 +400,11 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
public void trace(String... val);
|
||||
}
|
||||
|
||||
public static interface FrameChangeListener {
|
||||
|
||||
public void frameChanged();
|
||||
}
|
||||
|
||||
public static interface BreakListener {
|
||||
|
||||
@@ -380,6 +416,14 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
public void addBreakListener(BreakListener l) {
|
||||
breakListeners.add(l);
|
||||
}
|
||||
|
||||
public void addFrameChangeListener(FrameChangeListener l) {
|
||||
frameChangeListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeFrameChangeListener(FrameChangeListener l) {
|
||||
frameChangeListeners.remove(l);
|
||||
}
|
||||
|
||||
public void addTraceListener(TraceListener l) {
|
||||
traceListeners.add(l);
|
||||
@@ -406,11 +450,14 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
frame = commands.getFrame(0);
|
||||
frame = commands.getFrame(depth);
|
||||
pool = commands.getConstantPool(0);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
for (FrameChangeListener l : frameChangeListeners) {
|
||||
l.frameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized InFrame getFrame() {
|
||||
@@ -438,8 +485,8 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
public List<InSwfInfo.SwfInfo> getSwfs() {
|
||||
return swfs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
frame = null;
|
||||
pool = null;
|
||||
@@ -586,6 +633,7 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
name = DottedChain.parseWithSuffix(pkg).addWithSuffix(clsNameWithSuffix).toString();
|
||||
}
|
||||
}
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINE, "Script added - index {0} name: {1}", new Object[]{file, name});
|
||||
modulePaths.put(file, name);
|
||||
scriptToModule.put(name, file);
|
||||
con.dropMessage(sc);
|
||||
@@ -714,6 +762,16 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
synchronized (DebuggerHandler.this) {
|
||||
breakScriptName = newBreakScriptName;
|
||||
breakIp = message.line;
|
||||
|
||||
if (breakInfo != null) {
|
||||
List<String> files = new ArrayList<>();
|
||||
for (int i = 0; i < breakInfo.files.size(); i++) {
|
||||
files.add(Main.getDebugHandler().moduleToString(breakInfo.files.get(i)));
|
||||
}
|
||||
stackScriptNames = files;
|
||||
List<Integer> lines = new ArrayList<>(breakInfo.lines);
|
||||
stackLines = lines;
|
||||
}
|
||||
}
|
||||
|
||||
if (reasonInt == InBreakReason.REASON_SCRIPT_LOADED) {
|
||||
@@ -725,9 +783,8 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
} else {
|
||||
Main.startWork(AppStrings.translate("work.breakat") + newBreakScriptName + ":" + message.line + " " + AppStrings.translate("debug.break.reason." + reason), null);
|
||||
}
|
||||
frame = commands.getFrame(0);
|
||||
pool = commands.getConstantPool(0);
|
||||
|
||||
depth = 0;
|
||||
refreshFrame();
|
||||
for (BreakListener l : breakListeners) {
|
||||
l.breakAt(newBreakScriptName, message.line,
|
||||
moduleToClassIndex.containsKey(message.file) ? moduleToClassIndex.get(message.file) : -1,
|
||||
@@ -746,13 +803,13 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
synchronized (this) {
|
||||
connected = true;
|
||||
}
|
||||
if (!isAS3) {
|
||||
/*if (!isAS3) {
|
||||
try {
|
||||
commands.getConnection().writeMessage(new OutRewind(commands.getConnection()));
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
for (ConnectionListener l : clisteners) {
|
||||
l.connected();
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.JsonValue;
|
||||
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.InCallFunction;
|
||||
@@ -682,6 +683,14 @@ public class Main {
|
||||
public static synchronized String getIpClass() {
|
||||
return getDebugHandler().getBreakScriptName();
|
||||
}
|
||||
|
||||
public static synchronized List<Integer> getStackLines() {
|
||||
return getDebugHandler().getStackLines();
|
||||
}
|
||||
|
||||
public static synchronized List<String> getStackClasses() {
|
||||
return getDebugHandler().getStackScripts();
|
||||
}
|
||||
|
||||
public static synchronized boolean isBreakPointValid(String scriptName, int line) {
|
||||
return !getDebugHandler().isBreakpointInvalid(scriptName, line);
|
||||
@@ -3201,6 +3210,6 @@ public class Main {
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Problems with creating the log files");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,11 +366,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
private static final String CARDHEADER = "Header card";
|
||||
|
||||
private static final String DETAILCARDAS3NAVIGATOR = "Traits list";
|
||||
private static final int DETAILCARDAS3NAVIGATOR = 1;
|
||||
|
||||
private static final String DETAILCARDTAGINFO = "Tag information";
|
||||
private static final int DETAILCARDTAGINFO = 0;
|
||||
|
||||
private static final String DETAILCARDEMPTYPANEL = "Empty card";
|
||||
private static final int DETAILCARDEMPTYPANEL = -1;
|
||||
|
||||
private static final int DETAILCARDDEBUGSTACKFRAME = 2;
|
||||
|
||||
private static final String SPLIT_PANE1 = "SPLITPANE1";
|
||||
|
||||
@@ -390,7 +392,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
private final JPersistentSplitPane splitPane2;
|
||||
|
||||
private JPanel detailPanel;
|
||||
private JTabbedPane detailPanel;
|
||||
|
||||
private QuickTreeFindPanel quickTreeFindPanel;
|
||||
|
||||
@@ -411,6 +413,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
private final PreviewPanel dumpPreviewPanel;
|
||||
|
||||
private final TagInfoPanel tagInfoPanel;
|
||||
|
||||
private final DebugStackPanel debugStackPanel;
|
||||
|
||||
private TreePanelMode treePanelMode;
|
||||
|
||||
@@ -1024,7 +1028,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
public String translate(String key) {
|
||||
return mainFrame.translate(key);
|
||||
}
|
||||
|
||||
|
||||
public MainPanel(MainFrame mainFrame, MainFrameMenu mainMenu, FlashPlayerPanel flashPanel, FlashPlayerPanel previewFlashPanel) {
|
||||
super();
|
||||
|
||||
@@ -1038,18 +1042,56 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
setLayout(new BorderLayout());
|
||||
openables = new ObservableList<>();
|
||||
|
||||
detailPanel = new JPanel();
|
||||
detailPanel.setLayout(new CardLayout());
|
||||
detailPanel = new JTabbedPane();
|
||||
//detailPanel.setLayout(new CardLayout());
|
||||
|
||||
JPanel whitePanel = new JPanel();
|
||||
/*JPanel whitePanel = new JPanel();
|
||||
if (View.isOceanic()) {
|
||||
whitePanel.setBackground(Color.white);
|
||||
}
|
||||
detailPanel.add(whitePanel, DETAILCARDEMPTYPANEL);
|
||||
|
||||
*/
|
||||
tagInfoPanel = new TagInfoPanel(this);
|
||||
detailPanel.add(tagInfoPanel, DETAILCARDTAGINFO);
|
||||
|
||||
debugStackPanel = new DebugStackPanel();
|
||||
Main.getDebugHandler().addBreakListener(new DebuggerHandler.BreakListener() {
|
||||
@Override
|
||||
public void breakAt(String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showDetail(DETAILCARDDEBUGSTACKFRAME);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doContinue() {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Main.getDebugHandler().addConnectionListener(new DebuggerHandler.ConnectionListener(){
|
||||
@Override
|
||||
public void connected() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reload(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName());
|
||||
tagTree = new TagTree(null, this);
|
||||
tagTree.addTreeSelectionListener(this);
|
||||
@@ -1412,8 +1454,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
public ABCPanel getABCPanel() {
|
||||
if (abcPanel == null) {
|
||||
abcPanel = new ABCPanel(this);
|
||||
displayPanel.add(abcPanel, CARDACTIONSCRIPT3PANEL);
|
||||
detailPanel.add(abcPanel.navigatorPanel, DETAILCARDAS3NAVIGATOR);
|
||||
displayPanel.add(abcPanel, CARDACTIONSCRIPT3PANEL);
|
||||
}
|
||||
|
||||
return abcPanel;
|
||||
@@ -2486,32 +2527,57 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
public void gotoScriptLine(SWF swf, String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
View.checkAccess();
|
||||
|
||||
gotoScriptName(swf, scriptName);
|
||||
if (abcPanel != null) {
|
||||
if (Main.isDebugPCode()) {
|
||||
if (classIndex != -1) {
|
||||
boolean classChanged = false;
|
||||
if (abcPanel.decompiledTextArea.getClassIndex() != classIndex) {
|
||||
abcPanel.decompiledTextArea.setClassIndex(classIndex);
|
||||
classChanged = true;
|
||||
}
|
||||
if (traitIndex != -10 && (classChanged || abcPanel.decompiledTextArea.lastTraitIndex != traitIndex)) {
|
||||
abcPanel.decompiledTextArea.gotoTrait(traitIndex);
|
||||
}
|
||||
}
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.gotoInstrLine(line);
|
||||
} else {
|
||||
abcPanel.decompiledTextArea.gotoLine(line);
|
||||
}
|
||||
} else if (actionPanel != null) {
|
||||
if (Main.isDebugPCode()) {
|
||||
actionPanel.editor.gotoLine(line);
|
||||
} else {
|
||||
actionPanel.decompiledEditor.gotoLine(line);
|
||||
}
|
||||
if (abcPanel != null && swf.isAS3()) {
|
||||
abcPanel.decompiledTextArea.addScriptListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
abcPanel.decompiledTextArea.removeScriptListener(this);
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Main.isDebugPCode()) {
|
||||
if (classIndex != -1) {
|
||||
boolean classChanged = false;
|
||||
if (abcPanel.decompiledTextArea.getClassIndex() != classIndex) {
|
||||
abcPanel.decompiledTextArea.setClassIndex(classIndex);
|
||||
classChanged = true;
|
||||
}
|
||||
if (traitIndex != -10 && (classChanged || abcPanel.decompiledTextArea.lastTraitIndex != traitIndex)) {
|
||||
abcPanel.decompiledTextArea.gotoTrait(traitIndex);
|
||||
}
|
||||
}
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.gotoInstrLine(line);
|
||||
} else {
|
||||
abcPanel.decompiledTextArea.gotoLine(line);
|
||||
}
|
||||
scrollPosStorage.saveScrollPos(oldItem);
|
||||
refreshBreakPoints();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
} else if (actionPanel != null && !swf.isAS3()) {
|
||||
actionPanel.addScriptListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
actionPanel.removeScriptListener(this);
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Main.isDebugPCode()) {
|
||||
actionPanel.editor.gotoLine(line);
|
||||
} else {
|
||||
actionPanel.decompiledEditor.gotoLine(line);
|
||||
}
|
||||
scrollPosStorage.saveScrollPos(oldItem);
|
||||
refreshBreakPoints();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
refreshBreakPoints();
|
||||
|
||||
gotoScriptName(swf, scriptName);
|
||||
}
|
||||
|
||||
public void refreshBreakPoints() {
|
||||
@@ -2561,11 +2627,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
String rawScriptName = scriptName;
|
||||
if (rawScriptName.startsWith("#PCODE ")) {
|
||||
rawScriptName = rawScriptName.substring("#PCODE ".length());
|
||||
}
|
||||
}
|
||||
Map<String, ASMSource> asms = swf.getASMs(true);
|
||||
if (actionPanel != null && asms.containsKey(rawScriptName)) {
|
||||
actionPanel.setSource(asms.get(rawScriptName), true);
|
||||
if (asms.containsKey(rawScriptName)) {
|
||||
oldItem = null;
|
||||
getCurrentTree().setSelectionPath(null);
|
||||
setTagTreeSelectedNode(getCurrentTree(), asms.get(rawScriptName));
|
||||
}
|
||||
/*if (actionPanel != null && asms.containsKey(rawScriptName)) {
|
||||
actionPanel.setSource(asms.get(rawScriptName), true);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4698,16 +4769,40 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void showDetail(String card) {
|
||||
CardLayout cl = (CardLayout) (detailPanel.getLayout());
|
||||
cl.show(detailPanel, card);
|
||||
if (card.equals(DETAILCARDEMPTYPANEL)) {
|
||||
if (detailPanel.isVisible()) {
|
||||
detailPanel.setVisible(false);
|
||||
private void showDetail(int card) {
|
||||
if (debugStackPanel.isActive() && card != DETAILCARDDEBUGSTACKFRAME) {
|
||||
return;
|
||||
}
|
||||
|
||||
detailPanel.removeAll();
|
||||
int pos = 0;
|
||||
|
||||
if (card == DETAILCARDTAGINFO) {
|
||||
detailPanel.addTab(AppStrings.translate("taginfo.header"), tagInfoPanel);
|
||||
if (card == DETAILCARDTAGINFO) {
|
||||
detailPanel.setSelectedIndex(pos);
|
||||
}
|
||||
} else if (!detailPanel.isVisible()) {
|
||||
pos++;
|
||||
}
|
||||
if (card == DETAILCARDAS3NAVIGATOR || card == DETAILCARDDEBUGSTACKFRAME) {
|
||||
if (abcPanel != null && getCurrentSwf() != null && getCurrentSwf().isAS3()) {
|
||||
detailPanel.addTab(AppStrings.translate("traits"), abcPanel.navigatorPanel);
|
||||
if (card == DETAILCARDAS3NAVIGATOR) {
|
||||
detailPanel.setSelectedIndex(pos);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (debugStackPanel.isActive()) {
|
||||
detailPanel.addTab(AppStrings.translate("callStack.header"), debugStackPanel);
|
||||
if (card == DETAILCARDDEBUGSTACKFRAME) {
|
||||
detailPanel.setSelectedIndex(pos);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
if (currentView != VIEW_DUMP) {
|
||||
detailPanel.setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -4971,9 +5066,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
showTreePanelCard(DUMP_VIEW);
|
||||
treePanelMode = TreePanelMode.DUMP_TREE;
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
//showDetail(DETAILCARDEMPTYPANEL);
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
reload(true);
|
||||
updateUiWithCurrentOpenable();
|
||||
detailPanel.setVisible(false);
|
||||
return true;
|
||||
case VIEW_RESOURCES:
|
||||
pinsPanel.setVisible(true);
|
||||
@@ -4993,6 +5090,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
});
|
||||
|
||||
detailPanel.setVisible(true);
|
||||
refreshPins();
|
||||
reload(true);
|
||||
updateUiWithCurrentOpenable();
|
||||
@@ -5029,6 +5127,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
showTreePanelCard(TAGLIST_VIEW);
|
||||
treePanelMode = TreePanelMode.TAGLIST_TREE;
|
||||
detailPanel.setVisible(true);
|
||||
refreshPins();
|
||||
reload(true);
|
||||
updateUiWithCurrentOpenable();
|
||||
|
||||
@@ -54,8 +54,8 @@ public class TagInfoPanel extends JPanel {
|
||||
public TagInfoPanel(MainPanel mainPanel) {
|
||||
this.mainPanel = mainPanel;
|
||||
setLayout(new BorderLayout());
|
||||
JLabel topLabel = new JLabel(AppStrings.translate("taginfo.header"), JLabel.CENTER);
|
||||
add(topLabel, BorderLayout.NORTH);
|
||||
//JLabel topLabel = new JLabel(AppStrings.translate("taginfo.header"), JLabel.CENTER);
|
||||
//add(topLabel, BorderLayout.NORTH);
|
||||
add(new FasterScrollPane(editorPane), BorderLayout.CENTER);
|
||||
|
||||
editorPane.setContentType("text/html");
|
||||
|
||||
@@ -1116,8 +1116,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
final JToggleButton sortButton = new JToggleButton(View.getIcon("sort16"));
|
||||
sortButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
navIconsPanel.add(sortButton);
|
||||
JLabel navigatorLabel = new JLabel(AppStrings.translate("traits"), JLabel.CENTER);
|
||||
navigatorPanel.add(navigatorLabel, BorderLayout.NORTH);
|
||||
//JLabel navigatorLabel = new JLabel(AppStrings.translate("traits"), JLabel.CENTER);
|
||||
//navigatorPanel.add(navigatorLabel, BorderLayout.NORTH);
|
||||
navigatorPanel.add(navIconsPanel, BorderLayout.SOUTH);
|
||||
navigatorPanel.add(new FasterScrollPane(navigator), BorderLayout.CENTER);
|
||||
sortButton.addActionListener(new ActionListener() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.action;
|
||||
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.ValueTooLargeException;
|
||||
@@ -86,7 +87,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.UIManager;
|
||||
import jsyntaxpane.components.BreakPointListener;
|
||||
@@ -39,6 +40,8 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP
|
||||
private static final Color BG_RULER_COLOR = new Color(0xe9, 0xe8, 0xe2);
|
||||
|
||||
private static Color BG_BREAKPOINT_COLOR = new Color(0xfc, 0x9d, 0x9f);
|
||||
|
||||
private static final Color BG_STACK_COLOR = new Color(0xe7, 0xe1, 0xef);
|
||||
|
||||
private static final Color FG_BREAKPOINT_COLOR = null;
|
||||
|
||||
@@ -47,6 +50,10 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP
|
||||
private static final Color BG_IP_COLOR = new Color(0xbd, 0xe6, 0xaa);
|
||||
|
||||
private static final Color FG_IP_COLOR = null;
|
||||
|
||||
private static final Color FG_STACK_COLOR = null;
|
||||
|
||||
private static final int PRIORITY_STACK = 30;
|
||||
|
||||
private static final int PRIORITY_IP = 0;
|
||||
|
||||
@@ -61,6 +68,8 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP
|
||||
public static final LineMarker IP_MARKER = new LineMarker(FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
|
||||
public static final LineMarker INVALID_BREAKPOINT_MARKER = new LineMarker(FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
|
||||
public static final LineMarker STACK_MARKER = new LineMarker(FG_STACK_COLOR, BG_STACK_COLOR, PRIORITY_STACK);
|
||||
|
||||
protected String scriptName = null;
|
||||
|
||||
@@ -122,6 +131,15 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP
|
||||
if (ip > 0 && ipPath != null && ipPath.equals(scriptName)) {
|
||||
addColorMarker(ip + firstLineOffset(), IP_MARKER);
|
||||
}
|
||||
List<Integer> stackLines = Main.getStackLines();
|
||||
List<String> stackClasses = Main.getStackClasses();
|
||||
for (int i = 1; i < stackClasses.size(); i++) {
|
||||
String cls = stackClasses.get(i);
|
||||
int line = stackLines.get(i);
|
||||
if (cls.equals(scriptName)) {
|
||||
addColorMarker(line + firstLineOffset(), STACK_MARKER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,6 +179,13 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP
|
||||
((Graphics2D) g).setStroke(new BasicStroke(0.5f));
|
||||
|
||||
boolean drawText = true;
|
||||
if (hasColorMarker(line, STACK_MARKER)) {
|
||||
g.setColor(BG_STACK_COLOR);
|
||||
g.fillPolygon(new int[]{x + 5, x + 15, x + 15}, new int[]{textY, textY, textY - 10}, 3);
|
||||
g.setColor(Color.black);
|
||||
g.drawPolygon(new int[]{x + 5, x + 15, x + 15}, new int[]{textY, textY, textY - 10}, 3);
|
||||
drawText = false;
|
||||
}
|
||||
if (hasColorMarker(line, INVALID_BREAKPOINT_MARKER)) {
|
||||
g.setColor(BG_INVALID_BREAKPOINT_COLOR);
|
||||
g.fillOval(x + 5, textY - 10, 10, 10);
|
||||
|
||||
@@ -218,6 +218,17 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
int pos = ActionUtils.getDocumentPosition(this, line, 0);
|
||||
if (pos != -1) {
|
||||
setCaretPosition(pos);
|
||||
com.jpexs.decompiler.flash.gui.View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Rectangle r = modelToView(pos);
|
||||
scrollRectToVisible(r);
|
||||
} catch (BadLocationException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user