From 38335ec2e47e0db3ce7f68116f3f2e411d326abb Mon Sep 17 00:00:00 2001 From: honfika Date: Sun, 22 Jun 2014 09:49:12 +0200 Subject: [PATCH] dump view: basic hex view (should be changed to a real hex view component) --- src/com/jpexs/decompiler/flash/SWF.java | 2 +- .../parser/script/ActionScriptParser.java | 6 +- .../abc/avm2/parser/script/BreakJumpIns.java | 72 +- .../abc/avm2/parser/script/ConstAVM2Item.java | 2 +- .../avm2/parser/script/ContinueJumpIns.java | 74 +- .../avm2/parser/script/FinallyJumpIns.java | 72 +- .../abc/avm2/parser/script/IndexAVM2Item.java | 2 +- .../avm2/parser/script/MethodAVM2Item.java | 6 +- .../avm2/parser/script/PropertyAVM2Item.java | 4 +- .../abc/avm2/parser/script/SlotAVM2Item.java | 2 +- .../parser/script/UnresolvedAVM2Item.java | 2 +- .../parser/script/ActionScriptParser.java | 2 +- .../parser/script/ActionSourceGenerator.java | 2 +- .../flash/gui/AdvancedSettingsDialog.java | 2 +- .../jpexs/decompiler/flash/gui/DumpTree.java | 14 + .../decompiler/flash/gui/DumpViewPanel.java | 126 ++ .../flash/gui/MainFrameClassic.java | 258 ++-- .../decompiler/flash/gui/MainFrameRibbon.java | 2 +- .../flash/gui/MainFrameRibbonMenu.java | 2 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 21 +- .../decompiler/flash/gui/QuickFindPanel.java | 2 +- .../flash/gui/abc/DecompiledEditorPane.java | 1088 ++++++++--------- .../jpexs/decompiler/flash/tags/TagStub.java | 2 +- 23 files changed, 953 insertions(+), 812 deletions(-) create mode 100644 src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index 4933516a3..778768942 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -1526,7 +1526,7 @@ public final class SWF implements TreeItem, Timelined { final Color fbackgroundColor=backgroundColor; final Iterator frameImages = new Iterator() { - private int pos=0; + private final int pos=0; @Override public boolean hasNext() { diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index 0ad7d27ec..de0850bc7 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -129,10 +129,10 @@ public class ActionScriptParser { private final boolean debugMode = false; private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin"; - private ABC abc; - private List otherABCs; + private final ABC abc; + private final List otherABCs; - private static List playerABCs = new ArrayList<>(); + private static final List playerABCs = new ArrayList<>(); private long uniqId() { uniqLast++; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/BreakJumpIns.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/BreakJumpIns.java index e62d9ca97..60619a4d0 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/BreakJumpIns.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/BreakJumpIns.java @@ -1,36 +1,36 @@ -/* - * Copyright (C) 2014 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 . - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; - -/** - * - * @author JPEXS - */ -public class BreakJumpIns extends JumpIns { - - private long loopId; - - public BreakJumpIns(long loopId) { - this.loopId = loopId; - } - - public long getLoopId() { - return loopId; - } -} +/* + * Copyright (C) 2014 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 . + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; + +/** + * + * @author JPEXS + */ +public class BreakJumpIns extends JumpIns { + + private final long loopId; + + public BreakJumpIns(long loopId) { + this.loopId = loopId; + } + + public long getLoopId() { + return loopId; + } +} diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java index 8575fe8a8..10d31eb7a 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java @@ -28,7 +28,7 @@ import com.jpexs.decompiler.graph.model.LocalData; public class ConstAVM2Item extends AVM2Item { private final int namespace; - private boolean isStatic; + private final boolean isStatic; public String var; public GraphTargetItem type; public String customNamespace; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ContinueJumpIns.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ContinueJumpIns.java index 4ded30d12..d38555821 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ContinueJumpIns.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ContinueJumpIns.java @@ -1,37 +1,37 @@ -/* - * Copyright (C) 2014 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 . - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; - -/** - * - * @author JPEXS - */ -public class ContinueJumpIns extends JumpIns { - - private long loopId; - - public ContinueJumpIns(long loopId) { - this.loopId = loopId; - } - - public long getLoopId() { - return loopId; - } - -} +/* + * Copyright (C) 2014 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 . + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; + +/** + * + * @author JPEXS + */ +public class ContinueJumpIns extends JumpIns { + + private final long loopId; + + public ContinueJumpIns(long loopId) { + this.loopId = loopId; + } + + public long getLoopId() { + return loopId; + } + +} diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FinallyJumpIns.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FinallyJumpIns.java index 656bf8599..06954388b 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FinallyJumpIns.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FinallyJumpIns.java @@ -1,36 +1,36 @@ -/* - * Copyright (C) 2014 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 . - */ -package com.jpexs.decompiler.flash.abc.avm2.parser.script; - -import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; - -/** - * - * @author JPEXS - */ -public class FinallyJumpIns extends JumpIns { - - private long finallyClauseId; - - public FinallyJumpIns(long finallyClauseId) { - this.finallyClauseId = finallyClauseId; - } - - public long getClauseId() { - return finallyClauseId; - } -} +/* + * Copyright (C) 2014 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 . + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; + +/** + * + * @author JPEXS + */ +public class FinallyJumpIns extends JumpIns { + + private final long finallyClauseId; + + public FinallyJumpIns(long finallyClauseId) { + this.finallyClauseId = finallyClauseId; + } + + public long getClauseId() { + return finallyClauseId; + } +} diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java index 503f00a3d..8116b6b35 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java @@ -52,7 +52,7 @@ import java.util.List; */ public class IndexAVM2Item extends AssignableAVM2Item { - private List openedNamespaces; + private final List openedNamespaces; public GraphTargetItem object; public GraphTargetItem index; public boolean attr; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java index e15eebd1b..d9429cbc8 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java @@ -27,9 +27,9 @@ import java.util.List; */ public class MethodAVM2Item extends FunctionAVM2Item { - private boolean isStatic; - private boolean isFinal; - private boolean override; + private final boolean isStatic; + private final boolean isFinal; + private final boolean override; public String customNamespace; public boolean isInterface; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java index aa3ca0ae4..14cbd0243 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java @@ -64,8 +64,8 @@ public class PropertyAVM2Item extends AssignableAVM2Item { public GraphTargetItem object; public ABC abc; public List otherABCs; - private List openedNamespaces; - private List callStack; + private final List openedNamespaces; + private final List callStack; public List scopeStack = new ArrayList(); @Override diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java index 73a8c2b69..2cab6b01e 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java @@ -28,7 +28,7 @@ import com.jpexs.decompiler.graph.model.LocalData; public class SlotAVM2Item extends AVM2Item { private final int namespace; - private boolean isStatic; + private final boolean isStatic; public String var; public GraphTargetItem type; public String customNamespace; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index 1c5aba921..9de173dc1 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -58,7 +58,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { //private GraphTargetItem ns = null; public GraphTargetItem resolved; public GraphTargetItem resolvedRoot; - private boolean mustBeType; + private final boolean mustBeType; public List importedClasses; public List scopeStack = new ArrayList(); public List subtypes; diff --git a/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java b/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java index 1ee93740d..b1a90a02e 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java +++ b/src/com/jpexs/decompiler/flash/action/parser/script/ActionScriptParser.java @@ -153,7 +153,7 @@ import java.util.List; */ public class ActionScriptParser { - private int swfVersion; + private final int swfVersion; public ActionScriptParser(int swfVersion) { this.swfVersion = swfVersion; diff --git a/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java b/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java index 48841d3ba..23cdc722c 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java +++ b/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java @@ -596,7 +596,7 @@ public class ActionSourceGenerator implements SourceGenerator { return ret; } private final List constantPool; - private int swfVersion; + private final int swfVersion; public int getSwfVersion() { return swfVersion; diff --git a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java index 0dfa9d507..81ad3ea80 100644 --- a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java @@ -56,7 +56,7 @@ import javax.swing.table.DefaultTableModel; */ public class AdvancedSettingsDialog extends AppDialog implements ActionListener { - private Map componentsMap = new HashMap<>(); + private final Map componentsMap = new HashMap<>(); /** * Creates new form AdvancedSettingsDialog diff --git a/src/com/jpexs/decompiler/flash/gui/DumpTree.java b/src/com/jpexs/decompiler/flash/gui/DumpTree.java index d30f0518b..bae0dfac0 100644 --- a/src/com/jpexs/decompiler/flash/gui/DumpTree.java +++ b/src/com/jpexs/decompiler/flash/gui/DumpTree.java @@ -24,6 +24,7 @@ import javax.swing.JTree; import javax.swing.plaf.basic.BasicLabelUI; import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeModel; /** * @@ -72,4 +73,17 @@ public class DumpTree extends JTree { }); } + @Override + public void setModel(TreeModel tm) { + super.setModel(tm); + if (tm != null) { + int rowCount = tm.getChildCount(tm.getRoot()); + for (int i = rowCount - 1; i >= 0; i--) { + expandRow(i); + } + } + } + + + } diff --git a/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java new file mode 100644 index 000000000..77585f7d1 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/DumpViewPanel.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2010-2014 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 . + */ +package com.jpexs.decompiler.flash.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +/** + * + * @author JPEXS + */ +public class DumpViewPanel extends JPanel { + + private final int bytesInRow = 16; + private final JLabel dumpViewLabel; + private final JTable dumpViewHexTable; + private byte[] data; + + public DumpViewPanel() { + super(new BorderLayout()); + + dumpViewLabel = new JLabel(); + dumpViewLabel.setMinimumSize(new Dimension(100, 20)); + add(dumpViewLabel, BorderLayout.SOUTH); + + dumpViewHexTable = new JTable(); + dumpViewHexTable.setBackground(Color.white); + dumpViewHexTable.setFont(new Font("Monospaced", Font.PLAIN, 12)); + dumpViewHexTable.setTableHeader(new JTableHeader()); + dumpViewHexTable.setMaximumSize(new Dimension(200, 200)); + TableColumnModel columnModel = dumpViewHexTable.getColumnModel(); + columnModel.addColumn(new TableColumn()); + columnModel.getColumn(0).setMinWidth(100); + for (int i = 0; i < bytesInRow; i++) { + columnModel.addColumn(new TableColumn()); + columnModel.getColumn(i + 1).setWidth(20); + } + for (int i = 0; i < bytesInRow; i++) { + columnModel.addColumn(new TableColumn()); + columnModel.getColumn(i + bytesInRow + 1).setWidth(10); + } + dumpViewHexTable.setShowHorizontalLines(false); + dumpViewHexTable.setModel(new AbstractTableModel() { + + @Override + public int getRowCount() { + if (data == null) { + return 0; + } + int byteCount = data.length; + int rowCount = byteCount / bytesInRow; + if (byteCount + bytesInRow != 0) { + rowCount++; + } + return rowCount; + } + + @Override + public int getColumnCount() { + return 2*bytesInRow + 1; + } + + @Override + public String getColumnName(int column) { + if (column == 0) { + return "Address"; + } else if (column <= bytesInRow) { + return String.format("%01X", column - 1); + } + return ""; + } + + @Override + public Object getValueAt(int row, int column) { + if (column == 0) { + return String.format("%08X", (long) row * bytesInRow); + } else if (column <= bytesInRow) { + int pos = row * bytesInRow + column - 1; + if (pos < data.length) { + return String.format("%02X", data[pos]); + } + return null; + } else { + int pos = row * bytesInRow + column - bytesInRow - 1; + if (pos < data.length) { + return (char)data[pos]; + } + return null; + } + } + }); + add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER); + } + + public void setData(byte[] data) { + this.data = data; + } + + public void setLabelText(String text) { + dumpViewLabel.setText(text); + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java b/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java index a5c9f6f7b..3591c139e 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java @@ -1,129 +1,129 @@ -/* - * Copyright (C) 2010-2014 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 . - */ -package com.jpexs.decompiler.flash.gui; - -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Window; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowStateListener; -import javax.swing.JFrame; - -/** - * - * @author JPEXS - */ -public final class MainFrameClassic extends AppFrame implements MainFrame { - - public MainPanel panel; - private MainFrameMenu mainMenu; - - public MainFrameClassic() { - super(); - - FlashPlayerPanel flashPanel = null; - try { - flashPanel = new FlashPlayerPanel(this); - } catch (FlashUnsupportedException fue) { - } - - boolean externalFlashPlayerUnavailable = flashPanel == null; - mainMenu = new MainFrameClassicMenu(this, externalFlashPlayerUnavailable); - - panel = new MainPanel(this, mainMenu, flashPanel); - - int w = Configuration.guiWindowWidth.get(); - int h = Configuration.guiWindowHeight.get(); - Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - if (w > dim.width) { - w = dim.width; - } - if (h > dim.height) { - h = dim.height; - } - setSize(w, h); - - boolean maximizedHorizontal = Configuration.guiWindowMaximizedHorizontal.get(); - boolean maximizedVertical = Configuration.guiWindowMaximizedVertical.get(); - - int state = 0; - if (maximizedHorizontal) { - state |= JFrame.MAXIMIZED_HORIZ; - } - if (maximizedVertical) { - state |= JFrame.MAXIMIZED_VERT; - } - setExtendedState(state); - - View.setWindowIcon(this); - addWindowStateListener(new WindowStateListener() { - @Override - public void windowStateChanged(WindowEvent e) { - int state = e.getNewState(); - Configuration.guiWindowMaximizedHorizontal.set((state & JFrame.MAXIMIZED_HORIZ) == JFrame.MAXIMIZED_HORIZ); - Configuration.guiWindowMaximizedVertical.set((state & JFrame.MAXIMIZED_VERT) == JFrame.MAXIMIZED_VERT); - } - }); - addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - int state = getExtendedState(); - if ((state & JFrame.MAXIMIZED_HORIZ) == 0) { - Configuration.guiWindowWidth.set(getWidth()); - } - if ((state & JFrame.MAXIMIZED_VERT) == 0) { - Configuration.guiWindowHeight.set(getHeight()); - } - } - }); - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - Main.exit(); - } - }); - - java.awt.Container cnt = getContentPane(); - cnt.setLayout(new BorderLayout()); - cnt.add(panel); - - View.centerScreen(this); - } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - panel.setVisible(b); - } - - @Override - public MainPanel getPanel() { - return panel; - } - - @Override - public Window getWindow() { - return this; - } - - -} +/* + * Copyright (C) 2010-2014 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 . + */ +package com.jpexs.decompiler.flash.gui; + +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; +import javax.swing.JFrame; + +/** + * + * @author JPEXS + */ +public final class MainFrameClassic extends AppFrame implements MainFrame { + + public MainPanel panel; + private final MainFrameMenu mainMenu; + + public MainFrameClassic() { + super(); + + FlashPlayerPanel flashPanel = null; + try { + flashPanel = new FlashPlayerPanel(this); + } catch (FlashUnsupportedException fue) { + } + + boolean externalFlashPlayerUnavailable = flashPanel == null; + mainMenu = new MainFrameClassicMenu(this, externalFlashPlayerUnavailable); + + panel = new MainPanel(this, mainMenu, flashPanel); + + int w = Configuration.guiWindowWidth.get(); + int h = Configuration.guiWindowHeight.get(); + Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + if (w > dim.width) { + w = dim.width; + } + if (h > dim.height) { + h = dim.height; + } + setSize(w, h); + + boolean maximizedHorizontal = Configuration.guiWindowMaximizedHorizontal.get(); + boolean maximizedVertical = Configuration.guiWindowMaximizedVertical.get(); + + int state = 0; + if (maximizedHorizontal) { + state |= JFrame.MAXIMIZED_HORIZ; + } + if (maximizedVertical) { + state |= JFrame.MAXIMIZED_VERT; + } + setExtendedState(state); + + View.setWindowIcon(this); + addWindowStateListener(new WindowStateListener() { + @Override + public void windowStateChanged(WindowEvent e) { + int state = e.getNewState(); + Configuration.guiWindowMaximizedHorizontal.set((state & JFrame.MAXIMIZED_HORIZ) == JFrame.MAXIMIZED_HORIZ); + Configuration.guiWindowMaximizedVertical.set((state & JFrame.MAXIMIZED_VERT) == JFrame.MAXIMIZED_VERT); + } + }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + int state = getExtendedState(); + if ((state & JFrame.MAXIMIZED_HORIZ) == 0) { + Configuration.guiWindowWidth.set(getWidth()); + } + if ((state & JFrame.MAXIMIZED_VERT) == 0) { + Configuration.guiWindowHeight.set(getHeight()); + } + } + }); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + Main.exit(); + } + }); + + java.awt.Container cnt = getContentPane(); + cnt.setLayout(new BorderLayout()); + cnt.add(panel); + + View.centerScreen(this); + } + + @Override + public void setVisible(boolean b) { + super.setVisible(b); + panel.setVisible(b); + } + + @Override + public MainPanel getPanel() { + return panel; + } + + @Override + public Window getWindow() { + return this; + } + + +} diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java index 84695aa67..100148b21 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java @@ -41,7 +41,7 @@ import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationM public final class MainFrameRibbon extends AppRibbonFrame implements MainFrame { public MainPanel panel; - private MainFrameMenu mainMenu; + private final MainFrameMenu mainMenu; public MainFrameRibbon() { super(); diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java index 6eb19f4df..232d36e50 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java @@ -619,7 +619,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { mainFrame.panel.reload(true); break; case ACTION_DUMP_VIEW_SWITCH: - Configuration.internalFlashViewer.set(miDumpView.isSelected()); + Configuration.dumpView.set(miDumpView.isSelected()); mainFrame.panel.showDumpView(miDumpView.isSelected()); break; case ACTION_SEARCH: diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index e28804183..6f4bad5fb 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -227,8 +227,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private final JPanel contentPanel; private final JPanel displayPanel; private JPanel folderPreviewPanel; - private JPanel dumpViewPanel; - private JLabel dumpViewLabel; // very very simple dump view, todo: hexview with virtual scrolling private boolean isWelcomeScreen = true; private static final String CARDPREVIEWPANEL = "Preview card"; private static final String CARDFOLDERPREVIEWPANEL = "Folder preview card"; @@ -246,8 +244,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private JPanel detailPanel; private JTextField filterField = new MyTextField(""); private JPanel searchPanel; - private PreviewPanel previewPanel; - private JPanel treePanel; + private final PreviewPanel previewPanel; + private DumpViewPanel dumpViewPanel; + private final JPanel treePanel; private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); private CancellableWorker setSourceWorker; public TreeNode oldNode; @@ -502,9 +501,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private JPanel createDumpPreviewCard() { JPanel dumpViewCard = new JPanel(new BorderLayout()); - dumpViewPanel = new JPanel(new WrapLayout(FlowLayout.LEFT)); - dumpViewLabel = new JLabel(); - dumpViewPanel.add(dumpViewLabel); + dumpViewPanel = new DumpViewPanel(); dumpViewCard.add(new JScrollPane(dumpViewPanel), BorderLayout.CENTER); return dumpViewCard; @@ -1761,7 +1758,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec File textsFolder = new File(Path.combine(folder, TextExporter.TEXT_EXPORT_FOLDER)); String[] files = textsFolder.list(new FilenameFilter() { - private Pattern pat = Pattern.compile("\\d+\\.txt", Pattern.CASE_INSENSITIVE); + private final Pattern pat = Pattern.compile("\\d+\\.txt", Pattern.CASE_INSENSITIVE); @Override public boolean accept(File dir, String name) { @@ -2385,15 +2382,19 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } private void dumpTreeValueChanged(TreeSelectionEvent e) { - showCard(CARDDUMPVIEW); DumpInfo dumpInfo = (DumpInfo) e.getPath().getLastPathComponent(); if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) { // todo - dumpViewLabel.setText("startByte: " + dumpInfo.startByte + + dumpViewPanel.setLabelText("startByte: " + dumpInfo.startByte + " startBit: " + dumpInfo.startBit + " lengthBytes: " + dumpInfo.lengthBytes + " lengthBits: " + dumpInfo.lengthBits); } + + // todo honfika: support multiple swf + dumpViewPanel.setData(swfs.get(0).swfs.get(0).uncompressedData); + dumpViewPanel.revalidate(); + showCard(CARDDUMPVIEW); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/QuickFindPanel.java b/src/com/jpexs/decompiler/flash/gui/QuickFindPanel.java index 288b8b197..58a027e31 100644 --- a/src/com/jpexs/decompiler/flash/gui/QuickFindPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/QuickFindPanel.java @@ -51,7 +51,7 @@ public class QuickFindPanel extends JPanel implements ActionListener, jsyntaxpan public JCheckBox ignoreCaseCheckbox,regExpCheckbox,wrapCheckbox; public JLabel statusLabel; - private Markers.SimpleMarker marker = new Markers.SimpleMarker(Color.PINK); + private final Markers.SimpleMarker marker = new Markers.SimpleMarker(Color.PINK); private WeakReference target; private WeakReference dsd; private int oldCaretPosition; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 032aabe0e..6125b1674 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -1,544 +1,544 @@ -/* - * Copyright (C) 2010-2014 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 . - */ -package com.jpexs.decompiler.flash.gui.abc; - -import com.jpexs.decompiler.flash.AppStrings; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.gui.View; -import com.jpexs.decompiler.flash.helpers.HilightedText; -import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; -import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.helpers.Cache; -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import javax.swing.SwingUtilities; -import javax.swing.event.CaretEvent; -import javax.swing.event.CaretListener; - -public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretListener { - - private List highlights = new ArrayList<>(); - private List specialHighlights = new ArrayList<>(); - private List traitHighlights = new ArrayList<>(); - private List methodHighlights = new ArrayList<>(); - private List classHighlights = new ArrayList<>(); - private Highlighting currentMethodHighlight; - private Highlighting currentTraitHighlight; - private ABC abc; - private ScriptPack script; - public int lastTraitIndex = 0; - public boolean ignoreCarret = false; - private boolean reset = false; - private final ABCPanel abcPanel; - private int classIndex = -1; - private boolean isStatic = false; - private final Cache cache = Cache.getInstance(true); - private Trait currentTrait = null; - - private List scriptListeners = new ArrayList(); - - public void addScriptListener(Runnable l){ - scriptListeners.add(l); - } - - public ABCPanel getAbcPanel() { - return abcPanel; - } - - - - public void removeScriptListener(Runnable l){ - scriptListeners.remove(l); - } - - public void fireScript(){ - for(int i=0;i allh = new ArrayList<>(); - for (Highlighting h : traitHighlights) { - if (h.getPropertyString("index").equals("" + lastTraitIndex)) { - for (Highlighting sh : specialHighlights) { - if (sh.startPos >= h.startPos && (sh.startPos + sh.len < h.startPos + h.len)) { - allh.add(sh); - } - } - } - } - if (currentMethodHighlight != null) { - for (Highlighting h : specialHighlights) { - if (h.startPos >= startPos && (h.startPos + h.len < endPos)) { - allh.add(h); - } - } - } - for (Highlighting h : allh) { - if (h.getPropertyString("subtype").equals(type) && ((long) h.getPropertyLong("index") == index)) { - ignoreCarret = true; - if (h.startPos <= getDocument().getLength()) { - setCaretPosition(h.startPos); - } - getCaret().setVisible(true); - ignoreCarret = false; - break; - } - } - } - - public void hilightOffset(long offset) { - if (currentMethodHighlight == null) { - return; - } - List allh = new ArrayList<>(); - for (Highlighting h : traitHighlights) { - if (h.getPropertyString("index").equals("" + lastTraitIndex)) { - Highlighting h2 = Highlighting.search(highlights, "offset", "" + offset, h.startPos, h.startPos + h.len); - if (h2 != null) { - ignoreCarret = true; - if (h2.startPos <= getDocument().getLength()) { - setCaretPosition(h2.startPos); - } - getCaret().setVisible(true); - ignoreCarret = false; - } - - } - } - } - - public synchronized void setClassIndex(int classIndex) { - this.classIndex = classIndex; - } - - private boolean displayMethod(int pos, int methodIndex, String name, Trait trait, boolean isStatic) { - if (abc == null) { - return false; - } - int bi = abc.findBodyIndex(methodIndex); - if (bi == -1) { - return false; - } - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - } - }); - //fix for inner functions: - if (trait instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait; - if (tm.method_info != methodIndex) { - trait = null; - } - } - if (trait instanceof TraitFunction) { - TraitFunction tf = (TraitFunction) trait; - if (tf.method_info != methodIndex) { - trait = null; - } - } - abcPanel.detailPanel.showCard(DetailPanel.METHOD_TRAIT_CARD, trait); - if (reset || (abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex() != bi)) { - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name, trait); - abcPanel.detailPanel.setEditMode(false); - this.isStatic = isStatic; - } - boolean success = false; - Highlighting h = Highlighting.search(highlights, pos); - if (h != null) { - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighOffset(h.getPropertyLong("offset")); - success = true; - } - Highlighting sh = Highlighting.search(specialHighlights, pos); - if (sh != null) { - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighSpecial(sh.getPropertyString("subtype"), (int) (long) sh.getPropertyLong("index")); - success = true; - } - return success; - } - - public void displayClass(int classIndex, int scriptIndex) { - if (abcPanel.navigator.getClassIndex() != classIndex) { - abcPanel.navigator.setClassIndex(classIndex, scriptIndex); - } - } - - public void resetEditing() { - reset = true; - caretUpdate(null); - reset = false; - } - - public int getMultinameUnderCursor() { - int pos = getCaretPosition(); - Highlighting h = Highlighting.search(highlights, pos); - if (h != null) { - List list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).code.code; - AVM2Instruction lastIns = null; - long inspos = 0; - AVM2Instruction selIns = null; - for (AVM2Instruction ins : list) { - if (h.getPropertyLong("offset") == ins.getOffset()) { - selIns = ins; - break; - } - if (ins.getOffset() > h.getPropertyLong("offset")) { - inspos = h.getPropertyLong("offset") - lastIns.offset; - selIns = lastIns; - break; - } - lastIns = ins; - } - if (selIns != null) { - for (int i = 0; i < selIns.definition.operands.length; i++) { - if (selIns.definition.operands[i] == AVM2Code.DAT_MULTINAME_INDEX) { - return selIns.operands[i]; - } - } - } - } - int currentMethod = -1; - if (currentTrait instanceof TraitMethodGetterSetter) { - currentMethod = ((TraitMethodGetterSetter) currentTrait).method_info; - } - if (currentMethodHighlight != null) { - currentMethod = (int) (long) currentMethodHighlight.getPropertyLong("index"); - } - Highlighting sh = Highlighting.search(specialHighlights, pos); - if (sh != null) { - switch (sh.getPropertyString("subtype")) { - case "traittypename": - if (currentTrait instanceof TraitSlotConst) { - TraitSlotConst ts = (TraitSlotConst) currentTrait; - return ts.type_index; - } - break; - case "traitname": - if (currentTrait != null) { - return currentTrait.name_index; - } - break; - case "returns": - if (currentMethod > -1) { - return abc.method_info.get(currentMethod).ret_type; - } - break; - case "param": - if (currentMethod > -1) { - return abc.method_info.get(currentMethod).param_types[(int) (long) sh.getPropertyLong("index")]; - } - break; - } - } - return -1; - } - - @Override - public void caretUpdate(final CaretEvent e) { - if (!SwingUtilities.isEventDispatchThread()) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - caretUpdate(e); - } - }); - return; - } - if (abc == null) { - return; - } - if (ignoreCarret) { - return; - } - - getCaret().setVisible(true); - int pos = getCaretPosition(); - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(true); - try { - classIndex = -1; - Highlighting cm = Highlighting.search(classHighlights, pos); - if (cm != null) { - classIndex = (int) (long) cm.getPropertyLong("index"); - displayClass(classIndex, script.scriptIndex); - } - Highlighting tm = Highlighting.search(methodHighlights, pos); - if (tm != null) { - String name = ""; - if (abc != null) { - if (classIndex > -1) { - name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants); - } - } - currentTrait = null; - currentTraitHighlight = Highlighting.search(traitHighlights, pos); - if (currentTraitHighlight != null) { - lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index"); - if ((abc != null) && (classIndex != -1)) { - currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex); - isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex); - if (currentTrait != null) { - name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList()); - } - } - } - - displayMethod(pos, (int) (long) tm.getPropertyLong("index"), name, currentTrait, isStatic); - currentMethodHighlight = tm; - return; - } - - if (classIndex == -1) { - setNoTrait(); - return; - } - currentTrait = null; - currentTraitHighlight = Highlighting.search(traitHighlights, pos); - if (currentTraitHighlight != null) { - lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index"); - currentTrait = abc.findTraitByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index")); - if (currentTrait != null) { - if (currentTrait instanceof TraitSlotConst) { - abcPanel.detailPanel.slotConstTraitPanel.load((TraitSlotConst) currentTrait, abc, - abc.isStaticTraitId(classIndex, lastTraitIndex)); - abcPanel.detailPanel.showCard(DetailPanel.SLOT_CONST_TRAIT_CARD, currentTrait); - abcPanel.detailPanel.setEditMode(false); - currentMethodHighlight = null; - Highlighting spec = Highlighting.search(specialHighlights, pos, null, null, currentTraitHighlight.startPos, currentTraitHighlight.startPos + currentTraitHighlight.len); - if (spec != null) { - abcPanel.detailPanel.slotConstTraitPanel.hilightSpecial(spec); - } - - return; - } - } - currentMethodHighlight = null; - String name = ""; - currentTrait = null; - if (abc != null) { - name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants); - currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex); - isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex); - if (currentTrait != null) { - name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList()); - } - } - - displayMethod(pos, abc.findMethodIdByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index")), name, currentTrait, isStatic); - return; - } - setNoTrait(); - } finally { - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(false); - } - } - - private void uncache(ScriptPack pack) { - cache.remove(pack); - } - - public boolean isCached(ScriptPack pack) { - return cache.contains(pack); - } - - private CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { - if (!cache.contains(pack)) { - cacheScriptPack(pack, abcList); - } - return (CachedDecompilation) cache.get(pack); - } - - public String getCachedText(ScriptPack pack) throws InterruptedException { - return getCached(pack).text; - } - - public void gotoLastTrait() { - gotoTrait(lastTraitIndex); - } - - public void gotoTrait(int traitId) { - if (traitId == -1) { - setCaretPosition(0); - return; - } - - Highlighting tc = Highlighting.search(classHighlights, "index", "" + classIndex); - if (tc != null) { - Highlighting th = Highlighting.search(traitHighlights, "index", "" + traitId, tc.startPos, tc.startPos + tc.len); - if (th != null) { - ignoreCarret = true; - int startPos = th.startPos + th.len - 1; - if (startPos <= getDocument().getLength()) { - setCaretPosition(startPos); - } - ignoreCarret = false; - final int pos = th.startPos; - new Timer().schedule(new TimerTask() { - @Override - public void run() { - if (pos <= getDocument().getLength()) { - setCaretPosition(pos); - } - } - }, 100); - return; - } - } - - setCaretPosition(0); - } - - public DecompiledEditorPane(ABCPanel abcPanel) { - super(); - setEditable(false); - getCaret().setVisible(true); - addCaretListener(this); - this.abcPanel = abcPanel; - } - private List abcList; - - public void clearScriptCache() { - cache.clear(); - } - - public void cacheScriptPack(ScriptPack scriptLeaf, List abcList) throws InterruptedException { - int maxCacheSize = 50; - int scriptIndex = scriptLeaf.scriptIndex; - HilightedText hilightedCode = null; - ScriptInfo script = null; - ABC abc = scriptLeaf.abc; - if (scriptIndex > -1) { - script = abc.script_info.get(scriptIndex); - } - if (!cache.contains(scriptLeaf)) { - boolean parallel = Configuration.parallelSpeedUp.get(); - HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true); - scriptLeaf.toSource(writer, abcList, script.traits.traits, ScriptExportMode.AS, parallel); - hilightedCode = new HilightedText(writer); - cache.put(scriptLeaf, new CachedDecompilation(hilightedCode)); - } - } - - public void setScript(ScriptPack scriptLeaf, List abcList) { - abcPanel.scriptNameLabel.setText(scriptLeaf.getPath().toString()); - int scriptIndex = scriptLeaf.scriptIndex; - ScriptInfo script = null; - ABC abc = scriptLeaf.abc; - if (scriptIndex > -1) { - script = abc.script_info.get(scriptIndex); - } - if (script == null) { - highlights = new ArrayList<>(); - specialHighlights = new ArrayList<>(); - traitHighlights = new ArrayList<>(); - methodHighlights = new ArrayList<>(); - this.script = scriptLeaf; - return; - } - setText("//" + AppStrings.translate("pleasewait") + "..."); - - this.abc = abc; - this.abcList = abcList; - this.script = scriptLeaf; - CachedDecompilation cd = null; - try { - cacheScriptPack(scriptLeaf, abcList); - cd = getCached(scriptLeaf); - } catch (InterruptedException ex) { - } - if (cd != null) { - final String hilightedCode = cd.text; - highlights = cd.getInstructionHighlights(); - specialHighlights = cd.getSpecialHighligths(); - traitHighlights = cd.getTraitHighlights(); - methodHighlights = cd.getMethodHighlights(); - classHighlights = cd.getClassHighlights(); - setContentType("text/actionscript"); - setText(hilightedCode); - } - fireScript(); - } - - public void reloadClass() { - int ci = classIndex; - uncache(script); - if ((script != null) && (abc != null)) { - setScript(script, abcList); - } - setNoTrait(); - setClassIndex(ci); - } - - public int getClassIndex() { - return classIndex; - } - - public void setABC(ABC abc) { - this.abc = abc; - cache.clear(); - setText(""); - } - - @Override - public void setText(String t) { - super.setText(t); - setCaretPosition(0); - } -} +/* + * Copyright (C) 2010-2014 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 . + */ +package com.jpexs.decompiler.flash.gui.abc; + +import com.jpexs.decompiler.flash.AppStrings; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.gui.View; +import com.jpexs.decompiler.flash.helpers.HilightedText; +import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; +import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.helpers.Cache; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import javax.swing.SwingUtilities; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; + +public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretListener { + + private List highlights = new ArrayList<>(); + private List specialHighlights = new ArrayList<>(); + private List traitHighlights = new ArrayList<>(); + private List methodHighlights = new ArrayList<>(); + private List classHighlights = new ArrayList<>(); + private Highlighting currentMethodHighlight; + private Highlighting currentTraitHighlight; + private ABC abc; + private ScriptPack script; + public int lastTraitIndex = 0; + public boolean ignoreCarret = false; + private boolean reset = false; + private final ABCPanel abcPanel; + private int classIndex = -1; + private boolean isStatic = false; + private final Cache cache = Cache.getInstance(true); + private Trait currentTrait = null; + + private final List scriptListeners = new ArrayList(); + + public void addScriptListener(Runnable l){ + scriptListeners.add(l); + } + + public ABCPanel getAbcPanel() { + return abcPanel; + } + + + + public void removeScriptListener(Runnable l){ + scriptListeners.remove(l); + } + + public void fireScript(){ + for(int i=0;i allh = new ArrayList<>(); + for (Highlighting h : traitHighlights) { + if (h.getPropertyString("index").equals("" + lastTraitIndex)) { + for (Highlighting sh : specialHighlights) { + if (sh.startPos >= h.startPos && (sh.startPos + sh.len < h.startPos + h.len)) { + allh.add(sh); + } + } + } + } + if (currentMethodHighlight != null) { + for (Highlighting h : specialHighlights) { + if (h.startPos >= startPos && (h.startPos + h.len < endPos)) { + allh.add(h); + } + } + } + for (Highlighting h : allh) { + if (h.getPropertyString("subtype").equals(type) && ((long) h.getPropertyLong("index") == index)) { + ignoreCarret = true; + if (h.startPos <= getDocument().getLength()) { + setCaretPosition(h.startPos); + } + getCaret().setVisible(true); + ignoreCarret = false; + break; + } + } + } + + public void hilightOffset(long offset) { + if (currentMethodHighlight == null) { + return; + } + List allh = new ArrayList<>(); + for (Highlighting h : traitHighlights) { + if (h.getPropertyString("index").equals("" + lastTraitIndex)) { + Highlighting h2 = Highlighting.search(highlights, "offset", "" + offset, h.startPos, h.startPos + h.len); + if (h2 != null) { + ignoreCarret = true; + if (h2.startPos <= getDocument().getLength()) { + setCaretPosition(h2.startPos); + } + getCaret().setVisible(true); + ignoreCarret = false; + } + + } + } + } + + public synchronized void setClassIndex(int classIndex) { + this.classIndex = classIndex; + } + + private boolean displayMethod(int pos, int methodIndex, String name, Trait trait, boolean isStatic) { + if (abc == null) { + return false; + } + int bi = abc.findBodyIndex(methodIndex); + if (bi == -1) { + return false; + } + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + } + }); + //fix for inner functions: + if (trait instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait; + if (tm.method_info != methodIndex) { + trait = null; + } + } + if (trait instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) trait; + if (tf.method_info != methodIndex) { + trait = null; + } + } + abcPanel.detailPanel.showCard(DetailPanel.METHOD_TRAIT_CARD, trait); + if (reset || (abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex() != bi)) { + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name, trait); + abcPanel.detailPanel.setEditMode(false); + this.isStatic = isStatic; + } + boolean success = false; + Highlighting h = Highlighting.search(highlights, pos); + if (h != null) { + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighOffset(h.getPropertyLong("offset")); + success = true; + } + Highlighting sh = Highlighting.search(specialHighlights, pos); + if (sh != null) { + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighSpecial(sh.getPropertyString("subtype"), (int) (long) sh.getPropertyLong("index")); + success = true; + } + return success; + } + + public void displayClass(int classIndex, int scriptIndex) { + if (abcPanel.navigator.getClassIndex() != classIndex) { + abcPanel.navigator.setClassIndex(classIndex, scriptIndex); + } + } + + public void resetEditing() { + reset = true; + caretUpdate(null); + reset = false; + } + + public int getMultinameUnderCursor() { + int pos = getCaretPosition(); + Highlighting h = Highlighting.search(highlights, pos); + if (h != null) { + List list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).code.code; + AVM2Instruction lastIns = null; + long inspos = 0; + AVM2Instruction selIns = null; + for (AVM2Instruction ins : list) { + if (h.getPropertyLong("offset") == ins.getOffset()) { + selIns = ins; + break; + } + if (ins.getOffset() > h.getPropertyLong("offset")) { + inspos = h.getPropertyLong("offset") - lastIns.offset; + selIns = lastIns; + break; + } + lastIns = ins; + } + if (selIns != null) { + for (int i = 0; i < selIns.definition.operands.length; i++) { + if (selIns.definition.operands[i] == AVM2Code.DAT_MULTINAME_INDEX) { + return selIns.operands[i]; + } + } + } + } + int currentMethod = -1; + if (currentTrait instanceof TraitMethodGetterSetter) { + currentMethod = ((TraitMethodGetterSetter) currentTrait).method_info; + } + if (currentMethodHighlight != null) { + currentMethod = (int) (long) currentMethodHighlight.getPropertyLong("index"); + } + Highlighting sh = Highlighting.search(specialHighlights, pos); + if (sh != null) { + switch (sh.getPropertyString("subtype")) { + case "traittypename": + if (currentTrait instanceof TraitSlotConst) { + TraitSlotConst ts = (TraitSlotConst) currentTrait; + return ts.type_index; + } + break; + case "traitname": + if (currentTrait != null) { + return currentTrait.name_index; + } + break; + case "returns": + if (currentMethod > -1) { + return abc.method_info.get(currentMethod).ret_type; + } + break; + case "param": + if (currentMethod > -1) { + return abc.method_info.get(currentMethod).param_types[(int) (long) sh.getPropertyLong("index")]; + } + break; + } + } + return -1; + } + + @Override + public void caretUpdate(final CaretEvent e) { + if (!SwingUtilities.isEventDispatchThread()) { + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + caretUpdate(e); + } + }); + return; + } + if (abc == null) { + return; + } + if (ignoreCarret) { + return; + } + + getCaret().setVisible(true); + int pos = getCaretPosition(); + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(true); + try { + classIndex = -1; + Highlighting cm = Highlighting.search(classHighlights, pos); + if (cm != null) { + classIndex = (int) (long) cm.getPropertyLong("index"); + displayClass(classIndex, script.scriptIndex); + } + Highlighting tm = Highlighting.search(methodHighlights, pos); + if (tm != null) { + String name = ""; + if (abc != null) { + if (classIndex > -1) { + name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants); + } + } + currentTrait = null; + currentTraitHighlight = Highlighting.search(traitHighlights, pos); + if (currentTraitHighlight != null) { + lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index"); + if ((abc != null) && (classIndex != -1)) { + currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex); + isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex); + if (currentTrait != null) { + name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList()); + } + } + } + + displayMethod(pos, (int) (long) tm.getPropertyLong("index"), name, currentTrait, isStatic); + currentMethodHighlight = tm; + return; + } + + if (classIndex == -1) { + setNoTrait(); + return; + } + currentTrait = null; + currentTraitHighlight = Highlighting.search(traitHighlights, pos); + if (currentTraitHighlight != null) { + lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index"); + currentTrait = abc.findTraitByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index")); + if (currentTrait != null) { + if (currentTrait instanceof TraitSlotConst) { + abcPanel.detailPanel.slotConstTraitPanel.load((TraitSlotConst) currentTrait, abc, + abc.isStaticTraitId(classIndex, lastTraitIndex)); + abcPanel.detailPanel.showCard(DetailPanel.SLOT_CONST_TRAIT_CARD, currentTrait); + abcPanel.detailPanel.setEditMode(false); + currentMethodHighlight = null; + Highlighting spec = Highlighting.search(specialHighlights, pos, null, null, currentTraitHighlight.startPos, currentTraitHighlight.startPos + currentTraitHighlight.len); + if (spec != null) { + abcPanel.detailPanel.slotConstTraitPanel.hilightSpecial(spec); + } + + return; + } + } + currentMethodHighlight = null; + String name = ""; + currentTrait = null; + if (abc != null) { + name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants); + currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex); + isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex); + if (currentTrait != null) { + name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList()); + } + } + + displayMethod(pos, abc.findMethodIdByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index")), name, currentTrait, isStatic); + return; + } + setNoTrait(); + } finally { + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(false); + } + } + + private void uncache(ScriptPack pack) { + cache.remove(pack); + } + + public boolean isCached(ScriptPack pack) { + return cache.contains(pack); + } + + private CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { + if (!cache.contains(pack)) { + cacheScriptPack(pack, abcList); + } + return (CachedDecompilation) cache.get(pack); + } + + public String getCachedText(ScriptPack pack) throws InterruptedException { + return getCached(pack).text; + } + + public void gotoLastTrait() { + gotoTrait(lastTraitIndex); + } + + public void gotoTrait(int traitId) { + if (traitId == -1) { + setCaretPosition(0); + return; + } + + Highlighting tc = Highlighting.search(classHighlights, "index", "" + classIndex); + if (tc != null) { + Highlighting th = Highlighting.search(traitHighlights, "index", "" + traitId, tc.startPos, tc.startPos + tc.len); + if (th != null) { + ignoreCarret = true; + int startPos = th.startPos + th.len - 1; + if (startPos <= getDocument().getLength()) { + setCaretPosition(startPos); + } + ignoreCarret = false; + final int pos = th.startPos; + new Timer().schedule(new TimerTask() { + @Override + public void run() { + if (pos <= getDocument().getLength()) { + setCaretPosition(pos); + } + } + }, 100); + return; + } + } + + setCaretPosition(0); + } + + public DecompiledEditorPane(ABCPanel abcPanel) { + super(); + setEditable(false); + getCaret().setVisible(true); + addCaretListener(this); + this.abcPanel = abcPanel; + } + private List abcList; + + public void clearScriptCache() { + cache.clear(); + } + + public void cacheScriptPack(ScriptPack scriptLeaf, List abcList) throws InterruptedException { + int maxCacheSize = 50; + int scriptIndex = scriptLeaf.scriptIndex; + HilightedText hilightedCode = null; + ScriptInfo script = null; + ABC abc = scriptLeaf.abc; + if (scriptIndex > -1) { + script = abc.script_info.get(scriptIndex); + } + if (!cache.contains(scriptLeaf)) { + boolean parallel = Configuration.parallelSpeedUp.get(); + HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true); + scriptLeaf.toSource(writer, abcList, script.traits.traits, ScriptExportMode.AS, parallel); + hilightedCode = new HilightedText(writer); + cache.put(scriptLeaf, new CachedDecompilation(hilightedCode)); + } + } + + public void setScript(ScriptPack scriptLeaf, List abcList) { + abcPanel.scriptNameLabel.setText(scriptLeaf.getPath().toString()); + int scriptIndex = scriptLeaf.scriptIndex; + ScriptInfo script = null; + ABC abc = scriptLeaf.abc; + if (scriptIndex > -1) { + script = abc.script_info.get(scriptIndex); + } + if (script == null) { + highlights = new ArrayList<>(); + specialHighlights = new ArrayList<>(); + traitHighlights = new ArrayList<>(); + methodHighlights = new ArrayList<>(); + this.script = scriptLeaf; + return; + } + setText("//" + AppStrings.translate("pleasewait") + "..."); + + this.abc = abc; + this.abcList = abcList; + this.script = scriptLeaf; + CachedDecompilation cd = null; + try { + cacheScriptPack(scriptLeaf, abcList); + cd = getCached(scriptLeaf); + } catch (InterruptedException ex) { + } + if (cd != null) { + final String hilightedCode = cd.text; + highlights = cd.getInstructionHighlights(); + specialHighlights = cd.getSpecialHighligths(); + traitHighlights = cd.getTraitHighlights(); + methodHighlights = cd.getMethodHighlights(); + classHighlights = cd.getClassHighlights(); + setContentType("text/actionscript"); + setText(hilightedCode); + } + fireScript(); + } + + public void reloadClass() { + int ci = classIndex; + uncache(script); + if ((script != null) && (abc != null)) { + setScript(script, abcList); + } + setNoTrait(); + setClassIndex(ci); + } + + public int getClassIndex() { + return classIndex; + } + + public void setABC(ABC abc) { + this.abc = abc; + cache.clear(); + setText(""); + } + + @Override + public void setText(String t) { + super.setText(t); + setCaretPosition(0); + } +} diff --git a/src/com/jpexs/decompiler/flash/tags/TagStub.java b/src/com/jpexs/decompiler/flash/tags/TagStub.java index adbd54b68..a56051260 100644 --- a/src/com/jpexs/decompiler/flash/tags/TagStub.java +++ b/src/com/jpexs/decompiler/flash/tags/TagStub.java @@ -26,7 +26,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; */ public class TagStub extends Tag { - private SWFInputStream dataStream; + private final SWFInputStream dataStream; /** * Constructor