diff --git a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java
index 2c223c83d..d36a02279 100644
--- a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java
@@ -1,508 +1,508 @@
-/*
- * Copyright (C) 2010-2016 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.debugger.flash.Variable;
-import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
-import com.jpexs.debugger.flash.messages.in.InConstantPool;
-import com.jpexs.debugger.flash.messages.in.InFrame;
-import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
-import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
-import de.hameister.treetable.MyTreeTable;
-import de.hameister.treetable.MyTreeTableModel;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.JButton;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTabbedPane;
-import javax.swing.JTable;
-import javax.swing.JTextArea;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
-import javax.swing.table.DefaultTableModel;
-import javax.swing.tree.TreePath;
-
-/**
- *
- * @author JPEXS
- */
-public class DebugPanel extends JPanel {
-
- private MyTreeTable debugRegistersTable;
-
- private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
-
- private MyTreeTable debugScopeTable;
-
- private JTable callStackTable;
-
- private JTable stackTable;
-
- private JTable constantPoolTable;
-
- private JTabbedPane varTabs;
-
- private BreakListener listener;
-
- private JTextArea traceLogTextarea;
-
- private int logLength = 0;
-
- private List tabTypes = new ArrayList<>();
-
- private boolean loading = false;
-
- public static enum SelectedTab {
-
- LOG, STACK, SCOPECHAIN, LOCALS, REGISTERS, CALLSTACK, CONSTANTPOOL
- }
-
- public synchronized boolean isLoading() {
- return loading;
- }
-
- public synchronized void setLoading(boolean loading) {
- this.loading = loading;
- }
-
- private SelectedTab selectedTab = null;
-
- private void safeSetTreeModel(MyTreeTable tt, MyTreeTableModel tmodel) {
- List> expanded = View.getExpandedNodes(tt.getTree());
-
- int[] selRows = tt.getSelectedRows();
-
- TreePath[] selPaths = new TreePath[selRows.length];
- for (int i = 0; i < selRows.length; i++) {
- selPaths[i] = tt.getTree().getPathForRow(selRows[i]);
- }
- tt.setTreeModel(tmodel);
- //tt.getTree().setRootVisible(false);
-
- View.expandTreeNodes(tt.getTree(), expanded);
- for (int i = 0; i < selRows.length; i++) {
- selRows[i] = tt.getTree().getRowForPath(selPaths[i]);
- if (i == 0) {
- tt.setRowSelectionInterval(selRows[i], selRows[i]);
- } else {
- tt.addRowSelectionInterval(selRows[i], selRows[i]);
- }
- }
-
- }
-
- public DebugPanel() {
- super(new BorderLayout());
- debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()), false);
- debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()), false);
-
- //Add watch feature, commented out. I tried it, but without success. I can't add watch in Flash Pro or FDB either. :-(
- /*
- //locales
- debug.watch.add = Add watch to %name%
- debug.watch.add.read = Read
- debug.watch.add.write = Write
- debug.watch.add.readwrite = Read+Write
-
- error.debug.watch.add = Cannot add watch to this variable.
-
-
- MouseAdapter watchHandler = new MouseAdapter() {
-
- @Override
- public void mousePressed(MouseEvent e) {
- if (e.isPopupTrigger()) {
- dopop(e);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- if (e.isPopupTrigger()) {
- dopop(e);
- }
- }
-
- private void dopop(MouseEvent e) {
- if (debugLocalsTable.getSelectedRow() == -1) {
- return;
- }
- Variable v = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVars().get(debugLocalsTable.getSelectedRow());
- final long v_id = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVarIds().get(debugLocalsTable.getSelectedRow());
-
- JPopupMenu pm = new JPopupMenu();
- JMenu addWatchMenu = new JMenu(AppStrings.translate("debug.watch.add").replace("%name%", v.name));
- JMenuItem watchReadMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.read"));
- watchReadMenuItem.addActionListener((ActionEvent e1) -> {
- if (!Main.addWatch(v, v_id, true, false)) {
- View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- }
- });
- JMenuItem watchWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.write"));
- watchWriteMenuItem.addActionListener((ActionEvent e1) -> {
- if (!Main.addWatch(v, v_id, false, true)) {
- View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- }
- });
- JMenuItem watchReadWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.readwrite"));
- watchReadWriteMenuItem.addActionListener((ActionEvent e1) -> {
- if (!Main.addWatch(v, v_id, true, true)) {
- View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- }
- });
-
- addWatchMenu.add(watchReadMenuItem);
- addWatchMenu.add(watchWriteMenuItem);
- addWatchMenu.add(watchReadWriteMenuItem);
- pm.add(addWatchMenu);
-
- pm.show(e.getComponent(), e.getX(), e.getY());
- }
- };
-
- debugLocalsTable.addMouseListener(watchHandler);
- debugScopeTable.addMouseListener(watchHandler);
-
- */
- debugScopeTable = new 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);
- traceLogTextarea.setOpaque(false);
- traceLogTextarea.setFont(new JLabel().getFont());
- traceLogTextarea.setBackground(Color.white);
-
- Main.getDebugHandler().addTraceListener(new DebuggerHandler.TraceListener() {
-
- @Override
- public void trace(String... val) {
- for (String s : val) {
- String add = "trace: " + s + "\r\n";
- boolean wasEmpty = logLength == 0;
- logLength += add.length();
- traceLogTextarea.append(add);
- try {
- traceLogTextarea.setCaretPosition(logLength);
- } catch (IllegalArgumentException iex) {
- //ignore
- }
- if (wasEmpty) {
- refresh();
- }
- }
- }
- });
-
- Main.getDebugHandler().addConnectionListener(new DebuggerHandler.ConnectionListener() {
-
- @Override
- public void connected() {
- }
-
- @Override
- public void disconnected() {
- refresh();
- }
- });
-
- Main.getDebugHandler().addBreakListener(listener = 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();
- }
- });
-
- }
- });
-
- varTabs = new JTabbedPane();
- varTabs.addChangeListener(new ChangeListener() {
-
- @Override
- public void stateChanged(ChangeEvent e) {
- if (e.getSource() == varTabs) {
- if (isLoading()) {
- return;
- }
- synchronized (DebugPanel.this) {
- int si = varTabs.getSelectedIndex();
- if (si > -1 && si < tabTypes.size()) {
- selectedTab = tabTypes.get(si);
- }
- }
- }
- }
- });
-
- add(new HeaderLabel(AppStrings.translate("debugpanel.header")), BorderLayout.NORTH);
- add(varTabs, BorderLayout.CENTER);
- }
-
- public void refresh() {
-
- View.execInEventDispatch(new Runnable() {
-
- @Override
- public void run() {
- setLoading(true);
- synchronized (DebugPanel.this) {
-
- SelectedTab oldSel = selectedTab;
- InFrame f = Main.getDebugHandler().getFrame();
- if (f != null) {
-
- List regVarIds = new ArrayList<>();
- for (int i = 0; i < f.registers.size(); i++) {
- regVarIds.add(0L);
- }
- safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers, regVarIds));
- List locals = new ArrayList<>();
- locals.addAll(f.arguments);
- locals.addAll(f.variables);
-
- List localIds = new ArrayList<>();
- localIds.addAll(f.argumentFrameIds);
- localIds.addAll(f.frameIds);
-
- safeSetTreeModel(debugLocalsTable, new ABCPanel.VariablesTableModel(debugLocalsTable, locals, localIds));
- safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain, f.scopeChainFrameIds));
-
- /*TableModelListener refreshListener = new TableModelListener() {
- @Override
- public void tableChanged(TableModelEvent e) {
- Main.getDebugHandler().refreshFrame();
- refresh();
- }
- };*/
- TreeModelListener refreshListener = new TreeModelListener() {
- @Override
- public void treeNodesChanged(TreeModelEvent e) {
- Main.getDebugHandler().refreshFrame();
- refresh();
- }
-
- @Override
- public void treeNodesInserted(TreeModelEvent e) {
- Main.getDebugHandler().refreshFrame();
- refresh();
- }
-
- @Override
- public void treeNodesRemoved(TreeModelEvent e) {
- Main.getDebugHandler().refreshFrame();
- refresh();
- }
-
- @Override
- public void treeStructureChanged(TreeModelEvent e) {
- Main.getDebugHandler().refreshFrame();
- refresh();
- }
- };
- debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener);
- debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener);
- } else {
- debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
- debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()));
- debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
- }
- InBreakAtExt info = Main.getDebugHandler().getBreakInfo();
- if (info != null) {
- //InBreakReason reason = Main.getDebugHandler().getBreakReason();
- List callStackFiles = new ArrayList<>();
- List 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];
- for (int i = 0; i < cpool.vars.size(); i++) {
- data2[i][0] = cpool.ids.get(i);
- data2[i][1] = cpool.vars.get(i).value;
- }
- constantPoolTable.setModel(new DefaultTableModel(data2, new Object[]{
- AppStrings.translate("constantpool.header.id"),
- AppStrings.translate("constantpool.header.value")
- }) {
- @Override
- public boolean isCellEditable(int row, int column) {
- return false;
- }
-
- });
- }
-
- varTabs.removeAll();
- tabTypes.clear();
- JPanel pa;
- if (debugRegistersTable.getRowCount() > 0) {
- tabTypes.add(SelectedTab.REGISTERS);
- pa = new JPanel(new BorderLayout());
- pa.add(new JScrollPane(debugRegistersTable), BorderLayout.CENTER);
- varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
- }
- if (debugLocalsTable.getRowCount() > 0) {
- tabTypes.add(SelectedTab.LOCALS);
-
- pa = new JPanel(new BorderLayout());
- pa.add(new JScrollPane(debugLocalsTable), BorderLayout.CENTER);
- varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
- }
-
- if (debugScopeTable.getRowCount() > 0) {
- tabTypes.add(SelectedTab.SCOPECHAIN);
-
- pa = new JPanel(new BorderLayout());
- pa.add(new JScrollPane(debugScopeTable), BorderLayout.CENTER);
- varTabs.addTab(AppStrings.translate("variables.header.scopeChain"), pa);
- }
-
- if (constantPoolTable.getRowCount() > 0) {
- tabTypes.add(SelectedTab.CONSTANTPOOL);
-
- pa = new JPanel(new BorderLayout());
- pa.add(new JScrollPane(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 JScrollPane(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 JScrollPane(stackTable), BorderLayout.CENTER);
- varTabs.addTab(AppStrings.translate("stack.header"), pa);
- }
- if (logLength > 0) {
- tabTypes.add(SelectedTab.LOG);
-
- pa = new JPanel(new BorderLayout());
- pa.add(new JScrollPane(traceLogTextarea), BorderLayout.CENTER);
- JButton clearButton = new JButton(AppStrings.translate("debuglog.button.clear"));
- clearButton.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- traceLogTextarea.setText("");
- logLength = 0;
- refresh();
- }
- });
- JPanel butPanel = new JPanel(new FlowLayout());
- butPanel.add(clearButton);
- pa.add(butPanel, BorderLayout.SOUTH);
- varTabs.addTab(AppStrings.translate("debuglog.header"), pa);
- }
- boolean newVisible = !tabTypes.isEmpty();
- if (newVisible != isVisible()) {
- setVisible(newVisible);
- }
- if (!tabTypes.isEmpty()) {
- if (oldSel != null && !tabTypes.contains(oldSel)) {
- oldSel = null;
- }
- }
- if (oldSel != null) {
- selectedTab = oldSel;
- varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
- }
- setLoading(false);
- }
-
- }
- });
-
- }
-
- public void dispose() {
- Main.getDebugHandler().removeBreakListener(listener);
- }
-}
+/*
+ * Copyright (C) 2010-2016 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.debugger.flash.Variable;
+import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
+import com.jpexs.debugger.flash.messages.in.InConstantPool;
+import com.jpexs.debugger.flash.messages.in.InFrame;
+import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
+import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
+import de.hameister.treetable.MyTreeTable;
+import de.hameister.treetable.MyTreeTableModel;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.tree.TreePath;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class DebugPanel extends JPanel {
+
+ private MyTreeTable debugRegistersTable;
+
+ private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
+
+ private MyTreeTable debugScopeTable;
+
+ private JTable callStackTable;
+
+ private JTable stackTable;
+
+ private JTable constantPoolTable;
+
+ private JTabbedPane varTabs;
+
+ private BreakListener listener;
+
+ private JTextArea traceLogTextarea;
+
+ private int logLength = 0;
+
+ private List tabTypes = new ArrayList<>();
+
+ private boolean loading = false;
+
+ public static enum SelectedTab {
+
+ LOG, STACK, SCOPECHAIN, LOCALS, REGISTERS, CALLSTACK, CONSTANTPOOL
+ }
+
+ public synchronized boolean isLoading() {
+ return loading;
+ }
+
+ public synchronized void setLoading(boolean loading) {
+ this.loading = loading;
+ }
+
+ private SelectedTab selectedTab = null;
+
+ private void safeSetTreeModel(MyTreeTable tt, MyTreeTableModel tmodel) {
+ List> expanded = View.getExpandedNodes(tt.getTree());
+
+ int[] selRows = tt.getSelectedRows();
+
+ TreePath[] selPaths = new TreePath[selRows.length];
+ for (int i = 0; i < selRows.length; i++) {
+ selPaths[i] = tt.getTree().getPathForRow(selRows[i]);
+ }
+ tt.setTreeModel(tmodel);
+ //tt.getTree().setRootVisible(false);
+
+ View.expandTreeNodes(tt.getTree(), expanded);
+ for (int i = 0; i < selRows.length; i++) {
+ selRows[i] = tt.getTree().getRowForPath(selPaths[i]);
+ if (i == 0) {
+ tt.setRowSelectionInterval(selRows[i], selRows[i]);
+ } else {
+ tt.addRowSelectionInterval(selRows[i], selRows[i]);
+ }
+ }
+
+ }
+
+ public DebugPanel() {
+ super(new BorderLayout());
+ debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()), false);
+ debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()), false);
+
+ //Add watch feature, commented out. I tried it, but without success. I can't add watch in Flash Pro or FDB either. :-(
+ /*
+ //locales
+ debug.watch.add = Add watch to %name%
+ debug.watch.add.read = Read
+ debug.watch.add.write = Write
+ debug.watch.add.readwrite = Read+Write
+
+ error.debug.watch.add = Cannot add watch to this variable.
+
+
+ MouseAdapter watchHandler = new MouseAdapter() {
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ dopop(e);
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ dopop(e);
+ }
+ }
+
+ private void dopop(MouseEvent e) {
+ if (debugLocalsTable.getSelectedRow() == -1) {
+ return;
+ }
+ Variable v = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVars().get(debugLocalsTable.getSelectedRow());
+ final long v_id = ((ABCPanel.VariablesTableModel) debugLocalsTable.getModel()).getVarIds().get(debugLocalsTable.getSelectedRow());
+
+ JPopupMenu pm = new JPopupMenu();
+ JMenu addWatchMenu = new JMenu(AppStrings.translate("debug.watch.add").replace("%name%", v.name));
+ JMenuItem watchReadMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.read"));
+ watchReadMenuItem.addActionListener((ActionEvent e1) -> {
+ if (!Main.addWatch(v, v_id, true, false)) {
+ View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+ JMenuItem watchWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.write"));
+ watchWriteMenuItem.addActionListener((ActionEvent e1) -> {
+ if (!Main.addWatch(v, v_id, false, true)) {
+ View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+ JMenuItem watchReadWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.readwrite"));
+ watchReadWriteMenuItem.addActionListener((ActionEvent e1) -> {
+ if (!Main.addWatch(v, v_id, true, true)) {
+ View.showMessageDialog(DebugPanel.this, AppStrings.translate("debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ addWatchMenu.add(watchReadMenuItem);
+ addWatchMenu.add(watchWriteMenuItem);
+ addWatchMenu.add(watchReadWriteMenuItem);
+ pm.add(addWatchMenu);
+
+ pm.show(e.getComponent(), e.getX(), e.getY());
+ }
+ };
+
+ debugLocalsTable.addMouseListener(watchHandler);
+ debugScopeTable.addMouseListener(watchHandler);
+
+ */
+ debugScopeTable = new 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);
+ traceLogTextarea.setOpaque(false);
+ traceLogTextarea.setFont(new JLabel().getFont());
+ traceLogTextarea.setBackground(Color.white);
+
+ Main.getDebugHandler().addTraceListener(new DebuggerHandler.TraceListener() {
+
+ @Override
+ public void trace(String... val) {
+ for (String s : val) {
+ String add = "trace: " + s + "\r\n";
+ boolean wasEmpty = logLength == 0;
+ logLength += add.length();
+ traceLogTextarea.append(add);
+ try {
+ traceLogTextarea.setCaretPosition(logLength);
+ } catch (IllegalArgumentException iex) {
+ //ignore
+ }
+ if (wasEmpty) {
+ refresh();
+ }
+ }
+ }
+ });
+
+ Main.getDebugHandler().addConnectionListener(new DebuggerHandler.ConnectionListener() {
+
+ @Override
+ public void connected() {
+ }
+
+ @Override
+ public void disconnected() {
+ refresh();
+ }
+ });
+
+ Main.getDebugHandler().addBreakListener(listener = 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();
+ }
+ });
+
+ }
+ });
+
+ varTabs = new JTabbedPane();
+ varTabs.addChangeListener(new ChangeListener() {
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if (e.getSource() == varTabs) {
+ if (isLoading()) {
+ return;
+ }
+ synchronized (DebugPanel.this) {
+ int si = varTabs.getSelectedIndex();
+ if (si > -1 && si < tabTypes.size()) {
+ selectedTab = tabTypes.get(si);
+ }
+ }
+ }
+ }
+ });
+
+ add(new HeaderLabel(AppStrings.translate("debugpanel.header")), BorderLayout.NORTH);
+ add(varTabs, BorderLayout.CENTER);
+ }
+
+ public void refresh() {
+
+ View.execInEventDispatch(new Runnable() {
+
+ @Override
+ public void run() {
+ setLoading(true);
+ synchronized (DebugPanel.this) {
+
+ SelectedTab oldSel = selectedTab;
+ InFrame f = Main.getDebugHandler().getFrame();
+ if (f != null) {
+
+ List regVarIds = new ArrayList<>();
+ for (int i = 0; i < f.registers.size(); i++) {
+ regVarIds.add(0L);
+ }
+ safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers, regVarIds));
+ List locals = new ArrayList<>();
+ locals.addAll(f.arguments);
+ locals.addAll(f.variables);
+
+ List localIds = new ArrayList<>();
+ localIds.addAll(f.argumentFrameIds);
+ localIds.addAll(f.frameIds);
+
+ safeSetTreeModel(debugLocalsTable, new ABCPanel.VariablesTableModel(debugLocalsTable, locals, localIds));
+ safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain, f.scopeChainFrameIds));
+
+ /*TableModelListener refreshListener = new TableModelListener() {
+ @Override
+ public void tableChanged(TableModelEvent e) {
+ Main.getDebugHandler().refreshFrame();
+ refresh();
+ }
+ };*/
+ TreeModelListener refreshListener = new TreeModelListener() {
+ @Override
+ public void treeNodesChanged(TreeModelEvent e) {
+ Main.getDebugHandler().refreshFrame();
+ refresh();
+ }
+
+ @Override
+ public void treeNodesInserted(TreeModelEvent e) {
+ Main.getDebugHandler().refreshFrame();
+ refresh();
+ }
+
+ @Override
+ public void treeNodesRemoved(TreeModelEvent e) {
+ Main.getDebugHandler().refreshFrame();
+ refresh();
+ }
+
+ @Override
+ public void treeStructureChanged(TreeModelEvent e) {
+ Main.getDebugHandler().refreshFrame();
+ refresh();
+ }
+ };
+ debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener);
+ debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener);
+ } else {
+ debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>()));
+ debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>()));
+ debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>()));
+ }
+ InBreakAtExt info = Main.getDebugHandler().getBreakInfo();
+ if (info != null) {
+ //InBreakReason reason = Main.getDebugHandler().getBreakReason();
+ List callStackFiles = new ArrayList<>();
+ List 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];
+ for (int i = 0; i < cpool.vars.size(); i++) {
+ data2[i][0] = cpool.ids.get(i);
+ data2[i][1] = cpool.vars.get(i).value;
+ }
+ constantPoolTable.setModel(new DefaultTableModel(data2, new Object[]{
+ AppStrings.translate("constantpool.header.id"),
+ AppStrings.translate("constantpool.header.value")
+ }) {
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ return false;
+ }
+
+ });
+ }
+
+ varTabs.removeAll();
+ tabTypes.clear();
+ JPanel pa;
+ if (debugRegistersTable.getRowCount() > 0) {
+ tabTypes.add(SelectedTab.REGISTERS);
+ pa = new JPanel(new BorderLayout());
+ pa.add(new JScrollPane(debugRegistersTable), BorderLayout.CENTER);
+ varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
+ }
+ if (debugLocalsTable.getRowCount() > 0) {
+ tabTypes.add(SelectedTab.LOCALS);
+
+ pa = new JPanel(new BorderLayout());
+ pa.add(new JScrollPane(debugLocalsTable), BorderLayout.CENTER);
+ varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
+ }
+
+ if (debugScopeTable.getRowCount() > 0) {
+ tabTypes.add(SelectedTab.SCOPECHAIN);
+
+ pa = new JPanel(new BorderLayout());
+ pa.add(new JScrollPane(debugScopeTable), BorderLayout.CENTER);
+ varTabs.addTab(AppStrings.translate("variables.header.scopeChain"), pa);
+ }
+
+ if (constantPoolTable.getRowCount() > 0) {
+ tabTypes.add(SelectedTab.CONSTANTPOOL);
+
+ pa = new JPanel(new BorderLayout());
+ pa.add(new JScrollPane(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 JScrollPane(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 JScrollPane(stackTable), BorderLayout.CENTER);
+ varTabs.addTab(AppStrings.translate("stack.header"), pa);
+ }
+ if (logLength > 0) {
+ tabTypes.add(SelectedTab.LOG);
+
+ pa = new JPanel(new BorderLayout());
+ pa.add(new JScrollPane(traceLogTextarea), BorderLayout.CENTER);
+ JButton clearButton = new JButton(AppStrings.translate("debuglog.button.clear"));
+ clearButton.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ traceLogTextarea.setText("");
+ logLength = 0;
+ refresh();
+ }
+ });
+ JPanel butPanel = new JPanel(new FlowLayout());
+ butPanel.add(clearButton);
+ pa.add(butPanel, BorderLayout.SOUTH);
+ varTabs.addTab(AppStrings.translate("debuglog.header"), pa);
+ }
+ boolean newVisible = !tabTypes.isEmpty();
+ if (newVisible != isVisible()) {
+ setVisible(newVisible);
+ }
+ if (!tabTypes.isEmpty()) {
+ if (oldSel != null && !tabTypes.contains(oldSel)) {
+ oldSel = null;
+ }
+ }
+ if (oldSel != null) {
+ selectedTab = oldSel;
+ varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
+ }
+ setLoading(false);
+ }
+
+ }
+ });
+
+ }
+
+ public void dispose() {
+ Main.getDebugHandler().removeBreakListener(listener);
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java
index fea512776..447234cba 100644
--- a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java
+++ b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java
@@ -1,366 +1,366 @@
-/*
- * Copyright (C) 2010-2016 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.abc.ScriptPack;
-import com.jpexs.decompiler.flash.configuration.Configuration;
-import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.ButtonExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.FrameExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.MorphShapeExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.SpriteExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.SymbolClassExportMode;
-import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
-import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel;
-import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
-import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
-import com.jpexs.decompiler.flash.tags.base.ASMSource;
-import com.jpexs.decompiler.flash.tags.base.ButtonTag;
-import com.jpexs.decompiler.flash.tags.base.FontTag;
-import com.jpexs.decompiler.flash.tags.base.ImageTag;
-import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
-import com.jpexs.decompiler.flash.tags.base.ShapeTag;
-import com.jpexs.decompiler.flash.tags.base.SoundTag;
-import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
-import com.jpexs.decompiler.flash.tags.base.TextTag;
-import com.jpexs.decompiler.flash.timeline.Frame;
-import com.jpexs.decompiler.flash.treeitems.TreeItem;
-import java.awt.BorderLayout;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.util.Arrays;
-import java.util.List;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-/**
- *
- * @author JPEXS
- */
-public class ExportDialog extends AppDialog {
-
- private int result = ERROR_OPTION;
-
- String[] optionNames = {
- TagTreeModel.FOLDER_SHAPES,
- TagTreeModel.FOLDER_TEXTS,
- TagTreeModel.FOLDER_IMAGES,
- TagTreeModel.FOLDER_MOVIES,
- TagTreeModel.FOLDER_SOUNDS,
- TagTreeModel.FOLDER_SCRIPTS,
- TagTreeModel.FOLDER_BINARY_DATA,
- TagTreeModel.FOLDER_FRAMES,
- TagTreeModel.FOLDER_SPRITES,
- TagTreeModel.FOLDER_BUTTONS,
- TagTreeModel.FOLDER_FONTS,
- TagTreeModel.FOLDER_MORPHSHAPES,
- "symbolclass"
- };
-
- //Display options only when these classes found
- Class[][] objClasses = {
- {ShapeTag.class},
- {TextTag.class},
- {ImageTag.class},
- {DefineVideoStreamTag.class},
- {SoundTag.class},
- {ASMSource.class, ScriptPack.class},
- {DefineBinaryDataTag.class},
- {Frame.class},
- {Frame.class},
- {ButtonTag.class},
- {FontTag.class},
- {MorphShapeTag.class},
- {SymbolClassTypeTag.class}
- };
-
- //Enum classes for values
- Class[] optionClasses = {
- ShapeExportMode.class,
- TextExportMode.class,
- ImageExportMode.class,
- MovieExportMode.class,
- SoundExportMode.class,
- ScriptExportMode.class,
- BinaryDataExportMode.class,
- FrameExportMode.class,
- SpriteExportMode.class,
- ButtonExportMode.class,
- FontExportMode.class,
- MorphShapeExportMode.class,
- SymbolClassExportMode.class
- };
-
- Class[] zoomClasses = {
- ShapeExportMode.class,
- TextExportMode.class,
- FrameExportMode.class,
- MorphShapeExportMode.class
- };
-
- private final JComboBox[] combos;
-
- private final JCheckBox[] checkBoxes;
-
- private final JCheckBox selectAllCheckBox;
-
- private JTextField zoomTextField = new JTextField();
-
- public E getValue(Class option) {
- for (int i = 0; i < optionClasses.length; i++) {
- if (option == optionClasses[i]) {
- E[] values = option.getEnumConstants();
- return values[combos[i].getSelectedIndex()];
- }
- }
-
- return null;
- }
-
- public boolean isOptionEnabled(Class> option) {
- for (int i = 0; i < optionClasses.length; i++) {
- if (option == optionClasses[i]) {
- return checkBoxes[i].isSelected();
- }
- }
-
- return false;
- }
-
- public double getZoom() {
- return Double.parseDouble(zoomTextField.getText()) / 100;
- }
-
- private void saveConfig() {
- StringBuilder cfg = new StringBuilder();
- for (int i = 0; i < optionNames.length; i++) {
- int selIndex = combos[i].getSelectedIndex();
- Class c = optionClasses[i];
- Object[] vals = c.getEnumConstants();
- String key = optionNames[i] + "." + vals[selIndex].toString().toLowerCase();
- if (i > 0) {
- cfg.append(",");
- }
- cfg.append(key);
- }
-
- Configuration.lastSelectedExportZoom.set(Double.parseDouble(zoomTextField.getText()) / 100);
- Configuration.lastSelectedExportFormats.set(cfg.toString());
- }
-
- public ExportDialog(List exportables) {
- setTitle(translate("dialog.title"));
- setResizable(false);
-
- Container cnt = getContentPane();
- cnt.setLayout(new BorderLayout());
- JPanel comboPanel = new JPanel(null);
- int labWidth = 0;
- boolean[] exportableExistsArray = new boolean[optionNames.length];
- for (int i = 0; i < optionNames.length; i++) {
- boolean exportableExists = false;
- if (exportables == null) {
- exportableExists = true;
- } else {
- for (TreeItem e : exportables) {
- for (int j = 0; j < objClasses[i].length; j++) {
- if (objClasses[i][j].isInstance(e)) {
- exportableExists = true;
- }
- }
- }
- }
-
- if (!exportableExists) {
- continue;
- }
-
- exportableExistsArray[i] = true;
-
- JLabel label = new JLabel(translate(optionNames[i]));
- if (label.getPreferredSize().width > labWidth) {
- labWidth = label.getPreferredSize().width;
- }
- }
-
- String exportFormatsStr = Configuration.lastSelectedExportFormats.get();
- if ("".equals(exportFormatsStr)) {
- exportFormatsStr = null;
- }
-
- String[] exportFormatsArr = new String[0];
- if (exportFormatsStr != null) {
- if (exportFormatsStr.contains(",")) {
- exportFormatsArr = exportFormatsStr.split(",");
- } else {
- exportFormatsArr = new String[]{exportFormatsStr};
- }
-
- }
-
- int comboWidth = 200;
- int checkBoxWidth;
- int top = 10;
-
- List exportFormats = Arrays.asList(exportFormatsArr);
- combos = new JComboBox[optionNames.length];
- checkBoxes = new JCheckBox[optionNames.length];
- selectAllCheckBox = new JCheckBox();
- checkBoxWidth = selectAllCheckBox.getPreferredSize().width;
- selectAllCheckBox.setBounds(10 + labWidth + 10 + comboWidth + 10, top, checkBoxWidth, selectAllCheckBox.getPreferredSize().height);
- selectAllCheckBox.setSelected(true);
- selectAllCheckBox.addActionListener((ActionEvent e) -> {
- boolean selected = selectAllCheckBox.isSelected();
- for (JCheckBox checkBox : checkBoxes) {
- if (checkBox != null) {
- checkBox.setSelected(selected);
- }
- }
- });
- comboPanel.add(selectAllCheckBox);
- top += selectAllCheckBox.getHeight();
-
- boolean zoomable = false;
- for (int i = 0; i < optionNames.length; i++) {
- Class c = optionClasses[i];
- Object[] vals = c.getEnumConstants();
- String[] names = new String[vals.length];
- int itemIndex = -1;
- for (int j = 0; j < vals.length; j++) {
-
- String key = optionNames[i] + "." + vals[j].toString().toLowerCase();
- if (exportFormats.contains(key)) {
- itemIndex = j;
- }
- names[j] = translate(key);
- }
-
- combos[i] = new JComboBox<>(names);
- if (itemIndex > -1) {
- combos[i].setSelectedIndex(itemIndex);
- }
-
- combos[i].setBounds(10 + labWidth + 10, top, comboWidth, combos[i].getPreferredSize().height);
-
- checkBoxes[i] = new JCheckBox();
- checkBoxes[i].setBounds(10 + labWidth + 10 + comboWidth + 10, top, checkBoxWidth, checkBoxes[i].getPreferredSize().height);
- checkBoxes[i].setSelected(true);
-
- if (!exportableExistsArray[i]) {
- continue;
- }
-
- if (Arrays.asList(zoomClasses).contains(c)) {
- zoomable = true;
- }
-
- JLabel lab = new JLabel(translate(optionNames[i]));
- lab.setBounds(10, top, lab.getPreferredSize().width, lab.getPreferredSize().height);
- comboPanel.add(lab);
- comboPanel.add(checkBoxes[i]);
- comboPanel.add(combos[i]);
- top += combos[i].getHeight();
- }
-
- int zoomWidth = 50;
- if (zoomable) {
- top += 2;
- JLabel zlab = new JLabel(translate("zoom"));
- zlab.setBounds(10, top + 4, zlab.getPreferredSize().width, zlab.getPreferredSize().height);
- zoomTextField.setBounds(10 + labWidth + 10, top, zoomWidth, zoomTextField.getPreferredSize().height);
- JLabel pctLabel = new JLabel(translate("zoom.percent"));
- pctLabel.setBounds(10 + labWidth + 10 + zoomWidth + 5, top + 4, 20, pctLabel.getPreferredSize().height);
-
- comboPanel.add(zlab);
- comboPanel.add(zoomTextField);
- comboPanel.add(pctLabel);
- top += zoomTextField.getHeight();
- }
-
- Dimension dim = new Dimension(10 + labWidth + 10 + checkBoxWidth + 10 + comboWidth + 10, top + 10);
- comboPanel.setMinimumSize(dim);
- comboPanel.setPreferredSize(dim);
- cnt.add(comboPanel, BorderLayout.CENTER);
-
- JPanel buttonsPanel = new JPanel(new FlowLayout());
- JButton okButton = new JButton(translate("button.ok"));
- okButton.addActionListener(this::okButtonActionPerformed);
-
- JButton cancelButton = new JButton(translate("button.cancel"));
- cancelButton.addActionListener(this::cancelButtonActionPerformed);
-
- buttonsPanel.add(okButton);
- buttonsPanel.add(cancelButton);
-
- cnt.add(buttonsPanel, BorderLayout.SOUTH);
- pack();
- View.centerScreen(this);
- View.setWindowIcon(this);
- getRootPane().setDefaultButton(okButton);
- setModal(true);
- String pct = "" + Configuration.lastSelectedExportZoom.get() * 100;
- if (pct.endsWith(".0")) {
- pct = pct.substring(0, pct.length() - 2);
- }
-
- zoomTextField.setText(pct);
- }
-
- @Override
- public void setVisible(boolean b) {
- if (b) {
- result = ERROR_OPTION;
- }
- super.setVisible(b);
- }
-
- private void okButtonActionPerformed(ActionEvent evt) {
- result = OK_OPTION;
- try {
- saveConfig();
- } catch (NumberFormatException nfe) {
- JOptionPane.showMessageDialog(ExportDialog.this, translate("zoom.invalid"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- zoomTextField.requestFocusInWindow();
- return;
- }
-
- setVisible(false);
- }
-
- private void cancelButtonActionPerformed(ActionEvent evt) {
- result = CANCEL_OPTION;
- setVisible(false);
- }
-
- public int showExportDialog() {
- setVisible(true);
- return result;
- }
-}
+/*
+ * Copyright (C) 2010-2016 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.abc.ScriptPack;
+import com.jpexs.decompiler.flash.configuration.Configuration;
+import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ButtonExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.FrameExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.MorphShapeExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.SpriteExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.SymbolClassExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
+import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel;
+import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
+import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
+import com.jpexs.decompiler.flash.tags.base.ASMSource;
+import com.jpexs.decompiler.flash.tags.base.ButtonTag;
+import com.jpexs.decompiler.flash.tags.base.FontTag;
+import com.jpexs.decompiler.flash.tags.base.ImageTag;
+import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
+import com.jpexs.decompiler.flash.tags.base.ShapeTag;
+import com.jpexs.decompiler.flash.tags.base.SoundTag;
+import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
+import com.jpexs.decompiler.flash.tags.base.TextTag;
+import com.jpexs.decompiler.flash.timeline.Frame;
+import com.jpexs.decompiler.flash.treeitems.TreeItem;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class ExportDialog extends AppDialog {
+
+ private int result = ERROR_OPTION;
+
+ String[] optionNames = {
+ TagTreeModel.FOLDER_SHAPES,
+ TagTreeModel.FOLDER_TEXTS,
+ TagTreeModel.FOLDER_IMAGES,
+ TagTreeModel.FOLDER_MOVIES,
+ TagTreeModel.FOLDER_SOUNDS,
+ TagTreeModel.FOLDER_SCRIPTS,
+ TagTreeModel.FOLDER_BINARY_DATA,
+ TagTreeModel.FOLDER_FRAMES,
+ TagTreeModel.FOLDER_SPRITES,
+ TagTreeModel.FOLDER_BUTTONS,
+ TagTreeModel.FOLDER_FONTS,
+ TagTreeModel.FOLDER_MORPHSHAPES,
+ "symbolclass"
+ };
+
+ //Display options only when these classes found
+ Class[][] objClasses = {
+ {ShapeTag.class},
+ {TextTag.class},
+ {ImageTag.class},
+ {DefineVideoStreamTag.class},
+ {SoundTag.class},
+ {ASMSource.class, ScriptPack.class},
+ {DefineBinaryDataTag.class},
+ {Frame.class},
+ {Frame.class},
+ {ButtonTag.class},
+ {FontTag.class},
+ {MorphShapeTag.class},
+ {SymbolClassTypeTag.class}
+ };
+
+ //Enum classes for values
+ Class[] optionClasses = {
+ ShapeExportMode.class,
+ TextExportMode.class,
+ ImageExportMode.class,
+ MovieExportMode.class,
+ SoundExportMode.class,
+ ScriptExportMode.class,
+ BinaryDataExportMode.class,
+ FrameExportMode.class,
+ SpriteExportMode.class,
+ ButtonExportMode.class,
+ FontExportMode.class,
+ MorphShapeExportMode.class,
+ SymbolClassExportMode.class
+ };
+
+ Class[] zoomClasses = {
+ ShapeExportMode.class,
+ TextExportMode.class,
+ FrameExportMode.class,
+ MorphShapeExportMode.class
+ };
+
+ private final JComboBox[] combos;
+
+ private final JCheckBox[] checkBoxes;
+
+ private final JCheckBox selectAllCheckBox;
+
+ private JTextField zoomTextField = new JTextField();
+
+ public E getValue(Class option) {
+ for (int i = 0; i < optionClasses.length; i++) {
+ if (option == optionClasses[i]) {
+ E[] values = option.getEnumConstants();
+ return values[combos[i].getSelectedIndex()];
+ }
+ }
+
+ return null;
+ }
+
+ public boolean isOptionEnabled(Class> option) {
+ for (int i = 0; i < optionClasses.length; i++) {
+ if (option == optionClasses[i]) {
+ return checkBoxes[i].isSelected();
+ }
+ }
+
+ return false;
+ }
+
+ public double getZoom() {
+ return Double.parseDouble(zoomTextField.getText()) / 100;
+ }
+
+ private void saveConfig() {
+ StringBuilder cfg = new StringBuilder();
+ for (int i = 0; i < optionNames.length; i++) {
+ int selIndex = combos[i].getSelectedIndex();
+ Class c = optionClasses[i];
+ Object[] vals = c.getEnumConstants();
+ String key = optionNames[i] + "." + vals[selIndex].toString().toLowerCase();
+ if (i > 0) {
+ cfg.append(",");
+ }
+ cfg.append(key);
+ }
+
+ Configuration.lastSelectedExportZoom.set(Double.parseDouble(zoomTextField.getText()) / 100);
+ Configuration.lastSelectedExportFormats.set(cfg.toString());
+ }
+
+ public ExportDialog(List exportables) {
+ setTitle(translate("dialog.title"));
+ setResizable(false);
+
+ Container cnt = getContentPane();
+ cnt.setLayout(new BorderLayout());
+ JPanel comboPanel = new JPanel(null);
+ int labWidth = 0;
+ boolean[] exportableExistsArray = new boolean[optionNames.length];
+ for (int i = 0; i < optionNames.length; i++) {
+ boolean exportableExists = false;
+ if (exportables == null) {
+ exportableExists = true;
+ } else {
+ for (TreeItem e : exportables) {
+ for (int j = 0; j < objClasses[i].length; j++) {
+ if (objClasses[i][j].isInstance(e)) {
+ exportableExists = true;
+ }
+ }
+ }
+ }
+
+ if (!exportableExists) {
+ continue;
+ }
+
+ exportableExistsArray[i] = true;
+
+ JLabel label = new JLabel(translate(optionNames[i]));
+ if (label.getPreferredSize().width > labWidth) {
+ labWidth = label.getPreferredSize().width;
+ }
+ }
+
+ String exportFormatsStr = Configuration.lastSelectedExportFormats.get();
+ if ("".equals(exportFormatsStr)) {
+ exportFormatsStr = null;
+ }
+
+ String[] exportFormatsArr = new String[0];
+ if (exportFormatsStr != null) {
+ if (exportFormatsStr.contains(",")) {
+ exportFormatsArr = exportFormatsStr.split(",");
+ } else {
+ exportFormatsArr = new String[]{exportFormatsStr};
+ }
+
+ }
+
+ int comboWidth = 200;
+ int checkBoxWidth;
+ int top = 10;
+
+ List exportFormats = Arrays.asList(exportFormatsArr);
+ combos = new JComboBox[optionNames.length];
+ checkBoxes = new JCheckBox[optionNames.length];
+ selectAllCheckBox = new JCheckBox();
+ checkBoxWidth = selectAllCheckBox.getPreferredSize().width;
+ selectAllCheckBox.setBounds(10 + labWidth + 10 + comboWidth + 10, top, checkBoxWidth, selectAllCheckBox.getPreferredSize().height);
+ selectAllCheckBox.setSelected(true);
+ selectAllCheckBox.addActionListener((ActionEvent e) -> {
+ boolean selected = selectAllCheckBox.isSelected();
+ for (JCheckBox checkBox : checkBoxes) {
+ if (checkBox != null) {
+ checkBox.setSelected(selected);
+ }
+ }
+ });
+ comboPanel.add(selectAllCheckBox);
+ top += selectAllCheckBox.getHeight();
+
+ boolean zoomable = false;
+ for (int i = 0; i < optionNames.length; i++) {
+ Class c = optionClasses[i];
+ Object[] vals = c.getEnumConstants();
+ String[] names = new String[vals.length];
+ int itemIndex = -1;
+ for (int j = 0; j < vals.length; j++) {
+
+ String key = optionNames[i] + "." + vals[j].toString().toLowerCase();
+ if (exportFormats.contains(key)) {
+ itemIndex = j;
+ }
+ names[j] = translate(key);
+ }
+
+ combos[i] = new JComboBox<>(names);
+ if (itemIndex > -1) {
+ combos[i].setSelectedIndex(itemIndex);
+ }
+
+ combos[i].setBounds(10 + labWidth + 10, top, comboWidth, combos[i].getPreferredSize().height);
+
+ checkBoxes[i] = new JCheckBox();
+ checkBoxes[i].setBounds(10 + labWidth + 10 + comboWidth + 10, top, checkBoxWidth, checkBoxes[i].getPreferredSize().height);
+ checkBoxes[i].setSelected(true);
+
+ if (!exportableExistsArray[i]) {
+ continue;
+ }
+
+ if (Arrays.asList(zoomClasses).contains(c)) {
+ zoomable = true;
+ }
+
+ JLabel lab = new JLabel(translate(optionNames[i]));
+ lab.setBounds(10, top, lab.getPreferredSize().width, lab.getPreferredSize().height);
+ comboPanel.add(lab);
+ comboPanel.add(checkBoxes[i]);
+ comboPanel.add(combos[i]);
+ top += combos[i].getHeight();
+ }
+
+ int zoomWidth = 50;
+ if (zoomable) {
+ top += 2;
+ JLabel zlab = new JLabel(translate("zoom"));
+ zlab.setBounds(10, top + 4, zlab.getPreferredSize().width, zlab.getPreferredSize().height);
+ zoomTextField.setBounds(10 + labWidth + 10, top, zoomWidth, zoomTextField.getPreferredSize().height);
+ JLabel pctLabel = new JLabel(translate("zoom.percent"));
+ pctLabel.setBounds(10 + labWidth + 10 + zoomWidth + 5, top + 4, 20, pctLabel.getPreferredSize().height);
+
+ comboPanel.add(zlab);
+ comboPanel.add(zoomTextField);
+ comboPanel.add(pctLabel);
+ top += zoomTextField.getHeight();
+ }
+
+ Dimension dim = new Dimension(10 + labWidth + 10 + checkBoxWidth + 10 + comboWidth + 10, top + 10);
+ comboPanel.setMinimumSize(dim);
+ comboPanel.setPreferredSize(dim);
+ cnt.add(comboPanel, BorderLayout.CENTER);
+
+ JPanel buttonsPanel = new JPanel(new FlowLayout());
+ JButton okButton = new JButton(translate("button.ok"));
+ okButton.addActionListener(this::okButtonActionPerformed);
+
+ JButton cancelButton = new JButton(translate("button.cancel"));
+ cancelButton.addActionListener(this::cancelButtonActionPerformed);
+
+ buttonsPanel.add(okButton);
+ buttonsPanel.add(cancelButton);
+
+ cnt.add(buttonsPanel, BorderLayout.SOUTH);
+ pack();
+ View.centerScreen(this);
+ View.setWindowIcon(this);
+ getRootPane().setDefaultButton(okButton);
+ setModal(true);
+ String pct = "" + Configuration.lastSelectedExportZoom.get() * 100;
+ if (pct.endsWith(".0")) {
+ pct = pct.substring(0, pct.length() - 2);
+ }
+
+ zoomTextField.setText(pct);
+ }
+
+ @Override
+ public void setVisible(boolean b) {
+ if (b) {
+ result = ERROR_OPTION;
+ }
+ super.setVisible(b);
+ }
+
+ private void okButtonActionPerformed(ActionEvent evt) {
+ result = OK_OPTION;
+ try {
+ saveConfig();
+ } catch (NumberFormatException nfe) {
+ JOptionPane.showMessageDialog(ExportDialog.this, translate("zoom.invalid"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ zoomTextField.requestFocusInWindow();
+ return;
+ }
+
+ setVisible(false);
+ }
+
+ private void cancelButtonActionPerformed(ActionEvent evt) {
+ result = CANCEL_OPTION;
+ setVisible(false);
+ }
+
+ public int showExportDialog() {
+ setVisible(true);
+ return result;
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java
index 5d34915e8..2579206b0 100644
--- a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java
+++ b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java
@@ -1,401 +1,401 @@
-/*
- * Copyright (C) 2010-2016 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.tags.font.CharacterRanges;
-import com.jpexs.helpers.Helper;
-import java.awt.BorderLayout;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JTextField;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.filechooser.FileFilter;
-
-/**
- *
- * @author JPEXS
- */
-public class FontEmbedDialog extends AppDialog {
-
- private static final int SAMPLE_MAX_LENGTH = 50;
-
- private final JComboBox familyNamesSelection;
-
- private final JComboBox faceSelection;
-
- private final JCheckBox[] rangeCheckboxes;
-
- private final String rangeNames[];
-
- private final JLabel[] rangeSamples;
-
- private final JTextField individualCharsField;
-
- private int result = ERROR_OPTION;
-
- private JLabel individialSample;
-
- private Font customFont;
-
- private final JCheckBox allCheckbox;
-
- public Font getSelectedFont() {
- if (ttfFileRadio.isSelected() && customFont != null) {
- return customFont;
- }
- return ((FontFace) faceSelection.getSelectedItem()).font;
- }
-
- public Set getSelectedChars() {
- Set chars = new TreeSet<>();
- Font f = getSelectedFont();
- if (allCheckbox.isSelected()) {
- for (int i = 0; i < rangeCheckboxes.length; i++) {
- int[] codes = CharacterRanges.rangeCodes(i);
- for (int c : codes) {
- if (f.canDisplay(c)) {
- chars.add(c);
- }
- }
- }
- } else {
- for (int i = 0; i < rangeCheckboxes.length; i++) {
- if (rangeCheckboxes[i].isSelected()) {
- int[] codes = CharacterRanges.rangeCodes(i);
- for (int c : codes) {
- if (f.canDisplay(c)) {
- chars.add(c);
- }
- }
- }
- }
- String indStr = individualCharsField.getText();
- for (int i = 0; i < indStr.length(); i++) {
- if (f.canDisplay(indStr.codePointAt(i))) {
- chars.add(indStr.codePointAt(i));
- }
- }
- }
- return chars;
- }
-
- private JRadioButton ttfFileRadio;
-
- private JRadioButton installedRadio;
-
- private void updateFaceSelection() {
- faceSelection.setModel(FontPanel.getFaceModel((FontFamily) familyNamesSelection.getSelectedItem()));
- }
-
- public FontEmbedDialog(FontFace selectedFace, String selectedChars) {
- setSize(900, 600);
- setDefaultCloseOperation(HIDE_ON_CLOSE);
- setTitle(translate("dialog.title"));
-
- Container cnt = getContentPane();
- cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
-
- JPanel selFontPanel = new JPanel(new FlowLayout());
-
- installedRadio = new JRadioButton(translate("installed"));
- ttfFileRadio = new JRadioButton(translate("ttffile.noselection"));
-
- ButtonGroup bg = new ButtonGroup();
- bg.add(installedRadio);
- bg.add(ttfFileRadio);
-
- installedRadio.setSelected(true);
-
- individialSample = new JLabel();
- familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel());
- familyNamesSelection.setSelectedItem(new FontFamily(selectedFace.font));
- faceSelection = new JComboBox<>();
- updateFaceSelection();
- faceSelection.setSelectedItem(selectedFace);
- JButton loadFromDiskButton = new JButton(View.getIcon("open16"));
- loadFromDiskButton.setToolTipText(translate("button.loadfont"));
- loadFromDiskButton.addActionListener(this::loadFromDiscButtonActionPerformed);
- selFontPanel.add(installedRadio);
- selFontPanel.add(familyNamesSelection);
- selFontPanel.add(faceSelection);
- selFontPanel.add(ttfFileRadio);
- selFontPanel.add(loadFromDiskButton);
-
- installedRadio.addItemListener(new ItemListener() {
-
- @Override
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- updateCheckboxes();
- }
- }
- });
-
- ttfFileRadio.addItemListener(new ItemListener() {
-
- @Override
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- if (ttfFileRadio.isSelected()) {
- if (customFont == null) {
- if (loadFromDisk()) {
- updateCheckboxes();
- } else {
- installedRadio.setSelected(true);
- }
- } else {
- updateCheckboxes();
- }
- }
- }
- }
- });
-
- cnt.add(selFontPanel);
- JPanel rangesPanel = new JPanel();
- rangesPanel.setLayout(new BoxLayout(rangesPanel, BoxLayout.Y_AXIS));
- final int rc = CharacterRanges.rangeCount();
- rangeCheckboxes = new JCheckBox[rc];
- rangeSamples = new JLabel[rc];
- rangeNames = new String[rc];
- allCheckbox = new JCheckBox(translate("allcharacters"));
- allCheckbox.addItemListener(new ItemListener() {
-
- @Override
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- for (int i = 0; i < rc; i++) {
- rangeCheckboxes[i].setEnabled(false);
- }
- individualCharsField.setEnabled(false);
- } else if (e.getStateChange() == ItemEvent.DESELECTED) {
- for (int i = 0; i < rc; i++) {
- rangeCheckboxes[i].setEnabled(true);
- }
- individualCharsField.setEnabled(true);
- }
- }
- });
- JPanel rangeRowPanel = new JPanel();
- rangeRowPanel.setLayout(new BorderLayout());
- rangeRowPanel.add(allCheckbox, BorderLayout.WEST);
- rangeRowPanel.setAlignmentX(0);
- rangesPanel.add(rangeRowPanel);
-
- for (int i = 0; i < rc; i++) {
- rangeNames[i] = CharacterRanges.rangeName(i);
- rangeSamples[i] = new JLabel("");
- rangeCheckboxes[i] = new JCheckBox(rangeNames[i]);
- rangeRowPanel = new JPanel();
- rangeRowPanel.setLayout(new BoxLayout(rangeRowPanel, BoxLayout.X_AXIS));
- rangeRowPanel.add(rangeCheckboxes[i]);
- rangeRowPanel.add(Box.createHorizontalGlue());
- rangeRowPanel.add(rangeSamples[i]);
- rangeRowPanel.setAlignmentX(0);
- rangesPanel.add(rangeRowPanel);
- }
- cnt.add(new JScrollPane(rangesPanel));
-
- JPanel specialPanel = new JPanel();
- specialPanel.setLayout(new BoxLayout(specialPanel, BoxLayout.X_AXIS));
- specialPanel.add(new JLabel(translate("label.individual")));
- individualCharsField = new JTextField();
- individualCharsField.setPreferredSize(new Dimension(100, individualCharsField.getPreferredSize().height));
- individialSample = new JLabel();
- specialPanel.add(individualCharsField);
-
- cnt.add(specialPanel);
- cnt.add(individialSample);
-
- JPanel buttonsPanel = new JPanel(new FlowLayout());
- JButton okButton = new JButton(AppStrings.translate("button.ok"));
- okButton.addActionListener(this::okButtonActionPerformed);
- JButton cancelButton = new JButton(AppStrings.translate("button.cancel"));
- cancelButton.addActionListener(this::cancelButtonActionPerformed);
- buttonsPanel.add(okButton);
- buttonsPanel.add(cancelButton);
- cnt.add(buttonsPanel);
- View.setWindowIcon(this);
- View.centerScreen(this);
- setModalityType(ModalityType.APPLICATION_MODAL);
- individualCharsField.setText(selectedChars);
- getRootPane().setDefaultButton(okButton);
- familyNamesSelection.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- updateFaceSelection();
- updateCheckboxes();
- }
- });
- faceSelection.addItemListener((ItemEvent e) -> {
- updateCheckboxes();
- });
- updateCheckboxes();
- individualCharsField.getDocument().addDocumentListener(new DocumentListener() {
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- updateIndividual();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- updateIndividual();
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- updateIndividual();
- }
- });
- }
-
- private void updateIndividual() {
- String chars = individualCharsField.getText();
- Font f = getSelectedFont();
- StringBuilder visibleChars = new StringBuilder();
- for (int i = 0; i < chars.length(); i++) {
- if (f.canDisplay(chars.codePointAt(i))) {
- visibleChars.append(chars.charAt(i));
- }
- }
- individialSample.setText(visibleChars.toString());
- }
-
- private void updateCheckboxes() {
- Font f = getSelectedFont().deriveFont(12f);
- int rc = CharacterRanges.rangeCount();
-
- Set allChars = new HashSet<>();
- for (int i = 0; i < rc; i++) {
- rangeNames[i] = CharacterRanges.rangeName(i);
- int[] codes = CharacterRanges.rangeCodes(i);
- int avail = 0;
- StringBuilder sample = new StringBuilder();
- for (int c = 0; c < codes.length; c++) {
- if (f.canDisplay(codes[c])) {
- allChars.add(codes[c]);
- if (avail < SAMPLE_MAX_LENGTH) {
- sample.append((char) codes[c]);
- }
- avail++;
- }
- }
- rangeSamples[i].setText(sample.toString());
- rangeSamples[i].setFont(f);
- rangeCheckboxes[i].setText(translate("range.description").replace("%available%", Integer.toString(avail)).replace("%name%", rangeNames[i]).replace("%total%", Integer.toString(codes.length)));
- }
- allCheckbox.setText(translate("allcharacters").replace("%available%", Integer.toString(allChars.size())));
- individialSample.setFont(f);
- updateIndividual();
- }
-
- @Override
- public void setVisible(boolean b) {
- if (b) {
- result = ERROR_OPTION;
- }
-
- super.setVisible(b);
- }
-
- private void okButtonActionPerformed(ActionEvent evt) {
- result = OK_OPTION;
- setVisible(false);
- }
-
- private void cancelButtonActionPerformed(ActionEvent evt) {
- result = CANCEL_OPTION;
- setVisible(false);
- }
-
- private void loadFromDiscButtonActionPerformed(ActionEvent evt) {
- if (customFont != null) {
- if (loadFromDisk()) {
- updateCheckboxes();
- }
- }
-
- ttfFileRadio.setSelected(true);
- }
-
- private boolean loadFromDisk() {
- JFileChooser fc = new JFileChooser();
- fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
- FileFilter ttfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".ttf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return translate("filter.ttf");
- }
- };
- fc.setFileFilter(ttfFilter);
- fc.setAcceptAllFileFilterUsed(true);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- int returnVal = fc.showOpenDialog(f);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
- File selfile = Helper.fixDialogFile(fc.getSelectedFile());
- try {
- customFont = Font.createFont(Font.TRUETYPE_FONT, selfile);
- ttfFileRadio.setText(translate("ttffile.selection").replace("%fontname%", customFont.getName()).replace("%filename%", selfile.getName()));
- return true;
- } catch (FontFormatException ex) {
- JOptionPane.showMessageDialog(this, translate("error.invalidfontfile"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- } catch (IOException ex) {
- JOptionPane.showMessageDialog(this, translate("error.cannotreadfontfile"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- }
- }
- return false;
- }
-
- public int showDialog() {
- setVisible(true);
- return result;
- }
-}
+/*
+ * Copyright (C) 2010-2016 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.tags.font.CharacterRanges;
+import com.jpexs.helpers.Helper;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.filechooser.FileFilter;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class FontEmbedDialog extends AppDialog {
+
+ private static final int SAMPLE_MAX_LENGTH = 50;
+
+ private final JComboBox familyNamesSelection;
+
+ private final JComboBox faceSelection;
+
+ private final JCheckBox[] rangeCheckboxes;
+
+ private final String rangeNames[];
+
+ private final JLabel[] rangeSamples;
+
+ private final JTextField individualCharsField;
+
+ private int result = ERROR_OPTION;
+
+ private JLabel individialSample;
+
+ private Font customFont;
+
+ private final JCheckBox allCheckbox;
+
+ public Font getSelectedFont() {
+ if (ttfFileRadio.isSelected() && customFont != null) {
+ return customFont;
+ }
+ return ((FontFace) faceSelection.getSelectedItem()).font;
+ }
+
+ public Set getSelectedChars() {
+ Set chars = new TreeSet<>();
+ Font f = getSelectedFont();
+ if (allCheckbox.isSelected()) {
+ for (int i = 0; i < rangeCheckboxes.length; i++) {
+ int[] codes = CharacterRanges.rangeCodes(i);
+ for (int c : codes) {
+ if (f.canDisplay(c)) {
+ chars.add(c);
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < rangeCheckboxes.length; i++) {
+ if (rangeCheckboxes[i].isSelected()) {
+ int[] codes = CharacterRanges.rangeCodes(i);
+ for (int c : codes) {
+ if (f.canDisplay(c)) {
+ chars.add(c);
+ }
+ }
+ }
+ }
+ String indStr = individualCharsField.getText();
+ for (int i = 0; i < indStr.length(); i++) {
+ if (f.canDisplay(indStr.codePointAt(i))) {
+ chars.add(indStr.codePointAt(i));
+ }
+ }
+ }
+ return chars;
+ }
+
+ private JRadioButton ttfFileRadio;
+
+ private JRadioButton installedRadio;
+
+ private void updateFaceSelection() {
+ faceSelection.setModel(FontPanel.getFaceModel((FontFamily) familyNamesSelection.getSelectedItem()));
+ }
+
+ public FontEmbedDialog(FontFace selectedFace, String selectedChars) {
+ setSize(900, 600);
+ setDefaultCloseOperation(HIDE_ON_CLOSE);
+ setTitle(translate("dialog.title"));
+
+ Container cnt = getContentPane();
+ cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
+
+ JPanel selFontPanel = new JPanel(new FlowLayout());
+
+ installedRadio = new JRadioButton(translate("installed"));
+ ttfFileRadio = new JRadioButton(translate("ttffile.noselection"));
+
+ ButtonGroup bg = new ButtonGroup();
+ bg.add(installedRadio);
+ bg.add(ttfFileRadio);
+
+ installedRadio.setSelected(true);
+
+ individialSample = new JLabel();
+ familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel());
+ familyNamesSelection.setSelectedItem(new FontFamily(selectedFace.font));
+ faceSelection = new JComboBox<>();
+ updateFaceSelection();
+ faceSelection.setSelectedItem(selectedFace);
+ JButton loadFromDiskButton = new JButton(View.getIcon("open16"));
+ loadFromDiskButton.setToolTipText(translate("button.loadfont"));
+ loadFromDiskButton.addActionListener(this::loadFromDiscButtonActionPerformed);
+ selFontPanel.add(installedRadio);
+ selFontPanel.add(familyNamesSelection);
+ selFontPanel.add(faceSelection);
+ selFontPanel.add(ttfFileRadio);
+ selFontPanel.add(loadFromDiskButton);
+
+ installedRadio.addItemListener(new ItemListener() {
+
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ updateCheckboxes();
+ }
+ }
+ });
+
+ ttfFileRadio.addItemListener(new ItemListener() {
+
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ if (ttfFileRadio.isSelected()) {
+ if (customFont == null) {
+ if (loadFromDisk()) {
+ updateCheckboxes();
+ } else {
+ installedRadio.setSelected(true);
+ }
+ } else {
+ updateCheckboxes();
+ }
+ }
+ }
+ }
+ });
+
+ cnt.add(selFontPanel);
+ JPanel rangesPanel = new JPanel();
+ rangesPanel.setLayout(new BoxLayout(rangesPanel, BoxLayout.Y_AXIS));
+ final int rc = CharacterRanges.rangeCount();
+ rangeCheckboxes = new JCheckBox[rc];
+ rangeSamples = new JLabel[rc];
+ rangeNames = new String[rc];
+ allCheckbox = new JCheckBox(translate("allcharacters"));
+ allCheckbox.addItemListener(new ItemListener() {
+
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ for (int i = 0; i < rc; i++) {
+ rangeCheckboxes[i].setEnabled(false);
+ }
+ individualCharsField.setEnabled(false);
+ } else if (e.getStateChange() == ItemEvent.DESELECTED) {
+ for (int i = 0; i < rc; i++) {
+ rangeCheckboxes[i].setEnabled(true);
+ }
+ individualCharsField.setEnabled(true);
+ }
+ }
+ });
+ JPanel rangeRowPanel = new JPanel();
+ rangeRowPanel.setLayout(new BorderLayout());
+ rangeRowPanel.add(allCheckbox, BorderLayout.WEST);
+ rangeRowPanel.setAlignmentX(0);
+ rangesPanel.add(rangeRowPanel);
+
+ for (int i = 0; i < rc; i++) {
+ rangeNames[i] = CharacterRanges.rangeName(i);
+ rangeSamples[i] = new JLabel("");
+ rangeCheckboxes[i] = new JCheckBox(rangeNames[i]);
+ rangeRowPanel = new JPanel();
+ rangeRowPanel.setLayout(new BoxLayout(rangeRowPanel, BoxLayout.X_AXIS));
+ rangeRowPanel.add(rangeCheckboxes[i]);
+ rangeRowPanel.add(Box.createHorizontalGlue());
+ rangeRowPanel.add(rangeSamples[i]);
+ rangeRowPanel.setAlignmentX(0);
+ rangesPanel.add(rangeRowPanel);
+ }
+ cnt.add(new JScrollPane(rangesPanel));
+
+ JPanel specialPanel = new JPanel();
+ specialPanel.setLayout(new BoxLayout(specialPanel, BoxLayout.X_AXIS));
+ specialPanel.add(new JLabel(translate("label.individual")));
+ individualCharsField = new JTextField();
+ individualCharsField.setPreferredSize(new Dimension(100, individualCharsField.getPreferredSize().height));
+ individialSample = new JLabel();
+ specialPanel.add(individualCharsField);
+
+ cnt.add(specialPanel);
+ cnt.add(individialSample);
+
+ JPanel buttonsPanel = new JPanel(new FlowLayout());
+ JButton okButton = new JButton(AppStrings.translate("button.ok"));
+ okButton.addActionListener(this::okButtonActionPerformed);
+ JButton cancelButton = new JButton(AppStrings.translate("button.cancel"));
+ cancelButton.addActionListener(this::cancelButtonActionPerformed);
+ buttonsPanel.add(okButton);
+ buttonsPanel.add(cancelButton);
+ cnt.add(buttonsPanel);
+ View.setWindowIcon(this);
+ View.centerScreen(this);
+ setModalityType(ModalityType.APPLICATION_MODAL);
+ individualCharsField.setText(selectedChars);
+ getRootPane().setDefaultButton(okButton);
+ familyNamesSelection.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateFaceSelection();
+ updateCheckboxes();
+ }
+ });
+ faceSelection.addItemListener((ItemEvent e) -> {
+ updateCheckboxes();
+ });
+ updateCheckboxes();
+ individualCharsField.getDocument().addDocumentListener(new DocumentListener() {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ updateIndividual();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ updateIndividual();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ updateIndividual();
+ }
+ });
+ }
+
+ private void updateIndividual() {
+ String chars = individualCharsField.getText();
+ Font f = getSelectedFont();
+ StringBuilder visibleChars = new StringBuilder();
+ for (int i = 0; i < chars.length(); i++) {
+ if (f.canDisplay(chars.codePointAt(i))) {
+ visibleChars.append(chars.charAt(i));
+ }
+ }
+ individialSample.setText(visibleChars.toString());
+ }
+
+ private void updateCheckboxes() {
+ Font f = getSelectedFont().deriveFont(12f);
+ int rc = CharacterRanges.rangeCount();
+
+ Set allChars = new HashSet<>();
+ for (int i = 0; i < rc; i++) {
+ rangeNames[i] = CharacterRanges.rangeName(i);
+ int[] codes = CharacterRanges.rangeCodes(i);
+ int avail = 0;
+ StringBuilder sample = new StringBuilder();
+ for (int c = 0; c < codes.length; c++) {
+ if (f.canDisplay(codes[c])) {
+ allChars.add(codes[c]);
+ if (avail < SAMPLE_MAX_LENGTH) {
+ sample.append((char) codes[c]);
+ }
+ avail++;
+ }
+ }
+ rangeSamples[i].setText(sample.toString());
+ rangeSamples[i].setFont(f);
+ rangeCheckboxes[i].setText(translate("range.description").replace("%available%", Integer.toString(avail)).replace("%name%", rangeNames[i]).replace("%total%", Integer.toString(codes.length)));
+ }
+ allCheckbox.setText(translate("allcharacters").replace("%available%", Integer.toString(allChars.size())));
+ individialSample.setFont(f);
+ updateIndividual();
+ }
+
+ @Override
+ public void setVisible(boolean b) {
+ if (b) {
+ result = ERROR_OPTION;
+ }
+
+ super.setVisible(b);
+ }
+
+ private void okButtonActionPerformed(ActionEvent evt) {
+ result = OK_OPTION;
+ setVisible(false);
+ }
+
+ private void cancelButtonActionPerformed(ActionEvent evt) {
+ result = CANCEL_OPTION;
+ setVisible(false);
+ }
+
+ private void loadFromDiscButtonActionPerformed(ActionEvent evt) {
+ if (customFont != null) {
+ if (loadFromDisk()) {
+ updateCheckboxes();
+ }
+ }
+
+ ttfFileRadio.setSelected(true);
+ }
+
+ private boolean loadFromDisk() {
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
+ FileFilter ttfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".ttf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return translate("filter.ttf");
+ }
+ };
+ fc.setFileFilter(ttfFilter);
+ fc.setAcceptAllFileFilterUsed(true);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ int returnVal = fc.showOpenDialog(f);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
+ File selfile = Helper.fixDialogFile(fc.getSelectedFile());
+ try {
+ customFont = Font.createFont(Font.TRUETYPE_FONT, selfile);
+ ttfFileRadio.setText(translate("ttffile.selection").replace("%fontname%", customFont.getName()).replace("%filename%", selfile.getName()));
+ return true;
+ } catch (FontFormatException ex) {
+ JOptionPane.showMessageDialog(this, translate("error.invalidfontfile"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ } catch (IOException ex) {
+ JOptionPane.showMessageDialog(this, translate("error.cannotreadfontfile"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ return false;
+ }
+
+ public int showDialog() {
+ setVisible(true);
+ return result;
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java
index 9694928c6..c554c43b1 100644
--- a/src/com/jpexs/decompiler/flash/gui/Main.java
+++ b/src/com/jpexs/decompiler/flash/gui/Main.java
@@ -1,2335 +1,2335 @@
-/*
- * Copyright (C) 2010-2016 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.debugger.flash.Debugger;
-import com.jpexs.debugger.flash.DebuggerCommands;
-import com.jpexs.debugger.flash.Variable;
-import com.jpexs.decompiler.flash.ApplicationInfo;
-import com.jpexs.decompiler.flash.EventListener;
-import com.jpexs.decompiler.flash.SWF;
-import com.jpexs.decompiler.flash.SWFBundle;
-import com.jpexs.decompiler.flash.SWFSourceInfo;
-import com.jpexs.decompiler.flash.SearchMode;
-import com.jpexs.decompiler.flash.SwfOpenException;
-import com.jpexs.decompiler.flash.UrlResolver;
-import com.jpexs.decompiler.flash.Version;
-import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
-import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
-import com.jpexs.decompiler.flash.configuration.Configuration;
-import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
-import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
-import com.jpexs.decompiler.flash.console.ContextMenuTools;
-import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
-import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
-import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
-import com.jpexs.decompiler.flash.gui.pipes.FirstInstance;
-import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
-import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
-import com.jpexs.decompiler.flash.tags.Tag;
-import com.jpexs.decompiler.flash.tags.base.FontTag;
-import com.jpexs.decompiler.flash.tags.base.ImportTag;
-import com.jpexs.decompiler.flash.treeitems.SWFList;
-import com.jpexs.helpers.Cache;
-import com.jpexs.helpers.CancellableWorker;
-import com.jpexs.helpers.Helper;
-import com.jpexs.helpers.Path;
-import com.jpexs.helpers.ProgressListener;
-import com.jpexs.helpers.Stopwatch;
-import com.jpexs.helpers.streams.SeekableInputStream;
-import com.sun.jna.Platform;
-import com.sun.jna.platform.win32.Advapi32Util;
-import com.sun.jna.platform.win32.Kernel32;
-import com.sun.jna.platform.win32.WinReg;
-import java.awt.AWTException;
-import java.awt.Frame;
-import java.awt.GraphicsEnvironment;
-import java.awt.MenuItem;
-import java.awt.PopupMenu;
-import java.awt.SystemTray;
-import java.awt.TrayIcon;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.URL;
-import java.net.URLConnection;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.FileHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.logging.SimpleFormatter;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.SwingWorker;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.filechooser.FileFilter;
-import org.pushingpixels.substance.api.SubstanceLookAndFeel;
-
-/**
- * Main executable class
- *
- * @author JPEXS
- */
-public class Main {
-
- protected static ProxyFrame proxyFrame;
-
- private static List sourceInfos = new ArrayList<>();
-
- public static LoadingDialog loadingDialog;
-
- private static boolean working = false;
-
- private static TrayIcon trayIcon;
-
- private static MenuItem stopMenuItem;
-
- private static volatile MainFrame mainFrame;
-
- public static final int UPDATE_SYSTEM_MAJOR = 1;
-
- public static final int UPDATE_SYSTEM_MINOR = 3;
-
- private static LoadFromMemoryFrame loadFromMemoryFrame;
-
- private static LoadFromCacheFrame loadFromCacheFrame;
-
- private static final Logger logger = Logger.getLogger(Main.class.getName());
-
- public static DebugLogDialog debugDialog;
-
- public static boolean shouldCloseWhenClosingLoadingDialog;
-
- private static Debugger flashDebugger;
-
- private static DebuggerHandler debugHandler = null;
-
- //private static int ip = 0;
- //private static String ipClass = null;
- private static Process runProcess;
-
- private static boolean runProcessDebug;
-
- private static boolean runProcessDebugPCode;
-
- private static boolean inited = false;
-
- private static File runTempFile;
-
- private static List runTempFiles = new ArrayList<>();
-
- public static void freeRun() {
- synchronized (Main.class) {
- if (runTempFile != null) {
- runTempFile.delete();
- runTempFile = null;
- }
- for (File f : runTempFiles) {
- f.delete();
- }
- runTempFiles.clear();
-
- runProcess = null;
- }
- if (mainFrame != null && mainFrame.getPanel() != null) {
- mainFrame.getPanel().clearDebuggerColors();
- }
- if (runProcessDebug) {
- Main.getDebugHandler().disconnect();
- }
- }
-
- public static synchronized boolean isDebugPaused() {
- return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
- }
-
- public static synchronized boolean isDebugRunning() {
- return runProcess != null && runProcessDebug;
- }
-
- public static synchronized boolean isDebugPCode() {
- return runProcessDebugPCode;
- }
-
- public static synchronized boolean isDebugConnected() {
- return getDebugHandler().isConnected();
- }
-
- public static synchronized boolean isRunning() {
- return runProcess != null && !runProcessDebug;
- }
-
- public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
- DebuggerCommands.Watch w = getDebugHandler().addWatch(v, v_id, watchRead, watchWrite);
- return w != null;
- }
-
- public static void runPlayer(String title, final String exePath, String file, String flashVars) {
- if (!new File(file).exists()) {
- return;
- }
- if (flashVars != null && !flashVars.isEmpty()) {
- file += "?" + flashVars;
- }
- final String ffile = file;
-
- CancellableWorker runWorker = new CancellableWorker() {
- @Override
- protected Object doInBackground() throws Exception {
- Process proc;
- try {
- proc = Runtime.getRuntime().exec(new String[]{exePath, ffile});
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- return null;
- }
- boolean isDebug;
-
- synchronized (Main.class) {
- runProcess = proc;
- isDebug = runProcessDebug;
- }
- if (isDebug) {
- mainFrame.getMenu().hilightPath("/debugging");
- }
- mainFrame.getMenu().updateComponents();
- try {
- if (proc != null) {
- proc.waitFor();
- }
- } catch (InterruptedException ex) {
- if (proc != null) {
- try {
- proc.destroy();
- } catch (Exception ex2) {
- //ignore
- }
- }
- }
- freeRun();
- stopDebugger();
- mainFrame.getMenu().updateComponents();
- return null;
- }
-
- @Override
- protected void done() {
- Main.stopWork();
- }
-
- @Override
- public void workerCancelled() {
- Main.stopWork();
- synchronized (Main.class) {
- if (runProcess != null) {
- try {
- runProcess.destroy();
- } catch (Exception ex) {
-
- }
- }
- }
- freeRun();
- mainFrame.getMenu().updateComponents();
- }
- };
-
- mainFrame.getMenu().updateComponents();
- Main.startWork(title + "...", runWorker);
- runWorker.execute();
- }
-
- public static void stopRun() {
-
- synchronized (Main.class) {
- if (runProcess != null) {
- runProcess.destroy();
- }
- }
- freeRun();
- stopDebugger();
- mainFrame.getMenu().updateComponents();
- }
-
- private static interface SwfPreparation {
-
- public SWF prepare(SWF swf);
- }
-
- private static class SwfRunPrepare implements SwfPreparation {
-
- @Override
- public SWF prepare(SWF swf) {
- if (Configuration.autoOpenLoadedSWFs.get()) {
- if (!DebuggerTools.hasDebugger(swf)) {
- DebuggerTools.switchDebugger(swf);
- }
- DebuggerTools.injectDebugLoader(swf);
- }
- return swf;
- }
- }
-
- private static class SwfDebugPrepare extends SwfRunPrepare {
-
- private boolean doPCode;
-
- public SwfDebugPrepare(boolean doPCode) {
- this.doPCode = doPCode;
- }
-
- @Override
- public SWF prepare(SWF instrSWF) {
- instrSWF = super.prepare(instrSWF);
- try {
- File fTempFile = new File(instrSWF.getFile());
- instrSWF.enableDebugging(true, new File("."), true, doPCode);
- FileOutputStream fos = new FileOutputStream(fTempFile);
- instrSWF.saveTo(fos);
- fos.close();
- if (!instrSWF.isAS3()) {
- //Read again, because line file offsets changed with adding debug tags
- //TODO: handle somehow without rereading?
- instrSWF = null;
- try (FileInputStream fis = new FileInputStream(fTempFile)) {
- instrSWF = new SWF(fis, false, false);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- if (instrSWF != null) {
- String swfFileName = fTempFile.getAbsolutePath();
- if (swfFileName.toLowerCase().endsWith(".swf")) {
- swfFileName = swfFileName.substring(0, swfFileName.length() - 4) + ".swd";
- } else {
- swfFileName = swfFileName + ".swd";
- }
- File swdFile = new File(swfFileName);
- if (doPCode) {
- instrSWF.generatePCodeSwdFile(swdFile, getPackBreakPoints(true));
- } else {
- instrSWF.generateSwdFile(swdFile, getPackBreakPoints(true));
- }
- }
- }
- } catch (IOException ex) {
- //ignore, return instrSWF
- }
- return instrSWF;
- }
- }
-
- private static void prepareSwf(SwfPreparation prep, File toPrepareFile, File origFile, List tempFiles) throws IOException {
- SWF instrSWF = null;
- try (FileInputStream fis = new FileInputStream(toPrepareFile)) {
- instrSWF = new SWF(fis, toPrepareFile.getAbsolutePath(), origFile.getName(), false);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- if (instrSWF != null) {
- for (Tag t : instrSWF.getLocalTags()) {
- if (t instanceof ImportTag) {
- ImportTag it = (ImportTag) t;
- String url = it.getUrl();
- File importedFile = new File(origFile.getParentFile(), url);
- if (importedFile.exists()) {
- File newTempFile = File.createTempFile("ffdec_run_import_", ".swf");
- it.setUrl("./" + newTempFile.getName());
- byte[] impData = Helper.readFile(importedFile.getAbsolutePath());
- Helper.writeFile(newTempFile.getAbsolutePath(), impData);
- tempFiles.add(newTempFile);
- prepareSwf(prep, newTempFile, importedFile, tempFiles);
- }
- }
- }
- if (prep != null) {
- instrSWF = prep.prepare(instrSWF);
- }
- try (FileOutputStream fos = new FileOutputStream(toPrepareFile)) {
- instrSWF.saveTo(fos);
- }
- }
- }
-
- public static void run(SWF swf) {
- String flashVars = "";//key=val&key2=val2
- String playerLocation = Configuration.playerLocation.get();
- if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
- View.showMessageDialog(null, AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- advancedSettings("paths");
- return;
- }
- if (swf == null) {
- return;
- }
- File tempFile;
- List tempFiles = new ArrayList<>();
- try {
- tempFile = File.createTempFile("ffdec_run_", ".swf");
-
- try (FileOutputStream fos = new FileOutputStream(tempFile)) {
- swf.saveTo(fos);
- }
-
- prepareSwf(new SwfRunPrepare(), tempFile, new File(swf.getFile()), tempFiles);
-
- } catch (IOException ex) {
- return;
-
- }
- if (tempFile != null) {
- synchronized (Main.class) {
- runTempFile = tempFile;
- runTempFiles = tempFiles;
- runProcessDebug = false;
- }
- runPlayer(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
- }
- }
-
- public static void runDebug(SWF swf, final boolean doPCode) {
- String flashVars = "";//key=val&key2=val2
- String playerLocation = Configuration.playerDebugLocation.get();
- if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
- View.showMessageDialog(null, AppStrings.translate("message.playerpath.debug.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- Main.advancedSettings("paths");
- return;
- }
- if (swf == null) {
- return;
- }
- File tempFile = null;
-
- try {
- tempFile = File.createTempFile("ffdec_debug_", ".swf");
- } catch (Exception ex) {
-
- }
-
- if (tempFile != null) {
- final File fTempFile = tempFile;
- final List tempFiles = new ArrayList<>();
- CancellableWorker instrumentWorker = new CancellableWorker() {
- @Override
- protected Object doInBackground() throws Exception {
-
- try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
- swf.saveTo(fos);
- }
- prepareSwf(new SwfDebugPrepare(doPCode), fTempFile, new File(swf.getFile()), tempFiles);
- return null;
- }
-
- @Override
- public void workerCancelled() {
- Main.stopWork();
- }
-
- @Override
- protected void done() {
- synchronized (Main.class) {
- runTempFile = fTempFile;
- runProcessDebug = true;
- runProcessDebugPCode = doPCode;
- runTempFiles = tempFiles;
- }
- Main.stopWork();
- Main.startDebugger();
- runPlayer(AppStrings.translate("work.debugging.wait"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
- }
- };
-
- Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
- instrumentWorker.execute();
- }
- }
-
- /* public static void debuggerNotSuspended() {
-
- }*/
- public static boolean isDebugging() {
- return isDebugRunning();
- }
-
- public synchronized static int getIp(Object pack) {
- return getDebugHandler().getBreakIp();
- }
-
- public synchronized static String getIpClass() {
- return getDebugHandler().getBreakScriptName();
- }
-
- public static synchronized boolean isBreakPointValid(String scriptName, int line) {
- return !getDebugHandler().isBreakpointInvalid(scriptName, line);
- }
-
- public synchronized static void addBreakPoint(String scriptName, int line) {
- getDebugHandler().addBreakPoint(scriptName, line);
- }
-
- public synchronized static void removeBreakPoint(String scriptName, int line) {
- getDebugHandler().removeBreakPoint(scriptName, line);
- }
-
- public synchronized static boolean toggleBreakPoint(String scriptName, int line) {
- if (getDebugHandler().isBreakpointToAdd(scriptName, line) || getDebugHandler().isBreakpointConfirmed(scriptName, line) || getDebugHandler().isBreakpointInvalid(scriptName, line)) {
- getDebugHandler().removeBreakPoint(scriptName, line);
- return false;
- } else {
- getDebugHandler().addBreakPoint(scriptName, line);
- return true;
- }
- }
-
- public synchronized static Map> getPackBreakPoints(boolean validOnly) {
- return getDebugHandler().getAllBreakPoints(validOnly);
- }
-
- public synchronized static Set getScriptBreakPoints(String pack, boolean onlyValid) {
- return getDebugHandler().getBreakPoints(pack, onlyValid);
- }
-
- public static DebuggerHandler getDebugHandler() {
- return debugHandler;
- }
-
- public static void ensureMainFrame() {
- if (mainFrame == null) {
- synchronized (Main.class) {
- if (mainFrame == null) {
- MainFrame frame;
- if (Configuration.useRibbonInterface.get()) {
- frame = new MainFrameRibbon();
- } else {
- frame = new MainFrameClassic();
- }
- frame.getPanel().setErrorState(ErrorLogFrame.getInstance().getErrorState());
- mainFrame = frame;
- }
- }
- }
- }
-
- public static MainFrame getMainFrame() {
- return mainFrame;
- }
-
- public static void loadFromCache() {
- if (loadFromCacheFrame == null) {
- loadFromCacheFrame = new LoadFromCacheFrame();
- }
- loadFromCacheFrame.setVisible(true);
- }
-
- public static void loadFromMemory() {
- if (loadFromMemoryFrame == null) {
- loadFromMemoryFrame = new LoadFromMemoryFrame(mainFrame);
- }
- loadFromMemoryFrame.setVisible(true);
- }
-
- public static void setVariable(long parentId, String varName, int valueType, Object value) {
- getDebugHandler().setVariable(parentId, varName, valueType, value);
- }
-
- public static void setSubLimiter(boolean value) {
- if (value) {
- AVM2Code.toSourceLimit = Configuration.sublimiter.get();
- } else {
- AVM2Code.toSourceLimit = -1;
- }
- }
-
- public synchronized static boolean isInited() {
- return inited;
- }
-
- public synchronized static void setSessionLoaded(boolean v) {
- inited = v;
- }
-
- public static boolean isWorking() {
- return working;
- }
-
- public static void startProxy(int port) {
- if (proxyFrame == null) {
- proxyFrame = new ProxyFrame(mainFrame);
- }
-
- proxyFrame.setPort(port);
- addTrayIcon();
- switchProxy();
- }
-
- public static void showProxy() {
- if (proxyFrame == null) {
- proxyFrame = new ProxyFrame(mainFrame);
- }
- proxyFrame.setVisible(true);
- proxyFrame.setState(Frame.NORMAL);
- }
-
- public static void startWork(String name, CancellableWorker worker) {
- startWork(name, -1, worker);
- }
-
- public static void startWork(final String name, final int percent, final CancellableWorker worker) {
- working = true;
- View.execInEventDispatchLater(() -> {
- if (mainFrame != null) {
- mainFrame.getPanel().setWorkStatus(name, worker);
- if (percent == -1) {
- mainFrame.getPanel().hidePercent();
- } else {
- mainFrame.getPanel().setPercent(percent);
- }
- }
- if (loadingDialog != null) {
- loadingDialog.setDetail(name);
- loadingDialog.setPercent(percent);
- }
- if (CommandLineArgumentParser.isCommandLineMode()) {
- System.out.println(name);
- }
- });
- }
-
- public static void stopWork() {
- working = false;
- View.execInEventDispatchLater(() -> {
- if (mainFrame != null) {
- mainFrame.getPanel().setWorkStatus("", null);
- }
- if (loadingDialog != null) {
- loadingDialog.setDetail("");
- }
- });
- }
-
- public static SWFList parseSWF(SWFSourceInfo sourceInfo) throws Exception {
- SWFList result = new SWFList();
-
- InputStream inputStream = sourceInfo.getInputStream();
- SWFBundle bundle = null;
- FileInputStream fis = null;
- if (inputStream == null) {
- inputStream = new BufferedInputStream(fis = new FileInputStream(sourceInfo.getFile()));
- bundle = sourceInfo.getBundle(false, SearchMode.ALL);
- logger.log(Level.INFO, "Load file: {0}", sourceInfo.getFile());
- } else if (inputStream instanceof SeekableInputStream
- || inputStream instanceof BufferedInputStream) {
- try {
- inputStream.reset();
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- logger.log(Level.INFO, "Load stream: {0}", sourceInfo.getFileTitle());
- }
-
- Stopwatch sw = Stopwatch.startNew();
- if (bundle != null) {
- result.bundle = bundle;
- result.name = new File(sourceInfo.getFileTitleOrName()).getName();
- for (Entry streamEntry : bundle.getAll().entrySet()) {
- InputStream stream = streamEntry.getValue();
- stream.reset();
- CancellableWorker worker = new CancellableWorker() {
- @Override
- public SWF doInBackground() throws Exception {
- final CancellableWorker worker = this;
- SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() {
- @Override
- public void progress(int p) {
- startWork(AppStrings.translate("work.reading.swf"), p, worker);
- }
- }, Configuration.parallelSpeedUp.get());
- return swf;
- }
- };
- loadingDialog.setWroker(worker);
- worker.execute();
-
- try {
- result.add(worker.get());
- } catch (CancellationException ex) {
- logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", streamEntry.getKey());
- }
- }
- } else {
- InputStream fInputStream = inputStream;
-
- final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
-
- CancellableWorker worker = new CancellableWorker() {
- private boolean yestoall = false;
-
- private boolean notoall = false;
-
- private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
- final CancellableWorker worker = this;
-
- SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
- @Override
- public void progress(int p) {
- startWork(AppStrings.translate("work.reading.swf"), p, worker);
- }
- }, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
- @Override
- public SWF resolveUrl(final String url) {
- int opt = -1;
- if (!(yestoall || notoall)) {
- opt = View.showOptionDialog(null, AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
- if (opt == 2) {
- yestoall = true;
- }
- if (opt == 3) {
- notoall = true;
- }
- }
-
- if (yestoall) {
- opt = 0; // yes
- } else if (notoall) {
- opt = 1; // no
- }
-
- if (opt == 1) //no
- {
- return null;
- }
-
- if (url.startsWith("http://") || url.startsWith("https://")) {
- try {
- URL u = new URL(url);
- return open(u.openStream(), null, url); //?
- } catch (Exception ex) {
- //ignore
- }
- } else {
- File f = new File(new File(file).getParentFile(), url);
- if (f.exists()) {
- try {
- return open(new FileInputStream(f), f.getAbsolutePath(), f.getName());
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- Reference ret = new Reference<>(null);
- View.execInEventDispatch(new Runnable() {
- @Override
- public void run() {
-
- while (JOptionPane.YES_OPTION == View.showConfirmDialog(null, AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
-
- JFileChooser fc = new JFileChooser();
- fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
- FileFilter allSupportedFilter = new FileFilter() {
- private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
-
- @Override
- public boolean accept(File f) {
- String name = f.getName().toLowerCase();
- for (String ext : supportedExtensions) {
- if (name.endsWith(ext)) {
- return true;
- }
- }
- return f.isDirectory();
- }
-
- @Override
- public String getDescription() {
- String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
- return AppStrings.translate("filter.supported") + " (" + exts + ")";
- }
- };
- fc.setFileFilter(allSupportedFilter);
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
- fc.addChoosableFileFilter(swfFilter);
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
- fc.addChoosableFileFilter(gfxFilter);
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- int returnVal = fc.showOpenDialog(f);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
- File selFile = Helper.fixDialogFile(fc.getSelectedFile());
- try {
- ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
- break;
- } catch (Exception ex) {
- //ignore;
- }
- } else {
- break;
- }
- }
- }
- });
- return ret.getVal();
- }
- });
- return swf;
- }
-
- @Override
- public SWF doInBackground() throws Exception {
- return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
- }
- };
- if (loadingDialog != null) {
- loadingDialog.setWroker(worker);
- }
- worker.execute();
-
- try {
- result.add(worker.get());
- } catch (CancellationException ex) {
- logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", sourceInfo.getFileTitleOrName());
- }
- }
-
- if (fis != null) {
- logger.log(Level.INFO, "File loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
- fis.close();
- } else {
- logger.log(Level.INFO, "Stream loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
- }
-
- result.sourceInfo = sourceInfo;
- for (SWF swf : result) {
- logger.log(Level.INFO, "");
- logger.log(Level.INFO, "== File information ==");
- logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
- logger.log(Level.INFO, "Flash version: {0}", swf.version);
- int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
- int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
- logger.log(Level.INFO, "Width: {0}", width);
- logger.log(Level.INFO, "Height: {0}", height);
-
- swf.swfList = result;
- swf.addEventListener(new EventListener() {
- @Override
- public void handleExportingEvent(String type, int index, int count, Object data) {
- String text = AppStrings.translate("work.exporting");
- if (type != null && type.length() > 0) {
- text += " " + type;
- }
-
- startWork(text + " " + index + "/" + count + " " + data, null);
- }
-
- @Override
- public void handleExportedEvent(String type, int index, int count, Object data) {
- String text = AppStrings.translate("work.exported");
- if (type != null && type.length() > 0) {
- text += " " + type;
- }
-
- startWork(text + " " + index + "/" + count + " " + data, null);
- }
-
- @Override
- public void handleEvent(String event, Object data) {
- if (event.equals("exporting") || event.equals("exported")) {
- throw new Error("Event is not supported by this handler.");
- }
- if (event.equals("getVariables")) {
- startWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data, null);
- }
- if (event.equals("deobfuscate")) {
- startWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data, null);
- }
- if (event.equals("rename")) {
- startWork(AppStrings.translate("work.renaming") + "..." + (String) data, null);
- }
- }
- });
- }
-
- return result;
- }
-
- public static void saveFile(SWF swf, String outfile) throws IOException {
- saveFile(swf, outfile, SaveFileMode.SAVE, null);
- }
-
- public static void saveFile(SWF swf, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
- if (mode == SaveFileMode.SAVEAS && !swf.swfList.isBundle()) {
- swf.setFile(outfile);
- swf.swfList.sourceInfo.setFile(outfile);
- }
- File outfileF = new File(outfile);
- File tmpFile = new File(outfile + ".tmp");
- try (FileOutputStream fos = new FileOutputStream(tmpFile);
- BufferedOutputStream bos = new BufferedOutputStream(fos)) {
- if (mode == SaveFileMode.EXE) {
- switch (exeExportMode) {
- case WRAPPER:
- InputStream exeStream = View.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/Swf2Exe.bin");
- Helper.copyStream(exeStream, bos);
- int width = swf.displayRect.Xmax - swf.displayRect.Xmin;
- int height = swf.displayRect.Ymax - swf.displayRect.Ymin;
- bos.write(width & 0xff);
- bos.write((width >> 8) & 0xff);
- bos.write((width >> 16) & 0xff);
- bos.write((width >> 24) & 0xff);
- bos.write(height & 0xff);
- bos.write((height >> 8) & 0xff);
- bos.write((height >> 16) & 0xff);
- bos.write((height >> 24) & 0xff);
- bos.write(Configuration.saveAsExeScaleMode.get());
- break;
- case PROJECTOR_WIN:
- case PROJECTOR_MAC:
- case PROJECTOR_LINUX:
- File projectorFile = Configuration.getProjectorFile(exeExportMode);
- if (projectorFile == null) {
- String message = "Projector not found, please place it to " + Configuration.getProjectorPath();
- logger.log(Level.SEVERE, message);
- throw new IOException(message);
- }
- Helper.copyStream(new FileInputStream(projectorFile), bos);
- bos.flush();
- break;
- }
- }
-
- long pos = fos.getChannel().position();
- swf.saveTo(bos);
-
- if (mode == SaveFileMode.EXE) {
- switch (exeExportMode) {
- case PROJECTOR_WIN:
- case PROJECTOR_MAC:
- case PROJECTOR_LINUX:
- bos.flush();
- int swfSize = (int) (fos.getChannel().position() - pos);
-
- // write magic number
- bos.write(0x56);
- bos.write(0x34);
- bos.write(0x12);
- bos.write(0xfa);
-
- bos.write(swfSize & 0xff);
- bos.write((swfSize >> 8) & 0xff);
- bos.write((swfSize >> 16) & 0xff);
- bos.write((swfSize >> 24) & 0xff);
- }
- }
- }
- if (tmpFile.exists()) {
- if (tmpFile.length() > 0) {
- outfileF.delete();
- if (!tmpFile.renameTo(outfileF)) {
- tmpFile.delete();
- throw new IOException("Cannot access " + outfile);
- }
- } else {
- throw new IOException("Output is empty");
- }
- } else {
- throw new IOException("Output not found");
- }
- }
-
- private static class OpenFileWorker extends SwingWorker {
-
- private final SWFSourceInfo[] sourceInfos;
-
- private final Runnable executeAfterOpen;
-
- private final int[] reloadIndices;
-
- public OpenFileWorker(SWFSourceInfo sourceInfo) {
- this(sourceInfo, -1);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, int reloadIndex) {
- this(sourceInfo, null, reloadIndex);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
- this(sourceInfo, executeAfterOpen, -1);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
- this.sourceInfos = new SWFSourceInfo[]{sourceInfo};
- this.executeAfterOpen = executeAfterOpen;
- this.reloadIndices = new int[]{reloadIndex};
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
- this(sourceInfos, null, null);
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
- this(sourceInfos, executeAfterOpen, null);
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
- this.sourceInfos = sourceInfos;
- this.executeAfterOpen = executeAfterOpen;
- int[] indices = new int[sourceInfos.length];
- for (int i = 0; i < indices.length; i++) {
- indices[i] = -1;
- }
- this.reloadIndices = reloadIndices == null ? indices : reloadIndices;
- }
-
- @Override
- protected Object doInBackground() throws Exception {
- boolean first = true;
- SWF firstSWF = null;
- for (int index = 0; index < sourceInfos.length; index++) {
- SWFSourceInfo sourceInfo = sourceInfos[index];
- SWFList swfs = null;
- try {
- Main.startWork(AppStrings.translate("work.reading.swf") + "...", null);
- try {
- swfs = parseSWF(sourceInfo);
- } catch (ExecutionException ex) {
- Throwable cause = ex.getCause();
- if (cause instanceof SwfOpenException) {
- throw (SwfOpenException) cause;
- }
-
- throw ex;
- }
- } catch (OutOfMemoryError ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
- continue;
- } catch (SwfOpenException ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, ex.getMessage());
- continue;
- } catch (Exception ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, "Cannot load SWF file.");
- continue;
- }
-
- final SWFList swfs1 = swfs;
- final boolean first1 = first;
- first = false;
- if (firstSWF == null && swfs1.size() > 0) {
- firstSWF = swfs1.get(0);
- }
-
- final int findex = index;
- try {
- View.execInEventDispatch(() -> {
- Main.startWork(AppStrings.translate("work.creatingwindow") + "...", null);
- ensureMainFrame();
- if (reloadIndices[findex] > -1) {
- mainFrame.getPanel().loadSwfAtPos(swfs1, reloadIndices[findex]);
- } else {
- mainFrame.getPanel().load(swfs1, first1);
- }
- });
- } catch (Exception ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- loadingDialog.setVisible(false);
- shouldCloseWhenClosingLoadingDialog = false;
-
- final SWF fswf = firstSWF;
- View.execInEventDispatch(() -> {
- if (mainFrame != null) {
- mainFrame.setVisible(true);
- }
-
- Main.stopWork();
-
- if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) {
- mainFrame.getPanel().gotoDocumentClass(fswf);
- }
-
- if (mainFrame != null && fswf != null) {
- SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortFileName());
- if (swfConf != null) {
- String pathStr = swfConf.lastSelectedPath;
- mainFrame.getPanel().tagTree.setSelectionPathString(pathStr);
- }
- }
-
- if (executeAfterOpen != null) {
- executeAfterOpen.run();
- }
- });
-
- return true;
- }
- }
-
- public static boolean reloadSWFs() {
- CancellableWorker.cancelBackgroundThreads();
- if (Main.sourceInfos.isEmpty()) {
- Helper.freeMem();
- showModeFrame();
- return true;
- } else {
- SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
- sourceInfos.toArray(sourceInfosCopy);
- sourceInfos.clear();
- openFile(sourceInfosCopy);
- return true;
- }
- }
-
- public static void reloadApp() {
- if (debugDialog != null) {
- debugDialog.setVisible(false);
- debugDialog.dispose();
- debugDialog = null;
- }
- if (loadingDialog != null) {
- synchronized (Main.class) {
- if (loadingDialog != null) {
- loadingDialog.setVisible(false);
- loadingDialog.dispose();
- loadingDialog = null;
- }
- }
- }
- if (proxyFrame != null) {
- proxyFrame.setVisible(false);
- proxyFrame.dispose();
- proxyFrame = null;
- }
- if (loadFromMemoryFrame != null) {
- loadFromMemoryFrame.setVisible(false);
- loadFromMemoryFrame.dispose();
- loadFromMemoryFrame = null;
- }
- if (loadFromCacheFrame != null) {
- loadFromCacheFrame.setVisible(false);
- loadFromCacheFrame.dispose();
- loadFromCacheFrame = null;
- }
- if (mainFrame != null) {
- mainFrame.setVisible(false);
- mainFrame.getPanel().closeAll(false);
- mainFrame.dispose();
- mainFrame = null;
- }
- FontTag.reload();
- Cache.clearAll();
- initGui();
- reloadSWFs();
- }
-
- public static OpenFileResult openFile(String swfFile, String fileTitle) {
- return openFile(swfFile, fileTitle, null);
- }
-
- public static OpenFileResult openFile(String swfFile, String fileTitle, Runnable executeAfterOpen) {
- try {
- File file = new File(swfFile);
- if (!file.exists()) {
- View.showMessageDialog(null, AppStrings.translate("open.error.fileNotFound"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
- return OpenFileResult.NOT_FOUND;
- }
- swfFile = file.getCanonicalPath();
- Configuration.addRecentFile(swfFile);
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
- OpenFileResult openResult = openFile(sourceInfo);
- return openResult;
- } catch (IOException ex) {
- View.showMessageDialog(null, AppStrings.translate("open.error.cannotOpen"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
- return OpenFileResult.ERROR;
- }
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
- return openFile(new SWFSourceInfo[]{sourceInfo});
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
- return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
- return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
- return openFile(newSourceInfos, null);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
- return openFile(newSourceInfos, executeAfterOpen, null);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
- if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
- sourceInfos.clear();
- mainFrame.getPanel().closeAll(false);
- mainFrame.setVisible(false);
- Helper.freeMem();
- reloadIndices = null;
- }
-
- loadingDialog.setVisible(true);
-
- OpenFileWorker wrk = new OpenFileWorker(newSourceInfos, executeAfterOpen, reloadIndices);
- wrk.execute();
- if (reloadIndices == null) {
- sourceInfos.addAll(Arrays.asList(newSourceInfos));
- } else {
- for (int i = 0; i < reloadIndices.length; i++) {
- sourceInfos.set(reloadIndices[i], newSourceInfos[i]);
- }
- }
- return OpenFileResult.OK;
- }
-
- public static void closeFile(SWFList swf) {
- sourceInfos.remove(swf.sourceInfo);
- mainFrame.getPanel().close(swf);
- }
-
- public static void reloadFile(SWFList swf) {
- //mainFrame.getPanel().close(swf);
- openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
- }
-
- public static boolean closeAll() {
- boolean closeResult = mainFrame.getPanel().closeAll(true);
- if (closeResult) {
- sourceInfos.clear();
- }
-
- return closeResult;
- }
-
- public static boolean saveFileDialog(SWF swf, final SaveFileMode mode) {
- JFileChooser fc = new JFileChooser();
- fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
- String ext = ".swf";
- switch (mode) {
- case SAVE:
- case SAVEAS:
- if (swf.getFile() != null) {
- ext = Path.getExtension(swf.getFile());
- }
- break;
- case EXE:
- ext = ".exe";
- break;
- }
-
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
-
- ExeExportMode exeExportMode = null;
- if (mode == SaveFileMode.EXE) {
- exeExportMode = Configuration.exeExportMode.get();
- if (exeExportMode == null) {
- exeExportMode = ExeExportMode.WRAPPER;
- }
- String filterDescription = null;
- switch (exeExportMode) {
- case WRAPPER:
- case PROJECTOR_WIN:
- ext = ".exe";
- filterDescription = "filter.exe";
- break;
- case PROJECTOR_MAC:
- ext = ".dmg";
- filterDescription = "filter.dmg";
- break;
- case PROJECTOR_LINUX:
- // linux projector is compressed with tar.gz
- // todo: decompress
- ext = "";
- filterDescription = "filter.linuxExe";
- break;
- }
-
- String fext = ext;
- String ffilterDescription = filterDescription;
- FileFilter exeFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(fext)) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate(ffilterDescription);
- }
- };
- fc.setFileFilter(exeFilter);
- } else if (swf.gfx) {
- fc.addChoosableFileFilter(swfFilter);
- fc.setFileFilter(gfxFilter);
- } else {
- fc.setFileFilter(swfFilter);
- fc.addChoosableFileFilter(gfxFilter);
- }
- final String extension = ext;
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- if (fc.showSaveDialog(f) == JFileChooser.APPROVE_OPTION) {
- File file = Helper.fixDialogFile(fc.getSelectedFile());
- FileFilter selFilter = fc.getFileFilter();
- try {
- String fileName = file.getAbsolutePath();
- if (selFilter == swfFilter) {
- if (!fileName.toLowerCase().endsWith(extension)) {
- fileName += extension;
- }
- swf.gfx = false;
- }
- if (selFilter == gfxFilter) {
- if (!fileName.toLowerCase().endsWith(".gfx")) {
- fileName += ".gfx";
- }
- swf.gfx = true;
- }
- Main.saveFile(swf, fileName, mode, exeExportMode);
- Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
- return true;
- } catch (IOException ex) {
- View.showMessageDialog(null, AppStrings.translate("error.file.write"));
- }
- }
- return false;
- }
-
- public static boolean openFileDialog() {
- JFileChooser fc = new JFileChooser();
- if (Configuration.openMultipleFiles.get()) {
- fc.setMultiSelectionEnabled(true);
- }
- fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
- FileFilter allSupportedFilter = new FileFilter() {
- private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip"};
-
- @Override
- public boolean accept(File f) {
- String name = f.getName().toLowerCase();
- for (String ext : supportedExtensions) {
- if (name.endsWith(ext)) {
- return true;
- }
- }
- return f.isDirectory();
- }
-
- @Override
- public String getDescription() {
- String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
- return AppStrings.translate("filter.supported") + " (" + exts + ")";
- }
- };
- fc.setFileFilter(allSupportedFilter);
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
- fc.addChoosableFileFilter(swfFilter);
-
- FileFilter swcFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swc")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swc");
- }
- };
- fc.addChoosableFileFilter(swcFilter);
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
- fc.addChoosableFileFilter(gfxFilter);
-
- FileFilter zipFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".zip")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.zip");
- }
- };
- fc.addChoosableFileFilter(zipFilter);
-
- FileFilter binaryFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return true;
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.binary");
- }
- };
- fc.addChoosableFileFilter(binaryFilter);
-
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- int returnVal = fc.showOpenDialog(f);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
- File[] selFiles = fc.getSelectedFiles();
- for (File file : selFiles) {
- File selfile = Helper.fixDialogFile(file);
- Main.openFile(selfile.getAbsolutePath(), null);
- }
- return true;
- } else {
- return false;
- }
- }
-
- public static void displayErrorFrame() {
- ErrorLogFrame.getInstance().setVisible(true);
- }
-
- private static String md5(byte data[]) {
- try {
- java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
- byte[] array = md.digest(data);
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < array.length; ++i) {
- sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
- }
- return sb.toString();
- } catch (java.security.NoSuchAlgorithmException e) {
- }
- return null;
- }
-
- private static void initGui() {
- if (GraphicsEnvironment.isHeadless()) {
- System.err.println("Error: Your system does not support Graphic User Interface");
- exit();
- }
-
- System.setProperty("sun.java2d.d3d", "false");
- System.setProperty("sun.java2d.noddraw", "true");
-
- if (Configuration.hwAcceleratedGraphics.get()) {
- System.setProperty("sun.java2d.opengl", Configuration._debugMode.get() ? "True" : "true");
- } else {
- System.setProperty("sun.java2d.opengl", "false");
- }
-
- initUiLang();
-
- if (Configuration.useRibbonInterface.get()) {
- View.setLookAndFeel();
- } else {
- try {
- UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null);
- UIManager.put("Tree.expandedIcon", null);
- UIManager.put("Tree.collapsedIcon", null);
- UIManager.put("ColorChooserUI", null);
- UIManager.put("ColorChooser.swatchesRecentSwatchSize", null);
- UIManager.put("ColorChooser.swatchesSwatchSize", null);
- UIManager.put("RibbonApplicationMenuPopupPanelUI", null);
- UIManager.put("RibbonApplicationMenuButtonUI", null);
- UIManager.put("ProgressBarUI", null);
- UIManager.put("TextField.background", null);
- UIManager.put("FormattedTextField.background", null);
- UIManager.put("CommandButtonUI", null);
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- View.execInEventDispatch(() -> {
- ErrorLogFrame.createNewInstance();
-
- autoCheckForUpdates();
- offerAssociation();
- loadingDialog = new LoadingDialog();
-
- DebuggerTools.initDebugger().addMessageListener(new DebugListener() {
- @Override
- public void onMessage(String clientId, String msg) {
- }
-
- @Override
- public void onLoaderURL(String clientId, String url) {
- }
-
- @Override
- public void onLoaderBytes(String clientId, byte[] data) {
- String hash = md5(data);
- for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
- for (int s = 0; s < sl.size(); s++) {
- String t = sl.get(s).getFileTitle();
- if (t == null) {
- t = "";
- }
- if (t.endsWith(":" + hash)) { //this one is already opened
- return;
- }
- }
- }
- SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
-
- String title = swf == null ? "?" : swf.getFileTitle();
- title = title + ":" + hash;
- String tfile;
- try {
- tfile = tempFile(title);
- Helper.writeFile(tfile, data);
- openFile(new SWFSourceInfo(null, tfile, title));
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "Cannot create tempfile");
- }
- }
-
- @Override
- public void onFinish(String clientId) {
- }
- });
-
- try {
- flashDebugger = new Debugger();
- debugHandler = new DebuggerHandler();
- debugHandler.addBreakListener(new DebuggerHandler.BreakListener() {
- @Override
- public void doContinue() {
- mainFrame.getPanel().clearDebuggerColors();
- }
-
- @Override
- public void breakAt(String scriptName, int line, final int classIndex, final int traitIndex, final int methodIndex) {
- View.execInEventDispatch(new Runnable() {
- @Override
- public void run() {
- mainFrame.getPanel().gotoScriptLine(getMainFrame().getPanel().getCurrentSwf(), scriptName, line, classIndex, traitIndex, methodIndex);
- }
- });
- }
- });
- debugHandler.addConnectionListener(new DebuggerHandler.ConnectionListener() {
- @Override
- public void connected() {
- Main.mainFrame.getMenu().updateComponents();
- }
-
- @Override
- public void disconnected() {
- if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
- Main.mainFrame.getPanel().refreshBreakPoints();
- }
- }
- });
- flashDebugger.addConnectionListener(debugHandler);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "eeex", ex);
- }
- });
- }
-
- public static void startDebugger() {
- flashDebugger.startDebugger();
- }
-
- public static void stopDebugger() {
- flashDebugger.stopDebugger();
- }
-
- public static void showModeFrame() {
- ensureMainFrame();
- mainFrame.setVisible(true);
- }
-
- private static void offerAssociation() {
- boolean offered = Configuration.offeredAssociation.get();
- if (!offered) {
- if (Platform.isWindows()) {
- if ((!ContextMenuTools.isAddedToContextMenu()) && View.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
- ContextMenuTools.addToContextMenu(true, false);
- }
- }
-
- Configuration.offeredAssociation.set(true);
- }
- }
-
- public static void initUiLang() {
- if (GraphicsEnvironment.isHeadless()) { //No GUI in OS
- return;
- }
- try {
- Class> cl = Class.forName("org.pushingpixels.substance.api.SubstanceLookAndFeel");
- Field field = cl.getDeclaredField("LABEL_BUNDLE");
- field.setAccessible(true);
- field.set(null, null);
- } catch (Throwable ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- UIManager.put("OptionPane.okButtonText", AppStrings.translate("button.ok"));
- UIManager.put("OptionPane.yesButtonText", AppStrings.translate("button.yes"));
- UIManager.put("OptionPane.noButtonText", AppStrings.translate("button.no"));
- UIManager.put("OptionPane.cancelButtonText", AppStrings.translate("button.cancel"));
- UIManager.put("OptionPane.messageDialogTitle", AppStrings.translate("dialog.message.title"));
- UIManager.put("OptionPane.titleText", AppStrings.translate("dialog.select.title"));
-
- UIManager.put("FileChooser.acceptAllFileFilterText", AppStrings.translate("FileChooser.acceptAllFileFilterText"));
- UIManager.put("FileChooser.lookInLabelText", AppStrings.translate("FileChooser.lookInLabelText"));
- UIManager.put("FileChooser.cancelButtonText", AppStrings.translate("button.cancel"));
- UIManager.put("FileChooser.cancelButtonToolTipText", AppStrings.translate("button.cancel"));
- UIManager.put("FileChooser.openButtonText", AppStrings.translate("FileChooser.openButtonText"));
- UIManager.put("FileChooser.openButtonToolTipText", AppStrings.translate("FileChooser.openButtonToolTipText"));
- UIManager.put("FileChooser.filesOfTypeLabelText", AppStrings.translate("FileChooser.filesOfTypeLabelText"));
- UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
- UIManager.put("FileChooser.listViewButtonToolTipText", AppStrings.translate("FileChooser.listViewButtonToolTipText"));
- UIManager.put("FileChooser.listViewButtonAccessibleName", AppStrings.translate("FileChooser.listViewButtonAccessibleName"));
- UIManager.put("FileChooser.detailsViewButtonToolTipText", AppStrings.translate("FileChooser.detailsViewButtonToolTipText"));
- UIManager.put("FileChooser.detailsViewButtonAccessibleName", AppStrings.translate("FileChooser.detailsViewButtonAccessibleName"));
- UIManager.put("FileChooser.upFolderToolTipText", AppStrings.translate("FileChooser.upFolderToolTipText"));
- UIManager.put("FileChooser.upFolderAccessibleName", AppStrings.translate("FileChooser.upFolderAccessibleName"));
- UIManager.put("FileChooser.homeFolderToolTipText", AppStrings.translate("FileChooser.homeFolderToolTipText"));
- UIManager.put("FileChooser.homeFolderAccessibleName", AppStrings.translate("FileChooser.homeFolderAccessibleName"));
- UIManager.put("FileChooser.fileNameHeaderText", AppStrings.translate("FileChooser.fileNameHeaderText"));
- UIManager.put("FileChooser.fileSizeHeaderText", AppStrings.translate("FileChooser.fileSizeHeaderText"));
- UIManager.put("FileChooser.fileTypeHeaderText", AppStrings.translate("FileChooser.fileTypeHeaderText"));
- UIManager.put("FileChooser.fileDateHeaderText", AppStrings.translate("FileChooser.fileDateHeaderText"));
- UIManager.put("FileChooser.fileAttrHeaderText", AppStrings.translate("FileChooser.fileAttrHeaderText"));
- UIManager.put("FileChooser.openDialogTitleText", AppStrings.translate("FileChooser.openDialogTitleText"));
- UIManager.put("FileChooser.directoryDescriptionText", AppStrings.translate("FileChooser.directoryDescriptionText"));
- UIManager.put("FileChooser.directoryOpenButtonText", AppStrings.translate("FileChooser.directoryOpenButtonText"));
- UIManager.put("FileChooser.directoryOpenButtonToolTipText", AppStrings.translate("FileChooser.directoryOpenButtonToolTipText"));
- UIManager.put("FileChooser.fileDescriptionText", AppStrings.translate("FileChooser.fileDescriptionText"));
- UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
- UIManager.put("FileChooser.helpButtonText", AppStrings.translate("FileChooser.helpButtonText"));
- UIManager.put("FileChooser.helpButtonToolTipText", AppStrings.translate("FileChooser.helpButtonToolTipText"));
- UIManager.put("FileChooser.newFolderAccessibleName", AppStrings.translate("FileChooser.newFolderAccessibleName"));
- UIManager.put("FileChooser.newFolderErrorText", AppStrings.translate("FileChooser.newFolderErrorText"));
- UIManager.put("FileChooser.newFolderToolTipText", AppStrings.translate("FileChooser.newFolderToolTipText"));
- UIManager.put("FileChooser.other.newFolder", AppStrings.translate("FileChooser.other.newFolder"));
- UIManager.put("FileChooser.other.newFolder.subsequent", AppStrings.translate("FileChooser.other.newFolder.subsequent"));
- UIManager.put("FileChooser.win32.newFolder", AppStrings.translate("FileChooser.win32.newFolder"));
- UIManager.put("FileChooser.win32.newFolder.subsequent", AppStrings.translate("FileChooser.win32.newFolder.subsequent"));
- UIManager.put("FileChooser.saveButtonText", AppStrings.translate("FileChooser.saveButtonText"));
- UIManager.put("FileChooser.saveButtonToolTipText", AppStrings.translate("FileChooser.saveButtonToolTipText"));
- UIManager.put("FileChooser.saveDialogTitleText", AppStrings.translate("FileChooser.saveDialogTitleText"));
- UIManager.put("FileChooser.saveInLabelText", AppStrings.translate("FileChooser.saveInLabelText"));
- UIManager.put("FileChooser.updateButtonText", AppStrings.translate("FileChooser.updateButtonText"));
- UIManager.put("FileChooser.updateButtonToolTipText", AppStrings.translate("FileChooser.updateButtonToolTipText"));
-
- UIManager.put("FileChooser.detailsViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.detailsViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewButtonToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.fileAttrHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileAttrHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileDateHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileDateHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileNameHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileNameHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.fileNameLabel.textAndMnemonic"));
- UIManager.put("FileChooser.fileSizeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileSizeHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileTypeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileTypeHeader.textAndMnemonic"));
- UIManager.put("FileChooser.filesOfTypeLabel.textAndMnemonic", AppStrings.translate("FileChooser.filesOfTypeLabel.textAndMnemonic"));
- UIManager.put("FileChooser.folderNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.folderNameLabel.textAndMnemonic"));
- UIManager.put("FileChooser.homeFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.homeFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.listViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.listViewActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.listViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.listViewButtonToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.lookInLabel.textAndMnemonic", AppStrings.translate("FileChooser.lookInLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.newFolderActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.newFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.refreshActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.refreshActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.saveInLabel.textAndMnemonic", AppStrings.translate("FileChooser.saveInLabel.textAndMnemonic"));
- UIManager.put("FileChooser.upFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.upFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.viewMenuButtonAccessibleName", AppStrings.translate("FileChooser.viewMenuButtonAccessibleName"));
- UIManager.put("FileChooser.viewMenuButtonToolTipText", AppStrings.translate("FileChooser.viewMenuButtonToolTipText"));
- UIManager.put("FileChooser.viewMenuLabel.textAndMnemonic", AppStrings.translate("FileChooser.viewMenuLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderActionLabelText", AppStrings.translate("FileChooser.newFolderActionLabelText"));
- UIManager.put("FileChooser.listViewActionLabelText", AppStrings.translate("FileChooser.listViewActionLabelText"));
- UIManager.put("FileChooser.detailsViewActionLabelText", AppStrings.translate("FileChooser.detailsViewActionLabelText"));
- UIManager.put("FileChooser.refreshActionLabelText", AppStrings.translate("FileChooser.refreshActionLabelText"));
- UIManager.put("FileChooser.sortMenuLabelText", AppStrings.translate("FileChooser.sortMenuLabelText"));
- UIManager.put("FileChooser.viewMenuLabelText", AppStrings.translate("FileChooser.viewMenuLabelText"));
- UIManager.put("FileChooser.fileSizeKiloBytes", AppStrings.translate("FileChooser.fileSizeKiloBytes"));
- UIManager.put("FileChooser.fileSizeMegaBytes", AppStrings.translate("FileChooser.fileSizeMegaBytes"));
- UIManager.put("FileChooser.fileSizeGigaBytes", AppStrings.translate("FileChooser.fileSizeGigaBytes"));
- UIManager.put("FileChooser.folderNameLabelText", AppStrings.translate("FileChooser.folderNameLabelText"));
-
- UIManager.put("ColorChooser.okText", AppStrings.translate("ColorChooser.okText"));
- UIManager.put("ColorChooser.cancelText", AppStrings.translate("ColorChooser.cancelText"));
- UIManager.put("ColorChooser.resetText", AppStrings.translate("ColorChooser.resetText"));
- UIManager.put("ColorChooser.previewText", AppStrings.translate("ColorChooser.previewText"));
- UIManager.put("ColorChooser.swatchesNameText", AppStrings.translate("ColorChooser.swatchesNameText"));
- UIManager.put("ColorChooser.swatchesRecentText", AppStrings.translate("ColorChooser.swatchesRecentText"));
- UIManager.put("ColorChooser.sampleText", AppStrings.translate("ColorChooser.sampleText"));
-
- }
-
- public static void initLang() {
- if (!Configuration.locale.hasValue()) {
- if (Platform.isWindows()) {
- //Load from Installer
- String uninstKey = "{E618D276-6596-41F4-8A98-447D442A77DB}_is1";
- uninstKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uninstKey;
- try {
- if (Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey)) {
- if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language")) {
- String installedLoc = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language");
- int lcid = Integer.parseInt(installedLoc);
- char[] buf = new char[9];
- int cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO639LANGNAME, buf, 9);
- String langCode = new String(buf, 0, cnt).trim().toLowerCase();
-
- cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO3166CTRYNAME, buf, 9);
- String countryCode = new String(buf, 0, cnt).trim().toLowerCase();
-
- List langs = Arrays.asList(SelectLanguageDialog.getAvailableLanguages());
- for (int i = 0; i < langs.size(); i++) {
- langs.set(i, langs.get(i).toLowerCase());
- }
-
- String selectedLang = null;
-
- if (langs.contains(langCode + "-" + countryCode)) {
- selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode + "-" + countryCode)];
- } else if (langs.contains(langCode)) {
- selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode)];
- }
- if (selectedLang != null) {
- Configuration.locale.set(selectedLang);
- }
- }
- }
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get()));
- AppStrings.updateLanguage();
-
- Helper.decompilationErrorAdd = AppStrings.translate(Configuration.autoDeobfuscate.get() ? "deobfuscation.comment.failed" : "deobfuscation.comment.tryenable");
- }
-
- /**
- * Clear old FFDec/JavactiveX temp files
- */
- private static void clearTemp() {
- String tempDirPath = System.getProperty("java.io.tmpdir");
- if (tempDirPath == null) {
- return;
- }
- File tempDir = new File(tempDirPath);
- if (!tempDir.exists()) {
- return;
- }
- File[] delFiles = tempDir.listFiles(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.matches("ffdec_cache.*\\.tmp") || name.matches("javactivex_.*\\.exe") || name.matches("temp[0-9]+\\.swf") || name.matches("ffdec_view_.*\\.swf");
- }
- });
-
- if (delFiles != null) {
- for (File f : delFiles) {
- try {
- f.delete();
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- }
-
- /**
- * @param args the command line arguments
- * @throws IOException On error
- */
- public static void main(String[] args) throws IOException {
- setSessionLoaded(false);
- clearTemp();
-
- try {
- SWFDecompilerPlugin.loadPlugins();
- } catch (Throwable ex) {
- logger.log(Level.SEVERE, "Failed to load plugins", ex);
- }
-
- AppStrings.setResourceClass(MainFrame.class);
- initLogging(Configuration._debugMode.get());
-
- initLang();
-
- if (Configuration.cacheOnDisk.get()) {
- Cache.setStorageType(Cache.STORAGE_FILES);
- } else {
- Cache.setStorageType(Cache.STORAGE_MEMORY);
- }
-
- if (args.length == 0) {
- initGui();
- View.execInEventDispatch(() -> {
- if (Configuration.allowOnlyOneInstance.get() && FirstInstance.focus()) { //Try to focus first instance
- Main.exit();
- } else {
- showModeFrame();
- reloadLastSession();
- }
- });
- } else {
- setSessionLoaded(true);
- String[] filesToOpen = CommandLineArgumentParser.parseArguments(args);
- if (filesToOpen != null && filesToOpen.length > 0) {
- View.execInEventDispatch(() -> {
- initGui();
- shouldCloseWhenClosingLoadingDialog = true;
- if (Configuration.allowOnlyOneInstance.get() && FirstInstance.openFiles(Arrays.asList(filesToOpen))) { //Try to open in first instance
- Main.exit();
- } else {
- for (String fileToOpen : filesToOpen) {
- openFile(fileToOpen, null);
- }
- }
- });
- }
- }
- }
-
- private static void reloadLastSession() {
- boolean openingFiles = false;
- if (Configuration.saveSessionOnExit.get()) {
- String lastSession = Configuration.lastSessionFiles.get();
- if (lastSession != null && lastSession.length() > 0) {
- String[] filesToOpen = lastSession.split(File.pathSeparator, -1);
- List exfiles = new ArrayList<>();
- List extitles = new ArrayList<>();
- String lastSessionTitles = Configuration.lastSessionFileTitles.get();
- String[] fileTitles = new String[0];
- if (lastSessionTitles != null && !lastSessionTitles.isEmpty()) {
- fileTitles = lastSessionTitles.split(File.pathSeparator, -1);
- }
- for (int i = 0; i < filesToOpen.length; i++) {
- if (new File(filesToOpen[i]).exists()) {
- exfiles.add(filesToOpen[i]);
- if (fileTitles.length > i) {
- extitles.add(fileTitles[i]);
- } else {
- extitles.add(null);
- }
- }
- }
- SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()];
- for (int i = 0; i < exfiles.size(); i++) {
- String extitle = extitles.get(i);
- sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
- }
- if (sourceInfos.length > 0) {
- openingFiles = true;
- openFile(sourceInfos, () -> {
- mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get());
- setSessionLoaded(true);
- });
- }
- }
- }
-
- if (!openingFiles) {
- setSessionLoaded(true);
- }
- }
-
- public static String tempFile(String url) throws IOException {
- File f = new File(Configuration.getFFDecHome() + "saved" + File.separator);
- Path.createDirectorySafe(f);
- return Configuration.getFFDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
- }
-
- public static void removeTrayIcon() {
- if (SystemTray.isSupported()) {
- SystemTray tray = SystemTray.getSystemTray();
- if (trayIcon != null) {
- tray.remove(trayIcon);
- trayIcon = null;
- }
- }
- }
-
- public static void switchProxy() {
- proxyFrame.switchState();
- if (stopMenuItem != null) {
- if (proxyFrame.isRunning()) {
- stopMenuItem.setLabel(AppStrings.translate("proxy.stop"));
- } else {
- stopMenuItem.setLabel(AppStrings.translate("proxy.start"));
- }
- }
- }
-
- public static void addTrayIcon() {
- if (trayIcon != null) {
- return;
- }
- if (SystemTray.isSupported()) {
- SystemTray tray = SystemTray.getSystemTray();
- trayIcon = new TrayIcon(View.loadImage("proxy16"), ApplicationInfo.VENDOR + " " + ApplicationInfo.SHORT_APPLICATION_NAME + " " + AppStrings.translate("proxy"));
- trayIcon.setImageAutoSize(true);
- PopupMenu trayPopup = new PopupMenu();
-
- ActionListener trayListener = new ActionListener() {
- /**
- * Invoked when an action occurs.
- */
- @Override
- public void actionPerformed(ActionEvent e) {
- if (e.getActionCommand().equals("EXIT")) {
- Main.exit();
- }
- if (e.getActionCommand().equals("SHOW")) {
- Main.showProxy();
- }
- if (e.getActionCommand().equals("SWITCH")) {
- Main.switchProxy();
- }
- }
- };
-
- MenuItem showMenuItem = new MenuItem(AppStrings.translate("proxy.show"));
- showMenuItem.setActionCommand("SHOW");
- showMenuItem.addActionListener(trayListener);
- trayPopup.add(showMenuItem);
- stopMenuItem = new MenuItem(AppStrings.translate("proxy.start"));
- stopMenuItem.setActionCommand("SWITCH");
- stopMenuItem.addActionListener(trayListener);
- trayPopup.add(stopMenuItem);
- trayPopup.addSeparator();
- MenuItem exitMenuItem = new MenuItem(AppStrings.translate("exit"));
- exitMenuItem.setActionCommand("EXIT");
- exitMenuItem.addActionListener(trayListener);
- trayPopup.add(exitMenuItem);
-
- trayIcon.setPopupMenu(trayPopup);
- trayIcon.addMouseListener(new MouseAdapter() {
- /**
- * {@inheritDoc}
- */
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getButton() == MouseEvent.BUTTON1) {
- Main.showProxy();
- }
- }
- });
- try {
- tray.add(trayIcon);
- } catch (AWTException ex) {
- }
- }
- }
-
- public static void exit() {
- Configuration.saveConfig();
- if (mainFrame != null && mainFrame.getPanel() != null) {
- mainFrame.getPanel().unloadFlashPlayer();
- mainFrame.dispose();
- }
- if (fileTxt != null) {
- try {
- fileTxt.flush();
- fileTxt.close();
- } catch (Exception ex) {
- //ignore
- }
- }
- System.exit(0);
- }
-
- public static void about() {
- (new AboutDialog()).setVisible(true);
- }
-
- public static void advancedSettings() {
- advancedSettings(null);
- }
-
- public static void advancedSettings(String category) {
- (new AdvancedSettingsDialog(category)).setVisible(true);
- }
-
- public static void autoCheckForUpdates() {
- if (Configuration.checkForUpdatesAuto.get()) {
- Calendar lastUpdatesCheckDate = Configuration.lastUpdatesCheckDate.get();
- if ((lastUpdatesCheckDate == null) || (lastUpdatesCheckDate.getTime().getTime() < Calendar.getInstance().getTime().getTime() - Configuration.checkForUpdatesDelay.get())) {
- new SwingWorker() {
- @Override
- protected Object doInBackground() throws Exception {
- checkForUpdates();
- return null;
- }
- }.execute();
- }
- }
- }
-
- public static boolean checkForUpdates() {
- String currentVersion = ApplicationInfo.version;
- if (currentVersion.equals("unknown")) {
- // sometimes during development the version information is not available
- return false;
- }
-
- List accepted = new ArrayList<>();
- if (Configuration.checkForUpdatesStable.get()) {
- accepted.add("stable");
- }
- if (Configuration.checkForUpdatesNightly.get()) {
- accepted.add("nightly");
- }
-
- if (accepted.isEmpty()) {
- return false;
- }
-
- String acceptVersions = String.join(",", accepted);
- try {
- String proxyAddress = Configuration.updateProxyAddress.get();
- URL url = new URL(ApplicationInfo.updateCheckUrl);
-
- URLConnection uc;
- if (proxyAddress != null && !proxyAddress.isEmpty()) {
- int port = 8080;
- if (proxyAddress.contains(":")) {
- String[] parts = proxyAddress.split(":");
- port = Integer.parseInt(parts[1]);
- proxyAddress = parts[0];
- }
-
- uc = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, port)));
- } else {
- uc = url.openConnection();
- }
- uc.setRequestProperty("X-Accept-Versions", acceptVersions);
- uc.setRequestProperty("X-Update-Major", "" + UPDATE_SYSTEM_MAJOR);
- uc.setRequestProperty("X-Update-Minor", "" + UPDATE_SYSTEM_MINOR);
- uc.setRequestProperty("User-Agent", ApplicationInfo.shortApplicationVerName);
- String currentLoc = Configuration.locale.get("en");
- uc.setRequestProperty("Accept-Language", currentLoc + ("en".equals(currentLoc) ? "" : ", en;q=0.8"));
-
- uc.connect();
-
- BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
- String s;
- final java.util.List versions = new ArrayList<>();
- String header = "";
- Pattern headerPat = Pattern.compile("\\[([a-zA-Z0-9]+)\\]");
- int updateMajor;
- int updateMinor;
- Version ver = null;
- while ((s = br.readLine()) != null) {
-
- Matcher m = headerPat.matcher(s);
- if (m.matches()) {
- header = m.group(1);
- if (header.equals("version")) {
- ver = new Version();
- versions.add(ver);
- }
- if (header.equals("noversion")) {
- break;
- }
- } else if (s.contains("=")) {
- String key = s.substring(0, s.indexOf('='));
- String val = s.substring(s.indexOf('=') + 1);
- if ("updateSystem".equals(header)) {
- if (key.equals("majorVersion")) {
- updateMajor = Integer.parseInt(val);
- if (updateMajor > UPDATE_SYSTEM_MAJOR) {
- break;
- }
- }
- if (key.equals("minorVersion")) {
- updateMinor = Integer.parseInt(val);
- }
- }
- if ("version".equals(header) && (ver != null)) {
- if (key.equals("versionId")) {
- ver.versionId = Integer.parseInt(val);
- }
- if (key.equals("versionName")) {
- ver.versionName = val;
- }
- if (key.equals("nightly")) {
- ver.nightly = val.equals("true");
- }
- if (key.equals("revision")) {
- ver.revision = val;
- }
- if (key.equals("build")) {
- ver.build = Integer.parseInt(val);
- }
- if (key.equals("major")) {
- ver.major = Integer.parseInt(val);
- }
- if (key.equals("minor")) {
- ver.minor = Integer.parseInt(val);
- }
- if (key.equals("release")) {
- ver.release = Integer.parseInt(val);
- }
- if (key.equals("longVersionName")) {
- ver.longVersionName = val;
- }
- if (key.equals("releaseDate")) {
- ver.releaseDate = val;
- }
- if (key.equals("appName")) {
- ver.appName = val;
- }
- if (key.equals("appFullName")) {
- ver.appFullName = val;
- }
- if (key.equals("updateLink")) {
- ver.updateLink = val;
- }
- if (key.equals("change[]")) {
- String changeType = val.substring(0, val.indexOf('|'));
- String change = val.substring(val.indexOf('|') + 1);
- if (!ver.changes.containsKey(changeType)) {
- ver.changes.put(changeType, new ArrayList<>());
- }
- List chlist = ver.changes.get(changeType);
- chlist.add(change);
- }
- }
- }
- }
-
- if (!versions.isEmpty()) {
- View.execInEventDispatch(() -> {
- NewVersionDialog newVersionDialog = new NewVersionDialog(versions);
- newVersionDialog.setVisible(true);
- Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
- });
-
- return true;
- }
- } catch (IOException | NumberFormatException ex) {
- return false;
- }
- Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
- return false;
- }
-
- private static FileHandler fileTxt;
-
- public static void clearLogFile() {
- Logger logger = Logger.getLogger("");
-
- FileHandler oldFileTxt = fileTxt;
- fileTxt = null;
- if (oldFileTxt != null) {
- logger.removeHandler(fileTxt);
- oldFileTxt.flush();
- oldFileTxt.close();
- }
-
- String fileName = null;
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
-
- try {
- fileName = Configuration.getFFDecHome() + "logs" + File.separator;
- if (Configuration.useDetailedLogging.get()) {
- fileName += "log-" + sdf.format(new Date()) + ".txt";
- } else {
- fileName += "log.txt";
- }
- File f = new File(fileName).getParentFile();
- if (!f.exists()) {
- f.mkdir();
- }
- fileTxt = new FileHandler(fileName);
- } catch (IOException | SecurityException ex) {
- //cannot get lock error
- if (ex.getMessage().contains("lock for")) {
- //remove all old log files and their .lck
- for (int i = 0; i <= 100; i++) {
- File flog = new File(fileName + (i == 0 ? "" : "." + i));
- File flog_lock = new File(fileName + (i == 0 ? "" : "." + i) + ".lck");
- flog.delete();
- flog_lock.delete();
- }
- try {
- fileTxt = new FileHandler(fileName);
- } catch (IOException | SecurityException ex1) {
- logger.log(Level.SEVERE, "Cannot initialize logging", ex);
- }
- } else {
- logger.log(Level.SEVERE, "Cannot initialize logging", ex);
- }
- }
-
- Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- logger.log(Level.SEVERE, "Uncaught exception in thread: " + t.getName(), e);
- if (e instanceof OutOfMemoryError || !Helper.is64BitJre() && Helper.is64BitOs()) {
- View.showMessageDialog(null, AppStrings.translate("message.warning.outOfMemory32BitJre"), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE);
- }
- }
- });
-
- Formatter formatterTxt = new LogFormatter();
- if (fileTxt != null) {
- fileTxt.setFormatter(formatterTxt);
- logger.addHandler(fileTxt);
- }
-
- if (!GraphicsEnvironment.isHeadless() && ErrorLogFrame.hasInstance()) {
- ErrorLogFrame.getInstance().clearErrorState();
- }
-
- sdf = new SimpleDateFormat("yyyy-MM-dd");
- logger.log(Level.INFO, "Date: {0}", sdf.format(new Date()));
- logger.log(Level.INFO, ApplicationInfo.applicationVerName);
- logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
- System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")});
- logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
- System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("os.arch")});
- }
-
- public static void initLogging(boolean debug) {
- try {
- Logger logger = Logger.getLogger("");
- logger.setLevel(Configuration.logLevel);
-
- Handler[] handlers = logger.getHandlers();
- for (int i = handlers.length - 1; i >= 0; i--) {
- logger.removeHandler(handlers[i]);
- }
-
- ConsoleHandler conHan = new ConsoleHandler();
- conHan.setLevel(debug ? Level.CONFIG : Level.WARNING);
- SimpleFormatter formatterTxt = new SimpleFormatter();
- conHan.setFormatter(formatterTxt);
- logger.addHandler(conHan);
- clearLogFile();
-
- } catch (Exception ex) {
- throw new RuntimeException("Problems with creating the log files");
- }
- }
-}
+/*
+ * Copyright (C) 2010-2016 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.debugger.flash.Debugger;
+import com.jpexs.debugger.flash.DebuggerCommands;
+import com.jpexs.debugger.flash.Variable;
+import com.jpexs.decompiler.flash.ApplicationInfo;
+import com.jpexs.decompiler.flash.EventListener;
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFBundle;
+import com.jpexs.decompiler.flash.SWFSourceInfo;
+import com.jpexs.decompiler.flash.SearchMode;
+import com.jpexs.decompiler.flash.SwfOpenException;
+import com.jpexs.decompiler.flash.UrlResolver;
+import com.jpexs.decompiler.flash.Version;
+import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
+import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
+import com.jpexs.decompiler.flash.configuration.Configuration;
+import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
+import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
+import com.jpexs.decompiler.flash.console.ContextMenuTools;
+import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
+import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
+import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
+import com.jpexs.decompiler.flash.gui.pipes.FirstInstance;
+import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
+import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
+import com.jpexs.decompiler.flash.tags.Tag;
+import com.jpexs.decompiler.flash.tags.base.FontTag;
+import com.jpexs.decompiler.flash.tags.base.ImportTag;
+import com.jpexs.decompiler.flash.treeitems.SWFList;
+import com.jpexs.helpers.Cache;
+import com.jpexs.helpers.CancellableWorker;
+import com.jpexs.helpers.Helper;
+import com.jpexs.helpers.Path;
+import com.jpexs.helpers.ProgressListener;
+import com.jpexs.helpers.Stopwatch;
+import com.jpexs.helpers.streams.SeekableInputStream;
+import com.sun.jna.Platform;
+import com.sun.jna.platform.win32.Advapi32Util;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.WinReg;
+import java.awt.AWTException;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.MenuItem;
+import java.awt.PopupMenu;
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.FileHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingWorker;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.filechooser.FileFilter;
+import org.pushingpixels.substance.api.SubstanceLookAndFeel;
+
+/**
+ * Main executable class
+ *
+ * @author JPEXS
+ */
+public class Main {
+
+ protected static ProxyFrame proxyFrame;
+
+ private static List sourceInfos = new ArrayList<>();
+
+ public static LoadingDialog loadingDialog;
+
+ private static boolean working = false;
+
+ private static TrayIcon trayIcon;
+
+ private static MenuItem stopMenuItem;
+
+ private static volatile MainFrame mainFrame;
+
+ public static final int UPDATE_SYSTEM_MAJOR = 1;
+
+ public static final int UPDATE_SYSTEM_MINOR = 3;
+
+ private static LoadFromMemoryFrame loadFromMemoryFrame;
+
+ private static LoadFromCacheFrame loadFromCacheFrame;
+
+ private static final Logger logger = Logger.getLogger(Main.class.getName());
+
+ public static DebugLogDialog debugDialog;
+
+ public static boolean shouldCloseWhenClosingLoadingDialog;
+
+ private static Debugger flashDebugger;
+
+ private static DebuggerHandler debugHandler = null;
+
+ //private static int ip = 0;
+ //private static String ipClass = null;
+ private static Process runProcess;
+
+ private static boolean runProcessDebug;
+
+ private static boolean runProcessDebugPCode;
+
+ private static boolean inited = false;
+
+ private static File runTempFile;
+
+ private static List runTempFiles = new ArrayList<>();
+
+ public static void freeRun() {
+ synchronized (Main.class) {
+ if (runTempFile != null) {
+ runTempFile.delete();
+ runTempFile = null;
+ }
+ for (File f : runTempFiles) {
+ f.delete();
+ }
+ runTempFiles.clear();
+
+ runProcess = null;
+ }
+ if (mainFrame != null && mainFrame.getPanel() != null) {
+ mainFrame.getPanel().clearDebuggerColors();
+ }
+ if (runProcessDebug) {
+ Main.getDebugHandler().disconnect();
+ }
+ }
+
+ public static synchronized boolean isDebugPaused() {
+ return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
+ }
+
+ public static synchronized boolean isDebugRunning() {
+ return runProcess != null && runProcessDebug;
+ }
+
+ public static synchronized boolean isDebugPCode() {
+ return runProcessDebugPCode;
+ }
+
+ public static synchronized boolean isDebugConnected() {
+ return getDebugHandler().isConnected();
+ }
+
+ public static synchronized boolean isRunning() {
+ return runProcess != null && !runProcessDebug;
+ }
+
+ public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
+ DebuggerCommands.Watch w = getDebugHandler().addWatch(v, v_id, watchRead, watchWrite);
+ return w != null;
+ }
+
+ public static void runPlayer(String title, final String exePath, String file, String flashVars) {
+ if (!new File(file).exists()) {
+ return;
+ }
+ if (flashVars != null && !flashVars.isEmpty()) {
+ file += "?" + flashVars;
+ }
+ final String ffile = file;
+
+ CancellableWorker runWorker = new CancellableWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+ Process proc;
+ try {
+ proc = Runtime.getRuntime().exec(new String[]{exePath, ffile});
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ return null;
+ }
+ boolean isDebug;
+
+ synchronized (Main.class) {
+ runProcess = proc;
+ isDebug = runProcessDebug;
+ }
+ if (isDebug) {
+ mainFrame.getMenu().hilightPath("/debugging");
+ }
+ mainFrame.getMenu().updateComponents();
+ try {
+ if (proc != null) {
+ proc.waitFor();
+ }
+ } catch (InterruptedException ex) {
+ if (proc != null) {
+ try {
+ proc.destroy();
+ } catch (Exception ex2) {
+ //ignore
+ }
+ }
+ }
+ freeRun();
+ stopDebugger();
+ mainFrame.getMenu().updateComponents();
+ return null;
+ }
+
+ @Override
+ protected void done() {
+ Main.stopWork();
+ }
+
+ @Override
+ public void workerCancelled() {
+ Main.stopWork();
+ synchronized (Main.class) {
+ if (runProcess != null) {
+ try {
+ runProcess.destroy();
+ } catch (Exception ex) {
+
+ }
+ }
+ }
+ freeRun();
+ mainFrame.getMenu().updateComponents();
+ }
+ };
+
+ mainFrame.getMenu().updateComponents();
+ Main.startWork(title + "...", runWorker);
+ runWorker.execute();
+ }
+
+ public static void stopRun() {
+
+ synchronized (Main.class) {
+ if (runProcess != null) {
+ runProcess.destroy();
+ }
+ }
+ freeRun();
+ stopDebugger();
+ mainFrame.getMenu().updateComponents();
+ }
+
+ private static interface SwfPreparation {
+
+ public SWF prepare(SWF swf);
+ }
+
+ private static class SwfRunPrepare implements SwfPreparation {
+
+ @Override
+ public SWF prepare(SWF swf) {
+ if (Configuration.autoOpenLoadedSWFs.get()) {
+ if (!DebuggerTools.hasDebugger(swf)) {
+ DebuggerTools.switchDebugger(swf);
+ }
+ DebuggerTools.injectDebugLoader(swf);
+ }
+ return swf;
+ }
+ }
+
+ private static class SwfDebugPrepare extends SwfRunPrepare {
+
+ private boolean doPCode;
+
+ public SwfDebugPrepare(boolean doPCode) {
+ this.doPCode = doPCode;
+ }
+
+ @Override
+ public SWF prepare(SWF instrSWF) {
+ instrSWF = super.prepare(instrSWF);
+ try {
+ File fTempFile = new File(instrSWF.getFile());
+ instrSWF.enableDebugging(true, new File("."), true, doPCode);
+ FileOutputStream fos = new FileOutputStream(fTempFile);
+ instrSWF.saveTo(fos);
+ fos.close();
+ if (!instrSWF.isAS3()) {
+ //Read again, because line file offsets changed with adding debug tags
+ //TODO: handle somehow without rereading?
+ instrSWF = null;
+ try (FileInputStream fis = new FileInputStream(fTempFile)) {
+ instrSWF = new SWF(fis, false, false);
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ if (instrSWF != null) {
+ String swfFileName = fTempFile.getAbsolutePath();
+ if (swfFileName.toLowerCase().endsWith(".swf")) {
+ swfFileName = swfFileName.substring(0, swfFileName.length() - 4) + ".swd";
+ } else {
+ swfFileName = swfFileName + ".swd";
+ }
+ File swdFile = new File(swfFileName);
+ if (doPCode) {
+ instrSWF.generatePCodeSwdFile(swdFile, getPackBreakPoints(true));
+ } else {
+ instrSWF.generateSwdFile(swdFile, getPackBreakPoints(true));
+ }
+ }
+ }
+ } catch (IOException ex) {
+ //ignore, return instrSWF
+ }
+ return instrSWF;
+ }
+ }
+
+ private static void prepareSwf(SwfPreparation prep, File toPrepareFile, File origFile, List tempFiles) throws IOException {
+ SWF instrSWF = null;
+ try (FileInputStream fis = new FileInputStream(toPrepareFile)) {
+ instrSWF = new SWF(fis, toPrepareFile.getAbsolutePath(), origFile.getName(), false);
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ if (instrSWF != null) {
+ for (Tag t : instrSWF.getLocalTags()) {
+ if (t instanceof ImportTag) {
+ ImportTag it = (ImportTag) t;
+ String url = it.getUrl();
+ File importedFile = new File(origFile.getParentFile(), url);
+ if (importedFile.exists()) {
+ File newTempFile = File.createTempFile("ffdec_run_import_", ".swf");
+ it.setUrl("./" + newTempFile.getName());
+ byte[] impData = Helper.readFile(importedFile.getAbsolutePath());
+ Helper.writeFile(newTempFile.getAbsolutePath(), impData);
+ tempFiles.add(newTempFile);
+ prepareSwf(prep, newTempFile, importedFile, tempFiles);
+ }
+ }
+ }
+ if (prep != null) {
+ instrSWF = prep.prepare(instrSWF);
+ }
+ try (FileOutputStream fos = new FileOutputStream(toPrepareFile)) {
+ instrSWF.saveTo(fos);
+ }
+ }
+ }
+
+ public static void run(SWF swf) {
+ String flashVars = "";//key=val&key2=val2
+ String playerLocation = Configuration.playerLocation.get();
+ if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
+ View.showMessageDialog(null, AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ advancedSettings("paths");
+ return;
+ }
+ if (swf == null) {
+ return;
+ }
+ File tempFile;
+ List tempFiles = new ArrayList<>();
+ try {
+ tempFile = File.createTempFile("ffdec_run_", ".swf");
+
+ try (FileOutputStream fos = new FileOutputStream(tempFile)) {
+ swf.saveTo(fos);
+ }
+
+ prepareSwf(new SwfRunPrepare(), tempFile, new File(swf.getFile()), tempFiles);
+
+ } catch (IOException ex) {
+ return;
+
+ }
+ if (tempFile != null) {
+ synchronized (Main.class) {
+ runTempFile = tempFile;
+ runTempFiles = tempFiles;
+ runProcessDebug = false;
+ }
+ runPlayer(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
+ }
+ }
+
+ public static void runDebug(SWF swf, final boolean doPCode) {
+ String flashVars = "";//key=val&key2=val2
+ String playerLocation = Configuration.playerDebugLocation.get();
+ if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
+ View.showMessageDialog(null, AppStrings.translate("message.playerpath.debug.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ Main.advancedSettings("paths");
+ return;
+ }
+ if (swf == null) {
+ return;
+ }
+ File tempFile = null;
+
+ try {
+ tempFile = File.createTempFile("ffdec_debug_", ".swf");
+ } catch (Exception ex) {
+
+ }
+
+ if (tempFile != null) {
+ final File fTempFile = tempFile;
+ final List tempFiles = new ArrayList<>();
+ CancellableWorker instrumentWorker = new CancellableWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+
+ try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
+ swf.saveTo(fos);
+ }
+ prepareSwf(new SwfDebugPrepare(doPCode), fTempFile, new File(swf.getFile()), tempFiles);
+ return null;
+ }
+
+ @Override
+ public void workerCancelled() {
+ Main.stopWork();
+ }
+
+ @Override
+ protected void done() {
+ synchronized (Main.class) {
+ runTempFile = fTempFile;
+ runProcessDebug = true;
+ runProcessDebugPCode = doPCode;
+ runTempFiles = tempFiles;
+ }
+ Main.stopWork();
+ Main.startDebugger();
+ runPlayer(AppStrings.translate("work.debugging.wait"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
+ }
+ };
+
+ Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
+ instrumentWorker.execute();
+ }
+ }
+
+ /* public static void debuggerNotSuspended() {
+
+ }*/
+ public static boolean isDebugging() {
+ return isDebugRunning();
+ }
+
+ public synchronized static int getIp(Object pack) {
+ return getDebugHandler().getBreakIp();
+ }
+
+ public synchronized static String getIpClass() {
+ return getDebugHandler().getBreakScriptName();
+ }
+
+ public static synchronized boolean isBreakPointValid(String scriptName, int line) {
+ return !getDebugHandler().isBreakpointInvalid(scriptName, line);
+ }
+
+ public synchronized static void addBreakPoint(String scriptName, int line) {
+ getDebugHandler().addBreakPoint(scriptName, line);
+ }
+
+ public synchronized static void removeBreakPoint(String scriptName, int line) {
+ getDebugHandler().removeBreakPoint(scriptName, line);
+ }
+
+ public synchronized static boolean toggleBreakPoint(String scriptName, int line) {
+ if (getDebugHandler().isBreakpointToAdd(scriptName, line) || getDebugHandler().isBreakpointConfirmed(scriptName, line) || getDebugHandler().isBreakpointInvalid(scriptName, line)) {
+ getDebugHandler().removeBreakPoint(scriptName, line);
+ return false;
+ } else {
+ getDebugHandler().addBreakPoint(scriptName, line);
+ return true;
+ }
+ }
+
+ public synchronized static Map> getPackBreakPoints(boolean validOnly) {
+ return getDebugHandler().getAllBreakPoints(validOnly);
+ }
+
+ public synchronized static Set getScriptBreakPoints(String pack, boolean onlyValid) {
+ return getDebugHandler().getBreakPoints(pack, onlyValid);
+ }
+
+ public static DebuggerHandler getDebugHandler() {
+ return debugHandler;
+ }
+
+ public static void ensureMainFrame() {
+ if (mainFrame == null) {
+ synchronized (Main.class) {
+ if (mainFrame == null) {
+ MainFrame frame;
+ if (Configuration.useRibbonInterface.get()) {
+ frame = new MainFrameRibbon();
+ } else {
+ frame = new MainFrameClassic();
+ }
+ frame.getPanel().setErrorState(ErrorLogFrame.getInstance().getErrorState());
+ mainFrame = frame;
+ }
+ }
+ }
+ }
+
+ public static MainFrame getMainFrame() {
+ return mainFrame;
+ }
+
+ public static void loadFromCache() {
+ if (loadFromCacheFrame == null) {
+ loadFromCacheFrame = new LoadFromCacheFrame();
+ }
+ loadFromCacheFrame.setVisible(true);
+ }
+
+ public static void loadFromMemory() {
+ if (loadFromMemoryFrame == null) {
+ loadFromMemoryFrame = new LoadFromMemoryFrame(mainFrame);
+ }
+ loadFromMemoryFrame.setVisible(true);
+ }
+
+ public static void setVariable(long parentId, String varName, int valueType, Object value) {
+ getDebugHandler().setVariable(parentId, varName, valueType, value);
+ }
+
+ public static void setSubLimiter(boolean value) {
+ if (value) {
+ AVM2Code.toSourceLimit = Configuration.sublimiter.get();
+ } else {
+ AVM2Code.toSourceLimit = -1;
+ }
+ }
+
+ public synchronized static boolean isInited() {
+ return inited;
+ }
+
+ public synchronized static void setSessionLoaded(boolean v) {
+ inited = v;
+ }
+
+ public static boolean isWorking() {
+ return working;
+ }
+
+ public static void startProxy(int port) {
+ if (proxyFrame == null) {
+ proxyFrame = new ProxyFrame(mainFrame);
+ }
+
+ proxyFrame.setPort(port);
+ addTrayIcon();
+ switchProxy();
+ }
+
+ public static void showProxy() {
+ if (proxyFrame == null) {
+ proxyFrame = new ProxyFrame(mainFrame);
+ }
+ proxyFrame.setVisible(true);
+ proxyFrame.setState(Frame.NORMAL);
+ }
+
+ public static void startWork(String name, CancellableWorker worker) {
+ startWork(name, -1, worker);
+ }
+
+ public static void startWork(final String name, final int percent, final CancellableWorker worker) {
+ working = true;
+ View.execInEventDispatchLater(() -> {
+ if (mainFrame != null) {
+ mainFrame.getPanel().setWorkStatus(name, worker);
+ if (percent == -1) {
+ mainFrame.getPanel().hidePercent();
+ } else {
+ mainFrame.getPanel().setPercent(percent);
+ }
+ }
+ if (loadingDialog != null) {
+ loadingDialog.setDetail(name);
+ loadingDialog.setPercent(percent);
+ }
+ if (CommandLineArgumentParser.isCommandLineMode()) {
+ System.out.println(name);
+ }
+ });
+ }
+
+ public static void stopWork() {
+ working = false;
+ View.execInEventDispatchLater(() -> {
+ if (mainFrame != null) {
+ mainFrame.getPanel().setWorkStatus("", null);
+ }
+ if (loadingDialog != null) {
+ loadingDialog.setDetail("");
+ }
+ });
+ }
+
+ public static SWFList parseSWF(SWFSourceInfo sourceInfo) throws Exception {
+ SWFList result = new SWFList();
+
+ InputStream inputStream = sourceInfo.getInputStream();
+ SWFBundle bundle = null;
+ FileInputStream fis = null;
+ if (inputStream == null) {
+ inputStream = new BufferedInputStream(fis = new FileInputStream(sourceInfo.getFile()));
+ bundle = sourceInfo.getBundle(false, SearchMode.ALL);
+ logger.log(Level.INFO, "Load file: {0}", sourceInfo.getFile());
+ } else if (inputStream instanceof SeekableInputStream
+ || inputStream instanceof BufferedInputStream) {
+ try {
+ inputStream.reset();
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ logger.log(Level.INFO, "Load stream: {0}", sourceInfo.getFileTitle());
+ }
+
+ Stopwatch sw = Stopwatch.startNew();
+ if (bundle != null) {
+ result.bundle = bundle;
+ result.name = new File(sourceInfo.getFileTitleOrName()).getName();
+ for (Entry streamEntry : bundle.getAll().entrySet()) {
+ InputStream stream = streamEntry.getValue();
+ stream.reset();
+ CancellableWorker worker = new CancellableWorker() {
+ @Override
+ public SWF doInBackground() throws Exception {
+ final CancellableWorker worker = this;
+ SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() {
+ @Override
+ public void progress(int p) {
+ startWork(AppStrings.translate("work.reading.swf"), p, worker);
+ }
+ }, Configuration.parallelSpeedUp.get());
+ return swf;
+ }
+ };
+ loadingDialog.setWroker(worker);
+ worker.execute();
+
+ try {
+ result.add(worker.get());
+ } catch (CancellationException ex) {
+ logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", streamEntry.getKey());
+ }
+ }
+ } else {
+ InputStream fInputStream = inputStream;
+
+ final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
+
+ CancellableWorker worker = new CancellableWorker() {
+ private boolean yestoall = false;
+
+ private boolean notoall = false;
+
+ private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
+ final CancellableWorker worker = this;
+
+ SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
+ @Override
+ public void progress(int p) {
+ startWork(AppStrings.translate("work.reading.swf"), p, worker);
+ }
+ }, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
+ @Override
+ public SWF resolveUrl(final String url) {
+ int opt = -1;
+ if (!(yestoall || notoall)) {
+ opt = View.showOptionDialog(null, AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
+ if (opt == 2) {
+ yestoall = true;
+ }
+ if (opt == 3) {
+ notoall = true;
+ }
+ }
+
+ if (yestoall) {
+ opt = 0; // yes
+ } else if (notoall) {
+ opt = 1; // no
+ }
+
+ if (opt == 1) //no
+ {
+ return null;
+ }
+
+ if (url.startsWith("http://") || url.startsWith("https://")) {
+ try {
+ URL u = new URL(url);
+ return open(u.openStream(), null, url); //?
+ } catch (Exception ex) {
+ //ignore
+ }
+ } else {
+ File f = new File(new File(file).getParentFile(), url);
+ if (f.exists()) {
+ try {
+ return open(new FileInputStream(f), f.getAbsolutePath(), f.getName());
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ Reference ret = new Reference<>(null);
+ View.execInEventDispatch(new Runnable() {
+ @Override
+ public void run() {
+
+ while (JOptionPane.YES_OPTION == View.showConfirmDialog(null, AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
+
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
+ FileFilter allSupportedFilter = new FileFilter() {
+ private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
+
+ @Override
+ public boolean accept(File f) {
+ String name = f.getName().toLowerCase();
+ for (String ext : supportedExtensions) {
+ if (name.endsWith(ext)) {
+ return true;
+ }
+ }
+ return f.isDirectory();
+ }
+
+ @Override
+ public String getDescription() {
+ String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
+ return AppStrings.translate("filter.supported") + " (" + exts + ")";
+ }
+ };
+ fc.setFileFilter(allSupportedFilter);
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+ fc.addChoosableFileFilter(swfFilter);
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+ fc.addChoosableFileFilter(gfxFilter);
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ int returnVal = fc.showOpenDialog(f);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
+ File selFile = Helper.fixDialogFile(fc.getSelectedFile());
+ try {
+ ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
+ break;
+ } catch (Exception ex) {
+ //ignore;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ });
+ return ret.getVal();
+ }
+ });
+ return swf;
+ }
+
+ @Override
+ public SWF doInBackground() throws Exception {
+ return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
+ }
+ };
+ if (loadingDialog != null) {
+ loadingDialog.setWroker(worker);
+ }
+ worker.execute();
+
+ try {
+ result.add(worker.get());
+ } catch (CancellationException ex) {
+ logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", sourceInfo.getFileTitleOrName());
+ }
+ }
+
+ if (fis != null) {
+ logger.log(Level.INFO, "File loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
+ fis.close();
+ } else {
+ logger.log(Level.INFO, "Stream loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
+ }
+
+ result.sourceInfo = sourceInfo;
+ for (SWF swf : result) {
+ logger.log(Level.INFO, "");
+ logger.log(Level.INFO, "== File information ==");
+ logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
+ logger.log(Level.INFO, "Flash version: {0}", swf.version);
+ int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
+ int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
+ logger.log(Level.INFO, "Width: {0}", width);
+ logger.log(Level.INFO, "Height: {0}", height);
+
+ swf.swfList = result;
+ swf.addEventListener(new EventListener() {
+ @Override
+ public void handleExportingEvent(String type, int index, int count, Object data) {
+ String text = AppStrings.translate("work.exporting");
+ if (type != null && type.length() > 0) {
+ text += " " + type;
+ }
+
+ startWork(text + " " + index + "/" + count + " " + data, null);
+ }
+
+ @Override
+ public void handleExportedEvent(String type, int index, int count, Object data) {
+ String text = AppStrings.translate("work.exported");
+ if (type != null && type.length() > 0) {
+ text += " " + type;
+ }
+
+ startWork(text + " " + index + "/" + count + " " + data, null);
+ }
+
+ @Override
+ public void handleEvent(String event, Object data) {
+ if (event.equals("exporting") || event.equals("exported")) {
+ throw new Error("Event is not supported by this handler.");
+ }
+ if (event.equals("getVariables")) {
+ startWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data, null);
+ }
+ if (event.equals("deobfuscate")) {
+ startWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data, null);
+ }
+ if (event.equals("rename")) {
+ startWork(AppStrings.translate("work.renaming") + "..." + (String) data, null);
+ }
+ }
+ });
+ }
+
+ return result;
+ }
+
+ public static void saveFile(SWF swf, String outfile) throws IOException {
+ saveFile(swf, outfile, SaveFileMode.SAVE, null);
+ }
+
+ public static void saveFile(SWF swf, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
+ if (mode == SaveFileMode.SAVEAS && !swf.swfList.isBundle()) {
+ swf.setFile(outfile);
+ swf.swfList.sourceInfo.setFile(outfile);
+ }
+ File outfileF = new File(outfile);
+ File tmpFile = new File(outfile + ".tmp");
+ try (FileOutputStream fos = new FileOutputStream(tmpFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos)) {
+ if (mode == SaveFileMode.EXE) {
+ switch (exeExportMode) {
+ case WRAPPER:
+ InputStream exeStream = View.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/Swf2Exe.bin");
+ Helper.copyStream(exeStream, bos);
+ int width = swf.displayRect.Xmax - swf.displayRect.Xmin;
+ int height = swf.displayRect.Ymax - swf.displayRect.Ymin;
+ bos.write(width & 0xff);
+ bos.write((width >> 8) & 0xff);
+ bos.write((width >> 16) & 0xff);
+ bos.write((width >> 24) & 0xff);
+ bos.write(height & 0xff);
+ bos.write((height >> 8) & 0xff);
+ bos.write((height >> 16) & 0xff);
+ bos.write((height >> 24) & 0xff);
+ bos.write(Configuration.saveAsExeScaleMode.get());
+ break;
+ case PROJECTOR_WIN:
+ case PROJECTOR_MAC:
+ case PROJECTOR_LINUX:
+ File projectorFile = Configuration.getProjectorFile(exeExportMode);
+ if (projectorFile == null) {
+ String message = "Projector not found, please place it to " + Configuration.getProjectorPath();
+ logger.log(Level.SEVERE, message);
+ throw new IOException(message);
+ }
+ Helper.copyStream(new FileInputStream(projectorFile), bos);
+ bos.flush();
+ break;
+ }
+ }
+
+ long pos = fos.getChannel().position();
+ swf.saveTo(bos);
+
+ if (mode == SaveFileMode.EXE) {
+ switch (exeExportMode) {
+ case PROJECTOR_WIN:
+ case PROJECTOR_MAC:
+ case PROJECTOR_LINUX:
+ bos.flush();
+ int swfSize = (int) (fos.getChannel().position() - pos);
+
+ // write magic number
+ bos.write(0x56);
+ bos.write(0x34);
+ bos.write(0x12);
+ bos.write(0xfa);
+
+ bos.write(swfSize & 0xff);
+ bos.write((swfSize >> 8) & 0xff);
+ bos.write((swfSize >> 16) & 0xff);
+ bos.write((swfSize >> 24) & 0xff);
+ }
+ }
+ }
+ if (tmpFile.exists()) {
+ if (tmpFile.length() > 0) {
+ outfileF.delete();
+ if (!tmpFile.renameTo(outfileF)) {
+ tmpFile.delete();
+ throw new IOException("Cannot access " + outfile);
+ }
+ } else {
+ throw new IOException("Output is empty");
+ }
+ } else {
+ throw new IOException("Output not found");
+ }
+ }
+
+ private static class OpenFileWorker extends SwingWorker {
+
+ private final SWFSourceInfo[] sourceInfos;
+
+ private final Runnable executeAfterOpen;
+
+ private final int[] reloadIndices;
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo) {
+ this(sourceInfo, -1);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, int reloadIndex) {
+ this(sourceInfo, null, reloadIndex);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
+ this(sourceInfo, executeAfterOpen, -1);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
+ this.sourceInfos = new SWFSourceInfo[]{sourceInfo};
+ this.executeAfterOpen = executeAfterOpen;
+ this.reloadIndices = new int[]{reloadIndex};
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
+ this(sourceInfos, null, null);
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
+ this(sourceInfos, executeAfterOpen, null);
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
+ this.sourceInfos = sourceInfos;
+ this.executeAfterOpen = executeAfterOpen;
+ int[] indices = new int[sourceInfos.length];
+ for (int i = 0; i < indices.length; i++) {
+ indices[i] = -1;
+ }
+ this.reloadIndices = reloadIndices == null ? indices : reloadIndices;
+ }
+
+ @Override
+ protected Object doInBackground() throws Exception {
+ boolean first = true;
+ SWF firstSWF = null;
+ for (int index = 0; index < sourceInfos.length; index++) {
+ SWFSourceInfo sourceInfo = sourceInfos[index];
+ SWFList swfs = null;
+ try {
+ Main.startWork(AppStrings.translate("work.reading.swf") + "...", null);
+ try {
+ swfs = parseSWF(sourceInfo);
+ } catch (ExecutionException ex) {
+ Throwable cause = ex.getCause();
+ if (cause instanceof SwfOpenException) {
+ throw (SwfOpenException) cause;
+ }
+
+ throw ex;
+ }
+ } catch (OutOfMemoryError ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
+ continue;
+ } catch (SwfOpenException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, ex.getMessage());
+ continue;
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, "Cannot load SWF file.");
+ continue;
+ }
+
+ final SWFList swfs1 = swfs;
+ final boolean first1 = first;
+ first = false;
+ if (firstSWF == null && swfs1.size() > 0) {
+ firstSWF = swfs1.get(0);
+ }
+
+ final int findex = index;
+ try {
+ View.execInEventDispatch(() -> {
+ Main.startWork(AppStrings.translate("work.creatingwindow") + "...", null);
+ ensureMainFrame();
+ if (reloadIndices[findex] > -1) {
+ mainFrame.getPanel().loadSwfAtPos(swfs1, reloadIndices[findex]);
+ } else {
+ mainFrame.getPanel().load(swfs1, first1);
+ }
+ });
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ }
+
+ loadingDialog.setVisible(false);
+ shouldCloseWhenClosingLoadingDialog = false;
+
+ final SWF fswf = firstSWF;
+ View.execInEventDispatch(() -> {
+ if (mainFrame != null) {
+ mainFrame.setVisible(true);
+ }
+
+ Main.stopWork();
+
+ if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) {
+ mainFrame.getPanel().gotoDocumentClass(fswf);
+ }
+
+ if (mainFrame != null && fswf != null) {
+ SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortFileName());
+ if (swfConf != null) {
+ String pathStr = swfConf.lastSelectedPath;
+ mainFrame.getPanel().tagTree.setSelectionPathString(pathStr);
+ }
+ }
+
+ if (executeAfterOpen != null) {
+ executeAfterOpen.run();
+ }
+ });
+
+ return true;
+ }
+ }
+
+ public static boolean reloadSWFs() {
+ CancellableWorker.cancelBackgroundThreads();
+ if (Main.sourceInfos.isEmpty()) {
+ Helper.freeMem();
+ showModeFrame();
+ return true;
+ } else {
+ SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
+ sourceInfos.toArray(sourceInfosCopy);
+ sourceInfos.clear();
+ openFile(sourceInfosCopy);
+ return true;
+ }
+ }
+
+ public static void reloadApp() {
+ if (debugDialog != null) {
+ debugDialog.setVisible(false);
+ debugDialog.dispose();
+ debugDialog = null;
+ }
+ if (loadingDialog != null) {
+ synchronized (Main.class) {
+ if (loadingDialog != null) {
+ loadingDialog.setVisible(false);
+ loadingDialog.dispose();
+ loadingDialog = null;
+ }
+ }
+ }
+ if (proxyFrame != null) {
+ proxyFrame.setVisible(false);
+ proxyFrame.dispose();
+ proxyFrame = null;
+ }
+ if (loadFromMemoryFrame != null) {
+ loadFromMemoryFrame.setVisible(false);
+ loadFromMemoryFrame.dispose();
+ loadFromMemoryFrame = null;
+ }
+ if (loadFromCacheFrame != null) {
+ loadFromCacheFrame.setVisible(false);
+ loadFromCacheFrame.dispose();
+ loadFromCacheFrame = null;
+ }
+ if (mainFrame != null) {
+ mainFrame.setVisible(false);
+ mainFrame.getPanel().closeAll(false);
+ mainFrame.dispose();
+ mainFrame = null;
+ }
+ FontTag.reload();
+ Cache.clearAll();
+ initGui();
+ reloadSWFs();
+ }
+
+ public static OpenFileResult openFile(String swfFile, String fileTitle) {
+ return openFile(swfFile, fileTitle, null);
+ }
+
+ public static OpenFileResult openFile(String swfFile, String fileTitle, Runnable executeAfterOpen) {
+ try {
+ File file = new File(swfFile);
+ if (!file.exists()) {
+ View.showMessageDialog(null, AppStrings.translate("open.error.fileNotFound"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
+ return OpenFileResult.NOT_FOUND;
+ }
+ swfFile = file.getCanonicalPath();
+ Configuration.addRecentFile(swfFile);
+ SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
+ OpenFileResult openResult = openFile(sourceInfo);
+ return openResult;
+ } catch (IOException ex) {
+ View.showMessageDialog(null, AppStrings.translate("open.error.cannotOpen"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
+ return OpenFileResult.ERROR;
+ }
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
+ return openFile(new SWFSourceInfo[]{sourceInfo});
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
+ return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
+ return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
+ return openFile(newSourceInfos, null);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
+ return openFile(newSourceInfos, executeAfterOpen, null);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
+ if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
+ sourceInfos.clear();
+ mainFrame.getPanel().closeAll(false);
+ mainFrame.setVisible(false);
+ Helper.freeMem();
+ reloadIndices = null;
+ }
+
+ loadingDialog.setVisible(true);
+
+ OpenFileWorker wrk = new OpenFileWorker(newSourceInfos, executeAfterOpen, reloadIndices);
+ wrk.execute();
+ if (reloadIndices == null) {
+ sourceInfos.addAll(Arrays.asList(newSourceInfos));
+ } else {
+ for (int i = 0; i < reloadIndices.length; i++) {
+ sourceInfos.set(reloadIndices[i], newSourceInfos[i]);
+ }
+ }
+ return OpenFileResult.OK;
+ }
+
+ public static void closeFile(SWFList swf) {
+ sourceInfos.remove(swf.sourceInfo);
+ mainFrame.getPanel().close(swf);
+ }
+
+ public static void reloadFile(SWFList swf) {
+ //mainFrame.getPanel().close(swf);
+ openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
+ }
+
+ public static boolean closeAll() {
+ boolean closeResult = mainFrame.getPanel().closeAll(true);
+ if (closeResult) {
+ sourceInfos.clear();
+ }
+
+ return closeResult;
+ }
+
+ public static boolean saveFileDialog(SWF swf, final SaveFileMode mode) {
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
+ String ext = ".swf";
+ switch (mode) {
+ case SAVE:
+ case SAVEAS:
+ if (swf.getFile() != null) {
+ ext = Path.getExtension(swf.getFile());
+ }
+ break;
+ case EXE:
+ ext = ".exe";
+ break;
+ }
+
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+
+ ExeExportMode exeExportMode = null;
+ if (mode == SaveFileMode.EXE) {
+ exeExportMode = Configuration.exeExportMode.get();
+ if (exeExportMode == null) {
+ exeExportMode = ExeExportMode.WRAPPER;
+ }
+ String filterDescription = null;
+ switch (exeExportMode) {
+ case WRAPPER:
+ case PROJECTOR_WIN:
+ ext = ".exe";
+ filterDescription = "filter.exe";
+ break;
+ case PROJECTOR_MAC:
+ ext = ".dmg";
+ filterDescription = "filter.dmg";
+ break;
+ case PROJECTOR_LINUX:
+ // linux projector is compressed with tar.gz
+ // todo: decompress
+ ext = "";
+ filterDescription = "filter.linuxExe";
+ break;
+ }
+
+ String fext = ext;
+ String ffilterDescription = filterDescription;
+ FileFilter exeFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(fext)) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate(ffilterDescription);
+ }
+ };
+ fc.setFileFilter(exeFilter);
+ } else if (swf.gfx) {
+ fc.addChoosableFileFilter(swfFilter);
+ fc.setFileFilter(gfxFilter);
+ } else {
+ fc.setFileFilter(swfFilter);
+ fc.addChoosableFileFilter(gfxFilter);
+ }
+ final String extension = ext;
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ if (fc.showSaveDialog(f) == JFileChooser.APPROVE_OPTION) {
+ File file = Helper.fixDialogFile(fc.getSelectedFile());
+ FileFilter selFilter = fc.getFileFilter();
+ try {
+ String fileName = file.getAbsolutePath();
+ if (selFilter == swfFilter) {
+ if (!fileName.toLowerCase().endsWith(extension)) {
+ fileName += extension;
+ }
+ swf.gfx = false;
+ }
+ if (selFilter == gfxFilter) {
+ if (!fileName.toLowerCase().endsWith(".gfx")) {
+ fileName += ".gfx";
+ }
+ swf.gfx = true;
+ }
+ Main.saveFile(swf, fileName, mode, exeExportMode);
+ Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
+ return true;
+ } catch (IOException ex) {
+ View.showMessageDialog(null, AppStrings.translate("error.file.write"));
+ }
+ }
+ return false;
+ }
+
+ public static boolean openFileDialog() {
+ JFileChooser fc = new JFileChooser();
+ if (Configuration.openMultipleFiles.get()) {
+ fc.setMultiSelectionEnabled(true);
+ }
+ fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
+ FileFilter allSupportedFilter = new FileFilter() {
+ private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip"};
+
+ @Override
+ public boolean accept(File f) {
+ String name = f.getName().toLowerCase();
+ for (String ext : supportedExtensions) {
+ if (name.endsWith(ext)) {
+ return true;
+ }
+ }
+ return f.isDirectory();
+ }
+
+ @Override
+ public String getDescription() {
+ String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
+ return AppStrings.translate("filter.supported") + " (" + exts + ")";
+ }
+ };
+ fc.setFileFilter(allSupportedFilter);
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+ fc.addChoosableFileFilter(swfFilter);
+
+ FileFilter swcFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swc")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swc");
+ }
+ };
+ fc.addChoosableFileFilter(swcFilter);
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+ fc.addChoosableFileFilter(gfxFilter);
+
+ FileFilter zipFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".zip")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.zip");
+ }
+ };
+ fc.addChoosableFileFilter(zipFilter);
+
+ FileFilter binaryFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return true;
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.binary");
+ }
+ };
+ fc.addChoosableFileFilter(binaryFilter);
+
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ int returnVal = fc.showOpenDialog(f);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
+ File[] selFiles = fc.getSelectedFiles();
+ for (File file : selFiles) {
+ File selfile = Helper.fixDialogFile(file);
+ Main.openFile(selfile.getAbsolutePath(), null);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void displayErrorFrame() {
+ ErrorLogFrame.getInstance().setVisible(true);
+ }
+
+ private static String md5(byte data[]) {
+ try {
+ java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
+ byte[] array = md.digest(data);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < array.length; ++i) {
+ sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
+ }
+ return sb.toString();
+ } catch (java.security.NoSuchAlgorithmException e) {
+ }
+ return null;
+ }
+
+ private static void initGui() {
+ if (GraphicsEnvironment.isHeadless()) {
+ System.err.println("Error: Your system does not support Graphic User Interface");
+ exit();
+ }
+
+ System.setProperty("sun.java2d.d3d", "false");
+ System.setProperty("sun.java2d.noddraw", "true");
+
+ if (Configuration.hwAcceleratedGraphics.get()) {
+ System.setProperty("sun.java2d.opengl", Configuration._debugMode.get() ? "True" : "true");
+ } else {
+ System.setProperty("sun.java2d.opengl", "false");
+ }
+
+ initUiLang();
+
+ if (Configuration.useRibbonInterface.get()) {
+ View.setLookAndFeel();
+ } else {
+ try {
+ UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null);
+ UIManager.put("Tree.expandedIcon", null);
+ UIManager.put("Tree.collapsedIcon", null);
+ UIManager.put("ColorChooserUI", null);
+ UIManager.put("ColorChooser.swatchesRecentSwatchSize", null);
+ UIManager.put("ColorChooser.swatchesSwatchSize", null);
+ UIManager.put("RibbonApplicationMenuPopupPanelUI", null);
+ UIManager.put("RibbonApplicationMenuButtonUI", null);
+ UIManager.put("ProgressBarUI", null);
+ UIManager.put("TextField.background", null);
+ UIManager.put("FormattedTextField.background", null);
+ UIManager.put("CommandButtonUI", null);
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ }
+
+ View.execInEventDispatch(() -> {
+ ErrorLogFrame.createNewInstance();
+
+ autoCheckForUpdates();
+ offerAssociation();
+ loadingDialog = new LoadingDialog();
+
+ DebuggerTools.initDebugger().addMessageListener(new DebugListener() {
+ @Override
+ public void onMessage(String clientId, String msg) {
+ }
+
+ @Override
+ public void onLoaderURL(String clientId, String url) {
+ }
+
+ @Override
+ public void onLoaderBytes(String clientId, byte[] data) {
+ String hash = md5(data);
+ for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
+ for (int s = 0; s < sl.size(); s++) {
+ String t = sl.get(s).getFileTitle();
+ if (t == null) {
+ t = "";
+ }
+ if (t.endsWith(":" + hash)) { //this one is already opened
+ return;
+ }
+ }
+ }
+ SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
+
+ String title = swf == null ? "?" : swf.getFileTitle();
+ title = title + ":" + hash;
+ String tfile;
+ try {
+ tfile = tempFile(title);
+ Helper.writeFile(tfile, data);
+ openFile(new SWFSourceInfo(null, tfile, title));
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Cannot create tempfile");
+ }
+ }
+
+ @Override
+ public void onFinish(String clientId) {
+ }
+ });
+
+ try {
+ flashDebugger = new Debugger();
+ debugHandler = new DebuggerHandler();
+ debugHandler.addBreakListener(new DebuggerHandler.BreakListener() {
+ @Override
+ public void doContinue() {
+ mainFrame.getPanel().clearDebuggerColors();
+ }
+
+ @Override
+ public void breakAt(String scriptName, int line, final int classIndex, final int traitIndex, final int methodIndex) {
+ View.execInEventDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mainFrame.getPanel().gotoScriptLine(getMainFrame().getPanel().getCurrentSwf(), scriptName, line, classIndex, traitIndex, methodIndex);
+ }
+ });
+ }
+ });
+ debugHandler.addConnectionListener(new DebuggerHandler.ConnectionListener() {
+ @Override
+ public void connected() {
+ Main.mainFrame.getMenu().updateComponents();
+ }
+
+ @Override
+ public void disconnected() {
+ if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
+ Main.mainFrame.getPanel().refreshBreakPoints();
+ }
+ }
+ });
+ flashDebugger.addConnectionListener(debugHandler);
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "eeex", ex);
+ }
+ });
+ }
+
+ public static void startDebugger() {
+ flashDebugger.startDebugger();
+ }
+
+ public static void stopDebugger() {
+ flashDebugger.stopDebugger();
+ }
+
+ public static void showModeFrame() {
+ ensureMainFrame();
+ mainFrame.setVisible(true);
+ }
+
+ private static void offerAssociation() {
+ boolean offered = Configuration.offeredAssociation.get();
+ if (!offered) {
+ if (Platform.isWindows()) {
+ if ((!ContextMenuTools.isAddedToContextMenu()) && View.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
+ ContextMenuTools.addToContextMenu(true, false);
+ }
+ }
+
+ Configuration.offeredAssociation.set(true);
+ }
+ }
+
+ public static void initUiLang() {
+ if (GraphicsEnvironment.isHeadless()) { //No GUI in OS
+ return;
+ }
+ try {
+ Class> cl = Class.forName("org.pushingpixels.substance.api.SubstanceLookAndFeel");
+ Field field = cl.getDeclaredField("LABEL_BUNDLE");
+ field.setAccessible(true);
+ field.set(null, null);
+ } catch (Throwable ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+
+ UIManager.put("OptionPane.okButtonText", AppStrings.translate("button.ok"));
+ UIManager.put("OptionPane.yesButtonText", AppStrings.translate("button.yes"));
+ UIManager.put("OptionPane.noButtonText", AppStrings.translate("button.no"));
+ UIManager.put("OptionPane.cancelButtonText", AppStrings.translate("button.cancel"));
+ UIManager.put("OptionPane.messageDialogTitle", AppStrings.translate("dialog.message.title"));
+ UIManager.put("OptionPane.titleText", AppStrings.translate("dialog.select.title"));
+
+ UIManager.put("FileChooser.acceptAllFileFilterText", AppStrings.translate("FileChooser.acceptAllFileFilterText"));
+ UIManager.put("FileChooser.lookInLabelText", AppStrings.translate("FileChooser.lookInLabelText"));
+ UIManager.put("FileChooser.cancelButtonText", AppStrings.translate("button.cancel"));
+ UIManager.put("FileChooser.cancelButtonToolTipText", AppStrings.translate("button.cancel"));
+ UIManager.put("FileChooser.openButtonText", AppStrings.translate("FileChooser.openButtonText"));
+ UIManager.put("FileChooser.openButtonToolTipText", AppStrings.translate("FileChooser.openButtonToolTipText"));
+ UIManager.put("FileChooser.filesOfTypeLabelText", AppStrings.translate("FileChooser.filesOfTypeLabelText"));
+ UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
+ UIManager.put("FileChooser.listViewButtonToolTipText", AppStrings.translate("FileChooser.listViewButtonToolTipText"));
+ UIManager.put("FileChooser.listViewButtonAccessibleName", AppStrings.translate("FileChooser.listViewButtonAccessibleName"));
+ UIManager.put("FileChooser.detailsViewButtonToolTipText", AppStrings.translate("FileChooser.detailsViewButtonToolTipText"));
+ UIManager.put("FileChooser.detailsViewButtonAccessibleName", AppStrings.translate("FileChooser.detailsViewButtonAccessibleName"));
+ UIManager.put("FileChooser.upFolderToolTipText", AppStrings.translate("FileChooser.upFolderToolTipText"));
+ UIManager.put("FileChooser.upFolderAccessibleName", AppStrings.translate("FileChooser.upFolderAccessibleName"));
+ UIManager.put("FileChooser.homeFolderToolTipText", AppStrings.translate("FileChooser.homeFolderToolTipText"));
+ UIManager.put("FileChooser.homeFolderAccessibleName", AppStrings.translate("FileChooser.homeFolderAccessibleName"));
+ UIManager.put("FileChooser.fileNameHeaderText", AppStrings.translate("FileChooser.fileNameHeaderText"));
+ UIManager.put("FileChooser.fileSizeHeaderText", AppStrings.translate("FileChooser.fileSizeHeaderText"));
+ UIManager.put("FileChooser.fileTypeHeaderText", AppStrings.translate("FileChooser.fileTypeHeaderText"));
+ UIManager.put("FileChooser.fileDateHeaderText", AppStrings.translate("FileChooser.fileDateHeaderText"));
+ UIManager.put("FileChooser.fileAttrHeaderText", AppStrings.translate("FileChooser.fileAttrHeaderText"));
+ UIManager.put("FileChooser.openDialogTitleText", AppStrings.translate("FileChooser.openDialogTitleText"));
+ UIManager.put("FileChooser.directoryDescriptionText", AppStrings.translate("FileChooser.directoryDescriptionText"));
+ UIManager.put("FileChooser.directoryOpenButtonText", AppStrings.translate("FileChooser.directoryOpenButtonText"));
+ UIManager.put("FileChooser.directoryOpenButtonToolTipText", AppStrings.translate("FileChooser.directoryOpenButtonToolTipText"));
+ UIManager.put("FileChooser.fileDescriptionText", AppStrings.translate("FileChooser.fileDescriptionText"));
+ UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
+ UIManager.put("FileChooser.helpButtonText", AppStrings.translate("FileChooser.helpButtonText"));
+ UIManager.put("FileChooser.helpButtonToolTipText", AppStrings.translate("FileChooser.helpButtonToolTipText"));
+ UIManager.put("FileChooser.newFolderAccessibleName", AppStrings.translate("FileChooser.newFolderAccessibleName"));
+ UIManager.put("FileChooser.newFolderErrorText", AppStrings.translate("FileChooser.newFolderErrorText"));
+ UIManager.put("FileChooser.newFolderToolTipText", AppStrings.translate("FileChooser.newFolderToolTipText"));
+ UIManager.put("FileChooser.other.newFolder", AppStrings.translate("FileChooser.other.newFolder"));
+ UIManager.put("FileChooser.other.newFolder.subsequent", AppStrings.translate("FileChooser.other.newFolder.subsequent"));
+ UIManager.put("FileChooser.win32.newFolder", AppStrings.translate("FileChooser.win32.newFolder"));
+ UIManager.put("FileChooser.win32.newFolder.subsequent", AppStrings.translate("FileChooser.win32.newFolder.subsequent"));
+ UIManager.put("FileChooser.saveButtonText", AppStrings.translate("FileChooser.saveButtonText"));
+ UIManager.put("FileChooser.saveButtonToolTipText", AppStrings.translate("FileChooser.saveButtonToolTipText"));
+ UIManager.put("FileChooser.saveDialogTitleText", AppStrings.translate("FileChooser.saveDialogTitleText"));
+ UIManager.put("FileChooser.saveInLabelText", AppStrings.translate("FileChooser.saveInLabelText"));
+ UIManager.put("FileChooser.updateButtonText", AppStrings.translate("FileChooser.updateButtonText"));
+ UIManager.put("FileChooser.updateButtonToolTipText", AppStrings.translate("FileChooser.updateButtonToolTipText"));
+
+ UIManager.put("FileChooser.detailsViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.detailsViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewButtonToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.fileAttrHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileAttrHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileDateHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileDateHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileNameHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileNameHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.fileNameLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.fileSizeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileSizeHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileTypeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileTypeHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.filesOfTypeLabel.textAndMnemonic", AppStrings.translate("FileChooser.filesOfTypeLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.folderNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.folderNameLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.homeFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.homeFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.listViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.listViewActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.listViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.listViewButtonToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.lookInLabel.textAndMnemonic", AppStrings.translate("FileChooser.lookInLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.newFolderActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.newFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.refreshActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.refreshActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.saveInLabel.textAndMnemonic", AppStrings.translate("FileChooser.saveInLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.upFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.upFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.viewMenuButtonAccessibleName", AppStrings.translate("FileChooser.viewMenuButtonAccessibleName"));
+ UIManager.put("FileChooser.viewMenuButtonToolTipText", AppStrings.translate("FileChooser.viewMenuButtonToolTipText"));
+ UIManager.put("FileChooser.viewMenuLabel.textAndMnemonic", AppStrings.translate("FileChooser.viewMenuLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderActionLabelText", AppStrings.translate("FileChooser.newFolderActionLabelText"));
+ UIManager.put("FileChooser.listViewActionLabelText", AppStrings.translate("FileChooser.listViewActionLabelText"));
+ UIManager.put("FileChooser.detailsViewActionLabelText", AppStrings.translate("FileChooser.detailsViewActionLabelText"));
+ UIManager.put("FileChooser.refreshActionLabelText", AppStrings.translate("FileChooser.refreshActionLabelText"));
+ UIManager.put("FileChooser.sortMenuLabelText", AppStrings.translate("FileChooser.sortMenuLabelText"));
+ UIManager.put("FileChooser.viewMenuLabelText", AppStrings.translate("FileChooser.viewMenuLabelText"));
+ UIManager.put("FileChooser.fileSizeKiloBytes", AppStrings.translate("FileChooser.fileSizeKiloBytes"));
+ UIManager.put("FileChooser.fileSizeMegaBytes", AppStrings.translate("FileChooser.fileSizeMegaBytes"));
+ UIManager.put("FileChooser.fileSizeGigaBytes", AppStrings.translate("FileChooser.fileSizeGigaBytes"));
+ UIManager.put("FileChooser.folderNameLabelText", AppStrings.translate("FileChooser.folderNameLabelText"));
+
+ UIManager.put("ColorChooser.okText", AppStrings.translate("ColorChooser.okText"));
+ UIManager.put("ColorChooser.cancelText", AppStrings.translate("ColorChooser.cancelText"));
+ UIManager.put("ColorChooser.resetText", AppStrings.translate("ColorChooser.resetText"));
+ UIManager.put("ColorChooser.previewText", AppStrings.translate("ColorChooser.previewText"));
+ UIManager.put("ColorChooser.swatchesNameText", AppStrings.translate("ColorChooser.swatchesNameText"));
+ UIManager.put("ColorChooser.swatchesRecentText", AppStrings.translate("ColorChooser.swatchesRecentText"));
+ UIManager.put("ColorChooser.sampleText", AppStrings.translate("ColorChooser.sampleText"));
+
+ }
+
+ public static void initLang() {
+ if (!Configuration.locale.hasValue()) {
+ if (Platform.isWindows()) {
+ //Load from Installer
+ String uninstKey = "{E618D276-6596-41F4-8A98-447D442A77DB}_is1";
+ uninstKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uninstKey;
+ try {
+ if (Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey)) {
+ if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language")) {
+ String installedLoc = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language");
+ int lcid = Integer.parseInt(installedLoc);
+ char[] buf = new char[9];
+ int cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO639LANGNAME, buf, 9);
+ String langCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO3166CTRYNAME, buf, 9);
+ String countryCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ List langs = Arrays.asList(SelectLanguageDialog.getAvailableLanguages());
+ for (int i = 0; i < langs.size(); i++) {
+ langs.set(i, langs.get(i).toLowerCase());
+ }
+
+ String selectedLang = null;
+
+ if (langs.contains(langCode + "-" + countryCode)) {
+ selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode + "-" + countryCode)];
+ } else if (langs.contains(langCode)) {
+ selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode)];
+ }
+ if (selectedLang != null) {
+ Configuration.locale.set(selectedLang);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get()));
+ AppStrings.updateLanguage();
+
+ Helper.decompilationErrorAdd = AppStrings.translate(Configuration.autoDeobfuscate.get() ? "deobfuscation.comment.failed" : "deobfuscation.comment.tryenable");
+ }
+
+ /**
+ * Clear old FFDec/JavactiveX temp files
+ */
+ private static void clearTemp() {
+ String tempDirPath = System.getProperty("java.io.tmpdir");
+ if (tempDirPath == null) {
+ return;
+ }
+ File tempDir = new File(tempDirPath);
+ if (!tempDir.exists()) {
+ return;
+ }
+ File[] delFiles = tempDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.matches("ffdec_cache.*\\.tmp") || name.matches("javactivex_.*\\.exe") || name.matches("temp[0-9]+\\.swf") || name.matches("ffdec_view_.*\\.swf");
+ }
+ });
+
+ if (delFiles != null) {
+ for (File f : delFiles) {
+ try {
+ f.delete();
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * @param args the command line arguments
+ * @throws IOException On error
+ */
+ public static void main(String[] args) throws IOException {
+ setSessionLoaded(false);
+ clearTemp();
+
+ try {
+ SWFDecompilerPlugin.loadPlugins();
+ } catch (Throwable ex) {
+ logger.log(Level.SEVERE, "Failed to load plugins", ex);
+ }
+
+ AppStrings.setResourceClass(MainFrame.class);
+ initLogging(Configuration._debugMode.get());
+
+ initLang();
+
+ if (Configuration.cacheOnDisk.get()) {
+ Cache.setStorageType(Cache.STORAGE_FILES);
+ } else {
+ Cache.setStorageType(Cache.STORAGE_MEMORY);
+ }
+
+ if (args.length == 0) {
+ initGui();
+ View.execInEventDispatch(() -> {
+ if (Configuration.allowOnlyOneInstance.get() && FirstInstance.focus()) { //Try to focus first instance
+ Main.exit();
+ } else {
+ showModeFrame();
+ reloadLastSession();
+ }
+ });
+ } else {
+ setSessionLoaded(true);
+ String[] filesToOpen = CommandLineArgumentParser.parseArguments(args);
+ if (filesToOpen != null && filesToOpen.length > 0) {
+ View.execInEventDispatch(() -> {
+ initGui();
+ shouldCloseWhenClosingLoadingDialog = true;
+ if (Configuration.allowOnlyOneInstance.get() && FirstInstance.openFiles(Arrays.asList(filesToOpen))) { //Try to open in first instance
+ Main.exit();
+ } else {
+ for (String fileToOpen : filesToOpen) {
+ openFile(fileToOpen, null);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private static void reloadLastSession() {
+ boolean openingFiles = false;
+ if (Configuration.saveSessionOnExit.get()) {
+ String lastSession = Configuration.lastSessionFiles.get();
+ if (lastSession != null && lastSession.length() > 0) {
+ String[] filesToOpen = lastSession.split(File.pathSeparator, -1);
+ List exfiles = new ArrayList<>();
+ List extitles = new ArrayList<>();
+ String lastSessionTitles = Configuration.lastSessionFileTitles.get();
+ String[] fileTitles = new String[0];
+ if (lastSessionTitles != null && !lastSessionTitles.isEmpty()) {
+ fileTitles = lastSessionTitles.split(File.pathSeparator, -1);
+ }
+ for (int i = 0; i < filesToOpen.length; i++) {
+ if (new File(filesToOpen[i]).exists()) {
+ exfiles.add(filesToOpen[i]);
+ if (fileTitles.length > i) {
+ extitles.add(fileTitles[i]);
+ } else {
+ extitles.add(null);
+ }
+ }
+ }
+ SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()];
+ for (int i = 0; i < exfiles.size(); i++) {
+ String extitle = extitles.get(i);
+ sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
+ }
+ if (sourceInfos.length > 0) {
+ openingFiles = true;
+ openFile(sourceInfos, () -> {
+ mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get());
+ setSessionLoaded(true);
+ });
+ }
+ }
+ }
+
+ if (!openingFiles) {
+ setSessionLoaded(true);
+ }
+ }
+
+ public static String tempFile(String url) throws IOException {
+ File f = new File(Configuration.getFFDecHome() + "saved" + File.separator);
+ Path.createDirectorySafe(f);
+ return Configuration.getFFDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
+ }
+
+ public static void removeTrayIcon() {
+ if (SystemTray.isSupported()) {
+ SystemTray tray = SystemTray.getSystemTray();
+ if (trayIcon != null) {
+ tray.remove(trayIcon);
+ trayIcon = null;
+ }
+ }
+ }
+
+ public static void switchProxy() {
+ proxyFrame.switchState();
+ if (stopMenuItem != null) {
+ if (proxyFrame.isRunning()) {
+ stopMenuItem.setLabel(AppStrings.translate("proxy.stop"));
+ } else {
+ stopMenuItem.setLabel(AppStrings.translate("proxy.start"));
+ }
+ }
+ }
+
+ public static void addTrayIcon() {
+ if (trayIcon != null) {
+ return;
+ }
+ if (SystemTray.isSupported()) {
+ SystemTray tray = SystemTray.getSystemTray();
+ trayIcon = new TrayIcon(View.loadImage("proxy16"), ApplicationInfo.VENDOR + " " + ApplicationInfo.SHORT_APPLICATION_NAME + " " + AppStrings.translate("proxy"));
+ trayIcon.setImageAutoSize(true);
+ PopupMenu trayPopup = new PopupMenu();
+
+ ActionListener trayListener = new ActionListener() {
+ /**
+ * Invoked when an action occurs.
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("EXIT")) {
+ Main.exit();
+ }
+ if (e.getActionCommand().equals("SHOW")) {
+ Main.showProxy();
+ }
+ if (e.getActionCommand().equals("SWITCH")) {
+ Main.switchProxy();
+ }
+ }
+ };
+
+ MenuItem showMenuItem = new MenuItem(AppStrings.translate("proxy.show"));
+ showMenuItem.setActionCommand("SHOW");
+ showMenuItem.addActionListener(trayListener);
+ trayPopup.add(showMenuItem);
+ stopMenuItem = new MenuItem(AppStrings.translate("proxy.start"));
+ stopMenuItem.setActionCommand("SWITCH");
+ stopMenuItem.addActionListener(trayListener);
+ trayPopup.add(stopMenuItem);
+ trayPopup.addSeparator();
+ MenuItem exitMenuItem = new MenuItem(AppStrings.translate("exit"));
+ exitMenuItem.setActionCommand("EXIT");
+ exitMenuItem.addActionListener(trayListener);
+ trayPopup.add(exitMenuItem);
+
+ trayIcon.setPopupMenu(trayPopup);
+ trayIcon.addMouseListener(new MouseAdapter() {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getButton() == MouseEvent.BUTTON1) {
+ Main.showProxy();
+ }
+ }
+ });
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException ex) {
+ }
+ }
+ }
+
+ public static void exit() {
+ Configuration.saveConfig();
+ if (mainFrame != null && mainFrame.getPanel() != null) {
+ mainFrame.getPanel().unloadFlashPlayer();
+ mainFrame.dispose();
+ }
+ if (fileTxt != null) {
+ try {
+ fileTxt.flush();
+ fileTxt.close();
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ System.exit(0);
+ }
+
+ public static void about() {
+ (new AboutDialog()).setVisible(true);
+ }
+
+ public static void advancedSettings() {
+ advancedSettings(null);
+ }
+
+ public static void advancedSettings(String category) {
+ (new AdvancedSettingsDialog(category)).setVisible(true);
+ }
+
+ public static void autoCheckForUpdates() {
+ if (Configuration.checkForUpdatesAuto.get()) {
+ Calendar lastUpdatesCheckDate = Configuration.lastUpdatesCheckDate.get();
+ if ((lastUpdatesCheckDate == null) || (lastUpdatesCheckDate.getTime().getTime() < Calendar.getInstance().getTime().getTime() - Configuration.checkForUpdatesDelay.get())) {
+ new SwingWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+ checkForUpdates();
+ return null;
+ }
+ }.execute();
+ }
+ }
+ }
+
+ public static boolean checkForUpdates() {
+ String currentVersion = ApplicationInfo.version;
+ if (currentVersion.equals("unknown")) {
+ // sometimes during development the version information is not available
+ return false;
+ }
+
+ List accepted = new ArrayList<>();
+ if (Configuration.checkForUpdatesStable.get()) {
+ accepted.add("stable");
+ }
+ if (Configuration.checkForUpdatesNightly.get()) {
+ accepted.add("nightly");
+ }
+
+ if (accepted.isEmpty()) {
+ return false;
+ }
+
+ String acceptVersions = String.join(",", accepted);
+ try {
+ String proxyAddress = Configuration.updateProxyAddress.get();
+ URL url = new URL(ApplicationInfo.updateCheckUrl);
+
+ URLConnection uc;
+ if (proxyAddress != null && !proxyAddress.isEmpty()) {
+ int port = 8080;
+ if (proxyAddress.contains(":")) {
+ String[] parts = proxyAddress.split(":");
+ port = Integer.parseInt(parts[1]);
+ proxyAddress = parts[0];
+ }
+
+ uc = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, port)));
+ } else {
+ uc = url.openConnection();
+ }
+ uc.setRequestProperty("X-Accept-Versions", acceptVersions);
+ uc.setRequestProperty("X-Update-Major", "" + UPDATE_SYSTEM_MAJOR);
+ uc.setRequestProperty("X-Update-Minor", "" + UPDATE_SYSTEM_MINOR);
+ uc.setRequestProperty("User-Agent", ApplicationInfo.shortApplicationVerName);
+ String currentLoc = Configuration.locale.get("en");
+ uc.setRequestProperty("Accept-Language", currentLoc + ("en".equals(currentLoc) ? "" : ", en;q=0.8"));
+
+ uc.connect();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
+ String s;
+ final java.util.List versions = new ArrayList<>();
+ String header = "";
+ Pattern headerPat = Pattern.compile("\\[([a-zA-Z0-9]+)\\]");
+ int updateMajor;
+ int updateMinor;
+ Version ver = null;
+ while ((s = br.readLine()) != null) {
+
+ Matcher m = headerPat.matcher(s);
+ if (m.matches()) {
+ header = m.group(1);
+ if (header.equals("version")) {
+ ver = new Version();
+ versions.add(ver);
+ }
+ if (header.equals("noversion")) {
+ break;
+ }
+ } else if (s.contains("=")) {
+ String key = s.substring(0, s.indexOf('='));
+ String val = s.substring(s.indexOf('=') + 1);
+ if ("updateSystem".equals(header)) {
+ if (key.equals("majorVersion")) {
+ updateMajor = Integer.parseInt(val);
+ if (updateMajor > UPDATE_SYSTEM_MAJOR) {
+ break;
+ }
+ }
+ if (key.equals("minorVersion")) {
+ updateMinor = Integer.parseInt(val);
+ }
+ }
+ if ("version".equals(header) && (ver != null)) {
+ if (key.equals("versionId")) {
+ ver.versionId = Integer.parseInt(val);
+ }
+ if (key.equals("versionName")) {
+ ver.versionName = val;
+ }
+ if (key.equals("nightly")) {
+ ver.nightly = val.equals("true");
+ }
+ if (key.equals("revision")) {
+ ver.revision = val;
+ }
+ if (key.equals("build")) {
+ ver.build = Integer.parseInt(val);
+ }
+ if (key.equals("major")) {
+ ver.major = Integer.parseInt(val);
+ }
+ if (key.equals("minor")) {
+ ver.minor = Integer.parseInt(val);
+ }
+ if (key.equals("release")) {
+ ver.release = Integer.parseInt(val);
+ }
+ if (key.equals("longVersionName")) {
+ ver.longVersionName = val;
+ }
+ if (key.equals("releaseDate")) {
+ ver.releaseDate = val;
+ }
+ if (key.equals("appName")) {
+ ver.appName = val;
+ }
+ if (key.equals("appFullName")) {
+ ver.appFullName = val;
+ }
+ if (key.equals("updateLink")) {
+ ver.updateLink = val;
+ }
+ if (key.equals("change[]")) {
+ String changeType = val.substring(0, val.indexOf('|'));
+ String change = val.substring(val.indexOf('|') + 1);
+ if (!ver.changes.containsKey(changeType)) {
+ ver.changes.put(changeType, new ArrayList<>());
+ }
+ List chlist = ver.changes.get(changeType);
+ chlist.add(change);
+ }
+ }
+ }
+ }
+
+ if (!versions.isEmpty()) {
+ View.execInEventDispatch(() -> {
+ NewVersionDialog newVersionDialog = new NewVersionDialog(versions);
+ newVersionDialog.setVisible(true);
+ Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
+ });
+
+ return true;
+ }
+ } catch (IOException | NumberFormatException ex) {
+ return false;
+ }
+ Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
+ return false;
+ }
+
+ private static FileHandler fileTxt;
+
+ public static void clearLogFile() {
+ Logger logger = Logger.getLogger("");
+
+ FileHandler oldFileTxt = fileTxt;
+ fileTxt = null;
+ if (oldFileTxt != null) {
+ logger.removeHandler(fileTxt);
+ oldFileTxt.flush();
+ oldFileTxt.close();
+ }
+
+ String fileName = null;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
+
+ try {
+ fileName = Configuration.getFFDecHome() + "logs" + File.separator;
+ if (Configuration.useDetailedLogging.get()) {
+ fileName += "log-" + sdf.format(new Date()) + ".txt";
+ } else {
+ fileName += "log.txt";
+ }
+ File f = new File(fileName).getParentFile();
+ if (!f.exists()) {
+ f.mkdir();
+ }
+ fileTxt = new FileHandler(fileName);
+ } catch (IOException | SecurityException ex) {
+ //cannot get lock error
+ if (ex.getMessage().contains("lock for")) {
+ //remove all old log files and their .lck
+ for (int i = 0; i <= 100; i++) {
+ File flog = new File(fileName + (i == 0 ? "" : "." + i));
+ File flog_lock = new File(fileName + (i == 0 ? "" : "." + i) + ".lck");
+ flog.delete();
+ flog_lock.delete();
+ }
+ try {
+ fileTxt = new FileHandler(fileName);
+ } catch (IOException | SecurityException ex1) {
+ logger.log(Level.SEVERE, "Cannot initialize logging", ex);
+ }
+ } else {
+ logger.log(Level.SEVERE, "Cannot initialize logging", ex);
+ }
+ }
+
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ logger.log(Level.SEVERE, "Uncaught exception in thread: " + t.getName(), e);
+ if (e instanceof OutOfMemoryError || !Helper.is64BitJre() && Helper.is64BitOs()) {
+ View.showMessageDialog(null, AppStrings.translate("message.warning.outOfMemory32BitJre"), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ });
+
+ Formatter formatterTxt = new LogFormatter();
+ if (fileTxt != null) {
+ fileTxt.setFormatter(formatterTxt);
+ logger.addHandler(fileTxt);
+ }
+
+ if (!GraphicsEnvironment.isHeadless() && ErrorLogFrame.hasInstance()) {
+ ErrorLogFrame.getInstance().clearErrorState();
+ }
+
+ sdf = new SimpleDateFormat("yyyy-MM-dd");
+ logger.log(Level.INFO, "Date: {0}", sdf.format(new Date()));
+ logger.log(Level.INFO, ApplicationInfo.applicationVerName);
+ logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
+ System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")});
+ logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
+ System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("os.arch")});
+ }
+
+ public static void initLogging(boolean debug) {
+ try {
+ Logger logger = Logger.getLogger("");
+ logger.setLevel(Configuration.logLevel);
+
+ Handler[] handlers = logger.getHandlers();
+ for (int i = handlers.length - 1; i >= 0; i--) {
+ logger.removeHandler(handlers[i]);
+ }
+
+ ConsoleHandler conHan = new ConsoleHandler();
+ conHan.setLevel(debug ? Level.CONFIG : Level.WARNING);
+ SimpleFormatter formatterTxt = new SimpleFormatter();
+ conHan.setFormatter(formatterTxt);
+ logger.addHandler(conHan);
+ clearLogFile();
+
+ } catch (Exception ex) {
+ throw new RuntimeException("Problems with creating the log files");
+ }
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java
index 28a3f9d6d..0b687bf5b 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java
@@ -1,1306 +1,1306 @@
-/*
- * Copyright (C) 2010-2016 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.debugger.flash.DebuggerCommands;
-import com.jpexs.decompiler.flash.ApplicationInfo;
-import com.jpexs.decompiler.flash.SWF;
-import com.jpexs.decompiler.flash.SWFBundle;
-import com.jpexs.decompiler.flash.SWFSourceInfo;
-import com.jpexs.decompiler.flash.configuration.Configuration;
-import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener;
-import com.jpexs.decompiler.flash.console.ContextMenuTools;
-import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
-import com.jpexs.decompiler.flash.gui.helpers.CheckResources;
-import com.jpexs.decompiler.flash.tags.ABCContainerTag;
-import com.jpexs.helpers.ByteArrayRange;
-import com.jpexs.helpers.Helper;
-import com.jpexs.helpers.utf8.Utf8Helper;
-import com.sun.jna.Platform;
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.KeyEventDispatcher;
-import java.awt.KeyboardFocusManager;
-import java.awt.ScrollPane;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.WindowEvent;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.AbstractButton;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JEditorPane;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-
-/**
- *
- * @author JPEXS
- */
-public abstract class MainFrameMenu implements MenuBuilder {
-
- private final MainFrame mainFrame;
-
- private KeyEventDispatcher keyEventDispatcher;
-
- private SWF swf;
-
- private ConfigurationItemChangeListener configListenerAutoDeobfuscate;
-
- private ConfigurationItemChangeListener configListenerSimplifyExpressions;
-
- private ConfigurationItemChangeListener configListenerInternalFlashViewer;
-
- private ConfigurationItemChangeListener configListenerParallelSpeedUp;
-
- private ConfigurationItemChangeListener configListenerDecompile;
-
- //private ConfigurationItemChangeListener configListenerCacheOnDisk;
- private ConfigurationItemChangeListener configListenerGotoMainClassOnStartup;
-
- private ConfigurationItemChangeListener configListenerAutoRenameIdentifiers;
-
- private ConfigurationItemChangeListener configListenerAutoOpenLoadedSWFs;
-
- protected final Map menuHotkeys = new HashMap<>();
-
- @Override
- public HotKey getMenuHotkey(String path) {
- return menuHotkeys.get(path);
- }
-
- protected final Map menuActions = new HashMap<>();
-
- public boolean isInternalFlashViewerSelected() {
- return isMenuChecked("/settings/internalViewer"); //miInternalViewer.isSelected();
- }
-
- private final boolean externalFlashPlayerUnavailable;
-
- public MainFrameMenu(MainFrame mainFrame, boolean externalFlashPlayerUnavailable) {
- registerHotKeys();
- this.mainFrame = mainFrame;
- this.externalFlashPlayerUnavailable = externalFlashPlayerUnavailable;
- }
-
- protected String translate(String key) {
- return mainFrame.translate(key);
- }
-
- protected boolean openActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- Main.openFileDialog();
- return true;
- }
-
- protected boolean saveActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- if (swf != null) {
- boolean saved = false;
- if (swf.swfList != null && swf.swfList.isBundle()) {
- SWFBundle bundle = swf.swfList.bundle;
- if (!bundle.isReadOnly()) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- swf.saveTo(baos);
- saved = bundle.putSWF(swf.getFileTitle(), new ByteArrayInputStream(baos.toByteArray()));
- } catch (IOException ex) {
- Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
- }
- }
- } else if (swf.binaryData != null) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- swf.saveTo(baos);
- swf.binaryData.binaryData = new ByteArrayRange(baos.toByteArray());
- swf.binaryData.setModified(true);
- saved = true;
- } catch (IOException ex) {
- Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
- }
- } else if (swf.getFile() == null) {
- saved = saveAs(swf, SaveFileMode.SAVEAS);
- } else {
- try {
- Main.saveFile(swf, swf.getFile());
- saved = true;
- } catch (IOException ex) {
- Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE);
- }
- }
- if (saved) {
- swf.clearModified();
- mainFrame.getPanel().refreshTree(swf);
- }
-
- return true;
- }
-
- return false;
- }
-
- protected boolean saveAsActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- if (swf != null) {
- if (saveAs(swf, SaveFileMode.SAVEAS)) {
- swf.clearModified();
- }
-
- return true;
- }
-
- return false;
- }
-
- private boolean saveAs(SWF swf, SaveFileMode mode) {
- if (Main.saveFileDialog(swf, mode)) {
- mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : ""));
- updateComponents(swf);
- return true;
- }
- return false;
- }
-
- protected void saveAsExeActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- if (swf != null) {
- saveAs(swf, SaveFileMode.EXE);
- }
- }
-
- protected void closeActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- if (swf == null) {
- return;
- }
-
- Main.closeFile(swf.swfList);
- }
-
- protected boolean closeAllActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- if (swf != null) {
- return Main.closeAll();
- }
-
- return false;
- }
-
- protected void importTextActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().importText(swf);
- }
-
- protected void importScriptActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().importScript(swf);
- }
-
- protected void importSymbolClassActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().importSymbolClass(swf);
- }
-
- protected boolean exportAllActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- return export(false);
- }
-
- protected boolean exportSelectedActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return false;
- }
-
- return export(true);
- }
-
- protected boolean export(boolean onlySelected) {
- if (swf != null) {
- mainFrame.getPanel().export(onlySelected);
- return true;
- }
-
- return false;
- }
-
- protected void exportFlaActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().exportFla(swf);
- }
-
- protected void importXmlActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().importSwfXml();
- }
-
- protected void exportXmlActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().exportSwfXml();
- }
-
- protected boolean searchActionPerformed(ActionEvent evt) {
- return search(evt, null);
- }
-
- protected boolean searchInTextPerformed(ActionEvent evt) {
- return search(evt, true);
- }
-
- protected boolean searchInActionPerformed(ActionEvent evt) {
- return search(evt, false);
- }
-
- protected boolean search(ActionEvent evt, Boolean searchInText) {
- if (swf != null) {
- mainFrame.getPanel().searchInActionScriptOrText(searchInText, swf);
- return true;
- }
-
- return false;
- }
-
- protected boolean replaceActionPerformed(ActionEvent evt) {
- if (swf != null) {
- mainFrame.getPanel().replaceText();
- return true;
- }
-
- return false;
- }
-
- protected void showProxyActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- Main.showProxy();
- }
-
- protected boolean clearLog(ActionEvent evt) {
- ErrorLogFrame.getInstance().clearLog();
- return true;
- }
-
- protected void renameOneIdentifier(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().renameOneIdentifier(swf);
- }
-
- protected void renameInvalidIdentifiers(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().renameIdentifiers(swf);
- }
-
- protected void deobfuscationActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- mainFrame.getPanel().deobfuscate();
- }
-
- protected void setSubLimiter(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
- Main.setSubLimiter(selected);
- }
-
- protected void switchDebugger() {
- DebuggerTools.switchDebugger(swf);
- }
-
- protected void debuggerShowLogActionPerformed(ActionEvent evt) {
- DebuggerTools.debuggerShowLog();
- }
-
- protected void debuggerInjectLoader(ActionEvent evt) {
- DebuggerTools.injectDebugLoader(swf);
- refreshDecompiled();
- }
-
- protected void debuggerReplaceTraceCallsActionPerformed(ActionEvent evt) {
- ReplaceTraceDialog rtd = new ReplaceTraceDialog(Configuration.lastDebuggerReplaceFunction.get());
- rtd.setVisible(true);
- if (rtd.getValue() != null) {
- String fname = rtd.getValue();
- DebuggerTools.replaceTraceCalls(swf, fname);
- mainFrame.getPanel().refreshDecompiled();
- Configuration.lastDebuggerReplaceFunction.set(rtd.getValue());
- }
- }
-
- protected void clearRecentFilesActionPerformed(ActionEvent evt) {
- Configuration.recentFiles.set(null);
- }
-
- protected void removeNonScripts() {
- mainFrame.getPanel().removeNonScripts(swf);
- }
-
- protected void removeExceptSelected() {
- mainFrame.getPanel().removeExceptSelected(swf);
- }
-
- protected void refreshDecompiled() {
- mainFrame.getPanel().refreshDecompiled();
- }
-
- protected boolean previousTag(ActionEvent evt) {
- return mainFrame.getPanel().previousTag();
- }
-
- protected boolean nextTag(ActionEvent evt) {
- return mainFrame.getPanel().nextTag();
- }
-
- protected void checkResources() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- PrintStream stream = new PrintStream(os);
- CheckResources.checkResources(stream, null);
- final String str = new String(os.toByteArray(), Utf8Helper.charset);
- JDialog dialog = new JDialog() {
- @Override
- public void setVisible(boolean bln) {
- setSize(new Dimension(800, 600));
- Container cnt = getContentPane();
- cnt.setLayout(new BorderLayout());
- String[] languages = SelectLanguageDialog.getAvailableLanguages().clone();
- languages[0] = "all";
- JComboBox languagesComboBox = new JComboBox<>(languages);
- this.add(languagesComboBox, BorderLayout.NORTH);
- ScrollPane scrollPane = new ScrollPane();
- JEditorPane editor = new JEditorPane();
- editor.setEditable(false);
- editor.setText(str);
- scrollPane.add(editor);
- this.add(scrollPane, BorderLayout.CENTER);
- this.setModal(true);
- View.centerScreen(this);
- languagesComboBox.addActionListener((ActionEvent e) -> {
- String lang = (String) languagesComboBox.getSelectedItem();
- if (lang.equals("all")) {
- lang = null;
- }
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- try (PrintStream stream = new PrintStream(os, false, "UTF-8")) {
- CheckResources.checkResources(stream, lang);
- String str = new String(os.toByteArray(), Utf8Helper.charset);
- editor.setText(str);
- } catch (UnsupportedEncodingException ex) {
- // ignore
- }
- });
- super.setVisible(bln);
- }
- };
- dialog.setVisible(true);
- }
-
- protected void checkUpdatesActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- if (!Main.checkForUpdates()) {
- View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE);
- }
- }
-
- protected void helpUsActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- String helpUsURL = ApplicationInfo.PROJECT_PAGE + "/help_us.html?utm_source=app&utm_medium=menu&utm_campaign=app";
- if (!View.navigateUrl(helpUsURL)) {
- View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL));
- }
- }
-
- protected void homePageActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- String homePageURL = ApplicationInfo.PROJECT_PAGE + "?utm_source=app&utm_medium=menu&utm_campaign=app";
- if (!View.navigateUrl(homePageURL)) {
- View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL));
- }
- }
-
- protected void aboutActionPerformed(ActionEvent evt) {
- if (Main.isWorking()) {
- return;
- }
-
- Main.about();
- }
-
- protected boolean reloadActionPerformed(ActionEvent evt) {
- if (swf != null) {
- if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
- Main.reloadFile(swf.swfList);
- }
- }
- return true;
- }
-
- protected boolean reloadAllActionPerformed(ActionEvent evt) {
- if (swf != null) {
- if (View.showConfirmDialog(null, translate("message.confirm.reloadAll"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
- Main.reloadApp();
- }
-
- return true;
- }
-
- Main.reloadApp();
- return true;
- }
-
- protected void advancedSettingsActionPerformed(ActionEvent evt) {
- Main.advancedSettings();
- }
-
- protected void searchMemoryActionPerformed(ActionEvent evt) {
- Main.loadFromMemory();
- }
-
- protected void searchCacheActionPerformed(ActionEvent evt) {
- Main.loadFromCache();
- }
-
- protected void gotoDucumentClassOnStartupActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.gotoMainClassOnStartup.set(selected);
- }
-
- protected void autoOpenLoadedSWFsActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.autoOpenLoadedSWFs.set(selected);
- }
-
- protected void autoRenameIdentifiersActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.autoRenameIdentifiers.set(selected);
- }
-
- /*protected void cacheOnDiskActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.cacheOnDisk.set(selected);
- if (selected) {
- Cache.setStorageType(Cache.STORAGE_FILES);
- } else {
- Cache.setStorageType(Cache.STORAGE_MEMORY);
- }
- }*/
- protected void setLanguageActionPerformed(ActionEvent evt) {
- new SelectLanguageDialog().display();
- }
-
- protected void disableDecompilationActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.decompile.set(!selected);
- mainFrame.getPanel().disableDecompilationChanged();
- }
-
- protected void associateActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- if (selected == ContextMenuTools.isAddedToContextMenu()) {
- return;
- }
- ContextMenuTools.addToContextMenu(selected, false);
-
- // Update checkbox menuitem accordingly (User can cancel rights elevation)
- new Timer().schedule(new TimerTask() {
- @Override
- public void run() {
- button.setSelected(ContextMenuTools.isAddedToContextMenu());
- }
- }, 1000); // It takes some time registry change to apply
- }
-
- protected void gotoDucumentClassActionPerformed(ActionEvent evt) {
- mainFrame.getPanel().gotoDocumentClass(mainFrame.getPanel().getCurrentSwf());
- }
-
- protected void parallelSpeedUpActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- String confStr = translate("message.confirm.parallel") + "\r\n";
- if (selected) {
- confStr += " " + translate("message.confirm.on");
- } else {
- confStr += " " + translate("message.confirm.off");
- }
- if (View.showConfirmDialog(null, confStr, translate("message.parallel"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
- Configuration.parallelSpeedUp.set(selected);
- } else {
- button.setSelected(Configuration.parallelSpeedUp.get());
- }
- }
-
- protected void internalViewerSwitchActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.internalFlashViewer.set(selected);
- mainFrame.getPanel().reload(true);
- }
-
- protected void simplifyExpressionsActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- Configuration.simplifyExpressions.set(selected);
- mainFrame.getPanel().autoDeobfuscateChanged();
- }
-
- protected void autoDeobfuscationActionPerformed(ActionEvent evt) {
- AbstractButton button = (AbstractButton) evt.getSource();
- boolean selected = button.isSelected();
-
- if (View.showConfirmDialog(mainFrame.getPanel(), translate("message.confirm.autodeobfuscate") + "\r\n" + (selected ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
- Configuration.autoDeobfuscate.set(selected);
- mainFrame.getPanel().autoDeobfuscateChanged();
- } else {
- button.setSelected(Configuration.autoDeobfuscate.get());
- }
- }
-
- /*protected void deobfuscationMode(ActionEvent evt, int mode) {
- Configuration.deobfuscationMode.set(mode);
- mainFrame.getPanel().autoDeobfuscateChanged();
- }*/
- protected void exitActionPerformed(ActionEvent evt) {
- JFrame frame = (JFrame) mainFrame;
- frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
- }
-
- public void updateComponents() {
- updateComponents(swf);
- }
-
- public void updateComponents(SWF swf) {
- this.swf = swf;
- boolean isRunning = Main.isRunning();
- boolean isDebugRunning = Main.isDebugRunning();
- boolean isDebugPaused = Main.isDebugPaused();
-
- boolean isRunningOrDebugging = isRunning || isDebugRunning;
-
- boolean swfSelected = swf != null;
- boolean isWorking = Main.isWorking();
- List abcList = swf != null ? swf.getAbcList() : null;
- boolean hasAbc = swfSelected && abcList != null && !abcList.isEmpty();
- boolean hasDebugger = hasAbc && DebuggerTools.hasDebugger(swf);
- MainPanel mainPanel = mainFrame.getPanel();
- boolean swfLoaded = mainPanel != null ? !mainPanel.getSwfs().isEmpty() : false;
-
- setMenuEnabled("_/open", !isWorking);
- setMenuEnabled("/file/open", !isWorking);
- setMenuEnabled("_/save", swfSelected && !isWorking);
- setMenuEnabled("/file/save", swfSelected && !isWorking);
- setMenuEnabled("_/saveAs", swfSelected && !isWorking);
- setMenuEnabled("/file/saveAs", swfSelected && !isWorking);
- setMenuEnabled("/file/saveAsExe", swfSelected && !isWorking);
- setMenuEnabled("_/close", swfSelected && !isWorking);
- setMenuEnabled("/file/close", swfSelected && !isWorking);
- setMenuEnabled("_/closeAll", swfLoaded && !isWorking);
- setMenuEnabled("/file/closeAll", swfLoaded && !isWorking);
-
- setMenuEnabled("/file/export", swfSelected);
- setMenuEnabled("_/exportAll", swfSelected && !isWorking);
- setMenuEnabled("/file/export/exportAll", swfSelected && !isWorking);
- setMenuEnabled("_/exportFla", swfSelected && !isWorking);
- setMenuEnabled("/file/export/exportFla", swfSelected && !isWorking);
- setMenuEnabled("_/exportSelected", swfSelected && !isWorking);
- setMenuEnabled("/file/export/exportSelected", swfSelected && !isWorking);
- setMenuEnabled("/file/export/exportXml", swfSelected && !isWorking);
-
- setMenuEnabled("/file/import", swfSelected);
- setMenuEnabled("/file/import/importText", swfSelected && !isWorking);
- setMenuEnabled("/file/import/importScript", swfSelected && !isWorking);
- setMenuEnabled("/file/import/importSymbolClass", swfSelected && !isWorking);
- setMenuEnabled("/file/import/importXml", swfSelected && !isWorking);
-
- setMenuEnabled("/tools/deobfuscation", swfSelected);
- setMenuEnabled("/tools/deobfuscation/renameOneIdentifier", swfSelected && !isWorking);
- setMenuEnabled("/tools/deobfuscation/renameInvalidIdentifiers", swfSelected && !isWorking);
- setMenuEnabled("/tools/deobfuscation/deobfuscation", hasAbc);
-
- setMenuEnabled("/tools/search", swfSelected);
- setMenuEnabled("/tools/replace", swfSelected);
- setMenuEnabled("/tools/timeline", swfSelected);
- setMenuEnabled("/tools/showProxy", !isWorking);
-
- setMenuEnabled("/tools/gotoDocumentClass", hasAbc);
- /*setMenuEnabled("/tools/debugger/debuggerSwitch", hasAbc);
- setMenuChecked("/tools/debugger/debuggerSwitch", hasDebugger);
- setMenuEnabled("/tools/debugger/debuggerReplaceTrace", hasAbc && hasDebugger);*/
- //setMenuEnabled("/tools/debugger/debuggerInjectLoader", hasAbc && hasDebugger);
-
- setMenuEnabled("_/checkUpdates", !isWorking);
- setMenuEnabled("/help/checkUpdates", !isWorking);
- setMenuEnabled("/help/helpUs", !isWorking);
- setMenuEnabled("/help/homePage", !isWorking);
- setMenuEnabled("_/about", !isWorking);
- setMenuEnabled("/help/about", !isWorking);
-
- setMenuEnabled("/file/start/run", swfSelected && !isRunningOrDebugging);
- setMenuEnabled("/file/start/debug", swfSelected && !isRunningOrDebugging);
- setMenuEnabled("/file/start/debugpcode", swfSelected && !isRunningOrDebugging);
-
- setMenuEnabled("/file/start/stop", isRunningOrDebugging);
- setMenuEnabled("/debugging/debug/stop", isRunningOrDebugging); //same as previous
-
- setPathVisible("/debugging", isDebugRunning);
- setMenuEnabled("/debugging/debug", isDebugRunning);
- //setMenuEnabled("/debugging/debug/pause", isDebugRunning);
- setMenuEnabled("/debugging/debug/stepOver", isDebugPaused);
- setMenuEnabled("/debugging/debug/stepInto", isDebugPaused);
- setMenuEnabled("/debugging/debug/stepOut", isDebugPaused);
- setMenuEnabled("/debugging/debug/continue", isDebugPaused);
- //setMenuEnabled("/debugging/debug/stack", isDebugPaused);
- //setMenuEnabled("/debugging/debug/watch", isDebugPaused);
-
- }
-
- private void registerHotKeys() {
-
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- manager.addKeyEventDispatcher(keyEventDispatcher = this::dispatchKeyEvent);
- }
-
- public void createMenuBar() {
- initMenu();
-
- if (supportsAppMenu()) {
- addMenuItem("_", null, null, null, 0, null, false, null, false);
- addMenuItem("_/open", translate("menu.file.open"), "open32", this::openActionPerformed, PRIORITY_TOP, this::loadRecent, false, null, false);
- addMenuItem("_/save", translate("menu.file.save"), "save32", this::saveActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/saveAs", translate("menu.file.saveas"), "saveas32", this::saveAsActionPerformed, PRIORITY_TOP, null, true, null, false);
- addSeparator("_");
- addMenuItem("_/exportFla", translate("menu.file.export.fla"), "exportfla32", this::exportFlaActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/exportAll", translate("menu.file.export.all"), "export32", this::exportAllActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/exportSelected", translate("menu.file.export.selection"), "exportsel32", this::exportSelectedActionPerformed, PRIORITY_TOP, null, true, null, false);
- addSeparator("_");
- addMenuItem("_/checkUpdates", translate("menu.help.checkupdates"), "update32", this::checkUpdatesActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/about", translate("menu.help.about"), "about32", this::aboutActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/close", translate("menu.file.close"), "close32", this::closeActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/closeAll", translate("menu.file.closeAll"), "closeall32", this::closeAllActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("_/$exit", translate("menu.file.exit"), "exit32", this::exitActionPerformed, PRIORITY_TOP, null, true, null, false);
- finishMenu("_");
- }
-
- addMenuItem("/file", translate("menu.file"), null, null, 0, null, false, null, false);
- addMenuItem("/file/open", translate("menu.file.open"), "open32", this::openActionPerformed, PRIORITY_TOP, this::loadRecent, !supportsMenuAction(), new HotKey("CTRL+SHIFT+O"), false);
-
- if (!supportsMenuAction()) {
- addMenuItem("/file/recent", translate("menu.recentFiles"), null, null, 0, this::loadRecent, false, null, false);
- finishMenu("/file/recent");
- } else {
- finishMenu("/file/open");
- }
-
- addMenuItem("/file/save", translate("menu.file.save"), "save32", this::saveActionPerformed, PRIORITY_TOP, null, true, new HotKey("CTRL+SHIFT+S"), false);
- addMenuItem("/file/saveAs", translate("menu.file.saveas"), "saveas16", this::saveAsActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+A"), false);
- addMenuItem("/file/saveAsExe", translate("menu.file.saveasexe"), "saveasexe16", this::saveAsExeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/file/reload", translate("menu.file.reload"), "reload16", this::reloadActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+R"), false);
- addMenuItem("/file/reloadAll", translate("menu.file.reloadAll"), "reload16", this::reloadAllActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
-
- addSeparator("/file");
-
- addMenuItem("/file/export", translate("menu.export"), null, null, 0, null, false, null, false);
- addMenuItem("/file/export/exportFla", translate("menu.file.export.fla"), "exportfla32", this::exportFlaActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("/file/export/exportXml", translate("menu.file.export.xml"), "exportxml32", this::exportXmlActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/file/export/exportAll", translate("menu.file.export.all"), "export16", this::exportAllActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+E"), false);
- addMenuItem("/file/export/exportSelected", translate("menu.file.export.selection"), "exportsel16", this::exportSelectedActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/file/export");
-
- addMenuItem("/file/import", translate("menu.import"), null, null, 0, null, false, null, false);
- addMenuItem("/file/import/importXml", translate("menu.file.import.xml"), "importxml32", this::importXmlActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("/file/import/importText", translate("menu.file.import.text"), "importtext32", this::importTextActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/file/import/importScript", translate("menu.file.import.script"), "importscript32", this::importScriptActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/file/import/importSymbolClass", translate("menu.file.import.symbolClass"), "importsymbolclass32", this::importSymbolClassActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/file/import");
-
- addMenuItem("/file/start", translate("menu.file.start"), null, null, 0, null, false, null, false);
- addMenuItem("/file/start/run", translate("menu.file.start.run"), "play32", this::runActionPerformed, PRIORITY_TOP, null, true, new HotKey("F6"), false);
- addMenuItem("/file/start/debug", translate("menu.file.start.debug"), "debug32", this::debugActionPerformed, PRIORITY_TOP, null, true, new HotKey("CTRL+F5"), false);
- addMenuItem("/file/start/stop", translate("menu.file.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("/file/start/debugpcode", translate("menu.file.start.debugpcode"), "debug32", this::debugPCodeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/file/start");
-
- addMenuItem("/file/view", translate("menu.view"), null, null, 0, null, false, null, false);
- addToggleMenuItem("/file/view/viewResources", translate("menu.file.view.resources"), "view", "viewresources16", this::viewResourcesActionPerformed, PRIORITY_MEDIUM, null);
- addToggleMenuItem("/file/view/viewHex", translate("menu.file.view.hex"), "view", "viewhex16", this::viewHexActionPerformed, PRIORITY_MEDIUM, null);
- finishMenu("/file/view");
-
- addSeparator("/file");
- addMenuItem("/file/close", translate("menu.file.close"), "close32", this::closeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/file/closeAll", translate("menu.file.closeAll"), "closeall32", this::closeAllActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+X"), false);
-
- if (!supportsAppMenu()) {
- addSeparator("/file");
- addMenuItem("/file/exit", translate("menu.file.exit"), "exit32", this::exitActionPerformed, PRIORITY_TOP, null, true, null, false);
- }
-
- finishMenu("/file");
-
- if (Configuration.dumpView.get()) {
- setGroupSelection("view", "/file/view/viewHex");
- } else {
- setGroupSelection("view", "/file/view/viewResources");
- }
-
- /*
- menu.file.start = Start
- menu.file.start.run = Run
- menu.file.start.stop = Stop
- menu.file.start.debug = Debug
- menu.debugging = Debugging
- menu.debugging.debug = Debug
- menu.debugging.debug.stop = Stop
- menu.debugging.debug.pause = Pause
- menu.debugging.debug.stepOver = Step over
- menu.debugging.debug.stepInto = Step into
- menu.debugging.debug.stepOut = Step out
- menu.debugging.debug.continue = Continue
- menu.debugging.debug.stack = Stack...
- menu.debugging.debug.watch = New watch...
- */
- addMenuItem("/debugging", translate("menu.debugging"), null, null, 0, null, false, null, true);
- addMenuItem("/debugging/debug", translate("menu.debugging.debug"), null, null, 0, null, false, null, false);
- addMenuItem("/debugging/debug/stop", translate("menu.file.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true, null, false);
- //addMenuItem("/debugging/debug/pause", translate("menu.debugging.debug.pause"), "pause32", this::pauseActionPerformed, PRIORITY_TOP, null, true,false);
- addMenuItem("/debugging/debug/continue", translate("menu.debugging.debug.continue"), "continue32", this::continueActionPerformed, PRIORITY_TOP, null, true, new HotKey("F5"), false);
- addMenuItem("/debugging/debug/stepOver", translate("menu.debugging.debug.stepOver"), "stepover32", this::stepOverActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("F8"), false);
- addMenuItem("/debugging/debug/stepInto", translate("menu.debugging.debug.stepInto"), "stepinto32", this::stepIntoActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("F7"), false);
- addMenuItem("/debugging/debug/stepOut", translate("menu.debugging.debug.stepOut"), "stepout32", this::stepOutActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+F7"), false);
- //addMenuItem("/debugging/debug/stack", translate("menu.debugging.debug.stack"), "stack32", this::stackActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- //addMenuItem("/debugging/debug/watch", translate("menu.debugging.debug.watch"), "watch32", this::watchActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/debugging/debug");
- finishMenu("/debugging");
-
- addMenuItem("/tools", translate("menu.tools"), null, null, 0, null, false, null, false);
- addMenuItem("/tools/search", translate("menu.tools.search"), "search16", this::searchActionPerformed, PRIORITY_TOP, null, true, null, false);
-
- addMenuItem("/tools/replace", translate("menu.tools.replace"), "replace32", this::replaceActionPerformed, PRIORITY_TOP, null, true, null, false);
- addToggleMenuItem("/tools/timeline", translate("menu.tools.timeline"), null, "timeline32", this::timelineActionPerformed, PRIORITY_TOP, null);
-
- addMenuItem("/tools/showProxy", translate("menu.tools.proxy"), "proxy16", this::showProxyActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- if (Platform.isWindows()) {
- addMenuItem("/tools/searchMemory", translate("menu.tools.searchMemory"), "loadmemory16", this::searchMemoryActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- }
-
- //addMenuItem("/tools/searchCache", translate("menu.tools.searchCache"), "loadcache16", this::searchCacheActionPerformed, PRIORITY_MEDIUM, null, true, null);
- addMenuItem("/tools/deobfuscation", translate("menu.tools.deobfuscation"), "deobfuscate16", null, 0, null, false, null, false);
- addMenuItem("/tools/deobfuscation/renameOneIdentifier", translate("menu.tools.deobfuscation.globalrename"), "rename16", this::renameOneIdentifier, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/tools/deobfuscation/renameInvalidIdentifiers", translate("menu.tools.deobfuscation.renameinvalid"), "renameall16", this::renameInvalidIdentifiers, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/tools/deobfuscation/deobfuscation", translate("menu.tools.deobfuscation.pcode"), "deobfuscate32", this::deobfuscationActionPerformed, PRIORITY_TOP, null, true, null, false);
- finishMenu("/tools/deobfuscation");
-
- /*addMenuItem("/tools/debugger", translate("menu.debugger"), null, null, 0, null, false, null,false);
- addToggleMenuItem("/tools/debugger/debuggerSwitch", translate("menu.debugger.switch"), null, "debugger32", this::debuggerSwitchActionPerformed, PRIORITY_TOP, null,false);
- addMenuItem("/tools/debugger/debuggerReplaceTrace", translate("menu.debugger.replacetrace"), "debuggerreplace16", this::debuggerReplaceTraceCallsActionPerformed, PRIORITY_MEDIUM, null, true, null,false);
- //addMenuItem("/tools/debugger/debuggerInjectLoader", "Inject Loader", "debuggerreplace16", this::debuggerInjectLoader, PRIORITY_MEDIUM, null, true,false);
- addMenuItem("/tools/debugger/debuggerShowLog", translate("menu.debugger.showlog"), "debuggerlog16", this::debuggerShowLogActionPerformed, PRIORITY_MEDIUM, null, true, null,false);
- finishMenu("/tools/debugger");*/
- addMenuItem("/tools/gotoDocumentClass", translate("menu.tools.gotoDocumentClass"), "gotomainclass32", this::gotoDucumentClassActionPerformed, PRIORITY_TOP, null, true, null, false);
- finishMenu("/tools");
-
- //Settings
- addMenuItem("/settings", translate("menu.settings"), null, null, 0, null, false, null, false);
-
- addToggleMenuItem("/settings/autoDeobfuscation", translate("menu.settings.autodeobfuscation"), null, null, this::autoDeobfuscationActionPerformed, 0, null);
- addToggleMenuItem("/settings/simplifyExpressions", translate("menu.settings.simplifyExpressions"), null, null, this::simplifyExpressionsActionPerformed, 0, null);
- addToggleMenuItem("/settings/internalViewer", translate("menu.settings.internalflashviewer"), null, null, this::internalViewerSwitchActionPerformed, 0, null);
- addToggleMenuItem("/settings/parallelSpeedUp", translate("menu.settings.parallelspeedup"), null, null, this::parallelSpeedUpActionPerformed, 0, null);
- addToggleMenuItem("/settings/disableDecompilation", translate("menu.settings.disabledecompilation"), null, null, this::disableDecompilationActionPerformed, 0, null);
- //addToggleMenuItem("/settings/cacheOnDisk", translate("menu.settings.cacheOnDisk"), null, null, this::cacheOnDiskActionPerformed, 0, null);
- addToggleMenuItem("/settings/gotoMainClassOnStartup", translate("menu.settings.gotoMainClassOnStartup"), null, null, this::gotoDucumentClassOnStartupActionPerformed, 0, null);
- addToggleMenuItem("/settings/autoRenameIdentifiers", translate("menu.settings.autoRenameIdentifiers"), null, null, this::autoRenameIdentifiersActionPerformed, 0, null);
- addToggleMenuItem("/settings/autoOpenLoadedSWFs", translate("menu.settings.autoOpenLoadedSWFs"), null, null, this::autoOpenLoadedSWFsActionPerformed, 0, null);
- if (Platform.isWindows()) {
- addToggleMenuItem("/settings/associate", translate("menu.settings.addtocontextmenu"), null, null, this::associateActionPerformed, 0, null);
- }
-
- addMenuItem("/settings/language", translate("menu.language"), null, null, 0, null, false, null, false);
- addMenuItem("/settings/language/setLanguage", translate("menu.settings.language"), "setlanguage32", this::setLanguageActionPerformed, PRIORITY_TOP, null, true, null, false);
- finishMenu("/settings/language");
-
- /*addMenuItem("/settings/deobfuscation", translate("menu.deobfuscation"), null, null, 0, null, false,false);
- addToggleMenuItem("/settings/deobfuscation/old", translate("menu.file.deobfuscation.old"), "deobfuscation", "deobfuscateold16", (ActionEvent e) -> {
- deobfuscationMode(e, 0);
- }, 0);
- addToggleMenuItem("/settings/deobfuscation/new", translate("menu.file.deobfuscation.new"), "deobfuscation", "deobfuscatenew16", (ActionEvent e) -> {
- deobfuscationMode(e, 1);
- }, 0);
-
- finishMenu("/settings/deobfuscation");*/
- addMenuItem("/settings/advancedSettings", translate("menu.advancedsettings.advancedsettings"), null, null, 0, null, false, null, false);
- addMenuItem("/settings/advancedSettings/advancedSettings", translate("menu.advancedsettings.advancedsettings"), "settings32", this::advancedSettingsActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("/settings/advancedSettings/clearRecentFiles", translate("menu.tools.otherTools.clearRecentFiles"), "clearrecent16", this::clearRecentFilesActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/settings/advancedSettings");
-
- finishMenu("/settings");
-
- setMenuChecked("/settings/autoDeobfuscation", Configuration.autoDeobfuscate.get());
- Configuration.autoDeobfuscate.addListener(configListenerAutoDeobfuscate = (Boolean newValue) -> {
- setMenuChecked("/settings/autoDeobfuscation", newValue);
- });
-
- setMenuChecked("/settings/simplifyExpressions", Configuration.simplifyExpressions.get());
- Configuration.simplifyExpressions.addListener(configListenerSimplifyExpressions = (Boolean newValue) -> {
- setMenuChecked("/settings/simplifyExpressions", newValue);
- });
-
- setMenuChecked("/settings/internalViewer", Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable);
- Configuration.internalFlashViewer.addListener(configListenerInternalFlashViewer = (Boolean newValue) -> {
- setMenuChecked("/settings/internalViewer", newValue || externalFlashPlayerUnavailable);
- });
-
- setMenuChecked("/settings/parallelSpeedUp", Configuration.parallelSpeedUp.get());
- Configuration.parallelSpeedUp.addListener(configListenerParallelSpeedUp = (Boolean newValue) -> {
- setMenuChecked("/settings/parallelSpeedUp", newValue);
- });
-
- setMenuChecked("/settings/disableDecompilation", !Configuration.decompile.get());
- Configuration.decompile.addListener(configListenerDecompile = (Boolean newValue) -> {
- setMenuChecked("/settings/disableDecompilation", !newValue);
- });
-
- /*setMenuChecked("/settings/cacheOnDisk", Configuration.cacheOnDisk.get());
- Configuration.cacheOnDisk.addListener(configListenerCacheOnDisk = (Boolean newValue) -> {
- setMenuChecked("/settings/cacheOnDisk", newValue);
- });*/
- setMenuChecked("/settings/gotoMainClassOnStartup", Configuration.gotoMainClassOnStartup.get());
- Configuration.gotoMainClassOnStartup.addListener(configListenerGotoMainClassOnStartup = (Boolean newValue) -> {
- setMenuChecked("/settings/gotoMainClassOnStartup", newValue);
- });
-
- setMenuChecked("/settings/autoRenameIdentifiers", Configuration.autoRenameIdentifiers.get());
- Configuration.autoRenameIdentifiers.addListener(configListenerAutoRenameIdentifiers = (Boolean newValue) -> {
- setMenuChecked("/settings/autoRenameIdentifiers", newValue);
- });
-
- setMenuChecked("/settings/autoOpenLoadedSWFs", Configuration.autoOpenLoadedSWFs.get());
- Configuration.autoOpenLoadedSWFs.addListener(configListenerAutoOpenLoadedSWFs = (Boolean newValue) -> {
- setMenuChecked("/settings/autoOpenLoadedSWFs", newValue);
- });
-
- if (externalFlashPlayerUnavailable) {
- setMenuEnabled("/settings/internalViewer", false);
- setMenuEnabled("/settings/autoOpenLoadedSWFs", false);
- }
-
- /*int deobfuscationMode = Configuration.deobfuscationMode.get();
- switch (deobfuscationMode) {
- case 0:
- setGroupSelection("deobfuscation", "/settings/deobfuscation/old");
- break;
- case 1:
- setGroupSelection("deobfuscation", "/settings/deobfuscation/new");
- break;
- }*/
- if (Platform.isWindows()) {
- setMenuChecked("/settings/associate", ContextMenuTools.isAddedToContextMenu());
- }
-
- //Help
- addMenuItem("/help", translate("menu.help"), null, null, 0, null, false, null, false);
- addMenuItem("/help/helpUs", translate("menu.help.helpus"), "donate32", this::helpUsActionPerformed, PRIORITY_TOP, null, true, null, false);
- addMenuItem("/help/homePage", translate("menu.help.homepage"), "homepage16", this::homePageActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addSeparator("/help");
- addMenuItem("/help/checkUpdates", translate("menu.help.checkupdates"), "update16", this::checkUpdatesActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/help/about", translate("menu.help.about"), "about32", this::aboutActionPerformed, PRIORITY_TOP, null, true, null, false);
- finishMenu("/help");
-
- if (Configuration._showDebugMenu.get() || Configuration._debugMode.get()) {
-
- addMenuItem("/debug", "# FFDec Debug #", null, null, 0, null, false, null, false);
- addMenuItem("/debug/removeNonScripts", "Remove non scripts", "continue16", e -> removeNonScripts(), PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/removeExceptSelected", "Remove except selected", "continue16", e -> removeExceptSelected(), PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/refreshDecompiled", "Refresh decompiled script", "continue16", e -> refreshDecompiled(), PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/checkResources", "Check resources", "continue16", e -> checkResources(), PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/callGc", "Call System.gc()", "continue16", e -> System.gc(), PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/emptyCache", "Empty cache", "continue16", e -> {
- SWF nswf = mainFrame.getPanel().getCurrentSwf();
- if (nswf != null) {
- nswf.clearAllCache();
- }
- }, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/memoryInformation", "Memory information", "continue16", e -> {
- String architecture = System.getProperty("sun.arch.data.model");
- Runtime runtime = Runtime.getRuntime();
- String info = "Architecture: " + architecture + Helper.newLine
- + "Jre 64bit: " + Helper.is64BitJre() + Helper.newLine
- + "Os 64bit: " + Helper.is64BitOs() + Helper.newLine
- + "Max: " + (runtime.maxMemory() / 1024 / 1024) + "MB" + Helper.newLine
- + "Used: " + (runtime.totalMemory() / 1024 / 1024) + "MB" + Helper.newLine
- + "Free: " + (runtime.freeMemory() / 1024 / 1024) + "MB";
- View.showMessageDialog(null, info);
- SWF nswf = mainFrame.getPanel().getCurrentSwf();
- if (nswf != null) {
- nswf.clearAllCache();
- }
- }, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/fixAs3Code", "Fix AS3 code", "continue16", e -> {
- SWF nswf = mainFrame.getPanel().getCurrentSwf();
- if (nswf != null) {
- nswf.fixAS3Code();
- }
- }, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/openTestSwfs", "Open test SWFs", "continue16", e -> {
- String path;
-
- SWFSourceInfo[] sourceInfos = new SWFSourceInfo[2];
- String mainPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
- path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as2\\as2.swf";
- sourceInfos[0] = new SWFSourceInfo(null, path, null);
- path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as3\\as3.swf";
- sourceInfos[1] = new SWFSourceInfo(null, path, null);
- Main.openFile(sourceInfos);
- }, PRIORITY_MEDIUM, null, true, null, false);
- addMenuItem("/debug/createNewSwf", "Create new SWF", "continue16", e -> {
- SWF swf = new SWF();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- swf.saveTo(baos);
- } catch (IOException ex) {
- Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- Main.openFile(new SWFSourceInfo(new ByteArrayInputStream(baos.toByteArray()), "New SWF", "New SWF"));
- }, PRIORITY_MEDIUM, null, true, null, false);
- finishMenu("/debug");
- }
-
- finishMenu("");
- }
-
- public void showResourcesView() {
- viewResourcesActionPerformed(null);
- }
-
- private void viewResourcesActionPerformed(ActionEvent evt) {
- Configuration.dumpView.set(false);
- mainFrame.getPanel().showView(MainPanel.VIEW_RESOURCES);
- setGroupSelection("view", "/file/view/viewResources");
- setMenuChecked("/tools/timeline", false);
- }
-
- private void viewHexActionPerformed(ActionEvent evt) {
- Configuration.dumpView.set(true);
- MainPanel mainPanel = mainFrame.getPanel();
- if (mainPanel.isModified()) {
- View.showMessageDialog(null, translate("message.warning.hexViewNotUpToDate"), translate("message.warning"), JOptionPane.WARNING_MESSAGE, Configuration.warningHexViewNotUpToDate);
- }
-
- mainPanel.showView(MainPanel.VIEW_DUMP);
- setGroupSelection("view", "/file/view/viewHex");
- setMenuChecked("/tools/timeline", false);
- }
-
- private void debuggerSwitchActionPerformed(ActionEvent evt) {
- boolean debuggerOn = isMenuChecked("/tools/debugger/debuggerSwitch");
- if (!debuggerOn || View.showConfirmDialog((Component) mainFrame, translate("message.debugger"), translate("dialog.message.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, Configuration.displayDebuggerInfo, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) {
- switchDebugger();
- mainFrame.getPanel().refreshDecompiled();
- } else {
- setMenuChecked("/tools/debugger/debuggerSwitch", false);
- }
- setMenuEnabled("/tools/debugger/debuggerReplaceTrace", isMenuChecked("/tools/debugger/debuggerSwitch"));
- //setMenuEnabled("/tools/debugger/debuggerInjectLoader", isMenuChecked("/tools/debugger/debuggerSwitch"));
- }
-
- private void timelineActionPerformed(ActionEvent evt) {
- if (isMenuChecked("/tools/timeline")) {
- if (!mainFrame.getPanel().showView(MainPanel.VIEW_TIMELINE)) {
- setMenuChecked("/tools/timeline", false);
- } else {
- setGroupSelection("view", null);
- }
- } else if (Configuration.dumpView.get()) {
- setGroupSelection("view", "/file/view/viewHex");
- mainFrame.getPanel().showView(MainPanel.VIEW_DUMP);
- } else {
- setGroupSelection("view", "/file/view/viewResources");
- mainFrame.getPanel().showView(MainPanel.VIEW_RESOURCES);
- }
- }
-
- protected void loadRecent(ActionEvent evt) {
- List recentFiles = Configuration.getRecentFiles();
- clearMenu("/file/" + (supportsMenuAction() ? "open" : "recent"));
- clearMenu("_/open");
-
- for (int i = recentFiles.size() - 1; i >= 0; i--) {
- final String f = recentFiles.get(i);
- ActionListener a = (ActionEvent e) -> {
- if (Main.openFile(f, null) == OpenFileResult.NOT_FOUND) {
- if (View.showConfirmDialog(null, translate("message.confirm.recentFileNotFound"), translate("message.confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_NO_OPTION) {
- Configuration.removeRecentFile(f);
- }
- }
- };
- addMenuItem("/file/" + (supportsMenuAction() ? "open" : "recent") + "/" + i, f, null, a, 0, null, true, null, false);
- addMenuItem("_/open/" + i, f, null, a, 0, null, true, null, false);
- }
-
- finishMenu("/file/" + (supportsMenuAction() ? "open" : "recent"));
- finishMenu("_/open");
- }
-
- public void dispose() {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- manager.removeKeyEventDispatcher(keyEventDispatcher);
-
- Configuration.autoDeobfuscate.removeListener(configListenerAutoDeobfuscate);
- Configuration.simplifyExpressions.removeListener(configListenerSimplifyExpressions);
- Configuration.internalFlashViewer.removeListener(configListenerInternalFlashViewer);
- Configuration.parallelSpeedUp.removeListener(configListenerParallelSpeedUp);
- Configuration.decompile.removeListener(configListenerDecompile);
- //Configuration.cacheOnDisk.removeListener(configListenerCacheOnDisk);
- Configuration.gotoMainClassOnStartup.removeListener(configListenerGotoMainClassOnStartup);
- Configuration.autoRenameIdentifiers.removeListener(configListenerAutoRenameIdentifiers);
- Configuration.autoOpenLoadedSWFs.removeListener(configListenerAutoOpenLoadedSWFs);
-
- Main.stopRun();
- }
-
- public boolean runActionPerformed(ActionEvent evt) {
- Main.run(swf);
- return true;
- }
-
- public boolean debugActionPerformed(ActionEvent evt) {
- Main.runDebug(swf, false);
- return true;
- }
-
- public boolean debugPCodeActionPerformed(ActionEvent evt) {
- Main.runDebug(swf, true);
- return true;
- }
-
- public boolean stopActionPerformed(ActionEvent evt) {
- Main.stopRun();
- return true;
- }
-
- public boolean pauseActionPerformed(ActionEvent evt) {
- try {
- DebuggerCommands cmd = Main.getDebugHandler().getCommands();
- //TODO
-
- } catch (IOException ex) {
- Main.getDebugHandler().disconnect();
- //ignore
- }
- return true;
- }
-
- public boolean stepOverActionPerformed(ActionEvent evt) {
-
- try {
-
- DebuggerCommands cmd = Main.getDebugHandler().getCommands();
- mainFrame.getPanel().clearDebuggerColors();
- Main.startWork(AppStrings.translate("work.debugging") + "...", null);
-
- cmd.stepOver();
- } catch (IOException ex) {
- Main.getDebugHandler().disconnect();
- //ignore
- }
- return true;
- }
-
- public boolean stepIntoActionPerformed(ActionEvent evt) {
- try {
- DebuggerCommands cmd = Main.getDebugHandler().getCommands();
- mainFrame.getPanel().clearDebuggerColors();
- Main.startWork(AppStrings.translate("work.debugging") + "...", null);
-
- cmd.stepInto();
- } catch (IOException ex) {
- Main.getDebugHandler().disconnect();
- //ignore
- }
-
- return true;
- }
-
- public boolean stepOutActionPerformed(ActionEvent evt) {
- try {
- DebuggerCommands cmd = Main.getDebugHandler().getCommands();
- mainFrame.getPanel().clearDebuggerColors();
- Main.startWork(AppStrings.translate("work.debugging") + "...", null);
- cmd.stepOut();
- } catch (IOException ex) {
- Main.getDebugHandler().disconnect();
- //ignore
- }
-
- return true;
- }
-
- public boolean continueActionPerformed(ActionEvent evt) {
- try {
- DebuggerCommands cmd = Main.getDebugHandler().getCommands();
- mainFrame.getPanel().clearDebuggerColors();
- Main.startWork(AppStrings.translate("work.debugging") + "...", null);
- cmd.sendContinue();
- } catch (IOException ex) {
- Main.getDebugHandler().disconnect();
- //ignore
- }
-
- return true;
- }
-
- public boolean stackActionPerformed(ActionEvent evt) {
- //TODO
- return true;
- }
-
- public boolean watchActionPerformed(ActionEvent evt) {
- //TODO
- return true;
- }
-
- public boolean dispatchKeyEvent(KeyEvent e) {
- if (((JFrame) mainFrame).isActive() && e.getID() == KeyEvent.KEY_PRESSED) {
-
- HotKey ek = new HotKey(e);
- for (String path : menuHotkeys.keySet()) {
- HotKey mk = menuHotkeys.get(path);
- if (ek.equals(mk)) {
- if (menuActions.containsKey(path)) {
- menuActions.get(path).actionPerformed(null);
- return true;
- }
- }
- }
-
- //other nonmenu actions
- int code = e.getKeyCode();
- if (e.isControlDown() && e.isShiftDown()) { //CTRL+SHIFT
- switch (code) {
- case KeyEvent.VK_F:
- return searchInActionPerformed(null);
- case KeyEvent.VK_T:
- return searchInTextPerformed(null);
- case KeyEvent.VK_D:
- return clearLog(null);
- }
- } else if (e.isControlDown() && !e.isShiftDown()) { //CTRL
- switch (code) {
- case KeyEvent.VK_UP:
- return previousTag(null);
- case KeyEvent.VK_DOWN:
- return nextTag(null);
- }
- }
- }
-
- return false;
- }
-
- public abstract void hilightPath(String path);
-
- public abstract void setPathVisible(String path, boolean val);
-}
+/*
+ * Copyright (C) 2010-2016 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.debugger.flash.DebuggerCommands;
+import com.jpexs.decompiler.flash.ApplicationInfo;
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFBundle;
+import com.jpexs.decompiler.flash.SWFSourceInfo;
+import com.jpexs.decompiler.flash.configuration.Configuration;
+import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener;
+import com.jpexs.decompiler.flash.console.ContextMenuTools;
+import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
+import com.jpexs.decompiler.flash.gui.helpers.CheckResources;
+import com.jpexs.decompiler.flash.tags.ABCContainerTag;
+import com.jpexs.helpers.ByteArrayRange;
+import com.jpexs.helpers.Helper;
+import com.jpexs.helpers.utf8.Utf8Helper;
+import com.sun.jna.Platform;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.KeyEventDispatcher;
+import java.awt.KeyboardFocusManager;
+import java.awt.ScrollPane;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+/**
+ *
+ * @author JPEXS
+ */
+public abstract class MainFrameMenu implements MenuBuilder {
+
+ private final MainFrame mainFrame;
+
+ private KeyEventDispatcher keyEventDispatcher;
+
+ private SWF swf;
+
+ private ConfigurationItemChangeListener configListenerAutoDeobfuscate;
+
+ private ConfigurationItemChangeListener configListenerSimplifyExpressions;
+
+ private ConfigurationItemChangeListener configListenerInternalFlashViewer;
+
+ private ConfigurationItemChangeListener configListenerParallelSpeedUp;
+
+ private ConfigurationItemChangeListener configListenerDecompile;
+
+ //private ConfigurationItemChangeListener configListenerCacheOnDisk;
+ private ConfigurationItemChangeListener configListenerGotoMainClassOnStartup;
+
+ private ConfigurationItemChangeListener configListenerAutoRenameIdentifiers;
+
+ private ConfigurationItemChangeListener configListenerAutoOpenLoadedSWFs;
+
+ protected final Map menuHotkeys = new HashMap<>();
+
+ @Override
+ public HotKey getMenuHotkey(String path) {
+ return menuHotkeys.get(path);
+ }
+
+ protected final Map menuActions = new HashMap<>();
+
+ public boolean isInternalFlashViewerSelected() {
+ return isMenuChecked("/settings/internalViewer"); //miInternalViewer.isSelected();
+ }
+
+ private final boolean externalFlashPlayerUnavailable;
+
+ public MainFrameMenu(MainFrame mainFrame, boolean externalFlashPlayerUnavailable) {
+ registerHotKeys();
+ this.mainFrame = mainFrame;
+ this.externalFlashPlayerUnavailable = externalFlashPlayerUnavailable;
+ }
+
+ protected String translate(String key) {
+ return mainFrame.translate(key);
+ }
+
+ protected boolean openActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ Main.openFileDialog();
+ return true;
+ }
+
+ protected boolean saveActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ if (swf != null) {
+ boolean saved = false;
+ if (swf.swfList != null && swf.swfList.isBundle()) {
+ SWFBundle bundle = swf.swfList.bundle;
+ if (!bundle.isReadOnly()) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ swf.saveTo(baos);
+ saved = bundle.putSWF(swf.getFileTitle(), new ByteArrayInputStream(baos.toByteArray()));
+ } catch (IOException ex) {
+ Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
+ }
+ }
+ } else if (swf.binaryData != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ swf.saveTo(baos);
+ swf.binaryData.binaryData = new ByteArrayRange(baos.toByteArray());
+ swf.binaryData.setModified(true);
+ saved = true;
+ } catch (IOException ex) {
+ Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
+ }
+ } else if (swf.getFile() == null) {
+ saved = saveAs(swf, SaveFileMode.SAVEAS);
+ } else {
+ try {
+ Main.saveFile(swf, swf.getFile());
+ saved = true;
+ } catch (IOException ex) {
+ Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ if (saved) {
+ swf.clearModified();
+ mainFrame.getPanel().refreshTree(swf);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ protected boolean saveAsActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ if (swf != null) {
+ if (saveAs(swf, SaveFileMode.SAVEAS)) {
+ swf.clearModified();
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean saveAs(SWF swf, SaveFileMode mode) {
+ if (Main.saveFileDialog(swf, mode)) {
+ mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : ""));
+ updateComponents(swf);
+ return true;
+ }
+ return false;
+ }
+
+ protected void saveAsExeActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ if (swf != null) {
+ saveAs(swf, SaveFileMode.EXE);
+ }
+ }
+
+ protected void closeActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ if (swf == null) {
+ return;
+ }
+
+ Main.closeFile(swf.swfList);
+ }
+
+ protected boolean closeAllActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ if (swf != null) {
+ return Main.closeAll();
+ }
+
+ return false;
+ }
+
+ protected void importTextActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().importText(swf);
+ }
+
+ protected void importScriptActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().importScript(swf);
+ }
+
+ protected void importSymbolClassActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().importSymbolClass(swf);
+ }
+
+ protected boolean exportAllActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ return export(false);
+ }
+
+ protected boolean exportSelectedActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return false;
+ }
+
+ return export(true);
+ }
+
+ protected boolean export(boolean onlySelected) {
+ if (swf != null) {
+ mainFrame.getPanel().export(onlySelected);
+ return true;
+ }
+
+ return false;
+ }
+
+ protected void exportFlaActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().exportFla(swf);
+ }
+
+ protected void importXmlActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().importSwfXml();
+ }
+
+ protected void exportXmlActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().exportSwfXml();
+ }
+
+ protected boolean searchActionPerformed(ActionEvent evt) {
+ return search(evt, null);
+ }
+
+ protected boolean searchInTextPerformed(ActionEvent evt) {
+ return search(evt, true);
+ }
+
+ protected boolean searchInActionPerformed(ActionEvent evt) {
+ return search(evt, false);
+ }
+
+ protected boolean search(ActionEvent evt, Boolean searchInText) {
+ if (swf != null) {
+ mainFrame.getPanel().searchInActionScriptOrText(searchInText, swf);
+ return true;
+ }
+
+ return false;
+ }
+
+ protected boolean replaceActionPerformed(ActionEvent evt) {
+ if (swf != null) {
+ mainFrame.getPanel().replaceText();
+ return true;
+ }
+
+ return false;
+ }
+
+ protected void showProxyActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ Main.showProxy();
+ }
+
+ protected boolean clearLog(ActionEvent evt) {
+ ErrorLogFrame.getInstance().clearLog();
+ return true;
+ }
+
+ protected void renameOneIdentifier(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().renameOneIdentifier(swf);
+ }
+
+ protected void renameInvalidIdentifiers(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().renameIdentifiers(swf);
+ }
+
+ protected void deobfuscationActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ mainFrame.getPanel().deobfuscate();
+ }
+
+ protected void setSubLimiter(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+ Main.setSubLimiter(selected);
+ }
+
+ protected void switchDebugger() {
+ DebuggerTools.switchDebugger(swf);
+ }
+
+ protected void debuggerShowLogActionPerformed(ActionEvent evt) {
+ DebuggerTools.debuggerShowLog();
+ }
+
+ protected void debuggerInjectLoader(ActionEvent evt) {
+ DebuggerTools.injectDebugLoader(swf);
+ refreshDecompiled();
+ }
+
+ protected void debuggerReplaceTraceCallsActionPerformed(ActionEvent evt) {
+ ReplaceTraceDialog rtd = new ReplaceTraceDialog(Configuration.lastDebuggerReplaceFunction.get());
+ rtd.setVisible(true);
+ if (rtd.getValue() != null) {
+ String fname = rtd.getValue();
+ DebuggerTools.replaceTraceCalls(swf, fname);
+ mainFrame.getPanel().refreshDecompiled();
+ Configuration.lastDebuggerReplaceFunction.set(rtd.getValue());
+ }
+ }
+
+ protected void clearRecentFilesActionPerformed(ActionEvent evt) {
+ Configuration.recentFiles.set(null);
+ }
+
+ protected void removeNonScripts() {
+ mainFrame.getPanel().removeNonScripts(swf);
+ }
+
+ protected void removeExceptSelected() {
+ mainFrame.getPanel().removeExceptSelected(swf);
+ }
+
+ protected void refreshDecompiled() {
+ mainFrame.getPanel().refreshDecompiled();
+ }
+
+ protected boolean previousTag(ActionEvent evt) {
+ return mainFrame.getPanel().previousTag();
+ }
+
+ protected boolean nextTag(ActionEvent evt) {
+ return mainFrame.getPanel().nextTag();
+ }
+
+ protected void checkResources() {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ PrintStream stream = new PrintStream(os);
+ CheckResources.checkResources(stream, null);
+ final String str = new String(os.toByteArray(), Utf8Helper.charset);
+ JDialog dialog = new JDialog() {
+ @Override
+ public void setVisible(boolean bln) {
+ setSize(new Dimension(800, 600));
+ Container cnt = getContentPane();
+ cnt.setLayout(new BorderLayout());
+ String[] languages = SelectLanguageDialog.getAvailableLanguages().clone();
+ languages[0] = "all";
+ JComboBox languagesComboBox = new JComboBox<>(languages);
+ this.add(languagesComboBox, BorderLayout.NORTH);
+ ScrollPane scrollPane = new ScrollPane();
+ JEditorPane editor = new JEditorPane();
+ editor.setEditable(false);
+ editor.setText(str);
+ scrollPane.add(editor);
+ this.add(scrollPane, BorderLayout.CENTER);
+ this.setModal(true);
+ View.centerScreen(this);
+ languagesComboBox.addActionListener((ActionEvent e) -> {
+ String lang = (String) languagesComboBox.getSelectedItem();
+ if (lang.equals("all")) {
+ lang = null;
+ }
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try (PrintStream stream = new PrintStream(os, false, "UTF-8")) {
+ CheckResources.checkResources(stream, lang);
+ String str = new String(os.toByteArray(), Utf8Helper.charset);
+ editor.setText(str);
+ } catch (UnsupportedEncodingException ex) {
+ // ignore
+ }
+ });
+ super.setVisible(bln);
+ }
+ };
+ dialog.setVisible(true);
+ }
+
+ protected void checkUpdatesActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ if (!Main.checkForUpdates()) {
+ View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE);
+ }
+ }
+
+ protected void helpUsActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ String helpUsURL = ApplicationInfo.PROJECT_PAGE + "/help_us.html?utm_source=app&utm_medium=menu&utm_campaign=app";
+ if (!View.navigateUrl(helpUsURL)) {
+ View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL));
+ }
+ }
+
+ protected void homePageActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ String homePageURL = ApplicationInfo.PROJECT_PAGE + "?utm_source=app&utm_medium=menu&utm_campaign=app";
+ if (!View.navigateUrl(homePageURL)) {
+ View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL));
+ }
+ }
+
+ protected void aboutActionPerformed(ActionEvent evt) {
+ if (Main.isWorking()) {
+ return;
+ }
+
+ Main.about();
+ }
+
+ protected boolean reloadActionPerformed(ActionEvent evt) {
+ if (swf != null) {
+ if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
+ Main.reloadFile(swf.swfList);
+ }
+ }
+ return true;
+ }
+
+ protected boolean reloadAllActionPerformed(ActionEvent evt) {
+ if (swf != null) {
+ if (View.showConfirmDialog(null, translate("message.confirm.reloadAll"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
+ Main.reloadApp();
+ }
+
+ return true;
+ }
+
+ Main.reloadApp();
+ return true;
+ }
+
+ protected void advancedSettingsActionPerformed(ActionEvent evt) {
+ Main.advancedSettings();
+ }
+
+ protected void searchMemoryActionPerformed(ActionEvent evt) {
+ Main.loadFromMemory();
+ }
+
+ protected void searchCacheActionPerformed(ActionEvent evt) {
+ Main.loadFromCache();
+ }
+
+ protected void gotoDucumentClassOnStartupActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.gotoMainClassOnStartup.set(selected);
+ }
+
+ protected void autoOpenLoadedSWFsActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.autoOpenLoadedSWFs.set(selected);
+ }
+
+ protected void autoRenameIdentifiersActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.autoRenameIdentifiers.set(selected);
+ }
+
+ /*protected void cacheOnDiskActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.cacheOnDisk.set(selected);
+ if (selected) {
+ Cache.setStorageType(Cache.STORAGE_FILES);
+ } else {
+ Cache.setStorageType(Cache.STORAGE_MEMORY);
+ }
+ }*/
+ protected void setLanguageActionPerformed(ActionEvent evt) {
+ new SelectLanguageDialog().display();
+ }
+
+ protected void disableDecompilationActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.decompile.set(!selected);
+ mainFrame.getPanel().disableDecompilationChanged();
+ }
+
+ protected void associateActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ if (selected == ContextMenuTools.isAddedToContextMenu()) {
+ return;
+ }
+ ContextMenuTools.addToContextMenu(selected, false);
+
+ // Update checkbox menuitem accordingly (User can cancel rights elevation)
+ new Timer().schedule(new TimerTask() {
+ @Override
+ public void run() {
+ button.setSelected(ContextMenuTools.isAddedToContextMenu());
+ }
+ }, 1000); // It takes some time registry change to apply
+ }
+
+ protected void gotoDucumentClassActionPerformed(ActionEvent evt) {
+ mainFrame.getPanel().gotoDocumentClass(mainFrame.getPanel().getCurrentSwf());
+ }
+
+ protected void parallelSpeedUpActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ String confStr = translate("message.confirm.parallel") + "\r\n";
+ if (selected) {
+ confStr += " " + translate("message.confirm.on");
+ } else {
+ confStr += " " + translate("message.confirm.off");
+ }
+ if (View.showConfirmDialog(null, confStr, translate("message.parallel"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
+ Configuration.parallelSpeedUp.set(selected);
+ } else {
+ button.setSelected(Configuration.parallelSpeedUp.get());
+ }
+ }
+
+ protected void internalViewerSwitchActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.internalFlashViewer.set(selected);
+ mainFrame.getPanel().reload(true);
+ }
+
+ protected void simplifyExpressionsActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ Configuration.simplifyExpressions.set(selected);
+ mainFrame.getPanel().autoDeobfuscateChanged();
+ }
+
+ protected void autoDeobfuscationActionPerformed(ActionEvent evt) {
+ AbstractButton button = (AbstractButton) evt.getSource();
+ boolean selected = button.isSelected();
+
+ if (View.showConfirmDialog(mainFrame.getPanel(), translate("message.confirm.autodeobfuscate") + "\r\n" + (selected ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
+ Configuration.autoDeobfuscate.set(selected);
+ mainFrame.getPanel().autoDeobfuscateChanged();
+ } else {
+ button.setSelected(Configuration.autoDeobfuscate.get());
+ }
+ }
+
+ /*protected void deobfuscationMode(ActionEvent evt, int mode) {
+ Configuration.deobfuscationMode.set(mode);
+ mainFrame.getPanel().autoDeobfuscateChanged();
+ }*/
+ protected void exitActionPerformed(ActionEvent evt) {
+ JFrame frame = (JFrame) mainFrame;
+ frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
+ }
+
+ public void updateComponents() {
+ updateComponents(swf);
+ }
+
+ public void updateComponents(SWF swf) {
+ this.swf = swf;
+ boolean isRunning = Main.isRunning();
+ boolean isDebugRunning = Main.isDebugRunning();
+ boolean isDebugPaused = Main.isDebugPaused();
+
+ boolean isRunningOrDebugging = isRunning || isDebugRunning;
+
+ boolean swfSelected = swf != null;
+ boolean isWorking = Main.isWorking();
+ List abcList = swf != null ? swf.getAbcList() : null;
+ boolean hasAbc = swfSelected && abcList != null && !abcList.isEmpty();
+ boolean hasDebugger = hasAbc && DebuggerTools.hasDebugger(swf);
+ MainPanel mainPanel = mainFrame.getPanel();
+ boolean swfLoaded = mainPanel != null ? !mainPanel.getSwfs().isEmpty() : false;
+
+ setMenuEnabled("_/open", !isWorking);
+ setMenuEnabled("/file/open", !isWorking);
+ setMenuEnabled("_/save", swfSelected && !isWorking);
+ setMenuEnabled("/file/save", swfSelected && !isWorking);
+ setMenuEnabled("_/saveAs", swfSelected && !isWorking);
+ setMenuEnabled("/file/saveAs", swfSelected && !isWorking);
+ setMenuEnabled("/file/saveAsExe", swfSelected && !isWorking);
+ setMenuEnabled("_/close", swfSelected && !isWorking);
+ setMenuEnabled("/file/close", swfSelected && !isWorking);
+ setMenuEnabled("_/closeAll", swfLoaded && !isWorking);
+ setMenuEnabled("/file/closeAll", swfLoaded && !isWorking);
+
+ setMenuEnabled("/file/export", swfSelected);
+ setMenuEnabled("_/exportAll", swfSelected && !isWorking);
+ setMenuEnabled("/file/export/exportAll", swfSelected && !isWorking);
+ setMenuEnabled("_/exportFla", swfSelected && !isWorking);
+ setMenuEnabled("/file/export/exportFla", swfSelected && !isWorking);
+ setMenuEnabled("_/exportSelected", swfSelected && !isWorking);
+ setMenuEnabled("/file/export/exportSelected", swfSelected && !isWorking);
+ setMenuEnabled("/file/export/exportXml", swfSelected && !isWorking);
+
+ setMenuEnabled("/file/import", swfSelected);
+ setMenuEnabled("/file/import/importText", swfSelected && !isWorking);
+ setMenuEnabled("/file/import/importScript", swfSelected && !isWorking);
+ setMenuEnabled("/file/import/importSymbolClass", swfSelected && !isWorking);
+ setMenuEnabled("/file/import/importXml", swfSelected && !isWorking);
+
+ setMenuEnabled("/tools/deobfuscation", swfSelected);
+ setMenuEnabled("/tools/deobfuscation/renameOneIdentifier", swfSelected && !isWorking);
+ setMenuEnabled("/tools/deobfuscation/renameInvalidIdentifiers", swfSelected && !isWorking);
+ setMenuEnabled("/tools/deobfuscation/deobfuscation", hasAbc);
+
+ setMenuEnabled("/tools/search", swfSelected);
+ setMenuEnabled("/tools/replace", swfSelected);
+ setMenuEnabled("/tools/timeline", swfSelected);
+ setMenuEnabled("/tools/showProxy", !isWorking);
+
+ setMenuEnabled("/tools/gotoDocumentClass", hasAbc);
+ /*setMenuEnabled("/tools/debugger/debuggerSwitch", hasAbc);
+ setMenuChecked("/tools/debugger/debuggerSwitch", hasDebugger);
+ setMenuEnabled("/tools/debugger/debuggerReplaceTrace", hasAbc && hasDebugger);*/
+ //setMenuEnabled("/tools/debugger/debuggerInjectLoader", hasAbc && hasDebugger);
+
+ setMenuEnabled("_/checkUpdates", !isWorking);
+ setMenuEnabled("/help/checkUpdates", !isWorking);
+ setMenuEnabled("/help/helpUs", !isWorking);
+ setMenuEnabled("/help/homePage", !isWorking);
+ setMenuEnabled("_/about", !isWorking);
+ setMenuEnabled("/help/about", !isWorking);
+
+ setMenuEnabled("/file/start/run", swfSelected && !isRunningOrDebugging);
+ setMenuEnabled("/file/start/debug", swfSelected && !isRunningOrDebugging);
+ setMenuEnabled("/file/start/debugpcode", swfSelected && !isRunningOrDebugging);
+
+ setMenuEnabled("/file/start/stop", isRunningOrDebugging);
+ setMenuEnabled("/debugging/debug/stop", isRunningOrDebugging); //same as previous
+
+ setPathVisible("/debugging", isDebugRunning);
+ setMenuEnabled("/debugging/debug", isDebugRunning);
+ //setMenuEnabled("/debugging/debug/pause", isDebugRunning);
+ setMenuEnabled("/debugging/debug/stepOver", isDebugPaused);
+ setMenuEnabled("/debugging/debug/stepInto", isDebugPaused);
+ setMenuEnabled("/debugging/debug/stepOut", isDebugPaused);
+ setMenuEnabled("/debugging/debug/continue", isDebugPaused);
+ //setMenuEnabled("/debugging/debug/stack", isDebugPaused);
+ //setMenuEnabled("/debugging/debug/watch", isDebugPaused);
+
+ }
+
+ private void registerHotKeys() {
+
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ manager.addKeyEventDispatcher(keyEventDispatcher = this::dispatchKeyEvent);
+ }
+
+ public void createMenuBar() {
+ initMenu();
+
+ if (supportsAppMenu()) {
+ addMenuItem("_", null, null, null, 0, null, false, null, false);
+ addMenuItem("_/open", translate("menu.file.open"), "open32", this::openActionPerformed, PRIORITY_TOP, this::loadRecent, false, null, false);
+ addMenuItem("_/save", translate("menu.file.save"), "save32", this::saveActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/saveAs", translate("menu.file.saveas"), "saveas32", this::saveAsActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addSeparator("_");
+ addMenuItem("_/exportFla", translate("menu.file.export.fla"), "exportfla32", this::exportFlaActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/exportAll", translate("menu.file.export.all"), "export32", this::exportAllActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/exportSelected", translate("menu.file.export.selection"), "exportsel32", this::exportSelectedActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addSeparator("_");
+ addMenuItem("_/checkUpdates", translate("menu.help.checkupdates"), "update32", this::checkUpdatesActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/about", translate("menu.help.about"), "about32", this::aboutActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/close", translate("menu.file.close"), "close32", this::closeActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/closeAll", translate("menu.file.closeAll"), "closeall32", this::closeAllActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("_/$exit", translate("menu.file.exit"), "exit32", this::exitActionPerformed, PRIORITY_TOP, null, true, null, false);
+ finishMenu("_");
+ }
+
+ addMenuItem("/file", translate("menu.file"), null, null, 0, null, false, null, false);
+ addMenuItem("/file/open", translate("menu.file.open"), "open32", this::openActionPerformed, PRIORITY_TOP, this::loadRecent, !supportsMenuAction(), new HotKey("CTRL+SHIFT+O"), false);
+
+ if (!supportsMenuAction()) {
+ addMenuItem("/file/recent", translate("menu.recentFiles"), null, null, 0, this::loadRecent, false, null, false);
+ finishMenu("/file/recent");
+ } else {
+ finishMenu("/file/open");
+ }
+
+ addMenuItem("/file/save", translate("menu.file.save"), "save32", this::saveActionPerformed, PRIORITY_TOP, null, true, new HotKey("CTRL+SHIFT+S"), false);
+ addMenuItem("/file/saveAs", translate("menu.file.saveas"), "saveas16", this::saveAsActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+A"), false);
+ addMenuItem("/file/saveAsExe", translate("menu.file.saveasexe"), "saveasexe16", this::saveAsExeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/file/reload", translate("menu.file.reload"), "reload16", this::reloadActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+R"), false);
+ addMenuItem("/file/reloadAll", translate("menu.file.reloadAll"), "reload16", this::reloadAllActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+
+ addSeparator("/file");
+
+ addMenuItem("/file/export", translate("menu.export"), null, null, 0, null, false, null, false);
+ addMenuItem("/file/export/exportFla", translate("menu.file.export.fla"), "exportfla32", this::exportFlaActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("/file/export/exportXml", translate("menu.file.export.xml"), "exportxml32", this::exportXmlActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/file/export/exportAll", translate("menu.file.export.all"), "export16", this::exportAllActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+E"), false);
+ addMenuItem("/file/export/exportSelected", translate("menu.file.export.selection"), "exportsel16", this::exportSelectedActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/file/export");
+
+ addMenuItem("/file/import", translate("menu.import"), null, null, 0, null, false, null, false);
+ addMenuItem("/file/import/importXml", translate("menu.file.import.xml"), "importxml32", this::importXmlActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("/file/import/importText", translate("menu.file.import.text"), "importtext32", this::importTextActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/file/import/importScript", translate("menu.file.import.script"), "importscript32", this::importScriptActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/file/import/importSymbolClass", translate("menu.file.import.symbolClass"), "importsymbolclass32", this::importSymbolClassActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/file/import");
+
+ addMenuItem("/file/start", translate("menu.file.start"), null, null, 0, null, false, null, false);
+ addMenuItem("/file/start/run", translate("menu.file.start.run"), "play32", this::runActionPerformed, PRIORITY_TOP, null, true, new HotKey("F6"), false);
+ addMenuItem("/file/start/debug", translate("menu.file.start.debug"), "debug32", this::debugActionPerformed, PRIORITY_TOP, null, true, new HotKey("CTRL+F5"), false);
+ addMenuItem("/file/start/stop", translate("menu.file.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("/file/start/debugpcode", translate("menu.file.start.debugpcode"), "debug32", this::debugPCodeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/file/start");
+
+ addMenuItem("/file/view", translate("menu.view"), null, null, 0, null, false, null, false);
+ addToggleMenuItem("/file/view/viewResources", translate("menu.file.view.resources"), "view", "viewresources16", this::viewResourcesActionPerformed, PRIORITY_MEDIUM, null);
+ addToggleMenuItem("/file/view/viewHex", translate("menu.file.view.hex"), "view", "viewhex16", this::viewHexActionPerformed, PRIORITY_MEDIUM, null);
+ finishMenu("/file/view");
+
+ addSeparator("/file");
+ addMenuItem("/file/close", translate("menu.file.close"), "close32", this::closeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/file/closeAll", translate("menu.file.closeAll"), "closeall32", this::closeAllActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+SHIFT+X"), false);
+
+ if (!supportsAppMenu()) {
+ addSeparator("/file");
+ addMenuItem("/file/exit", translate("menu.file.exit"), "exit32", this::exitActionPerformed, PRIORITY_TOP, null, true, null, false);
+ }
+
+ finishMenu("/file");
+
+ if (Configuration.dumpView.get()) {
+ setGroupSelection("view", "/file/view/viewHex");
+ } else {
+ setGroupSelection("view", "/file/view/viewResources");
+ }
+
+ /*
+ menu.file.start = Start
+ menu.file.start.run = Run
+ menu.file.start.stop = Stop
+ menu.file.start.debug = Debug
+ menu.debugging = Debugging
+ menu.debugging.debug = Debug
+ menu.debugging.debug.stop = Stop
+ menu.debugging.debug.pause = Pause
+ menu.debugging.debug.stepOver = Step over
+ menu.debugging.debug.stepInto = Step into
+ menu.debugging.debug.stepOut = Step out
+ menu.debugging.debug.continue = Continue
+ menu.debugging.debug.stack = Stack...
+ menu.debugging.debug.watch = New watch...
+ */
+ addMenuItem("/debugging", translate("menu.debugging"), null, null, 0, null, false, null, true);
+ addMenuItem("/debugging/debug", translate("menu.debugging.debug"), null, null, 0, null, false, null, false);
+ addMenuItem("/debugging/debug/stop", translate("menu.file.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true, null, false);
+ //addMenuItem("/debugging/debug/pause", translate("menu.debugging.debug.pause"), "pause32", this::pauseActionPerformed, PRIORITY_TOP, null, true,false);
+ addMenuItem("/debugging/debug/continue", translate("menu.debugging.debug.continue"), "continue32", this::continueActionPerformed, PRIORITY_TOP, null, true, new HotKey("F5"), false);
+ addMenuItem("/debugging/debug/stepOver", translate("menu.debugging.debug.stepOver"), "stepover32", this::stepOverActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("F8"), false);
+ addMenuItem("/debugging/debug/stepInto", translate("menu.debugging.debug.stepInto"), "stepinto32", this::stepIntoActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("F7"), false);
+ addMenuItem("/debugging/debug/stepOut", translate("menu.debugging.debug.stepOut"), "stepout32", this::stepOutActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+F7"), false);
+ //addMenuItem("/debugging/debug/stack", translate("menu.debugging.debug.stack"), "stack32", this::stackActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ //addMenuItem("/debugging/debug/watch", translate("menu.debugging.debug.watch"), "watch32", this::watchActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/debugging/debug");
+ finishMenu("/debugging");
+
+ addMenuItem("/tools", translate("menu.tools"), null, null, 0, null, false, null, false);
+ addMenuItem("/tools/search", translate("menu.tools.search"), "search16", this::searchActionPerformed, PRIORITY_TOP, null, true, null, false);
+
+ addMenuItem("/tools/replace", translate("menu.tools.replace"), "replace32", this::replaceActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addToggleMenuItem("/tools/timeline", translate("menu.tools.timeline"), null, "timeline32", this::timelineActionPerformed, PRIORITY_TOP, null);
+
+ addMenuItem("/tools/showProxy", translate("menu.tools.proxy"), "proxy16", this::showProxyActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ if (Platform.isWindows()) {
+ addMenuItem("/tools/searchMemory", translate("menu.tools.searchMemory"), "loadmemory16", this::searchMemoryActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ }
+
+ //addMenuItem("/tools/searchCache", translate("menu.tools.searchCache"), "loadcache16", this::searchCacheActionPerformed, PRIORITY_MEDIUM, null, true, null);
+ addMenuItem("/tools/deobfuscation", translate("menu.tools.deobfuscation"), "deobfuscate16", null, 0, null, false, null, false);
+ addMenuItem("/tools/deobfuscation/renameOneIdentifier", translate("menu.tools.deobfuscation.globalrename"), "rename16", this::renameOneIdentifier, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/tools/deobfuscation/renameInvalidIdentifiers", translate("menu.tools.deobfuscation.renameinvalid"), "renameall16", this::renameInvalidIdentifiers, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/tools/deobfuscation/deobfuscation", translate("menu.tools.deobfuscation.pcode"), "deobfuscate32", this::deobfuscationActionPerformed, PRIORITY_TOP, null, true, null, false);
+ finishMenu("/tools/deobfuscation");
+
+ /*addMenuItem("/tools/debugger", translate("menu.debugger"), null, null, 0, null, false, null,false);
+ addToggleMenuItem("/tools/debugger/debuggerSwitch", translate("menu.debugger.switch"), null, "debugger32", this::debuggerSwitchActionPerformed, PRIORITY_TOP, null,false);
+ addMenuItem("/tools/debugger/debuggerReplaceTrace", translate("menu.debugger.replacetrace"), "debuggerreplace16", this::debuggerReplaceTraceCallsActionPerformed, PRIORITY_MEDIUM, null, true, null,false);
+ //addMenuItem("/tools/debugger/debuggerInjectLoader", "Inject Loader", "debuggerreplace16", this::debuggerInjectLoader, PRIORITY_MEDIUM, null, true,false);
+ addMenuItem("/tools/debugger/debuggerShowLog", translate("menu.debugger.showlog"), "debuggerlog16", this::debuggerShowLogActionPerformed, PRIORITY_MEDIUM, null, true, null,false);
+ finishMenu("/tools/debugger");*/
+ addMenuItem("/tools/gotoDocumentClass", translate("menu.tools.gotoDocumentClass"), "gotomainclass32", this::gotoDucumentClassActionPerformed, PRIORITY_TOP, null, true, null, false);
+ finishMenu("/tools");
+
+ //Settings
+ addMenuItem("/settings", translate("menu.settings"), null, null, 0, null, false, null, false);
+
+ addToggleMenuItem("/settings/autoDeobfuscation", translate("menu.settings.autodeobfuscation"), null, null, this::autoDeobfuscationActionPerformed, 0, null);
+ addToggleMenuItem("/settings/simplifyExpressions", translate("menu.settings.simplifyExpressions"), null, null, this::simplifyExpressionsActionPerformed, 0, null);
+ addToggleMenuItem("/settings/internalViewer", translate("menu.settings.internalflashviewer"), null, null, this::internalViewerSwitchActionPerformed, 0, null);
+ addToggleMenuItem("/settings/parallelSpeedUp", translate("menu.settings.parallelspeedup"), null, null, this::parallelSpeedUpActionPerformed, 0, null);
+ addToggleMenuItem("/settings/disableDecompilation", translate("menu.settings.disabledecompilation"), null, null, this::disableDecompilationActionPerformed, 0, null);
+ //addToggleMenuItem("/settings/cacheOnDisk", translate("menu.settings.cacheOnDisk"), null, null, this::cacheOnDiskActionPerformed, 0, null);
+ addToggleMenuItem("/settings/gotoMainClassOnStartup", translate("menu.settings.gotoMainClassOnStartup"), null, null, this::gotoDucumentClassOnStartupActionPerformed, 0, null);
+ addToggleMenuItem("/settings/autoRenameIdentifiers", translate("menu.settings.autoRenameIdentifiers"), null, null, this::autoRenameIdentifiersActionPerformed, 0, null);
+ addToggleMenuItem("/settings/autoOpenLoadedSWFs", translate("menu.settings.autoOpenLoadedSWFs"), null, null, this::autoOpenLoadedSWFsActionPerformed, 0, null);
+ if (Platform.isWindows()) {
+ addToggleMenuItem("/settings/associate", translate("menu.settings.addtocontextmenu"), null, null, this::associateActionPerformed, 0, null);
+ }
+
+ addMenuItem("/settings/language", translate("menu.language"), null, null, 0, null, false, null, false);
+ addMenuItem("/settings/language/setLanguage", translate("menu.settings.language"), "setlanguage32", this::setLanguageActionPerformed, PRIORITY_TOP, null, true, null, false);
+ finishMenu("/settings/language");
+
+ /*addMenuItem("/settings/deobfuscation", translate("menu.deobfuscation"), null, null, 0, null, false,false);
+ addToggleMenuItem("/settings/deobfuscation/old", translate("menu.file.deobfuscation.old"), "deobfuscation", "deobfuscateold16", (ActionEvent e) -> {
+ deobfuscationMode(e, 0);
+ }, 0);
+ addToggleMenuItem("/settings/deobfuscation/new", translate("menu.file.deobfuscation.new"), "deobfuscation", "deobfuscatenew16", (ActionEvent e) -> {
+ deobfuscationMode(e, 1);
+ }, 0);
+
+ finishMenu("/settings/deobfuscation");*/
+ addMenuItem("/settings/advancedSettings", translate("menu.advancedsettings.advancedsettings"), null, null, 0, null, false, null, false);
+ addMenuItem("/settings/advancedSettings/advancedSettings", translate("menu.advancedsettings.advancedsettings"), "settings32", this::advancedSettingsActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("/settings/advancedSettings/clearRecentFiles", translate("menu.tools.otherTools.clearRecentFiles"), "clearrecent16", this::clearRecentFilesActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/settings/advancedSettings");
+
+ finishMenu("/settings");
+
+ setMenuChecked("/settings/autoDeobfuscation", Configuration.autoDeobfuscate.get());
+ Configuration.autoDeobfuscate.addListener(configListenerAutoDeobfuscate = (Boolean newValue) -> {
+ setMenuChecked("/settings/autoDeobfuscation", newValue);
+ });
+
+ setMenuChecked("/settings/simplifyExpressions", Configuration.simplifyExpressions.get());
+ Configuration.simplifyExpressions.addListener(configListenerSimplifyExpressions = (Boolean newValue) -> {
+ setMenuChecked("/settings/simplifyExpressions", newValue);
+ });
+
+ setMenuChecked("/settings/internalViewer", Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable);
+ Configuration.internalFlashViewer.addListener(configListenerInternalFlashViewer = (Boolean newValue) -> {
+ setMenuChecked("/settings/internalViewer", newValue || externalFlashPlayerUnavailable);
+ });
+
+ setMenuChecked("/settings/parallelSpeedUp", Configuration.parallelSpeedUp.get());
+ Configuration.parallelSpeedUp.addListener(configListenerParallelSpeedUp = (Boolean newValue) -> {
+ setMenuChecked("/settings/parallelSpeedUp", newValue);
+ });
+
+ setMenuChecked("/settings/disableDecompilation", !Configuration.decompile.get());
+ Configuration.decompile.addListener(configListenerDecompile = (Boolean newValue) -> {
+ setMenuChecked("/settings/disableDecompilation", !newValue);
+ });
+
+ /*setMenuChecked("/settings/cacheOnDisk", Configuration.cacheOnDisk.get());
+ Configuration.cacheOnDisk.addListener(configListenerCacheOnDisk = (Boolean newValue) -> {
+ setMenuChecked("/settings/cacheOnDisk", newValue);
+ });*/
+ setMenuChecked("/settings/gotoMainClassOnStartup", Configuration.gotoMainClassOnStartup.get());
+ Configuration.gotoMainClassOnStartup.addListener(configListenerGotoMainClassOnStartup = (Boolean newValue) -> {
+ setMenuChecked("/settings/gotoMainClassOnStartup", newValue);
+ });
+
+ setMenuChecked("/settings/autoRenameIdentifiers", Configuration.autoRenameIdentifiers.get());
+ Configuration.autoRenameIdentifiers.addListener(configListenerAutoRenameIdentifiers = (Boolean newValue) -> {
+ setMenuChecked("/settings/autoRenameIdentifiers", newValue);
+ });
+
+ setMenuChecked("/settings/autoOpenLoadedSWFs", Configuration.autoOpenLoadedSWFs.get());
+ Configuration.autoOpenLoadedSWFs.addListener(configListenerAutoOpenLoadedSWFs = (Boolean newValue) -> {
+ setMenuChecked("/settings/autoOpenLoadedSWFs", newValue);
+ });
+
+ if (externalFlashPlayerUnavailable) {
+ setMenuEnabled("/settings/internalViewer", false);
+ setMenuEnabled("/settings/autoOpenLoadedSWFs", false);
+ }
+
+ /*int deobfuscationMode = Configuration.deobfuscationMode.get();
+ switch (deobfuscationMode) {
+ case 0:
+ setGroupSelection("deobfuscation", "/settings/deobfuscation/old");
+ break;
+ case 1:
+ setGroupSelection("deobfuscation", "/settings/deobfuscation/new");
+ break;
+ }*/
+ if (Platform.isWindows()) {
+ setMenuChecked("/settings/associate", ContextMenuTools.isAddedToContextMenu());
+ }
+
+ //Help
+ addMenuItem("/help", translate("menu.help"), null, null, 0, null, false, null, false);
+ addMenuItem("/help/helpUs", translate("menu.help.helpus"), "donate32", this::helpUsActionPerformed, PRIORITY_TOP, null, true, null, false);
+ addMenuItem("/help/homePage", translate("menu.help.homepage"), "homepage16", this::homePageActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addSeparator("/help");
+ addMenuItem("/help/checkUpdates", translate("menu.help.checkupdates"), "update16", this::checkUpdatesActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/help/about", translate("menu.help.about"), "about32", this::aboutActionPerformed, PRIORITY_TOP, null, true, null, false);
+ finishMenu("/help");
+
+ if (Configuration._showDebugMenu.get() || Configuration._debugMode.get()) {
+
+ addMenuItem("/debug", "# FFDec Debug #", null, null, 0, null, false, null, false);
+ addMenuItem("/debug/removeNonScripts", "Remove non scripts", "continue16", e -> removeNonScripts(), PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/removeExceptSelected", "Remove except selected", "continue16", e -> removeExceptSelected(), PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/refreshDecompiled", "Refresh decompiled script", "continue16", e -> refreshDecompiled(), PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/checkResources", "Check resources", "continue16", e -> checkResources(), PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/callGc", "Call System.gc()", "continue16", e -> System.gc(), PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/emptyCache", "Empty cache", "continue16", e -> {
+ SWF nswf = mainFrame.getPanel().getCurrentSwf();
+ if (nswf != null) {
+ nswf.clearAllCache();
+ }
+ }, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/memoryInformation", "Memory information", "continue16", e -> {
+ String architecture = System.getProperty("sun.arch.data.model");
+ Runtime runtime = Runtime.getRuntime();
+ String info = "Architecture: " + architecture + Helper.newLine
+ + "Jre 64bit: " + Helper.is64BitJre() + Helper.newLine
+ + "Os 64bit: " + Helper.is64BitOs() + Helper.newLine
+ + "Max: " + (runtime.maxMemory() / 1024 / 1024) + "MB" + Helper.newLine
+ + "Used: " + (runtime.totalMemory() / 1024 / 1024) + "MB" + Helper.newLine
+ + "Free: " + (runtime.freeMemory() / 1024 / 1024) + "MB";
+ View.showMessageDialog(null, info);
+ SWF nswf = mainFrame.getPanel().getCurrentSwf();
+ if (nswf != null) {
+ nswf.clearAllCache();
+ }
+ }, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/fixAs3Code", "Fix AS3 code", "continue16", e -> {
+ SWF nswf = mainFrame.getPanel().getCurrentSwf();
+ if (nswf != null) {
+ nswf.fixAS3Code();
+ }
+ }, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/openTestSwfs", "Open test SWFs", "continue16", e -> {
+ String path;
+
+ SWFSourceInfo[] sourceInfos = new SWFSourceInfo[2];
+ String mainPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as2\\as2.swf";
+ sourceInfos[0] = new SWFSourceInfo(null, path, null);
+ path = mainPath + "\\..\\..\\libsrc\\ffdec_lib\\testdata\\as3\\as3.swf";
+ sourceInfos[1] = new SWFSourceInfo(null, path, null);
+ Main.openFile(sourceInfos);
+ }, PRIORITY_MEDIUM, null, true, null, false);
+ addMenuItem("/debug/createNewSwf", "Create new SWF", "continue16", e -> {
+ SWF swf = new SWF();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ swf.saveTo(baos);
+ } catch (IOException ex) {
+ Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ Main.openFile(new SWFSourceInfo(new ByteArrayInputStream(baos.toByteArray()), "New SWF", "New SWF"));
+ }, PRIORITY_MEDIUM, null, true, null, false);
+ finishMenu("/debug");
+ }
+
+ finishMenu("");
+ }
+
+ public void showResourcesView() {
+ viewResourcesActionPerformed(null);
+ }
+
+ private void viewResourcesActionPerformed(ActionEvent evt) {
+ Configuration.dumpView.set(false);
+ mainFrame.getPanel().showView(MainPanel.VIEW_RESOURCES);
+ setGroupSelection("view", "/file/view/viewResources");
+ setMenuChecked("/tools/timeline", false);
+ }
+
+ private void viewHexActionPerformed(ActionEvent evt) {
+ Configuration.dumpView.set(true);
+ MainPanel mainPanel = mainFrame.getPanel();
+ if (mainPanel.isModified()) {
+ View.showMessageDialog(null, translate("message.warning.hexViewNotUpToDate"), translate("message.warning"), JOptionPane.WARNING_MESSAGE, Configuration.warningHexViewNotUpToDate);
+ }
+
+ mainPanel.showView(MainPanel.VIEW_DUMP);
+ setGroupSelection("view", "/file/view/viewHex");
+ setMenuChecked("/tools/timeline", false);
+ }
+
+ private void debuggerSwitchActionPerformed(ActionEvent evt) {
+ boolean debuggerOn = isMenuChecked("/tools/debugger/debuggerSwitch");
+ if (!debuggerOn || View.showConfirmDialog((Component) mainFrame, translate("message.debugger"), translate("dialog.message.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, Configuration.displayDebuggerInfo, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) {
+ switchDebugger();
+ mainFrame.getPanel().refreshDecompiled();
+ } else {
+ setMenuChecked("/tools/debugger/debuggerSwitch", false);
+ }
+ setMenuEnabled("/tools/debugger/debuggerReplaceTrace", isMenuChecked("/tools/debugger/debuggerSwitch"));
+ //setMenuEnabled("/tools/debugger/debuggerInjectLoader", isMenuChecked("/tools/debugger/debuggerSwitch"));
+ }
+
+ private void timelineActionPerformed(ActionEvent evt) {
+ if (isMenuChecked("/tools/timeline")) {
+ if (!mainFrame.getPanel().showView(MainPanel.VIEW_TIMELINE)) {
+ setMenuChecked("/tools/timeline", false);
+ } else {
+ setGroupSelection("view", null);
+ }
+ } else if (Configuration.dumpView.get()) {
+ setGroupSelection("view", "/file/view/viewHex");
+ mainFrame.getPanel().showView(MainPanel.VIEW_DUMP);
+ } else {
+ setGroupSelection("view", "/file/view/viewResources");
+ mainFrame.getPanel().showView(MainPanel.VIEW_RESOURCES);
+ }
+ }
+
+ protected void loadRecent(ActionEvent evt) {
+ List recentFiles = Configuration.getRecentFiles();
+ clearMenu("/file/" + (supportsMenuAction() ? "open" : "recent"));
+ clearMenu("_/open");
+
+ for (int i = recentFiles.size() - 1; i >= 0; i--) {
+ final String f = recentFiles.get(i);
+ ActionListener a = (ActionEvent e) -> {
+ if (Main.openFile(f, null) == OpenFileResult.NOT_FOUND) {
+ if (View.showConfirmDialog(null, translate("message.confirm.recentFileNotFound"), translate("message.confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_NO_OPTION) {
+ Configuration.removeRecentFile(f);
+ }
+ }
+ };
+ addMenuItem("/file/" + (supportsMenuAction() ? "open" : "recent") + "/" + i, f, null, a, 0, null, true, null, false);
+ addMenuItem("_/open/" + i, f, null, a, 0, null, true, null, false);
+ }
+
+ finishMenu("/file/" + (supportsMenuAction() ? "open" : "recent"));
+ finishMenu("_/open");
+ }
+
+ public void dispose() {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ manager.removeKeyEventDispatcher(keyEventDispatcher);
+
+ Configuration.autoDeobfuscate.removeListener(configListenerAutoDeobfuscate);
+ Configuration.simplifyExpressions.removeListener(configListenerSimplifyExpressions);
+ Configuration.internalFlashViewer.removeListener(configListenerInternalFlashViewer);
+ Configuration.parallelSpeedUp.removeListener(configListenerParallelSpeedUp);
+ Configuration.decompile.removeListener(configListenerDecompile);
+ //Configuration.cacheOnDisk.removeListener(configListenerCacheOnDisk);
+ Configuration.gotoMainClassOnStartup.removeListener(configListenerGotoMainClassOnStartup);
+ Configuration.autoRenameIdentifiers.removeListener(configListenerAutoRenameIdentifiers);
+ Configuration.autoOpenLoadedSWFs.removeListener(configListenerAutoOpenLoadedSWFs);
+
+ Main.stopRun();
+ }
+
+ public boolean runActionPerformed(ActionEvent evt) {
+ Main.run(swf);
+ return true;
+ }
+
+ public boolean debugActionPerformed(ActionEvent evt) {
+ Main.runDebug(swf, false);
+ return true;
+ }
+
+ public boolean debugPCodeActionPerformed(ActionEvent evt) {
+ Main.runDebug(swf, true);
+ return true;
+ }
+
+ public boolean stopActionPerformed(ActionEvent evt) {
+ Main.stopRun();
+ return true;
+ }
+
+ public boolean pauseActionPerformed(ActionEvent evt) {
+ try {
+ DebuggerCommands cmd = Main.getDebugHandler().getCommands();
+ //TODO
+
+ } catch (IOException ex) {
+ Main.getDebugHandler().disconnect();
+ //ignore
+ }
+ return true;
+ }
+
+ public boolean stepOverActionPerformed(ActionEvent evt) {
+
+ try {
+
+ DebuggerCommands cmd = Main.getDebugHandler().getCommands();
+ mainFrame.getPanel().clearDebuggerColors();
+ Main.startWork(AppStrings.translate("work.debugging") + "...", null);
+
+ cmd.stepOver();
+ } catch (IOException ex) {
+ Main.getDebugHandler().disconnect();
+ //ignore
+ }
+ return true;
+ }
+
+ public boolean stepIntoActionPerformed(ActionEvent evt) {
+ try {
+ DebuggerCommands cmd = Main.getDebugHandler().getCommands();
+ mainFrame.getPanel().clearDebuggerColors();
+ Main.startWork(AppStrings.translate("work.debugging") + "...", null);
+
+ cmd.stepInto();
+ } catch (IOException ex) {
+ Main.getDebugHandler().disconnect();
+ //ignore
+ }
+
+ return true;
+ }
+
+ public boolean stepOutActionPerformed(ActionEvent evt) {
+ try {
+ DebuggerCommands cmd = Main.getDebugHandler().getCommands();
+ mainFrame.getPanel().clearDebuggerColors();
+ Main.startWork(AppStrings.translate("work.debugging") + "...", null);
+ cmd.stepOut();
+ } catch (IOException ex) {
+ Main.getDebugHandler().disconnect();
+ //ignore
+ }
+
+ return true;
+ }
+
+ public boolean continueActionPerformed(ActionEvent evt) {
+ try {
+ DebuggerCommands cmd = Main.getDebugHandler().getCommands();
+ mainFrame.getPanel().clearDebuggerColors();
+ Main.startWork(AppStrings.translate("work.debugging") + "...", null);
+ cmd.sendContinue();
+ } catch (IOException ex) {
+ Main.getDebugHandler().disconnect();
+ //ignore
+ }
+
+ return true;
+ }
+
+ public boolean stackActionPerformed(ActionEvent evt) {
+ //TODO
+ return true;
+ }
+
+ public boolean watchActionPerformed(ActionEvent evt) {
+ //TODO
+ return true;
+ }
+
+ public boolean dispatchKeyEvent(KeyEvent e) {
+ if (((JFrame) mainFrame).isActive() && e.getID() == KeyEvent.KEY_PRESSED) {
+
+ HotKey ek = new HotKey(e);
+ for (String path : menuHotkeys.keySet()) {
+ HotKey mk = menuHotkeys.get(path);
+ if (ek.equals(mk)) {
+ if (menuActions.containsKey(path)) {
+ menuActions.get(path).actionPerformed(null);
+ return true;
+ }
+ }
+ }
+
+ //other nonmenu actions
+ int code = e.getKeyCode();
+ if (e.isControlDown() && e.isShiftDown()) { //CTRL+SHIFT
+ switch (code) {
+ case KeyEvent.VK_F:
+ return searchInActionPerformed(null);
+ case KeyEvent.VK_T:
+ return searchInTextPerformed(null);
+ case KeyEvent.VK_D:
+ return clearLog(null);
+ }
+ } else if (e.isControlDown() && !e.isShiftDown()) { //CTRL
+ switch (code) {
+ case KeyEvent.VK_UP:
+ return previousTag(null);
+ case KeyEvent.VK_DOWN:
+ return nextTag(null);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public abstract void hilightPath(String path);
+
+ public abstract void setPathVisible(String path, boolean val);
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
index c6343785b..44f7441cc 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
@@ -1,649 +1,649 @@
-/*
- * Copyright (C) 2010-2016 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 java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JToggleButton;
-import javax.swing.SwingUtilities;
-import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
-import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
-import org.pushingpixels.flamingo.api.common.CommandToggleButtonGroup;
-import org.pushingpixels.flamingo.api.common.JCommandButton;
-import org.pushingpixels.flamingo.api.common.JCommandButtonPanel;
-import org.pushingpixels.flamingo.api.common.JCommandToggleButton;
-import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
-import org.pushingpixels.flamingo.api.common.popup.PopupPanelCallback;
-import org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand;
-import org.pushingpixels.flamingo.api.ribbon.JRibbon;
-import org.pushingpixels.flamingo.api.ribbon.JRibbonBand;
-import org.pushingpixels.flamingo.api.ribbon.JRibbonComponent;
-import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenu;
-import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenuEntryFooter;
-import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenuEntryPrimary;
-import org.pushingpixels.flamingo.api.ribbon.RibbonContextualTaskGroup;
-import org.pushingpixels.flamingo.api.ribbon.RibbonElementPriority;
-import org.pushingpixels.flamingo.api.ribbon.RibbonTask;
-import org.pushingpixels.flamingo.api.ribbon.resize.BaseRibbonBandResizePolicy;
-import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies;
-import org.pushingpixels.flamingo.api.ribbon.resize.IconRibbonBandResizePolicy;
-import org.pushingpixels.flamingo.api.ribbon.resize.RibbonBandResizePolicy;
-import org.pushingpixels.flamingo.internal.ui.ribbon.AbstractBandControlPanel;
-
-/**
- *
- * @author JPEXS
- */
-public class MainFrameRibbonMenu extends MainFrameMenu {
-
- private final JRibbon ribbon;
-
- private final Map menuItems = new HashMap<>();
-
- private final Map menuTitles = new HashMap<>();
-
- private final Map menuOptional = new HashMap<>();
-
- private final Map menuIcons = new HashMap<>();
-
- private final Map menuLoaders = new HashMap<>();
-
- private final Map menuPriorities = new HashMap<>();
-
- private final Map> menuSubs = new HashMap<>();
-
- private final Map menuType = new HashMap<>();
-
- private final Map menuGroup = new HashMap<>();
-
- private final Map menuToggleGroups = new HashMap<>();
-
- private final Map menuToToggleGroup = new HashMap<>();
-
- private static final int TYPE_MENU = 1;
-
- private static final int TYPE_MENUITEM = 2;
-
- private static final int TYPE_TOGGLEMENUITEM = 3;
-
- private final Map optionalGroups = new HashMap<>();
-
- public MainFrameRibbonMenu(MainFrameRibbon mainFrame, JRibbon ribbon, boolean externalFlashPlayerUnavailable) {
- super(mainFrame, externalFlashPlayerUnavailable);
- this.ribbon = ribbon;
- }
-
- private String fixCommandTitle(String title) {
- if (title.length() > 2) {
- if (title.charAt(1) == ' ') {
- title = title.charAt(0) + "\u00A0" + title.substring(2);
- }
- }
- return title;
- }
-
- private RibbonBandResizePolicy titleResizePolicies(final JRibbonBand ribbonBand) {
- return new BaseRibbonBandResizePolicy(ribbonBand.getControlPanel()) {
- @Override
- public int getPreferredWidth(int i, int i1) {
- return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle()) + 20;
- }
-
- @Override
- public void install(int i, int i1) {
- }
- };
- }
-
- private List getResizePolicies(JRibbonBand ribbonBand) {
- final List myResizePolicies = new ArrayList<>();
- myResizePolicies.add(new CoreRibbonResizePolicies.Mirror(ribbonBand.getControlPanel()));
- myResizePolicies.add(titleResizePolicies(ribbonBand));
- myResizePolicies.add(new IconRibbonBandResizePolicy(ribbonBand.getControlPanel()));
-
- List resizePolicies = new ArrayList<>();
-
- resizePolicies.add(new RibbonBandResizePolicy() {
-
- @Override
- public int getPreferredWidth(int i, int i1) {
- int pw = 0;
- for (RibbonBandResizePolicy p : myResizePolicies) {
- int npw = p.getPreferredWidth(i, i1);
- if (npw > pw) {
- pw = npw;
- }
- }
- return pw;
- }
-
- @Override
- public void install(int i, int i1) {
- for (RibbonBandResizePolicy p : myResizePolicies) {
- p.install(i, i1);
- }
- }
- });
- return resizePolicies;
- }
-
- @Override
- protected void loadRecent(ActionEvent evt) {
- if (evt.getSource() instanceof JPanel) {
- JPanel targetPanel = (JPanel) evt.getSource();
- targetPanel.removeAll();
- JCommandButtonPanel openHistoryPanel = new JCommandButtonPanel(CommandButtonDisplayState.MEDIUM);
- String groupName = translate("menu.recentFiles");
- openHistoryPanel.addButtonGroup(groupName);
- List recentFiles = Configuration.getRecentFiles();
- int j = 0;
- for (int i = recentFiles.size() - 1; i >= 0; i--) {
- String path = recentFiles.get(i);
- RecentFilesButton historyButton = new RecentFilesButton(j + " " + path, null);
- historyButton.fileName = path;
- historyButton.addActionListener((ActionEvent ae) -> {
- RecentFilesButton source = (RecentFilesButton) ae.getSource();
- if (Main.openFile(source.fileName, null) == OpenFileResult.NOT_FOUND) {
- if (View.showConfirmDialog(null, translate("message.confirm.recentFileNotFound"), translate("message.confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_NO_OPTION) {
- Configuration.removeRecentFile(source.fileName);
- }
- }
- });
- j++;
- historyButton.setHorizontalAlignment(SwingUtilities.LEFT);
- openHistoryPanel.addButtonToLastGroup(historyButton);
- }
-
- if (recentFiles.isEmpty()) {
- JCommandButton emptyLabel = new JCommandButton(translate("menu.recentFiles.empty"));
- emptyLabel.setHorizontalAlignment(SwingUtilities.LEFT);
- emptyLabel.setEnabled(false);
- openHistoryPanel.addButtonToLastGroup(emptyLabel);
- }
-
- openHistoryPanel.setMaxButtonColumns(1);
- targetPanel.setLayout(new BorderLayout());
- targetPanel.add(openHistoryPanel, BorderLayout.CENTER);
- }
- }
-
- @Override
- public void finishMenu(String path) {
- if (!menuTitles.containsKey(path)) {
- throw new IllegalArgumentException("Menu not started: " + path);
- }
- boolean isAppMenu = path.equals("_");
- String title = menuTitles.get(path);
- String icon = menuIcons.get(path);
- ActionListener action = menuActions.get(path);
- int priority = menuPriorities.get(path);
- int type = menuType.get(path);
- if (type != TYPE_MENU) {
- throw new IllegalArgumentException("Not a menu: " + path);
- }
-
- String[] parts = path.contains("/") ? path.split("\\/") : new String[]{""};
- List subs = menuSubs.get(path);
-
- boolean onlyCheckboxes = true;
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
- int subType = menuType.get(sub);
- if (subType == TYPE_MENUITEM) {
- onlyCheckboxes = false;
- break;
- }
- String subIcon = menuIcons.get(sub);
- if (subIcon != null) {
- onlyCheckboxes = false;
- break;
- }
- }
- if (subs.isEmpty()) {
- onlyCheckboxes = false;
- }
-
- if (isAppMenu) {
- RibbonApplicationMenu mainMenu = new RibbonApplicationMenu();
- for (String sub : subs) {
- if (sub.equals("-")) {
- mainMenu.addMenuSeparator();
- continue;
- }
-
- String subTitle = menuTitles.get(sub);
- String subIcon = menuIcons.get(sub);
- int subType = menuType.get(sub);
- ActionListener subAction = menuActions.get(sub);
- final ActionListener subLoader = menuLoaders.get(sub);
-
- if (sub.startsWith("_/$")) //FooterMenu
- {
- RibbonApplicationMenuEntryFooter footerMenu = new RibbonApplicationMenuEntryFooter(View.getResizableIcon(subIcon, 16), subTitle, subAction);
- menuItems.put(sub, footerMenu);
- mainMenu.addFooterEntry(footerMenu);
- } else {
- RibbonApplicationMenuEntryPrimary menu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon(subIcon, 32), subTitle, subAction,
- subType == TYPE_MENU ? JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION : JCommandButton.CommandButtonKind.ACTION_ONLY);
-
- if (subLoader != null) {
- menu.setRolloverCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() {
- @Override
- public void menuEntryActivated(JPanel targetPanel) {
- subLoader.actionPerformed(new ActionEvent(targetPanel, 0, "load:" + sub));
- }
- });
- }
- menuItems.put(sub, menu);
- mainMenu.addMenuEntry(menu);
- }
-
- }
-
- ribbon.setApplicationMenu(mainMenu);
- return;
- }
-
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
- int subType = menuType.get(sub);
- ActionListener subAction = menuActions.get(sub);
- String subTitle = menuTitles.get(sub);
- String subIcon = menuIcons.get(sub);
- String subGroup = menuGroup.get(sub);
- HotKey subKey = menuHotkeys.get(sub);
- if (subKey != null) {
- String keyStr = subKey.toString();
- if (keyStr.length() < 8) {
- subTitle += " (" + keyStr + ")";
- }
- }
- int subPriority = menuPriorities.get(sub);
- final ActionListener subLoader = menuLoaders.get(sub);
- AbstractCommandButton but = null;
- if (subType == TYPE_MENUITEM || (subType == TYPE_MENU && subAction != null)) {
- JCommandButton cbut;
- if (subIcon != null) {
- cbut = new JCommandButton(fixCommandTitle(subTitle), View.getResizableIcon(subIcon, subPriority == PRIORITY_TOP ? 32 : 16));
- } else {
- cbut = new JCommandButton(fixCommandTitle(subTitle));
- }
- if (subKey != null) {
- //cbut.setActionRichTooltip(new RichTooltip(subTitle, subKey.toString()));
- }
- if (subLoader != null) {
- cbut.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION);
- cbut.setPopupCallback(new PopupPanelCallback() {
-
- @Override
- public JPopupPanel getPopupPanel(JCommandButton jcb) {
- JPopupPanel jp = new JPopupPanel() {
- };
-
- subLoader.actionPerformed(new ActionEvent(jp, 0, "load:" + sub));
- return jp;
- }
- });
- }
- but = cbut;
- } else if (subType == TYPE_TOGGLEMENUITEM) {
- if (onlyCheckboxes) {
- JCheckBox cb = new JCheckBox(subTitle);
- if (subAction != null) {
- cb.addActionListener(subAction);
- }
- menuItems.put(sub, cb);
- } else {
- if (subIcon != null) {
- but = new JCommandToggleButton(fixCommandTitle(subTitle), View.getResizableIcon(subIcon, subPriority == PRIORITY_TOP ? 32 : 16));
- } else {
- but = new JCommandToggleButton(fixCommandTitle(subTitle));
- }
- menuToToggleGroup.get(sub).add((JCommandToggleButton) but);
- }
- }
- if (but != null) {
- if (subAction != null) {
- but.addActionListener(subAction);
- }
- menuItems.put(sub, but);
- }
- }
-
- //if (parts.length == 3)
- { //3rd level - it's a Band!
- JRibbonBand band = new JRibbonBand(title, icon != null ? View.getResizableIcon(icon, 16) : null, null);
- band.setResizePolicies(getResizePolicies(band));
- int cnt = 0;
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
-
- Object o = menuItems.get(sub);
- int subPriority = menuPriorities.get(sub);
- int subType = menuType.get(sub);
- ActionListener subAction = menuActions.get(sub);
- if (subType != TYPE_MENU || (subAction != null)) {
- if (o instanceof AbstractCommandButton) {
- RibbonElementPriority ribbonPriority = RibbonElementPriority.MEDIUM;
- switch (subPriority) {
- case PRIORITY_LOW:
- ribbonPriority = RibbonElementPriority.LOW;
- break;
- case PRIORITY_MEDIUM:
- ribbonPriority = RibbonElementPriority.MEDIUM;
- break;
- case PRIORITY_TOP:
- ribbonPriority = RibbonElementPriority.TOP;
- break;
- }
-
- band.addCommandButton((AbstractCommandButton) o, ribbonPriority);
- cnt++;
- } else if (o instanceof JComponent) {
- band.addRibbonComponent(new JRibbonComponent((JComponent) o));
- cnt++;
- }
- }
- }
- if (cnt > 0) {
- if (parts.length != 3) {
- if (!menuSubs.containsKey(path)) {
- menuSubs.put(path, new ArrayList<>());
- }
- if (!menuSubs.get(path).contains(path + "/_")) {
- menuSubs.get(path).add(0, path + "/_");
- }
- menuItems.put(path + "/_", band);
-
- } else {
- menuItems.put(path, band);
- }
-
- }
-
- }
-
- if (parts.length == 1) { //1st level - it's ribbon
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
- if (menuItems.get(sub) instanceof RibbonTask) {
- RibbonTask rt = (RibbonTask) menuItems.get(sub);
- if (menuOptional.get(sub)) {
- RibbonContextualTaskGroup rct = new RibbonContextualTaskGroup("", new Color(128, 0, 0), rt);
- ribbon.addContextualTaskGroup(rct);
- optionalGroups.put(sub, rct);
- //ribbon.setVisible(rct, false);
- } else {
- ribbon.addTask(rt);
- }
- }
- }
- } else if (parts.length == 2) { //2nd level - it's a Task!
- int bandCount = 0;
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
-
- if (menuItems.get(sub) instanceof AbstractRibbonBand) {
- bandCount++;
- }
- }
- AbstractRibbonBand[] bands = new AbstractRibbonBand[bandCount];
- int b = 0;
- for (String sub : subs) {
- if (sub.equals("-")) {
- continue;
- }
- if (menuItems.get(sub) instanceof AbstractRibbonBand) {
- bands[b++] = (AbstractRibbonBand) menuItems.get(sub);
- }
- }
- if (bands.length > 0) {
- RibbonTask task = new RibbonTask(title, bands);
- menuItems.put(path, task);
- }
- }
- }
-
- @Override
- public void addMenuItem(String path, String title, String icon, ActionListener action, int priority, ActionListener subLoader, boolean isLeaf, HotKey key, boolean isOptional) {
- String parentPath = path.contains("/") ? path.substring(0, path.lastIndexOf('/')) : "";
- if (!menuSubs.containsKey(parentPath)) {
- throw new IllegalArgumentException("No parent menu exists: " + parentPath);
- }
- menuOptional.put(path, isOptional);
- menuHotkeys.put(path, key);
- menuSubs.get(parentPath).add(path);
- if (!isLeaf) {
- menuSubs.put(path, new ArrayList<>());
- }
- menuLoaders.put(path, subLoader);
- menuTitles.put(path, title);
- menuIcons.put(path, icon);
- menuActions.put(path, action);
- menuPriorities.put(path, priority);
- menuType.put(path, isLeaf ? TYPE_MENUITEM : TYPE_MENU);
- }
-
- @Override
- public void addToggleMenuItem(String path, String title, String group, String icon, ActionListener action, int priority, HotKey key) {
- addMenuItem(path, title, icon, action, priority, action, true, key, false);
- menuType.put(path, TYPE_TOGGLEMENUITEM);
- menuGroup.put(path, group);
- if (group == null) {
- group = path;
- }
- if (!menuToggleGroups.containsKey(group)) {
- menuToggleGroups.put(group, new CommandToggleButtonGroup());
- }
- menuToToggleGroup.put(path, menuToggleGroups.get(group));
- }
-
- @Override
- public boolean isMenuChecked(String path) {
- Object o = menuItems.get(path);
- if (o instanceof JCommandToggleButton) {
- JCommandToggleButton t = (JCommandToggleButton) o;
- if (!menuToToggleGroup.containsKey(path)) {
- throw new IllegalArgumentException("No toggle group for " + path);
- }
- return menuToToggleGroup.get(path).getSelected() == t;
- }
- if (o instanceof JCheckBox) {
- return ((JCheckBox) o).isSelected();
- }
- throw new IllegalArgumentException("Not a toggle menu");
- }
-
- @Override
- public void setMenuChecked(String path, boolean checked) {
- Object o = menuItems.get(path);
- if (o instanceof JCommandToggleButton) {
- JCommandToggleButton t = (JCommandToggleButton) o;
- if (!menuToToggleGroup.containsKey(path)) {
- throw new IllegalArgumentException("No toggle group for " + path);
- }
- menuToToggleGroup.get(path).setSelected(t, checked);
- } else if (o instanceof JToggleButton) {
- ((JToggleButton) o).setSelected(checked);
- } else {
- throw new IllegalArgumentException("Not a toggle menu");
- }
- }
-
- @Override
- public void setGroupSelection(String group, String selected) {
- if (!menuToggleGroups.containsKey(group)) {
- throw new IllegalArgumentException("Group " + group + " does not exist");
- }
- menuToggleGroups.get(group).clearSelection();
- if (selected == null) {
- return;
- }
- if (!menuItems.containsKey(selected)) {
- throw new IllegalArgumentException("Selection " + selected + " not found");
- }
- JCommandToggleButton c = (JCommandToggleButton) menuItems.get(selected);
- menuToggleGroups.get(group).setSelected(c, true);
- }
-
- @Override
- public String getGroupSelection(String group) {
- if (!menuToggleGroups.containsKey(group)) {
- throw new IllegalArgumentException("Group " + group + " does not exist");
- }
- JCommandToggleButton c = menuToggleGroups.get(group).getSelected();
- for (String path : menuItems.keySet()) {
- if (menuItems.get(path) == c) {
- return path;
- }
- }
- return null;
- }
-
- @Override
- public void clearMenu(String path) {
-
- }
-
- @Override
- public void setMenuEnabled(String path, boolean enabled) {
- if (!menuItems.containsKey(path)) {
- throw new IllegalArgumentException("Menu not found: " + path);
- }
- Object o = menuItems.get(path);
- try {
- if (o instanceof JRibbonBand) {
- ((JRibbonBand) o).setEnabled(enabled);
- } else if (o instanceof AbstractCommandButton) {
- ((AbstractCommandButton) o).setEnabled(enabled);
- } else if (o instanceof RibbonApplicationMenuEntryPrimary) {
- ((RibbonApplicationMenuEntryPrimary) o).setEnabled(enabled);
- } else if (o instanceof RibbonApplicationMenuEntryFooter) {
- ((RibbonApplicationMenuEntryFooter) o).setEnabled(enabled);
- } else if (o instanceof JComponent) {
- ((JComponent) o).setEnabled(enabled);
- } else {
- throw new IllegalArgumentException("Cannot set enabled to: " + path);
- }
- } catch (Exception ex) {
- //some substance issues, ignore
- }
- }
-
- @Override
- public void initMenu() {
- menuSubs.put("", new ArrayList<>());
- menuPriorities.put("", 0);
- menuActions.put("", null);
- menuTitles.put("", null);
- menuIcons.put("", null);
- menuType.put("", TYPE_MENU);
- }
-
- @Override
- public void addSeparator(String parentPath) {
- if (!menuSubs.containsKey(parentPath)) {
- throw new IllegalArgumentException("Menu does not exist: " + parentPath);
- }
- menuSubs.get(parentPath).add("-");
- }
-
- @Override
- public boolean supportsMenuAction() {
- return true;
- }
-
- @Override
- public boolean supportsAppMenu() {
- return true;
- }
-
- @Override
- public void setPathVisible(String path, boolean val) {
- Object o = menuItems.get(path);
- if (o instanceof RibbonTask) {
- if (menuOptional.get(path)) {
- RibbonContextualTaskGroup rg = optionalGroups.get(path);
-
- if (ribbon.isVisible(rg) != val) {
- View.execInEventDispatch(new Runnable() {
-
- @Override
- public void run() {
- try {
- ribbon.setVisible(rg, val);
- } catch (Exception ex) {
-
- }
- }
- });
-
- }
- }
- }
- }
-
- @Override
- public void hilightPath(String path) {
- Object o = menuItems.get(path);
- if (o instanceof RibbonTask) {
- if (menuOptional.get(path)) {
- View.execInEventDispatch(new Runnable() {
-
- @Override
- public void run() {
- if (!ribbon.isVisible(optionalGroups.get(path))) {
- ribbon.setVisible(optionalGroups.get(path), true);
- }
- ribbon.setSelectedTask((RibbonTask) o);
- }
- });
- return;
- }
- final RibbonTask rt = (RibbonTask) o;
- View.execInEventDispatch(new Runnable() {
-
- @Override
- public void run() {
- ribbon.setSelectedTask(rt);
- }
- });
-
- }
- }
-}
+/*
+ * Copyright (C) 2010-2016 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 java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+import javax.swing.SwingUtilities;
+import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
+import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
+import org.pushingpixels.flamingo.api.common.CommandToggleButtonGroup;
+import org.pushingpixels.flamingo.api.common.JCommandButton;
+import org.pushingpixels.flamingo.api.common.JCommandButtonPanel;
+import org.pushingpixels.flamingo.api.common.JCommandToggleButton;
+import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
+import org.pushingpixels.flamingo.api.common.popup.PopupPanelCallback;
+import org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand;
+import org.pushingpixels.flamingo.api.ribbon.JRibbon;
+import org.pushingpixels.flamingo.api.ribbon.JRibbonBand;
+import org.pushingpixels.flamingo.api.ribbon.JRibbonComponent;
+import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenu;
+import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenuEntryFooter;
+import org.pushingpixels.flamingo.api.ribbon.RibbonApplicationMenuEntryPrimary;
+import org.pushingpixels.flamingo.api.ribbon.RibbonContextualTaskGroup;
+import org.pushingpixels.flamingo.api.ribbon.RibbonElementPriority;
+import org.pushingpixels.flamingo.api.ribbon.RibbonTask;
+import org.pushingpixels.flamingo.api.ribbon.resize.BaseRibbonBandResizePolicy;
+import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizePolicies;
+import org.pushingpixels.flamingo.api.ribbon.resize.IconRibbonBandResizePolicy;
+import org.pushingpixels.flamingo.api.ribbon.resize.RibbonBandResizePolicy;
+import org.pushingpixels.flamingo.internal.ui.ribbon.AbstractBandControlPanel;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class MainFrameRibbonMenu extends MainFrameMenu {
+
+ private final JRibbon ribbon;
+
+ private final Map menuItems = new HashMap<>();
+
+ private final Map menuTitles = new HashMap<>();
+
+ private final Map menuOptional = new HashMap<>();
+
+ private final Map menuIcons = new HashMap<>();
+
+ private final Map menuLoaders = new HashMap<>();
+
+ private final Map menuPriorities = new HashMap<>();
+
+ private final Map> menuSubs = new HashMap<>();
+
+ private final Map menuType = new HashMap<>();
+
+ private final Map menuGroup = new HashMap<>();
+
+ private final Map menuToggleGroups = new HashMap<>();
+
+ private final Map menuToToggleGroup = new HashMap<>();
+
+ private static final int TYPE_MENU = 1;
+
+ private static final int TYPE_MENUITEM = 2;
+
+ private static final int TYPE_TOGGLEMENUITEM = 3;
+
+ private final Map optionalGroups = new HashMap<>();
+
+ public MainFrameRibbonMenu(MainFrameRibbon mainFrame, JRibbon ribbon, boolean externalFlashPlayerUnavailable) {
+ super(mainFrame, externalFlashPlayerUnavailable);
+ this.ribbon = ribbon;
+ }
+
+ private String fixCommandTitle(String title) {
+ if (title.length() > 2) {
+ if (title.charAt(1) == ' ') {
+ title = title.charAt(0) + "\u00A0" + title.substring(2);
+ }
+ }
+ return title;
+ }
+
+ private RibbonBandResizePolicy titleResizePolicies(final JRibbonBand ribbonBand) {
+ return new BaseRibbonBandResizePolicy(ribbonBand.getControlPanel()) {
+ @Override
+ public int getPreferredWidth(int i, int i1) {
+ return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle()) + 20;
+ }
+
+ @Override
+ public void install(int i, int i1) {
+ }
+ };
+ }
+
+ private List getResizePolicies(JRibbonBand ribbonBand) {
+ final List myResizePolicies = new ArrayList<>();
+ myResizePolicies.add(new CoreRibbonResizePolicies.Mirror(ribbonBand.getControlPanel()));
+ myResizePolicies.add(titleResizePolicies(ribbonBand));
+ myResizePolicies.add(new IconRibbonBandResizePolicy(ribbonBand.getControlPanel()));
+
+ List resizePolicies = new ArrayList<>();
+
+ resizePolicies.add(new RibbonBandResizePolicy() {
+
+ @Override
+ public int getPreferredWidth(int i, int i1) {
+ int pw = 0;
+ for (RibbonBandResizePolicy p : myResizePolicies) {
+ int npw = p.getPreferredWidth(i, i1);
+ if (npw > pw) {
+ pw = npw;
+ }
+ }
+ return pw;
+ }
+
+ @Override
+ public void install(int i, int i1) {
+ for (RibbonBandResizePolicy p : myResizePolicies) {
+ p.install(i, i1);
+ }
+ }
+ });
+ return resizePolicies;
+ }
+
+ @Override
+ protected void loadRecent(ActionEvent evt) {
+ if (evt.getSource() instanceof JPanel) {
+ JPanel targetPanel = (JPanel) evt.getSource();
+ targetPanel.removeAll();
+ JCommandButtonPanel openHistoryPanel = new JCommandButtonPanel(CommandButtonDisplayState.MEDIUM);
+ String groupName = translate("menu.recentFiles");
+ openHistoryPanel.addButtonGroup(groupName);
+ List recentFiles = Configuration.getRecentFiles();
+ int j = 0;
+ for (int i = recentFiles.size() - 1; i >= 0; i--) {
+ String path = recentFiles.get(i);
+ RecentFilesButton historyButton = new RecentFilesButton(j + " " + path, null);
+ historyButton.fileName = path;
+ historyButton.addActionListener((ActionEvent ae) -> {
+ RecentFilesButton source = (RecentFilesButton) ae.getSource();
+ if (Main.openFile(source.fileName, null) == OpenFileResult.NOT_FOUND) {
+ if (View.showConfirmDialog(null, translate("message.confirm.recentFileNotFound"), translate("message.confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_NO_OPTION) {
+ Configuration.removeRecentFile(source.fileName);
+ }
+ }
+ });
+ j++;
+ historyButton.setHorizontalAlignment(SwingUtilities.LEFT);
+ openHistoryPanel.addButtonToLastGroup(historyButton);
+ }
+
+ if (recentFiles.isEmpty()) {
+ JCommandButton emptyLabel = new JCommandButton(translate("menu.recentFiles.empty"));
+ emptyLabel.setHorizontalAlignment(SwingUtilities.LEFT);
+ emptyLabel.setEnabled(false);
+ openHistoryPanel.addButtonToLastGroup(emptyLabel);
+ }
+
+ openHistoryPanel.setMaxButtonColumns(1);
+ targetPanel.setLayout(new BorderLayout());
+ targetPanel.add(openHistoryPanel, BorderLayout.CENTER);
+ }
+ }
+
+ @Override
+ public void finishMenu(String path) {
+ if (!menuTitles.containsKey(path)) {
+ throw new IllegalArgumentException("Menu not started: " + path);
+ }
+ boolean isAppMenu = path.equals("_");
+ String title = menuTitles.get(path);
+ String icon = menuIcons.get(path);
+ ActionListener action = menuActions.get(path);
+ int priority = menuPriorities.get(path);
+ int type = menuType.get(path);
+ if (type != TYPE_MENU) {
+ throw new IllegalArgumentException("Not a menu: " + path);
+ }
+
+ String[] parts = path.contains("/") ? path.split("\\/") : new String[]{""};
+ List subs = menuSubs.get(path);
+
+ boolean onlyCheckboxes = true;
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+ int subType = menuType.get(sub);
+ if (subType == TYPE_MENUITEM) {
+ onlyCheckboxes = false;
+ break;
+ }
+ String subIcon = menuIcons.get(sub);
+ if (subIcon != null) {
+ onlyCheckboxes = false;
+ break;
+ }
+ }
+ if (subs.isEmpty()) {
+ onlyCheckboxes = false;
+ }
+
+ if (isAppMenu) {
+ RibbonApplicationMenu mainMenu = new RibbonApplicationMenu();
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ mainMenu.addMenuSeparator();
+ continue;
+ }
+
+ String subTitle = menuTitles.get(sub);
+ String subIcon = menuIcons.get(sub);
+ int subType = menuType.get(sub);
+ ActionListener subAction = menuActions.get(sub);
+ final ActionListener subLoader = menuLoaders.get(sub);
+
+ if (sub.startsWith("_/$")) //FooterMenu
+ {
+ RibbonApplicationMenuEntryFooter footerMenu = new RibbonApplicationMenuEntryFooter(View.getResizableIcon(subIcon, 16), subTitle, subAction);
+ menuItems.put(sub, footerMenu);
+ mainMenu.addFooterEntry(footerMenu);
+ } else {
+ RibbonApplicationMenuEntryPrimary menu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon(subIcon, 32), subTitle, subAction,
+ subType == TYPE_MENU ? JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION : JCommandButton.CommandButtonKind.ACTION_ONLY);
+
+ if (subLoader != null) {
+ menu.setRolloverCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() {
+ @Override
+ public void menuEntryActivated(JPanel targetPanel) {
+ subLoader.actionPerformed(new ActionEvent(targetPanel, 0, "load:" + sub));
+ }
+ });
+ }
+ menuItems.put(sub, menu);
+ mainMenu.addMenuEntry(menu);
+ }
+
+ }
+
+ ribbon.setApplicationMenu(mainMenu);
+ return;
+ }
+
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+ int subType = menuType.get(sub);
+ ActionListener subAction = menuActions.get(sub);
+ String subTitle = menuTitles.get(sub);
+ String subIcon = menuIcons.get(sub);
+ String subGroup = menuGroup.get(sub);
+ HotKey subKey = menuHotkeys.get(sub);
+ if (subKey != null) {
+ String keyStr = subKey.toString();
+ if (keyStr.length() < 8) {
+ subTitle += " (" + keyStr + ")";
+ }
+ }
+ int subPriority = menuPriorities.get(sub);
+ final ActionListener subLoader = menuLoaders.get(sub);
+ AbstractCommandButton but = null;
+ if (subType == TYPE_MENUITEM || (subType == TYPE_MENU && subAction != null)) {
+ JCommandButton cbut;
+ if (subIcon != null) {
+ cbut = new JCommandButton(fixCommandTitle(subTitle), View.getResizableIcon(subIcon, subPriority == PRIORITY_TOP ? 32 : 16));
+ } else {
+ cbut = new JCommandButton(fixCommandTitle(subTitle));
+ }
+ if (subKey != null) {
+ //cbut.setActionRichTooltip(new RichTooltip(subTitle, subKey.toString()));
+ }
+ if (subLoader != null) {
+ cbut.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION);
+ cbut.setPopupCallback(new PopupPanelCallback() {
+
+ @Override
+ public JPopupPanel getPopupPanel(JCommandButton jcb) {
+ JPopupPanel jp = new JPopupPanel() {
+ };
+
+ subLoader.actionPerformed(new ActionEvent(jp, 0, "load:" + sub));
+ return jp;
+ }
+ });
+ }
+ but = cbut;
+ } else if (subType == TYPE_TOGGLEMENUITEM) {
+ if (onlyCheckboxes) {
+ JCheckBox cb = new JCheckBox(subTitle);
+ if (subAction != null) {
+ cb.addActionListener(subAction);
+ }
+ menuItems.put(sub, cb);
+ } else {
+ if (subIcon != null) {
+ but = new JCommandToggleButton(fixCommandTitle(subTitle), View.getResizableIcon(subIcon, subPriority == PRIORITY_TOP ? 32 : 16));
+ } else {
+ but = new JCommandToggleButton(fixCommandTitle(subTitle));
+ }
+ menuToToggleGroup.get(sub).add((JCommandToggleButton) but);
+ }
+ }
+ if (but != null) {
+ if (subAction != null) {
+ but.addActionListener(subAction);
+ }
+ menuItems.put(sub, but);
+ }
+ }
+
+ //if (parts.length == 3)
+ { //3rd level - it's a Band!
+ JRibbonBand band = new JRibbonBand(title, icon != null ? View.getResizableIcon(icon, 16) : null, null);
+ band.setResizePolicies(getResizePolicies(band));
+ int cnt = 0;
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+
+ Object o = menuItems.get(sub);
+ int subPriority = menuPriorities.get(sub);
+ int subType = menuType.get(sub);
+ ActionListener subAction = menuActions.get(sub);
+ if (subType != TYPE_MENU || (subAction != null)) {
+ if (o instanceof AbstractCommandButton) {
+ RibbonElementPriority ribbonPriority = RibbonElementPriority.MEDIUM;
+ switch (subPriority) {
+ case PRIORITY_LOW:
+ ribbonPriority = RibbonElementPriority.LOW;
+ break;
+ case PRIORITY_MEDIUM:
+ ribbonPriority = RibbonElementPriority.MEDIUM;
+ break;
+ case PRIORITY_TOP:
+ ribbonPriority = RibbonElementPriority.TOP;
+ break;
+ }
+
+ band.addCommandButton((AbstractCommandButton) o, ribbonPriority);
+ cnt++;
+ } else if (o instanceof JComponent) {
+ band.addRibbonComponent(new JRibbonComponent((JComponent) o));
+ cnt++;
+ }
+ }
+ }
+ if (cnt > 0) {
+ if (parts.length != 3) {
+ if (!menuSubs.containsKey(path)) {
+ menuSubs.put(path, new ArrayList<>());
+ }
+ if (!menuSubs.get(path).contains(path + "/_")) {
+ menuSubs.get(path).add(0, path + "/_");
+ }
+ menuItems.put(path + "/_", band);
+
+ } else {
+ menuItems.put(path, band);
+ }
+
+ }
+
+ }
+
+ if (parts.length == 1) { //1st level - it's ribbon
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+ if (menuItems.get(sub) instanceof RibbonTask) {
+ RibbonTask rt = (RibbonTask) menuItems.get(sub);
+ if (menuOptional.get(sub)) {
+ RibbonContextualTaskGroup rct = new RibbonContextualTaskGroup("", new Color(128, 0, 0), rt);
+ ribbon.addContextualTaskGroup(rct);
+ optionalGroups.put(sub, rct);
+ //ribbon.setVisible(rct, false);
+ } else {
+ ribbon.addTask(rt);
+ }
+ }
+ }
+ } else if (parts.length == 2) { //2nd level - it's a Task!
+ int bandCount = 0;
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+
+ if (menuItems.get(sub) instanceof AbstractRibbonBand) {
+ bandCount++;
+ }
+ }
+ AbstractRibbonBand[] bands = new AbstractRibbonBand[bandCount];
+ int b = 0;
+ for (String sub : subs) {
+ if (sub.equals("-")) {
+ continue;
+ }
+ if (menuItems.get(sub) instanceof AbstractRibbonBand) {
+ bands[b++] = (AbstractRibbonBand) menuItems.get(sub);
+ }
+ }
+ if (bands.length > 0) {
+ RibbonTask task = new RibbonTask(title, bands);
+ menuItems.put(path, task);
+ }
+ }
+ }
+
+ @Override
+ public void addMenuItem(String path, String title, String icon, ActionListener action, int priority, ActionListener subLoader, boolean isLeaf, HotKey key, boolean isOptional) {
+ String parentPath = path.contains("/") ? path.substring(0, path.lastIndexOf('/')) : "";
+ if (!menuSubs.containsKey(parentPath)) {
+ throw new IllegalArgumentException("No parent menu exists: " + parentPath);
+ }
+ menuOptional.put(path, isOptional);
+ menuHotkeys.put(path, key);
+ menuSubs.get(parentPath).add(path);
+ if (!isLeaf) {
+ menuSubs.put(path, new ArrayList<>());
+ }
+ menuLoaders.put(path, subLoader);
+ menuTitles.put(path, title);
+ menuIcons.put(path, icon);
+ menuActions.put(path, action);
+ menuPriorities.put(path, priority);
+ menuType.put(path, isLeaf ? TYPE_MENUITEM : TYPE_MENU);
+ }
+
+ @Override
+ public void addToggleMenuItem(String path, String title, String group, String icon, ActionListener action, int priority, HotKey key) {
+ addMenuItem(path, title, icon, action, priority, action, true, key, false);
+ menuType.put(path, TYPE_TOGGLEMENUITEM);
+ menuGroup.put(path, group);
+ if (group == null) {
+ group = path;
+ }
+ if (!menuToggleGroups.containsKey(group)) {
+ menuToggleGroups.put(group, new CommandToggleButtonGroup());
+ }
+ menuToToggleGroup.put(path, menuToggleGroups.get(group));
+ }
+
+ @Override
+ public boolean isMenuChecked(String path) {
+ Object o = menuItems.get(path);
+ if (o instanceof JCommandToggleButton) {
+ JCommandToggleButton t = (JCommandToggleButton) o;
+ if (!menuToToggleGroup.containsKey(path)) {
+ throw new IllegalArgumentException("No toggle group for " + path);
+ }
+ return menuToToggleGroup.get(path).getSelected() == t;
+ }
+ if (o instanceof JCheckBox) {
+ return ((JCheckBox) o).isSelected();
+ }
+ throw new IllegalArgumentException("Not a toggle menu");
+ }
+
+ @Override
+ public void setMenuChecked(String path, boolean checked) {
+ Object o = menuItems.get(path);
+ if (o instanceof JCommandToggleButton) {
+ JCommandToggleButton t = (JCommandToggleButton) o;
+ if (!menuToToggleGroup.containsKey(path)) {
+ throw new IllegalArgumentException("No toggle group for " + path);
+ }
+ menuToToggleGroup.get(path).setSelected(t, checked);
+ } else if (o instanceof JToggleButton) {
+ ((JToggleButton) o).setSelected(checked);
+ } else {
+ throw new IllegalArgumentException("Not a toggle menu");
+ }
+ }
+
+ @Override
+ public void setGroupSelection(String group, String selected) {
+ if (!menuToggleGroups.containsKey(group)) {
+ throw new IllegalArgumentException("Group " + group + " does not exist");
+ }
+ menuToggleGroups.get(group).clearSelection();
+ if (selected == null) {
+ return;
+ }
+ if (!menuItems.containsKey(selected)) {
+ throw new IllegalArgumentException("Selection " + selected + " not found");
+ }
+ JCommandToggleButton c = (JCommandToggleButton) menuItems.get(selected);
+ menuToggleGroups.get(group).setSelected(c, true);
+ }
+
+ @Override
+ public String getGroupSelection(String group) {
+ if (!menuToggleGroups.containsKey(group)) {
+ throw new IllegalArgumentException("Group " + group + " does not exist");
+ }
+ JCommandToggleButton c = menuToggleGroups.get(group).getSelected();
+ for (String path : menuItems.keySet()) {
+ if (menuItems.get(path) == c) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void clearMenu(String path) {
+
+ }
+
+ @Override
+ public void setMenuEnabled(String path, boolean enabled) {
+ if (!menuItems.containsKey(path)) {
+ throw new IllegalArgumentException("Menu not found: " + path);
+ }
+ Object o = menuItems.get(path);
+ try {
+ if (o instanceof JRibbonBand) {
+ ((JRibbonBand) o).setEnabled(enabled);
+ } else if (o instanceof AbstractCommandButton) {
+ ((AbstractCommandButton) o).setEnabled(enabled);
+ } else if (o instanceof RibbonApplicationMenuEntryPrimary) {
+ ((RibbonApplicationMenuEntryPrimary) o).setEnabled(enabled);
+ } else if (o instanceof RibbonApplicationMenuEntryFooter) {
+ ((RibbonApplicationMenuEntryFooter) o).setEnabled(enabled);
+ } else if (o instanceof JComponent) {
+ ((JComponent) o).setEnabled(enabled);
+ } else {
+ throw new IllegalArgumentException("Cannot set enabled to: " + path);
+ }
+ } catch (Exception ex) {
+ //some substance issues, ignore
+ }
+ }
+
+ @Override
+ public void initMenu() {
+ menuSubs.put("", new ArrayList<>());
+ menuPriorities.put("", 0);
+ menuActions.put("", null);
+ menuTitles.put("", null);
+ menuIcons.put("", null);
+ menuType.put("", TYPE_MENU);
+ }
+
+ @Override
+ public void addSeparator(String parentPath) {
+ if (!menuSubs.containsKey(parentPath)) {
+ throw new IllegalArgumentException("Menu does not exist: " + parentPath);
+ }
+ menuSubs.get(parentPath).add("-");
+ }
+
+ @Override
+ public boolean supportsMenuAction() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsAppMenu() {
+ return true;
+ }
+
+ @Override
+ public void setPathVisible(String path, boolean val) {
+ Object o = menuItems.get(path);
+ if (o instanceof RibbonTask) {
+ if (menuOptional.get(path)) {
+ RibbonContextualTaskGroup rg = optionalGroups.get(path);
+
+ if (ribbon.isVisible(rg) != val) {
+ View.execInEventDispatch(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ ribbon.setVisible(rg, val);
+ } catch (Exception ex) {
+
+ }
+ }
+ });
+
+ }
+ }
+ }
+ }
+
+ @Override
+ public void hilightPath(String path) {
+ Object o = menuItems.get(path);
+ if (o instanceof RibbonTask) {
+ if (menuOptional.get(path)) {
+ View.execInEventDispatch(new Runnable() {
+
+ @Override
+ public void run() {
+ if (!ribbon.isVisible(optionalGroups.get(path))) {
+ ribbon.setVisible(optionalGroups.get(path), true);
+ }
+ ribbon.setSelectedTask((RibbonTask) o);
+ }
+ });
+ return;
+ }
+ final RibbonTask rt = (RibbonTask) o;
+ View.execInEventDispatch(new Runnable() {
+
+ @Override
+ public void run() {
+ ribbon.setSelectedTask(rt);
+ }
+ });
+
+ }
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/MenuBuilder.java b/src/com/jpexs/decompiler/flash/gui/MenuBuilder.java
index 6443ad35a..29da062ab 100644
--- a/src/com/jpexs/decompiler/flash/gui/MenuBuilder.java
+++ b/src/com/jpexs/decompiler/flash/gui/MenuBuilder.java
@@ -1,293 +1,293 @@
-/*
- * Copyright (C) 2010-2016 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.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Menu Builder. Creates menu.
- *
- * @author JPEXS
- */
-public interface MenuBuilder {
-
- public static class HotKey {
-
- private static Map keyCodesToNames = new HashMap<>();
-
- private static Map keyNamesToCodes = new HashMap<>();
-
- {
-
- Field[] fields = KeyEvent.class.getFields();
-
- for (int i = 0; i < fields.length; i++) {
-
- String fieldName = fields[i].getName();
-
- // We only care about the field names corresponding to key codes
- if (fieldName.startsWith("VK")) {
- try {
- int keyCode = fields[i].getInt(null);
- String keyName = fieldName.substring(3);
- keyCodesToNames.put(keyCode, keyName);
- keyNamesToCodes.put(keyName, keyCode);
- } catch (Exception ex) {
-
- }
- }
- }
- }
-
- public int key;
-
- public boolean shiftDown;
-
- public boolean ctrlDown;
-
- public boolean altDown;
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 41 * hash + this.key;
- hash = 41 * hash + (this.shiftDown ? 1 : 0);
- hash = 41 * hash + (this.ctrlDown ? 1 : 0);
- hash = 41 * hash + (this.altDown ? 1 : 0);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final HotKey other = (HotKey) obj;
- if (this.key != other.key) {
- return false;
- }
- if (this.shiftDown != other.shiftDown) {
- return false;
- }
- if (this.ctrlDown != other.ctrlDown) {
- return false;
- }
- return (this.altDown == other.altDown);
- }
-
- public boolean matches(KeyEvent ev) {
- return ev.getKeyCode() == key && ev.isControlDown() == ctrlDown && ev.isShiftDown() == shiftDown && ev.isAltDown() == altDown;
- }
-
- public int getModifier() {
- return (shiftDown ? KeyEvent.SHIFT_MASK : 0) + (ctrlDown ? KeyEvent.CTRL_MASK : 0) + (altDown ? KeyEvent.ALT_MASK : 0);
- }
-
- public HotKey(String h) {
- String[] parts = h.contains("+") ? h.split("\\+") : new String[]{h};
- for (String s : parts) {
- switch (s) {
- case "SHIFT":
- shiftDown = true;
- break;
- case "CTRL":
- ctrlDown = true;
- break;
- case "ALT":
- altDown = true;
- break;
- default:
- if (keyNamesToCodes.containsKey(s)) {
- key = keyNamesToCodes.get(s);
- } else {
- throw new IllegalArgumentException("Key " + s + " not found!");
- }
- }
- }
- }
-
- public HotKey(KeyEvent ev) {
- this(ev.getKeyCode(), ev.isShiftDown(), ev.isControlDown(), ev.isAltDown());
- }
-
- public HotKey(int key) {
- this(key, false, false, false);
- }
-
- public HotKey(int key, boolean shiftDown, boolean ctrlDown, boolean altDown) {
- this.key = key;
- this.shiftDown = shiftDown;
- this.ctrlDown = ctrlDown;
- this.altDown = altDown;
- }
-
- @Override
- public String toString() {
- String s = "";
- if (shiftDown) {
- s += "SHIFT";
- }
- if (ctrlDown) {
- if (!s.isEmpty()) {
- s += "+";
- }
- s += "CTRL";
- }
- if (altDown) {
- if (!s.isEmpty()) {
- s += "+";
- }
- s += "ALT";
- }
- if (!s.isEmpty()) {
- s += "+";
- }
- s += keyCodesToNames.get(key);
-
- return s;
- }
- }
-
- public static final int PRIORITY_LOW = 1;
-
- public static final int PRIORITY_MEDIUM = 2;
-
- public static final int PRIORITY_TOP = 3;
-
- /**
- * Initializes menuBuilder
- */
- public void initMenu();
-
- /**
- * Adds separator
- *
- * @param parentPath Parent menu path
- */
- public void addSeparator(String parentPath);
-
- /**
- * Adds menu item
- *
- * @param path Path
- * @param title Title
- * @param icon Icon - resource name
- * @param action Action for clicking
- * @param priority Priority
- * @param subloader Action which loads menu inside
- * @param isLeaf Has no subitems?
- * @param key
- * @param isOptional
- */
- public void addMenuItem(String path, String title, String icon, ActionListener action, int priority, ActionListener subloader, boolean isLeaf, HotKey key, boolean isOptional);
-
- /**
- * Adds toggle item (radio/checkbox)
- *
- * @param path Path
- * @param title Title
- * @param group Group for toggling. Null = checkbox
- * @param icon Icon - resource name
- * @param action Action for clicking
- * @param priority Priority
- * @param key
- */
- public void addToggleMenuItem(String path, String title, String group, String icon, ActionListener action, int priority, HotKey key);
-
- /**
- * Test menu checked (toggle)
- *
- * @param path Menu path
- * @return True when checked
- */
- public boolean isMenuChecked(String path);
-
- /**
- * Hotkey for menu
- *
- * @param path Menu path
- * @return
- */
- public HotKey getMenuHotkey(String path);
-
- /**
- * Sets menu checked (toggle)
- *
- * @param path Menu path
- * @param checked Checked?
- */
- public void setMenuChecked(String path, boolean checked);
-
- /**
- * Sets checked item from group
- *
- * @param group Group name
- * @param selected Selected path
- */
- public void setGroupSelection(String group, String selected);
-
- /**
- * Gets selected path from group
- *
- * @param group Group name
- * @return Path
- */
- public String getGroupSelection(String group);
-
- /**
- * Clears menu
- *
- * @param path Path of menu
- */
- public void clearMenu(String path);
-
- /**
- * Sets enabled property of menu
- *
- * @param path Menu path
- * @param enabled Enabled?
- */
- public void setMenuEnabled(String path, boolean enabled);
-
- /**
- * Finished creating menu
- *
- * @param path Menu path
- */
- public void finishMenu(String path);
-
- /**
- * Does this builder support actions for menus? (not menuitems)
- *
- * @return True if supports
- */
- public boolean supportsMenuAction();
-
- /**
- * Does this builder support application menu (Path "_/...")
- *
- * @return True if supports
- */
- public boolean supportsAppMenu();
-}
+/*
+ * Copyright (C) 2010-2016 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.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Menu Builder. Creates menu.
+ *
+ * @author JPEXS
+ */
+public interface MenuBuilder {
+
+ public static class HotKey {
+
+ private static Map keyCodesToNames = new HashMap<>();
+
+ private static Map keyNamesToCodes = new HashMap<>();
+
+ {
+
+ Field[] fields = KeyEvent.class.getFields();
+
+ for (int i = 0; i < fields.length; i++) {
+
+ String fieldName = fields[i].getName();
+
+ // We only care about the field names corresponding to key codes
+ if (fieldName.startsWith("VK")) {
+ try {
+ int keyCode = fields[i].getInt(null);
+ String keyName = fieldName.substring(3);
+ keyCodesToNames.put(keyCode, keyName);
+ keyNamesToCodes.put(keyName, keyCode);
+ } catch (Exception ex) {
+
+ }
+ }
+ }
+ }
+
+ public int key;
+
+ public boolean shiftDown;
+
+ public boolean ctrlDown;
+
+ public boolean altDown;
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 41 * hash + this.key;
+ hash = 41 * hash + (this.shiftDown ? 1 : 0);
+ hash = 41 * hash + (this.ctrlDown ? 1 : 0);
+ hash = 41 * hash + (this.altDown ? 1 : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final HotKey other = (HotKey) obj;
+ if (this.key != other.key) {
+ return false;
+ }
+ if (this.shiftDown != other.shiftDown) {
+ return false;
+ }
+ if (this.ctrlDown != other.ctrlDown) {
+ return false;
+ }
+ return (this.altDown == other.altDown);
+ }
+
+ public boolean matches(KeyEvent ev) {
+ return ev.getKeyCode() == key && ev.isControlDown() == ctrlDown && ev.isShiftDown() == shiftDown && ev.isAltDown() == altDown;
+ }
+
+ public int getModifier() {
+ return (shiftDown ? KeyEvent.SHIFT_MASK : 0) + (ctrlDown ? KeyEvent.CTRL_MASK : 0) + (altDown ? KeyEvent.ALT_MASK : 0);
+ }
+
+ public HotKey(String h) {
+ String[] parts = h.contains("+") ? h.split("\\+") : new String[]{h};
+ for (String s : parts) {
+ switch (s) {
+ case "SHIFT":
+ shiftDown = true;
+ break;
+ case "CTRL":
+ ctrlDown = true;
+ break;
+ case "ALT":
+ altDown = true;
+ break;
+ default:
+ if (keyNamesToCodes.containsKey(s)) {
+ key = keyNamesToCodes.get(s);
+ } else {
+ throw new IllegalArgumentException("Key " + s + " not found!");
+ }
+ }
+ }
+ }
+
+ public HotKey(KeyEvent ev) {
+ this(ev.getKeyCode(), ev.isShiftDown(), ev.isControlDown(), ev.isAltDown());
+ }
+
+ public HotKey(int key) {
+ this(key, false, false, false);
+ }
+
+ public HotKey(int key, boolean shiftDown, boolean ctrlDown, boolean altDown) {
+ this.key = key;
+ this.shiftDown = shiftDown;
+ this.ctrlDown = ctrlDown;
+ this.altDown = altDown;
+ }
+
+ @Override
+ public String toString() {
+ String s = "";
+ if (shiftDown) {
+ s += "SHIFT";
+ }
+ if (ctrlDown) {
+ if (!s.isEmpty()) {
+ s += "+";
+ }
+ s += "CTRL";
+ }
+ if (altDown) {
+ if (!s.isEmpty()) {
+ s += "+";
+ }
+ s += "ALT";
+ }
+ if (!s.isEmpty()) {
+ s += "+";
+ }
+ s += keyCodesToNames.get(key);
+
+ return s;
+ }
+ }
+
+ public static final int PRIORITY_LOW = 1;
+
+ public static final int PRIORITY_MEDIUM = 2;
+
+ public static final int PRIORITY_TOP = 3;
+
+ /**
+ * Initializes menuBuilder
+ */
+ public void initMenu();
+
+ /**
+ * Adds separator
+ *
+ * @param parentPath Parent menu path
+ */
+ public void addSeparator(String parentPath);
+
+ /**
+ * Adds menu item
+ *
+ * @param path Path
+ * @param title Title
+ * @param icon Icon - resource name
+ * @param action Action for clicking
+ * @param priority Priority
+ * @param subloader Action which loads menu inside
+ * @param isLeaf Has no subitems?
+ * @param key
+ * @param isOptional
+ */
+ public void addMenuItem(String path, String title, String icon, ActionListener action, int priority, ActionListener subloader, boolean isLeaf, HotKey key, boolean isOptional);
+
+ /**
+ * Adds toggle item (radio/checkbox)
+ *
+ * @param path Path
+ * @param title Title
+ * @param group Group for toggling. Null = checkbox
+ * @param icon Icon - resource name
+ * @param action Action for clicking
+ * @param priority Priority
+ * @param key
+ */
+ public void addToggleMenuItem(String path, String title, String group, String icon, ActionListener action, int priority, HotKey key);
+
+ /**
+ * Test menu checked (toggle)
+ *
+ * @param path Menu path
+ * @return True when checked
+ */
+ public boolean isMenuChecked(String path);
+
+ /**
+ * Hotkey for menu
+ *
+ * @param path Menu path
+ * @return
+ */
+ public HotKey getMenuHotkey(String path);
+
+ /**
+ * Sets menu checked (toggle)
+ *
+ * @param path Menu path
+ * @param checked Checked?
+ */
+ public void setMenuChecked(String path, boolean checked);
+
+ /**
+ * Sets checked item from group
+ *
+ * @param group Group name
+ * @param selected Selected path
+ */
+ public void setGroupSelection(String group, String selected);
+
+ /**
+ * Gets selected path from group
+ *
+ * @param group Group name
+ * @return Path
+ */
+ public String getGroupSelection(String group);
+
+ /**
+ * Clears menu
+ *
+ * @param path Path of menu
+ */
+ public void clearMenu(String path);
+
+ /**
+ * Sets enabled property of menu
+ *
+ * @param path Menu path
+ * @param enabled Enabled?
+ */
+ public void setMenuEnabled(String path, boolean enabled);
+
+ /**
+ * Finished creating menu
+ *
+ * @param path Menu path
+ */
+ public void finishMenu(String path);
+
+ /**
+ * Does this builder support actions for menus? (not menuitems)
+ *
+ * @return True if supports
+ */
+ public boolean supportsMenuAction();
+
+ /**
+ * Does this builder support application menu (Path "_/...")
+ *
+ * @return True if supports
+ */
+ public boolean supportsAppMenu();
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java
index b34802995..add04b510 100644
--- a/src/com/jpexs/decompiler/flash/gui/View.java
+++ b/src/com/jpexs/decompiler/flash/gui/View.java
@@ -1,768 +1,768 @@
-/*
- * Copyright (C) 2010-2016 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.configuration.ConfigurationItem;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Desktop;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.SystemColor;
-import java.awt.TexturePaint;
-import java.awt.Window;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.WindowEvent;
-import java.awt.image.BufferedImage;
-import java.awt.image.VolatileImage;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.imageio.ImageIO;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JEditorPane;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.JRootPane;
-import javax.swing.JTable;
-import javax.swing.JTree;
-import javax.swing.KeyStroke;
-import javax.swing.LookAndFeel;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.plaf.FontUIResource;
-import javax.swing.plaf.basic.BasicColorChooserUI;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.DefaultTableColumnModel;
-import javax.swing.table.TableCellRenderer;
-import javax.swing.table.TableColumn;
-import javax.swing.table.TableModel;
-import javax.swing.text.JTextComponent;
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreePath;
-import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon;
-import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
-import org.pushingpixels.substance.api.ComponentState;
-import org.pushingpixels.substance.api.DecorationAreaType;
-import org.pushingpixels.substance.api.SubstanceColorScheme;
-import org.pushingpixels.substance.api.SubstanceConstants;
-import org.pushingpixels.substance.api.SubstanceLookAndFeel;
-import org.pushingpixels.substance.api.SubstanceSkin;
-import org.pushingpixels.substance.api.fonts.FontPolicy;
-import org.pushingpixels.substance.api.fonts.FontSet;
-import org.pushingpixels.substance.api.skin.SubstanceOfficeBlue2007LookAndFeel;
-import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
-
-/**
- * Contains methods for GUI
- *
- * @author JPEXS
- */
-public class View {
-
- public static Color getDefaultBackgroundColor() {
- if (Configuration.useRibbonInterface.get()) {
- return SubstanceLookAndFeel.getCurrentSkin().getColorScheme(DecorationAreaType.GENERAL, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getBackgroundFillColor();
- } else {
- return SystemColor.control;
- }
- }
-
- private static Color swfBackgroundColor = null;
-
- public static void setSwfBackgroundColor(Color swfBackgroundColor) {
- View.swfBackgroundColor = swfBackgroundColor;
- }
-
- public static Color getSwfBackgroundColor() {
- if (swfBackgroundColor == null) {
- return getDefaultBackgroundColor();
- }
- return swfBackgroundColor;
- }
-
- private static final BufferedImage transparentTexture;
-
- public static final TexturePaint transparentPaint;
-
- private static final Color transparentColor1 = new Color(0x99, 0x99, 0x99);
-
- private static final Color transparentColor2 = new Color(0x66, 0x66, 0x66);
-
- static {
- transparentTexture = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
- Graphics g = transparentTexture.getGraphics();
- g.setColor(transparentColor1);
- g.fillRect(0, 0, 16, 16);
- g.setColor(transparentColor2);
- g.fillRect(0, 0, 8, 8);
- g.fillRect(8, 8, 8, 8);
- transparentPaint = new TexturePaint(View.transparentTexture, new Rectangle(0, 0, transparentTexture.getWidth(), transparentTexture.getHeight()));
- }
-
- /**
- * Sets windows Look and Feel
- */
- public static void setLookAndFeel() {
-
- //Save default font for Chinese characters
- final Font defaultFont = (new JLabel()).getFont();
- try {
-
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-
- } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) {
- }
-
- try {
- LookAndFeel oldLookAndFeel = UIManager.getLookAndFeel();
- if (!(oldLookAndFeel instanceof SubstanceOfficeBlue2007LookAndFeel)) {
- UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel());
- oldLookAndFeel.uninitialize();
- }
-
- SubstanceSkin currentSkin = SubstanceLookAndFeel.getCurrentSkin();
- if (currentSkin != null) {
- String currentSkinName = currentSkin.getClass().getName();
- String newSkinName = Configuration.guiSkin.get();
- if (!currentSkinName.equals(newSkinName)) {
- SubstanceLookAndFeel.setSkin(newSkinName);
- }
- } else {
- Logger.getLogger(View.class.getName()).log(Level.SEVERE, "Current skin is null");
- SubstanceLookAndFeel.setSkin("com.jpexs.decompiler.flash.gui.OceanicSkin");
- }
-
- UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, 0.999);//This works for not changing labels color and not changing Dialogs title
- UIManager.put("Tree.expandedIcon", getIcon("expand16"));
- UIManager.put("Tree.collapsedIcon", getIcon("collapse16"));
- UIManager.put("ColorChooserUI", BasicColorChooserUI.class.getName());
- UIManager.put("ColorChooser.swatchesRecentSwatchSize", new Dimension(20, 20));
- UIManager.put("ColorChooser.swatchesSwatchSize", new Dimension(20, 20));
- UIManager.put("RibbonApplicationMenuPopupPanelUI", MyRibbonApplicationMenuPopupPanelUI.class.getName());
- UIManager.put("RibbonApplicationMenuButtonUI", MyRibbonApplicationMenuButtonUI.class.getName());
- UIManager.put("ProgressBarUI", MyProgressBarUI.class.getName());
- UIManager.put("TextField.background", Color.white);
- UIManager.put("FormattedTextField.background", Color.white);
- UIManager.put("CommandButtonUI", MyCommandButtonUI.class.getName());
-
- FontPolicy pol = SubstanceLookAndFeel.getFontPolicy();
- final FontSet fs = pol.getFontSet("Substance", null);
-
- //Restore default font for chinese characters
- SubstanceLookAndFeel.setFontPolicy(new FontPolicy() {
-
- private final FontSet fontSet = new FontSet() {
-
- private FontUIResource controlFont;
-
- private FontUIResource menuFont;
-
- private FontUIResource titleFont;
-
- private FontUIResource windowTitleFont;
-
- private FontUIResource smallFont;
-
- private FontUIResource messageFont;
-
- @Override
- public FontUIResource getControlFont() {
- if (controlFont == null) {
- FontUIResource f = fs.getControlFont();
- controlFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return controlFont;
- }
-
- @Override
- public FontUIResource getMenuFont() {
- if (menuFont == null) {
- FontUIResource f = fs.getMenuFont();
- menuFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return menuFont;
- }
-
- @Override
- public FontUIResource getTitleFont() {
- if (titleFont == null) {
- FontUIResource f = fs.getTitleFont();
- titleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return titleFont;
- }
-
- @Override
- public FontUIResource getWindowTitleFont() {
- if (windowTitleFont == null) {
- FontUIResource f = fs.getWindowTitleFont();
- windowTitleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return windowTitleFont;
- }
-
- @Override
- public FontUIResource getSmallFont() {
- if (smallFont == null) {
- FontUIResource f = fs.getSmallFont();
- smallFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return smallFont;
- }
-
- @Override
- public FontUIResource getMessageFont() {
- if (messageFont == null) {
- FontUIResource f = fs.getMessageFont();
- messageFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
- }
- return messageFont;
- }
- };
-
- @Override
- public FontSet getFontSet(String string, UIDefaults uid) {
- return fontSet;
- }
- });
- } catch (UnsupportedLookAndFeelException ex) {
- Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- UIManager.put(SubstanceLookAndFeel.TABBED_PANE_CONTENT_BORDER_KIND, SubstanceConstants.TabContentPaneBorderKind.SINGLE_FULL);
-
- JFrame.setDefaultLookAndFeelDecorated(true);
- JDialog.setDefaultLookAndFeelDecorated(true);
- }
-
- /**
- * Loads image from resources
- *
- * @param name Name of the image
- * @return loaded Image
- */
- public static BufferedImage loadImage(String name) {
- URL imageURL = View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + name + ".png");
- try {
- return ImageIO.read(imageURL);
- } catch (IOException ex) {
- return null;
- }
- }
-
- /**
- * Sets icon of specified frame to ASDec icon
- *
- * @param f Frame to set icon in
- */
- public static void setWindowIcon(Window f) {
- if (Configuration.useRibbonInterface.get()) {
- List images = new ArrayList<>();
- MyResizableIcon[] icons = MyRibbonApplicationMenuButtonUI.getIcons();
- MyResizableIcon icon = icons[1];
- int[] sizes = new int[]{256, 128, 64, 42, 40, 32, 20, 16};
- for (int size : sizes) {
- icon.setIconSize(size, size);
- BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_4BYTE_ABGR);
- icon.paintIcon(f, bi.getGraphics(), 0, 0);
- images.add(bi);
- }
- f.setIconImages(images);
- } else {
- List images = new ArrayList<>();
- images.add(loadImage("icon16"));
- images.add(loadImage("icon32"));
- images.add(loadImage("icon48"));
- images.add(loadImage("icon256"));
- f.setIconImages(images);
- }
- }
-
- /**
- * Centers specified frame on the screen
- *
- * @param f Frame to center on the screen
- */
- public static void centerScreen(Window f) {
- centerScreen(f, 0); // todo, set screen to the currently active screen instead of the first screen in a multi screen setup, (maybe by using the screen where the main window is now classic or ribbon?)
- }
-
- public static void centerScreen(Window f, int screen) {
-
- GraphicsDevice[] allDevices = getEnv().getScreenDevices();
- int topLeftX, topLeftY, screenX, screenY, windowPosX, windowPosY;
-
- if (screen < allDevices.length && screen > -1) {
- topLeftX = allDevices[screen].getDefaultConfiguration().getBounds().x;
- topLeftY = allDevices[screen].getDefaultConfiguration().getBounds().y;
-
- screenX = allDevices[screen].getDefaultConfiguration().getBounds().width;
- screenY = allDevices[screen].getDefaultConfiguration().getBounds().height;
- } else {
- topLeftX = allDevices[0].getDefaultConfiguration().getBounds().x;
- topLeftY = allDevices[0].getDefaultConfiguration().getBounds().y;
-
- screenX = allDevices[0].getDefaultConfiguration().getBounds().width;
- screenY = allDevices[0].getDefaultConfiguration().getBounds().height;
- }
-
- windowPosX = ((screenX - f.getWidth()) / 2) + topLeftX;
- windowPosY = ((screenY - f.getHeight()) / 2) + topLeftY;
-
- f.setLocation(windowPosX, windowPosY);
- }
-
- public static ImageIcon getIcon(String name, int size) {
- ImageIcon icon = getIcon(getPrefferedIconName(name, size));
- if (icon.getIconWidth() == size && icon.getIconHeight() == size) {
- return icon;
- }
- icon.getImage();
- BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
- bi.createGraphics().drawImage(icon.getImage(), 0, 0, size, size, null, null);
- return new ImageIcon(bi);
- }
-
- public static ImageIcon getIcon(String name) {
- return new ImageIcon(View.class.getClassLoader().getResource("com/jpexs/decompiler/flash/gui/graphics/" + name + ".png"));
- }
-
- private static final KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
-
- private static final String dispatchWindowClosingActionMapKey = "com.jpexs.dispatch:WINDOW_CLOSING";
-
- public static void installEscapeCloseOperation(final JDialog dialog) {
- Action dispatchClosing = new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent event) {
- dialog.dispatchEvent(new WindowEvent(
- dialog, WindowEvent.WINDOW_CLOSING));
- }
- };
- JRootPane root = dialog.getRootPane();
- root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
- escapeStroke, dispatchWindowClosingActionMapKey);
- root.getActionMap().put(dispatchWindowClosingActionMapKey, dispatchClosing);
- }
-
- public static boolean iconExists(String resource) {
- return View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + resource + ".png") != null;
- }
-
- private static String getPrefferedIconName(String resource, int preferredSize) {
- Matcher m = Pattern.compile("(.*[^0-9])([0-9]+)").matcher(resource);
- if (m.matches()) {
- int origSize = Integer.parseInt(m.group(2));
- String name = m.group(1);
- if (origSize != preferredSize) {
- if (iconExists(name + preferredSize)) {
- return name + preferredSize;
- }
- }
- }
- return resource;
- }
-
- public static ImageWrapperResizableIcon getResizableIcon(String resource, int preferredSize) {
- return getResizableIcon(getPrefferedIconName(resource, preferredSize));
- }
-
- public static ImageWrapperResizableIcon getResizableIcon(String resource) {
- return ImageWrapperResizableIcon.getIcon(View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + resource + ".png"), new Dimension(256, 256));
- }
-
- public static MyResizableIcon getMyResizableIcon(String resource) {
- try {
- return new MyResizableIcon(ImageIO.read(View.class.getResourceAsStream("/com/jpexs/decompiler/flash/gui/graphics/" + resource + ".png")));
- } catch (IOException ex) {
- Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
- return null;
- }
- }
-
- public static void execInEventDispatch(Runnable r) {
- if (SwingUtilities.isEventDispatchThread()) {
- r.run();
- } else {
- try {
- SwingUtilities.invokeAndWait(r);
- } catch (InterruptedException ex) {
- } catch (InvocationTargetException ex) {
- Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public static void execInEventDispatchLater(Runnable r) {
- if (SwingUtilities.isEventDispatchThread()) {
- r.run();
- } else {
- SwingUtilities.invokeLater(r);
- }
- }
-
- public static int showOptionDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageType, final Icon icon, final Object[] options, final Object initialValue) {
- final int[] ret = new int[1];
- execInEventDispatch(() -> {
- ret[0] = JOptionPane.showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, initialValue);
- });
- return ret[0];
- }
-
- public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) {
- return showConfirmDialog(parentComponent, message, title, optionType, JOptionPane.PLAIN_MESSAGE);
- }
-
- public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageTyp) {
- final int[] ret = new int[1];
- execInEventDispatch(() -> {
- ret[0] = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageTyp);
- });
- return ret[0];
- }
-
- public static int showConfirmDialog(Component parentComponent, String message, String title, int optionType, ConfigurationItem showAgainConfig, int defaultOption) {
- return showConfirmDialog(parentComponent, message, title, optionType, JOptionPane.PLAIN_MESSAGE, showAgainConfig, defaultOption);
- }
-
- public static int showConfirmDialog(final Component parentComponent, String message, final String title, final int optionType, final int messageType, ConfigurationItem showAgainConfig, int defaultOption) {
-
- JCheckBox donotShowAgainCheckBox = null;
- JPanel warPanel = null;
- if (showAgainConfig != null) {
- if (!showAgainConfig.get()) {
- return defaultOption;
- }
-
- JLabel warLabel = new JLabel("" + message.replace("\r\n", "
") + "");
- warPanel = new JPanel(new BorderLayout());
- warPanel.add(warLabel, BorderLayout.CENTER);
- donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain"));
- warPanel.add(donotShowAgainCheckBox, BorderLayout.SOUTH);
- }
-
- final int[] ret = new int[1];
- final Object messageObj = warPanel == null ? message : warPanel;
- execInEventDispatch(() -> {
- ret[0] = JOptionPane.showConfirmDialog(parentComponent, messageObj, title, optionType, messageType);
- });
-
- if (donotShowAgainCheckBox != null) {
- showAgainConfig.set(!donotShowAgainCheckBox.isSelected());
- }
-
- return ret[0];
- }
-
- public static void showMessageDialog(final Component parentComponent, final String message, final String title, final int messageType) {
- showMessageDialog(parentComponent, message, title, messageType, null);
- }
-
- public static void showMessageDialog(final Component parentComponent, final String message, final String title, final int messageType, ConfigurationItem showAgainConfig) {
-
- execInEventDispatch(() -> {
- Object msg = message;
- JCheckBox donotShowAgainCheckBox = null;
- if (showAgainConfig != null) {
- if (!showAgainConfig.get()) {
- return;
- }
-
- JLabel warLabel = new JLabel("" + message.replace("\r\n", "
") + "");
- final JPanel warPanel = new JPanel(new BorderLayout());
- warPanel.add(warLabel, BorderLayout.CENTER);
- donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain"));
- warPanel.add(donotShowAgainCheckBox, BorderLayout.SOUTH);
- msg = warPanel;
- }
- final Object fmsg = msg;
-
- JOptionPane.showMessageDialog(parentComponent, fmsg, title, messageType);
- if (donotShowAgainCheckBox != null) {
- showAgainConfig.set(!donotShowAgainCheckBox.isSelected());
- }
- });
- }
-
- public static void showMessageDialog(final Component parentComponent, final Object message) {
- execInEventDispatch(() -> {
- JOptionPane.showMessageDialog(parentComponent, message);
- });
- }
-
- public static String showInputDialog(final Object message, final Object initialSelection) {
- final String[] ret = new String[1];
- execInEventDispatch(() -> {
- ret[0] = JOptionPane.showInputDialog(message, initialSelection);
- });
- return ret[0];
- }
-
- public static SubstanceColorScheme getColorScheme() {
- return SubstanceColorSchemeUtilities.getActiveColorScheme(new JButton(), ComponentState.ENABLED);
- }
-
- public static void refreshTree(JTree tree, TreeModel model) {
- List> expandedNodes = getExpandedNodes(tree);
- tree.setModel(model);
- expandTreeNodes(tree, expandedNodes);
- }
-
- public static List> getExpandedNodes(JTree tree) {
- List> expandedNodes = new ArrayList<>();
- int rowCount = tree.getRowCount();
- for (int i = 0; i < rowCount; i++) {
- try {
- TreePath path = tree.getPathForRow(i);
- if (tree.isExpanded(path)) {
- List pathAsStringList = new ArrayList<>();
- for (Object pathCompnent : path.getPath()) {
- pathAsStringList.add(pathCompnent.toString());
- }
- expandedNodes.add(pathAsStringList);
- }
- } catch (IndexOutOfBoundsException | NullPointerException ex) {
- // TreeNode was removed, ignore
- }
- }
- return expandedNodes;
- }
-
- public static void expandTreeNodes(JTree tree, List> pathsToExpand) {
- for (List pathAsStringList : pathsToExpand) {
- expandTreeNode(tree, pathAsStringList);
- }
- }
-
- private static TreePath expandTreeNode(JTree tree, List pathAsStringList) {
- TreePath tp = getTreePathByPathStrings(tree, pathAsStringList);
- tree.expandPath(tp);
- return tp;
- }
-
- public static TreePath getTreePathByPathStrings(JTree tree, List pathAsStringList) {
- TreeModel model = tree.getModel();
- if (model == null) {
- return null;
- }
-
- Object node = model.getRoot();
-
- if (pathAsStringList.isEmpty()) {
- return null;
- }
- if (!pathAsStringList.get(0).equals(node.toString())) {
- return null;
- }
-
- List