diff --git a/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 9a6e3b7e3..ced6ed93f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -79,6 +79,8 @@ public class Configuration { public static final ConfigurationItem decimalAddress = null; @ConfigurationDefaultBoolean(false) public static final ConfigurationItem showAllAddresses = null; + @ConfigurationDefaultBoolean(true) + public static final ConfigurationItem useRibbonInterface = null; /** * Debug mode = throwing an error when comparing original file and diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/AppFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/AppFrame.java index 90482a55b..6e75882c4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/AppFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/AppFrame.java @@ -25,9 +25,14 @@ import javax.swing.JFrame; */ public abstract class AppFrame extends JFrame { - private ResourceBundle resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass())); + private ResourceBundle resourceBundle; public AppFrame() { + if (getClass().equals(MainFrameClassic.class)) { + resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(MainFrame.class)); + } else { + resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass())); + } } public String translate(String key) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/AppRibbonFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/AppRibbonFrame.java index 4cbb042f4..28e492ec9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/AppRibbonFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/AppRibbonFrame.java @@ -25,9 +25,14 @@ import org.pushingpixels.flamingo.api.ribbon.JRibbonFrame; */ public abstract class AppRibbonFrame extends JRibbonFrame { - private ResourceBundle resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass())); + private ResourceBundle resourceBundle; public AppRibbonFrame() { + if (getClass().equals(MainFrameRibbon.class)) { + resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(MainFrame.class)); + } else { + resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass())); + } } public String translate(String key) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 03d4b8d8c..cec012725 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -54,7 +54,7 @@ public class FontPanel extends JPanel implements ActionListener { static final String ACTION_FONT_EMBED = "FONTEMBED"; static final String ACTION_FONT_ADD_CHARS = "FONTADDCHARS"; - private MainFrame mainFrame; + private MainFramePanel mainFramePanel; public Map sourceFontsMap = new HashMap<>(); @@ -69,8 +69,8 @@ public class FontPanel extends JPanel implements ActionListener { private ComponentListener fontChangeList; private JComboBox fontSelection; - public FontPanel(MainFrame mainFrame) { - this.mainFrame = mainFrame; + public FontPanel(MainFramePanel mainFramePanel) { + this.mainFramePanel = mainFramePanel; createFontPanel(); } @@ -181,8 +181,8 @@ public class FontPanel extends JPanel implements ActionListener { fontSelection.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - if (mainFrame.oldValue instanceof FontTag) { - FontTag f = (FontTag) mainFrame.oldValue; + if (mainFramePanel.oldValue instanceof FontTag) { + FontTag f = (FontTag) mainFramePanel.oldValue; sourceFontsMap.put(f.getFontId(), (String) fontSelection.getSelectedItem()); } } @@ -207,11 +207,11 @@ public class FontPanel extends JPanel implements ActionListener { } private String translate(String key) { - return mainFrame.translate(key); + return mainFramePanel.translate(key); } private void fontAddChars(FontTag ft, Set selChars, String selFont) { - FontTag f = (FontTag) mainFrame.oldValue; + FontTag f = (FontTag) mainFramePanel.oldValue; SWF swf = ft.getSwf(); String oldchars = f.getCharacters(swf.tags); for (int ic : selChars) { @@ -280,30 +280,30 @@ public class FontPanel extends JPanel implements ActionListener { public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { case ACTION_FONT_EMBED: - if (mainFrame.oldValue instanceof FontTag) { - FontEmbedDialog fed = new FontEmbedDialog(fontSelection.getSelectedItem().toString(), fontAddCharactersField.getText(), ((FontTag) mainFrame.oldValue).getFontStyle()); + if (mainFramePanel.oldValue instanceof FontTag) { + FontEmbedDialog fed = new FontEmbedDialog(fontSelection.getSelectedItem().toString(), fontAddCharactersField.getText(), ((FontTag) mainFramePanel.oldValue).getFontStyle()); if (fed.display()) { Set selChars = fed.getSelectedChars(); if (!selChars.isEmpty()) { String selFont = fed.getSelectedFont(); fontSelection.setSelectedItem(selFont); - fontAddChars((FontTag) mainFrame.oldValue, selChars, selFont); + fontAddChars((FontTag) mainFramePanel.oldValue, selChars, selFont); fontAddCharactersField.setText(""); - mainFrame.reload(true); + mainFramePanel.reload(true); } } } break; case ACTION_FONT_ADD_CHARS: String newchars = fontAddCharactersField.getText(); - if (mainFrame.oldValue instanceof FontTag) { + if (mainFramePanel.oldValue instanceof FontTag) { Set selChars = new TreeSet<>(); for (int c = 0; c < newchars.length(); c++) { selChars.add(newchars.codePointAt(c)); } - fontAddChars((FontTag) mainFrame.oldValue, selChars, fontSelection.getSelectedItem().toString()); + fontAddChars((FontTag) mainFramePanel.oldValue, selChars, fontSelection.getSelectedItem().toString()); fontAddCharactersField.setText(""); - mainFrame.reload(true); + mainFramePanel.reload(true); } break; } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 3bb2e2ea9..c8cf9a381 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -148,11 +148,11 @@ public class Main { @Override public void run() { if (mainFrame != null) { - mainFrame.setWorkStatus(name, worker); + mainFrame.getPanel().setWorkStatus(name, worker); if (percent == -1) { - mainFrame.hidePercent(); + mainFrame.getPanel().hidePercent(); } else { - mainFrame.setPercent(percent); + mainFrame.getPanel().setPercent(percent); } } if (loadingDialog != null) { @@ -177,7 +177,7 @@ public class Main { @Override public void run() { if (mainFrame != null) { - mainFrame.setWorkStatus("", null); + mainFrame.getPanel().setWorkStatus("", null); } if (loadingDialog != null) { loadingDialog.setDetail(""); @@ -324,11 +324,15 @@ public class Main { @Override public void run() { if (mainFrame == null) { - mainFrame = new MainFrame(); + if (Configuration.useRibbonInterface.get()) { + mainFrame = new MainFrameRibbon(); + } else { + mainFrame = new MainFrameClassic(); + } } - mainFrame.load(swf1); + mainFrame.getPanel().load(swf1); if (errorState) { - mainFrame.setErrorState(); + mainFrame.getPanel().setErrorState(); } } }); @@ -356,7 +360,7 @@ public class Main { public static boolean reloadSWFs() { CancellableWorker.cancelBackgroundThreads(); if (mainFrame != null) { - mainFrame.closeAll(); + mainFrame.getPanel().closeAll(); } if (Main.sourceInfos.isEmpty()) { Cache.clearAll(); @@ -421,7 +425,7 @@ public class Main { public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) { if (mainFrame != null && !Configuration.openMultipleFiles.get()) { sourceInfos.clear(); - mainFrame.closeAll(); + mainFrame.getPanel().closeAll(); mainFrame.setVisible(false); Cache.clearAll(); System.gc(); @@ -450,7 +454,7 @@ public class Main { public static void closeFile(SWF swf) { sourceInfos.remove(swf.sourceInfo); - mainFrame.close(swf); + mainFrame.getPanel().close(swf); } public static boolean saveFileDialog(SWF swf) { @@ -586,7 +590,9 @@ public class Main { private static boolean errorState = false; private static void initGui() { - View.setLookAndFeel(); + if (Configuration.useRibbonInterface.get()) { + View.setLookAndFeel(); + } View.execInEventDispatch(new Runnable() { @Override public void run() { @@ -604,7 +610,7 @@ public class Main { if (record.getLevel() == Level.SEVERE) { errorState = true; if (mainFrame != null) { - mainFrame.setErrorState(); + mainFrame.getPanel().setErrorState(); } } } @@ -631,9 +637,13 @@ public class Main { @Override public void run() { if (mainFrame == null) { - mainFrame = new MainFrame(); + if (Configuration.useRibbonInterface.get()) { + mainFrame = new MainFrameRibbon(); + } else { + mainFrame = new MainFrameClassic(); + } if (errorState) { - mainFrame.setErrorState(); + mainFrame.getPanel().setErrorState(); } } mainFrame.setVisible(true); @@ -1033,7 +1043,7 @@ public class Main { errorState = false; if (mainFrame != null) { - mainFrame.clearErrorState(); + mainFrame.getPanel().clearErrorState(); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 5e0dcded1..2dece4258 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -16,2995 +16,15 @@ */ package com.jpexs.decompiler.flash.gui; -import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; -import com.jpexs.decompiler.flash.ApplicationInfo; -import com.jpexs.decompiler.flash.FrameNode; -import com.jpexs.decompiler.flash.PackageNode; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFOutputStream; -import com.jpexs.decompiler.flash.TagNode; -import com.jpexs.decompiler.flash.TreeElementItem; -import com.jpexs.decompiler.flash.TreeNode; -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.RenameType; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.gui.abc.ABCPanel; -import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; -import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog; -import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane; -import com.jpexs.decompiler.flash.gui.abc.TreeElement; -import com.jpexs.decompiler.flash.gui.action.ActionPanel; -import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; -import com.jpexs.decompiler.flash.gui.player.PlayerControls; -import com.jpexs.decompiler.flash.helpers.Freed; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; -import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; -import com.jpexs.decompiler.flash.tags.DefineBitsTag; -import com.jpexs.decompiler.flash.tags.DefineButton2Tag; -import com.jpexs.decompiler.flash.tags.DefineButtonTag; -import com.jpexs.decompiler.flash.tags.DefineEditTextTag; -import com.jpexs.decompiler.flash.tags.DefineFont2Tag; -import com.jpexs.decompiler.flash.tags.DefineFont3Tag; -import com.jpexs.decompiler.flash.tags.DefineFont4Tag; -import com.jpexs.decompiler.flash.tags.DefineFontTag; -import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; -import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; -import com.jpexs.decompiler.flash.tags.DefineShape2Tag; -import com.jpexs.decompiler.flash.tags.DefineShape3Tag; -import com.jpexs.decompiler.flash.tags.DefineShape4Tag; -import com.jpexs.decompiler.flash.tags.DefineShapeTag; -import com.jpexs.decompiler.flash.tags.DefineSoundTag; -import com.jpexs.decompiler.flash.tags.DefineSpriteTag; -import com.jpexs.decompiler.flash.tags.DefineText2Tag; -import com.jpexs.decompiler.flash.tags.DefineTextTag; -import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; -import com.jpexs.decompiler.flash.tags.DoActionTag; -import com.jpexs.decompiler.flash.tags.EndTag; -import com.jpexs.decompiler.flash.tags.ExportAssetsTag; -import com.jpexs.decompiler.flash.tags.JPEGTablesTag; -import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; -import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; -import com.jpexs.decompiler.flash.tags.ShowFrameTag; -import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; -import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; -import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; -import com.jpexs.decompiler.flash.tags.SymbolClassTag; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.VideoFrameTag; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.AloneTag; -import com.jpexs.decompiler.flash.tags.base.BoundedTag; -import com.jpexs.decompiler.flash.tags.base.CharacterTag; -import com.jpexs.decompiler.flash.tags.base.Container; -import com.jpexs.decompiler.flash.tags.base.ContainerItem; -import com.jpexs.decompiler.flash.tags.base.DrawableTag; -import com.jpexs.decompiler.flash.tags.base.FontTag; -import com.jpexs.decompiler.flash.tags.base.ImageTag; -import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; -import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; -import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; -import com.jpexs.decompiler.flash.tags.base.TextTag; -import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; -import com.jpexs.decompiler.flash.tags.text.ParseException; -import com.jpexs.decompiler.flash.types.GLYPHENTRY; -import com.jpexs.decompiler.flash.types.MATRIX; -import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGB; -import com.jpexs.decompiler.flash.types.TEXTRECORD; -import com.jpexs.decompiler.graph.ExportMode; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Insets; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DragGestureEvent; -import java.awt.dnd.DragGestureListener; -import java.awt.dnd.DragSource; -import java.awt.dnd.DragSourceDragEvent; -import java.awt.dnd.DragSourceDropEvent; -import java.awt.dnd.DragSourceEvent; -import java.awt.dnd.DragSourceListener; -import java.awt.dnd.DropTarget; -import java.awt.dnd.DropTargetDropEvent; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowStateListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.CancellationException; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JColorChooser; -import javax.swing.JComponent; -import javax.swing.JFileChooser; -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.JProgressBar; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.JTextField; -import javax.swing.JTree; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.filechooser.FileFilter; -import javax.swing.plaf.basic.BasicLabelUI; -import javax.swing.plaf.basic.BasicTreeUI; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; -import org.pushingpixels.flamingo.api.common.AbstractCommandButton; -import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState; -import org.pushingpixels.flamingo.api.common.CommandButtonLayoutManager; -import org.pushingpixels.flamingo.api.common.icon.ResizableIcon; -import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton; - /** * * @author JPEXS */ -public final class MainFrame extends AppRibbonFrame implements ActionListener, TreeSelectionListener, Freed { - - private List swfs; - private ABCPanel abcPanel; - private ActionPanel actionPanel; - private JPanel welcomePanel; - private MainFrameStatusPanel statusPanel; - private MainFrameRibbon mainRibbon; - private FontPanel fontPanel; - private JProgressBar progressBar = new JProgressBar(0, 100); - private DeobfuscationDialog deobfuscationDialog; - public JTree tagTree; - private FlashPlayerPanel flashPanel; - private JPanel contentPanel; - private JPanel displayPanel; - private ImagePanel imagePanel; - private ImagePanel previewImagePanel; - private SWFPreviwPanel swfPreviewPanel; - private boolean isWelcomeScreen = true; - private static final String CARDFLASHPANEL = "Flash card"; - private static final String CARDSWFPREVIEWPANEL = "SWF card"; - private static final String CARDDRAWPREVIEWPANEL = "Draw card"; - private static final String CARDIMAGEPANEL = "Image card"; - private static final String CARDEMPTYPANEL = "Empty card"; - private static final String CARDACTIONSCRIPTPANEL = "ActionScript card"; - private static final String CARDACTIONSCRIPT3PANEL = "ActionScript3 card"; - private static final String DETAILCARDAS3NAVIGATOR = "Traits list"; - private static final String DETAILCARDEMPTYPANEL = "Empty card"; - private static final String CARDTEXTPANEL = "Text card"; - private static final String CARDFONTPANEL = "Font card"; - private static final String FLASH_VIEWER_CARD = "FLASHVIEWER"; - private static final String INTERNAL_VIEWER_CARD = "INTERNALVIEWER"; - private static final String SPLIT_PANE1 = "SPLITPANE1"; - private static final String WELCOME_PANEL = "WELCOMEPANEL"; - private LineMarkedEditorPane textValue; - private JSplitPane splitPane1; - private JSplitPane splitPane2; - private boolean splitsInited = false; - private JPanel detailPanel; - private JTextField filterField = new MyTextField(""); - private JPanel searchPanel; - private JPanel displayWithPreview; - private JButton textSaveButton; - private JButton textEditButton; - private JButton textCancelButton; - private JPanel parametersPanel; - private JSplitPane previewSplitPane; - private JButton imageReplaceButton; - private JPanel imageButtonsPanel; - private PlayerControls flashControls; - private ImagePanel internelViewerPanel; - private JPanel viewerCards; - private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); - private CancellableWorker setSourceWorker; - public TreeNode oldValue; - private File tempFile; - - private static final String ACTION_SELECT_COLOR = "SELECTCOLOR"; - private static final String ACTION_REPLACE_IMAGE = "REPLACEIMAGE"; - private static final String ACTION_REPLACE_BINARY = "REPLACEBINARY"; - private static final String ACTION_REMOVE_ITEM = "REMOVEITEM"; - private static final String ACTION_EDIT_TEXT = "EDITTEXT"; - private static final String ACTION_CANCEL_TEXT = "CANCELTEXT"; - private static final String ACTION_SAVE_TEXT = "SAVETEXT"; - private static final String ACTION_CLOSE_SWF = "CLOSESWF"; +public interface MainFrame { - public void setPercent(int percent) { - progressBar.setValue(percent); - progressBar.setVisible(true); - } - - public void hidePercent() { - if (progressBar.isVisible()) { - progressBar.setVisible(false); - } - } - - static { - try { - File.createTempFile("temp", ".swf").delete(); //First call to this is slow, so make it first - } catch (IOException ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private static void addTab(JTabbedPane tabbedPane, Component tab, String title, Icon icon) { - tabbedPane.add(tab); - - JLabel lbl = new JLabel(title); - lbl.setIcon(icon); - lbl.setIconTextGap(5); - lbl.setHorizontalTextPosition(SwingConstants.RIGHT); - - tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, lbl); - } - - public void setStatus(String s) { - statusPanel.setStatus(s); - } - - public void setWorkStatus(String s, CancellableWorker worker) { - statusPanel.setWorkStatus(s, worker); - } - - private void createContextMenu() { - final JPopupMenu contextPopupMenu = new JPopupMenu(); - final JMenuItem removeMenuItem = new JMenuItem(translate("contextmenu.remove")); - removeMenuItem.addActionListener(this); - removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM); - final JMenuItem exportSelectionMenuItem = new JMenuItem(translate("menu.file.export.selection")); - exportSelectionMenuItem.setActionCommand(MainFrameRibbon.ACTION_EXPORT_SEL); - exportSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(exportSelectionMenuItem); - final JMenuItem replaceImageSelectionMenuItem = new JMenuItem(translate("button.replace")); - replaceImageSelectionMenuItem.setActionCommand(ACTION_REPLACE_IMAGE); - replaceImageSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(replaceImageSelectionMenuItem); - final JMenuItem replaceBinarySelectionMenuItem = new JMenuItem(translate("button.replace")); - replaceBinarySelectionMenuItem.setActionCommand(ACTION_REPLACE_BINARY); - replaceBinarySelectionMenuItem.addActionListener(this); - contextPopupMenu.add(replaceBinarySelectionMenuItem); - final JMenuItem closeSelectionMenuItem = new JMenuItem(translate("contextmenu.closeSwf")); - closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF); - closeSelectionMenuItem.addActionListener(this); - contextPopupMenu.add(closeSelectionMenuItem); - - contextPopupMenu.add(removeMenuItem); - tagTree.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (SwingUtilities.isRightMouseButton(e)) { - - int row = tagTree.getClosestRowForLocation(e.getX(), e.getY()); - int[] selectionRows = tagTree.getSelectionRows(); - if (!Helper.contains(selectionRows, row)) { - tagTree.setSelectionRow(row); - } - - TreePath[] paths = tagTree.getSelectionPaths(); - if (paths == null || paths.length == 0) { - return; - } - boolean allSelectedIsTag = true; - for (TreePath treePath : paths) { - Object tagObj = treePath.getLastPathComponent(); - - if (tagObj instanceof TagNode) { - Object tag = ((TagNode) tagObj).tag; - if (!(tag instanceof Tag)) { - allSelectedIsTag = false; - break; - } - } else { - allSelectedIsTag = false; - } - } - - replaceImageSelectionMenuItem.setVisible(false); - replaceBinarySelectionMenuItem.setVisible(false); - closeSelectionMenuItem.setVisible(false); - - if (paths.length == 1) { - Object tagObj = paths[0].getLastPathComponent(); - - if (tagObj instanceof TagNode) { - Object tag = ((TagNode) tagObj).tag; - - if (tag instanceof ImageTag && ((ImageTag) tag).importSupported()) { - replaceImageSelectionMenuItem.setVisible(true); - } - if (tag instanceof DefineBinaryDataTag) { - replaceBinarySelectionMenuItem.setVisible(true); - } - } - - if (tagObj instanceof SWFRoot) { - closeSelectionMenuItem.setVisible(true); - } - } - - removeMenuItem.setVisible(allSelectedIsTag); - contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); - } - } - }); - } - - private JPanel createWelcomePanel() { - JPanel welcomePanel = new JPanel(); - welcomePanel.setLayout(new BoxLayout(welcomePanel, BoxLayout.Y_AXIS)); - JLabel welcomeToLabel = new JLabel(translate("startup.welcometo")); - welcomeToLabel.setFont(welcomeToLabel.getFont().deriveFont(40)); - welcomeToLabel.setAlignmentX(0.5f); - JPanel appNamePanel = new JPanel(new FlowLayout()); - JLabel jpLabel = new JLabel("JPEXS "); - jpLabel.setAlignmentX(0.5f); - jpLabel.setForeground(new Color(0, 0, 160)); - jpLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); - jpLabel.setHorizontalAlignment(SwingConstants.CENTER); - appNamePanel.add(jpLabel); - - JLabel ffLabel = new JLabel("Free Flash "); - ffLabel.setAlignmentX(0.5f); - ffLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); - ffLabel.setHorizontalAlignment(SwingConstants.CENTER); - appNamePanel.add(ffLabel); - - JLabel decLabel = new JLabel("Decompiler"); - decLabel.setAlignmentX(0.5f); - decLabel.setForeground(Color.red); - decLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); - decLabel.setHorizontalAlignment(SwingConstants.CENTER); - appNamePanel.add(decLabel); - appNamePanel.setAlignmentX(0.5f); - welcomePanel.add(Box.createGlue()); - welcomePanel.add(welcomeToLabel); - welcomePanel.add(appNamePanel); - JLabel startLabel = new JLabel(translate("startup.selectopen")); - startLabel.setAlignmentX(0.5f); - startLabel.setFont(startLabel.getFont().deriveFont(30)); - welcomePanel.add(startLabel); - welcomePanel.add(Box.createGlue()); - return welcomePanel; - } - - private JPanel createImagesCard() { - JPanel imagesCard = new JPanel(new BorderLayout()); - imagePanel = new ImagePanel(); - imagesCard.add(imagePanel, BorderLayout.CENTER); - - imageReplaceButton = new JButton(translate("button.replace"), View.getIcon("edit16")); - imageReplaceButton.setMargin(new Insets(3, 3, 3, 10)); - imageReplaceButton.setActionCommand(ACTION_REPLACE_IMAGE); - imageReplaceButton.addActionListener(this); - imageButtonsPanel = new JPanel(new FlowLayout()); - imageButtonsPanel.add(imageReplaceButton); - - imagesCard.add(imageButtonsPanel, BorderLayout.SOUTH); - return imagesCard; - } - - private void showHideImageReplaceButton(boolean show) { - imageReplaceButton.setVisible(show); - setImageButtonPanelVisibility(); - } - - private void setImageButtonPanelVisibility() { - // hide button panel when no button is visible - // now there is only one button, later add here the other buttons - boolean visible = imageReplaceButton.isVisible(); - imageButtonsPanel.setVisible(visible); - } - - public MainFrame() { - super(); - - try { - flashPanel = new FlashPlayerPanel(this); - } catch (FlashUnsupportedException fue) { - } - - boolean externalFlashPlayerUnavailable = flashPanel == null; - mainRibbon = new MainFrameRibbon(this, getRibbon(), externalFlashPlayerUnavailable); - - int w = Configuration.guiWindowWidth.get(); - int h = Configuration.guiWindowHeight.get(); - Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - if (w > dim.width) { - w = dim.width; - } - if (h > dim.height) { - h = dim.height; - } - setSize(w, h); - - boolean maximizedHorizontal = Configuration.guiWindowMaximizedHorizontal.get(); - boolean maximizedVertical = Configuration.guiWindowMaximizedVertical.get(); - - int state = 0; - if (maximizedHorizontal) { - state |= JFrame.MAXIMIZED_HORIZ; - } - if (maximizedVertical) { - state |= JFrame.MAXIMIZED_VERT; - } - setExtendedState(state); - - View.setWindowIcon(this); - addWindowStateListener(new WindowStateListener() { - @Override - public void windowStateChanged(WindowEvent e) { - int state = e.getNewState(); - Configuration.guiWindowMaximizedHorizontal.set((state & JFrame.MAXIMIZED_HORIZ) == JFrame.MAXIMIZED_HORIZ); - Configuration.guiWindowMaximizedVertical.set((state & JFrame.MAXIMIZED_VERT) == JFrame.MAXIMIZED_VERT); - } - }); - addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - int state = getExtendedState(); - if ((state & JFrame.MAXIMIZED_HORIZ) == 0) { - Configuration.guiWindowWidth.set(getWidth()); - } - if ((state & JFrame.MAXIMIZED_VERT) == 0) { - Configuration.guiWindowHeight.set(getHeight()); - } - } - }); - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - if (Main.proxyFrame != null) { - if (Main.proxyFrame.isVisible()) { - return; - } - } - if (Main.loadFromMemoryFrame != null) { - if (Main.loadFromMemoryFrame.isVisible()) { - return; - } - } - if (Main.loadFromCacheFrame != null) { - if (Main.loadFromCacheFrame.isVisible()) { - return; - } - } - Main.exit(); - } - }); - setTitle(ApplicationInfo.applicationVerName); - - swfs = new ArrayList<>(); - java.awt.Container cnt = getContentPane(); - cnt.setLayout(new BorderLayout()); - cnt.add(getRibbon(), BorderLayout.NORTH); - - detailPanel = new JPanel(); - detailPanel.setLayout(new CardLayout()); - JPanel whitePanel = new JPanel(); - whitePanel.setBackground(Color.white); - detailPanel.add(whitePanel, DETAILCARDEMPTYPANEL); - CardLayout cl2 = (CardLayout) (detailPanel.getLayout()); - cl2.show(detailPanel, DETAILCARDEMPTYPANEL); - - UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName()); - tagTree = new JTree((TreeModel) null); - tagTree.setRootVisible(false); - tagTree.addTreeSelectionListener(this); - tagTree.setBackground(Color.white); - tagTree.setUI(new BasicTreeUI() { - @Override - public void paint(Graphics g, JComponent c) { - setHashColor(Color.gray); - super.paint(g, c); - } - }); - - - - DragSource dragSource = DragSource.getDefaultDragSource(); - dragSource.createDefaultDragGestureRecognizer(tagTree, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() { - @Override - public void dragGestureRecognized(DragGestureEvent dge) { - dge.startDrag(DragSource.DefaultCopyDrop, new Transferable() { - @Override - public DataFlavor[] getTransferDataFlavors() { - return new DataFlavor[]{DataFlavor.javaFileListFlavor}; - } - - @Override - public boolean isDataFlavorSupported(DataFlavor flavor) { - return flavor.equals(DataFlavor.javaFileListFlavor); - } - - @Override - public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { - if (flavor.equals(DataFlavor.javaFileListFlavor)) { - List files = new ArrayList<>(); - String tempDir = System.getProperty("java.io.tmpdir"); - if (!tempDir.endsWith(File.separator)) { - tempDir += File.separator; - } - Random rnd = new Random(); - tempDir += "ffdec" + File.separator + "export" + File.separator + System.currentTimeMillis() + "_" + rnd.nextInt(1000); - File fTempDir = new File(tempDir); - if (!fTempDir.exists()) { - if (!fTempDir.mkdirs()) { - if (!fTempDir.exists()) { - throw new IOException("cannot create directory " + fTempDir); - } - } - } - final ExportDialog export = new ExportDialog(); - - try { - File ftemp = new File(tempDir); - files = exportSelection(errorHandler, tempDir, export); - files.clear(); - - File[] fs = ftemp.listFiles(); - files.addAll(Arrays.asList(fs)); - - Main.stopWork(); - } catch (IOException ex) { - return null; - } - for (File f : files) { - f.deleteOnExit(); - } - new File(tempDir).deleteOnExit(); - return files; - - } - return null; - } - }, new DragSourceListener() { - @Override - public void dragEnter(DragSourceDragEvent dsde) { - enableDrop(false); - } - - @Override - public void dragOver(DragSourceDragEvent dsde) { - } - - @Override - public void dropActionChanged(DragSourceDragEvent dsde) { - } - - @Override - public void dragExit(DragSourceEvent dse) { - } - - @Override - public void dragDropEnd(DragSourceDropEvent dsde) { - enableDrop(true); - } - }); - } - }); - - createContextMenu(); - - TreeCellRenderer tcr = new DefaultTreeCellRenderer() { - @Override - public Component getTreeCellRendererComponent( - JTree tree, - Object value, - boolean sel, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - - super.getTreeCellRendererComponent( - tree, value, sel, - expanded, leaf, row, - hasFocus); - Object val = value; - if (val instanceof TagNode) { - val = ((TagNode) val).tag; - } - TagType type = getTagType(val); - if (val instanceof SWFRoot) { - setIcon(View.getIcon("flash16")); - } else if (type != null) { - if (type == TagType.FOLDER && expanded) { - type = TagType.FOLDER_OPEN; - } - String tagTypeStr = type.toString().toLowerCase().replace("_", ""); - setIcon(View.getIcon(tagTypeStr + "16")); - //setToolTipText("This book is in the Tutorial series."); - } else { - //setToolTipText(null); //no tool tip - } - - String tos = value.toString(); - int sw = getFontMetrics(getFont()).stringWidth(tos); - setPreferredSize(new Dimension(18 + sw, getPreferredSize().height)); - setUI(new BasicLabelUI()); - setOpaque(false); - //setBackground(Color.green); - setBackgroundNonSelectionColor(Color.white); - //setBackgroundSelectionColor(Color.ORANGE); - return this; - } - }; - - tagTree.setCellRenderer(tcr); - - statusPanel = new MainFrameStatusPanel(this); - cnt.add(statusPanel, BorderLayout.SOUTH); - - JPanel textTopPanel = new JPanel(new BorderLayout()); - textValue = new LineMarkedEditorPane(); - textTopPanel.add(new JScrollPane(textValue), BorderLayout.CENTER); - textValue.setEditable(false); - //textValue.setFont(UIManager.getFont("TextField.font")); - - - - JPanel textButtonsPanel = new JPanel(); - textButtonsPanel.setLayout(new FlowLayout()); - - - textSaveButton = new JButton(translate("button.save"), View.getIcon("save16")); - textSaveButton.setMargin(new Insets(3, 3, 3, 10)); - textSaveButton.setActionCommand(ACTION_SAVE_TEXT); - textSaveButton.addActionListener(this); - - textEditButton = new JButton(translate("button.edit"), View.getIcon("edit16")); - textEditButton.setMargin(new Insets(3, 3, 3, 10)); - textEditButton.setActionCommand(ACTION_EDIT_TEXT); - textEditButton.addActionListener(this); - - textCancelButton = new JButton(translate("button.cancel"), View.getIcon("cancel16")); - textCancelButton.setMargin(new Insets(3, 3, 3, 10)); - textCancelButton.setActionCommand(ACTION_CANCEL_TEXT); - textCancelButton.addActionListener(this); - - textButtonsPanel.add(textEditButton); - textButtonsPanel.add(textSaveButton); - textButtonsPanel.add(textCancelButton); - - textSaveButton.setVisible(false); - textCancelButton.setVisible(false); - - textTopPanel.add(textButtonsPanel, BorderLayout.SOUTH); - - displayWithPreview = new JPanel(new CardLayout()); - - displayWithPreview.add(textTopPanel, CARDTEXTPANEL); - - fontPanel = new FontPanel(this); - displayWithPreview.add(fontPanel, CARDFONTPANEL); - - - Component leftComponent; - - - displayPanel = new JPanel(new CardLayout()); - - if (flashPanel != null) { - JPanel flashPlayPanel = new JPanel(new BorderLayout()); - flashPlayPanel.add(flashPanel, BorderLayout.CENTER); - flashPlayPanel.add(flashControls = new PlayerControls(flashPanel), BorderLayout.SOUTH); - leftComponent = flashPlayPanel; - } else { - JPanel swtPanel = new JPanel(new BorderLayout()); - swtPanel.add(new JLabel("
" + translate("notavailonthisplatform") + "
", JLabel.CENTER), BorderLayout.CENTER); - swtPanel.setBackground(View.DEFAULT_BACKGROUND_COLOR); - leftComponent = swtPanel; - } - - textValue.setContentType("text/swf_text"); - - previewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - previewSplitPane.setDividerLocation(300); - JPanel pan = new JPanel(new BorderLayout()); - JLabel prevLabel = new HeaderLabel(translate("swfpreview")); - prevLabel.setHorizontalAlignment(SwingConstants.CENTER); - //prevLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); - - JLabel paramsLabel = new HeaderLabel(translate("parameters")); - paramsLabel.setHorizontalAlignment(SwingConstants.CENTER); - //paramsLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); - pan.add(prevLabel, BorderLayout.NORTH); - - viewerCards = new JPanel(); - viewerCards.setLayout(new CardLayout()); - //viewerCards.add(leftComponent,FLASH_VIEWER_CARD); - - internelViewerPanel = new ImagePanel(); - JPanel ivPanel = new JPanel(new BorderLayout()); - ivPanel.add(new HeaderLabel(translate("swfpreview.internal")), BorderLayout.NORTH); - ivPanel.add(internelViewerPanel, BorderLayout.CENTER); - viewerCards.add(ivPanel, INTERNAL_VIEWER_CARD); - - ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); - - if (flashPanel != null) { - JPanel bottomPanel = new JPanel(new BorderLayout()); - JPanel buttonsPanel = new JPanel(new FlowLayout()); - JButton selectColorButton = new JButton(View.getIcon("color16")); - selectColorButton.addActionListener(this); - selectColorButton.setActionCommand(ACTION_SELECT_COLOR); - selectColorButton.setToolTipText(AppStrings.translate("button.selectcolor.hint")); - buttonsPanel.add(selectColorButton); - bottomPanel.add(buttonsPanel, BorderLayout.EAST); - pan.add(bottomPanel, BorderLayout.SOUTH); - } - pan.add(leftComponent, BorderLayout.CENTER); - viewerCards.add(pan, FLASH_VIEWER_CARD); - previewSplitPane.setLeftComponent(viewerCards); - - parametersPanel = new JPanel(new BorderLayout()); - parametersPanel.add(paramsLabel, BorderLayout.NORTH); - parametersPanel.add(displayWithPreview, BorderLayout.CENTER); - previewSplitPane.setRightComponent(parametersPanel); - parametersPanel.setVisible(false); - displayPanel.add(previewSplitPane, CARDFLASHPANEL); - - displayPanel.add(createImagesCard(), CARDIMAGEPANEL); - - JPanel shapesCard = new JPanel(new BorderLayout()); - - JPanel previewPanel = new JPanel(new BorderLayout()); - - previewImagePanel = new ImagePanel(); - - JPanel previewCnt = new JPanel(new BorderLayout()); - previewCnt.add(previewImagePanel, BorderLayout.CENTER); - previewCnt.add(new PlayerControls(previewImagePanel), BorderLayout.SOUTH); - previewPanel.add(previewCnt, BorderLayout.CENTER); - JLabel prevIntLabel = new HeaderLabel(translate("swfpreview.internal")); - prevIntLabel.setHorizontalAlignment(SwingConstants.CENTER); - //prevIntLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); - previewPanel.add(prevIntLabel, BorderLayout.NORTH); - shapesCard.add(previewPanel, BorderLayout.CENTER); - displayPanel.add(shapesCard, CARDDRAWPREVIEWPANEL); - - swfPreviewPanel = new SWFPreviwPanel(); - displayPanel.add(swfPreviewPanel, CARDSWFPREVIEWPANEL); - - - displayPanel.add(new JPanel(), CARDEMPTYPANEL); - CardLayout cl = (CardLayout) (displayPanel.getLayout()); - cl.show(displayPanel, CARDEMPTYPANEL); - - searchPanel = new JPanel(); - searchPanel.setLayout(new BorderLayout()); - searchPanel.add(filterField, BorderLayout.CENTER); - searchPanel.add(new JLabel(View.getIcon("search16")), BorderLayout.WEST); - JLabel closeSearchButton = new JLabel(View.getIcon("cancel16")); - closeSearchButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - filterField.setText(""); - doFilter(); - searchPanel.setVisible(false); - } - }); - searchPanel.add(closeSearchButton, BorderLayout.EAST); - JPanel pan1 = new JPanel(new BorderLayout()); - pan1.add(new JScrollPane(tagTree), BorderLayout.CENTER); - pan1.add(searchPanel, BorderLayout.SOUTH); - - filterField.setActionCommand(ABCPanel.ACTION_FILTER_SCRIPT); - filterField.addActionListener(this); - - searchPanel.setVisible(false); - - filterField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void changedUpdate(DocumentEvent e) { - warn(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - warn(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - warn(); - } - - public void warn() { - doFilter(); - } - }); - - //displayPanel.setBorder(BorderFactory.createLineBorder(Color.black)); - splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pan1, detailPanel); - splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitPane2, displayPanel); - - - welcomePanel = createWelcomePanel(); - cnt.add(welcomePanel, BorderLayout.CENTER); - //splitPane1.setDividerLocation(0.5); - - splitPane1.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent pce) { - if (splitsInited) { - Configuration.guiSplitPane1DividerLocation.set((int) pce.getNewValue()); - } - } - }); - - splitPane2.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent pce) { - if (detailPanel.isVisible()) { - Configuration.guiSplitPane2DividerLocation.set((int) pce.getNewValue()); - } - } - }); - - CardLayout cl3 = new CardLayout(); - contentPanel = new JPanel(cl3); - contentPanel.add(welcomePanel, WELCOME_PANEL); - contentPanel.add(splitPane1, SPLIT_PANE1); - cnt.add(contentPanel); - cl3.show(contentPanel, WELCOME_PANEL); - - View.centerScreen(this); - tagTree.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == 'F') && (e.isControlDown())) { - searchPanel.setVisible(true); - filterField.requestFocusInWindow(); - } - } - }); - detailPanel.setVisible(false); - - updateUi(); - - //Opening files with drag&drop to main window - enableDrop(true); - } - - public void load(SWF swf) { - List objs = new ArrayList<>(); - if (swf != null) { - objs.addAll(swf.tags); - } - - ArrayList abcList = new ArrayList<>(); - getActionScript3(objs, abcList); - - swfs.add(swf); - swf.abcList = abcList; - - boolean hasAbc = !abcList.isEmpty(); - - if (hasAbc) { - if (abcPanel == null) { - abcPanel = new ABCPanel(this); - displayPanel.add(abcPanel, CARDACTIONSCRIPT3PANEL); - detailPanel.add(abcPanel.tabbedPane, DETAILCARDAS3NAVIGATOR); - } - abcPanel.setSwf(abcList, swf); - } else { - if (actionPanel == null) { - actionPanel = new ActionPanel(this); - displayPanel.add(actionPanel, CARDACTIONSCRIPTPANEL); - } - } - - tagTree.setModel(new TagTreeModel(this, swfs)); - expandSwfRoots(); - - for (Tag t : swf.tags) { - if (t instanceof JPEGTablesTag) { - swf.jtt = (JPEGTablesTag) t; - } - } - - List list2 = new ArrayList<>(); - list2.addAll(swf.tags); - swf.characters = new HashMap<>(); - parseCharacters(swf, list2); - - if (Configuration.autoRenameIdentifiers.get()) { - try { - swf.deobfuscateIdentifiers(RenameType.TYPENUMBER); - swf.assignClassesToSymbols(); - clearCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - updateClassesList(); - } catch (InterruptedException ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); - } - } - - showDetail(DETAILCARDEMPTYPANEL); - showCard(CARDEMPTYPANEL); - updateUi(swf); - } - - private void updateUi(final SWF swf) { - - setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); - - List abcList = swf.abcList; - - boolean hasAbc = !abcList.isEmpty(); - - if (hasAbc) { - abcPanel.setSwf(abcList, swf); - } - - if (isWelcomeScreen) { - CardLayout cl = (CardLayout) (contentPanel.getLayout()); - cl.show(contentPanel, SPLIT_PANE1); - isWelcomeScreen = false; - } - - mainRibbon.updateComponets(swf, abcList); - } - - private void updateUi() { - if (!isWelcomeScreen) { - CardLayout cl = (CardLayout) (contentPanel.getLayout()); - cl.show(contentPanel, WELCOME_PANEL); - isWelcomeScreen = true; - } - - if (swfs.isEmpty()) { - mainRibbon.updateComponets(null, null); - } else { - SWF swf = swfs.get(0); - updateUi(swf); - } - } - - public void closeAll() { - swfs.clear(); - oldValue = null; - if (abcPanel != null) { - abcPanel.clearSwf(); - } - if (actionPanel != null) { - actionPanel.clearSource(); - } - updateUi(); - updateTagTree(); - } - - public void close(SWF swf) { - swfs.remove(swf); - if (abcPanel != null && abcPanel.swf == swf) { - abcPanel.clearSwf(); - } - if (actionPanel != null) { - actionPanel.clearSource(); - } - oldValue = null; - updateUi(); - updateTagTree(); - } - - private void updateTagTree() { - tagTree.setModel(new TagTreeModel(this, swfs)); - expandSwfRoots(); - } - - public void enableDrop(boolean value) { - if (value) { - setDropTarget(new DropTarget() { - @Override - public synchronized void drop(DropTargetDropEvent dtde) { - try { - dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - @SuppressWarnings("unchecked") - List droppedFiles = (List) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); - if (!droppedFiles.isEmpty()) { - String path = droppedFiles.get(0).getAbsolutePath(); - Main.openFile(path, null); - } - } catch (UnsupportedFlavorException | IOException ex) { - } - } - }); - } else { - setDropTarget(null); - } - } - - public void updateClassesList() { - List nodes = getASTagNode(tagTree); - boolean updateNeeded = false; - for (TagNode n : nodes) { - if (n.tag instanceof ClassesListTreeModel) { - ((ClassesListTreeModel) n.tag).update(); - updateNeeded = true; - } - } - - refreshTree(); - - if (updateNeeded) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - tagTree.updateUI(); - } - }); - } - } - - public void doFilter() { - List nodes = getASTagNode(tagTree); - boolean updateNeeded = false; - for (TagNode n : nodes) { - if (n.tag instanceof ClassesListTreeModel) { - ((ClassesListTreeModel) n.tag).setFilter(filterField.getText()); - updateNeeded = true; - } - } - - if (updateNeeded) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - tagTree.updateUI(); - } - }); - } - } - - private static void getApplicationMenuButtons(Component comp, List ret) { - if (comp instanceof JRibbonApplicationMenuButton) { - ret.add((JRibbonApplicationMenuButton) comp); - return; - } - if (comp instanceof java.awt.Container) { - java.awt.Container cont = (java.awt.Container) comp; - for (int i = 0; i < cont.getComponentCount(); i++) { - getApplicationMenuButtons(cont.getComponent(i), ret); - } - } - } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (b) { - if (abcPanel != null) { - abcPanel.initSplits(); - } - if (actionPanel != null) { - actionPanel.initSplits(); - } - - final MainFrame t = this; - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - List mbuttons = new ArrayList<>(); - getApplicationMenuButtons(t, mbuttons); - - for (final JRibbonApplicationMenuButton mbutton : mbuttons) { - mbutton.setIcon(View.getResizableIcon("buttonicon_256")); - mbutton.setDisplayState(new CommandButtonDisplayState( - "My Ribbon Application Menu Button", mbutton.getSize().width) { - @Override - public CommandButtonLayoutManager createLayoutManager( - AbstractCommandButton commandButton) { - return new CommandButtonLayoutManager() { - @Override - public int getPreferredIconSize() { - return mbutton.getSize().width; - } - - @Override - public CommandButtonLayoutManager.CommandButtonLayoutInfo getLayoutInfo( - AbstractCommandButton commandButton, Graphics g) { - CommandButtonLayoutManager.CommandButtonLayoutInfo result = new CommandButtonLayoutManager.CommandButtonLayoutInfo(); - result.actionClickArea = new Rectangle(0, 0, 0, 0); - result.popupClickArea = new Rectangle(0, 0, commandButton - .getWidth(), commandButton.getHeight()); - result.popupActionRect = new Rectangle(0, 0, 0, 0); - ResizableIcon icon = commandButton.getIcon(); - icon.setDimension(new Dimension(commandButton.getWidth(), commandButton.getHeight())); - result.iconRect = new Rectangle( - 0, - 0, - commandButton.getWidth(), commandButton.getHeight()); - result.isTextInActionArea = false; - return result; - } - - @Override - public Dimension getPreferredSize( - AbstractCommandButton commandButton) { - return new Dimension(40, 40); - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - } - - @Override - public Point getKeyTipAnchorCenterPoint( - AbstractCommandButton commandButton) { - // dead center - return new Point(commandButton.getWidth() / 2, - commandButton.getHeight() / 2); - } - }; - } - }); - - MyRibbonApplicationMenuButtonUI mui = (MyRibbonApplicationMenuButtonUI) mbutton.getUI(); - mui.setHoverIcon(View.getResizableIcon("buttonicon_hover_256")); - mui.setNormalIcon(View.getResizableIcon("buttonicon_256")); - mui.setClickIcon(View.getResizableIcon("buttonicon_down_256")); - } - splitPane1.setDividerLocation(Configuration.guiSplitPane1DividerLocation.get(getWidth() / 3)); - int confDivLoc = Configuration.guiSplitPane2DividerLocation.get(splitPane2.getHeight() * 3 / 5); - if (confDivLoc > splitPane2.getHeight() - 10) { //In older releases, divider location was saved when detailPanel was invisible too - confDivLoc = splitPane2.getHeight() * 3 / 5; - } - splitPane2.setDividerLocation(confDivLoc); - - splitPos = splitPane2.getDividerLocation(); - splitsInited = true; - if (Configuration.gotoMainClassOnStartup.get()) { - gotoDocumentClass(getCurrentSwf()); - } - } - }); - - - } - } - - private void parseCharacters(SWF swf, List list) { - for (ContainerItem t : list) { - if (t instanceof CharacterTag) { - swf.characters.put(((CharacterTag) t).getCharacterId(), (CharacterTag) t); - } - if (t instanceof Container) { - parseCharacters(swf, ((Container) t).getSubItems()); - } - } - } - - public static void getShapes(List list, List shapes) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getShapes(((Container) t).getSubItems(), shapes); - } - if ((t instanceof DefineShapeTag) - || (t instanceof DefineShape2Tag) - || (t instanceof DefineShape3Tag) - || (t instanceof DefineShape4Tag)) { - shapes.add((Tag) t); - } - } - } - - public static void getFonts(List list, List fonts) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getFonts(((Container) t).getSubItems(), fonts); - } - if ((t instanceof DefineFontTag) - || (t instanceof DefineFont2Tag) - || (t instanceof DefineFont3Tag) - || (t instanceof DefineFont4Tag)) { - fonts.add((Tag) t); - } - } - } - - public static void getActionScript3(List list, List actionScripts) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getActionScript3(((Container) t).getSubItems(), actionScripts); - } - if (t instanceof ABCContainerTag) { - actionScripts.add((ABCContainerTag) t); - } - } - } - - public static void getMorphShapes(List list, List morphShapes) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getMorphShapes(((Container) t).getSubItems(), morphShapes); - } - if ((t instanceof DefineMorphShapeTag) || (t instanceof DefineMorphShape2Tag)) { - morphShapes.add((Tag) t); - } - } - } - - public static void getImages(List list, List images) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getImages(((Container) t).getSubItems(), images); - } - if ((t instanceof DefineBitsTag) - || (t instanceof DefineBitsJPEG2Tag) - || (t instanceof DefineBitsJPEG3Tag) - || (t instanceof DefineBitsJPEG4Tag) - || (t instanceof DefineBitsLosslessTag) - || (t instanceof DefineBitsLossless2Tag)) { - images.add((Tag) t); - } - } - } - - public static void getTexts(List list, List texts) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getTexts(((Container) t).getSubItems(), texts); - } - if ((t instanceof DefineTextTag) - || (t instanceof DefineText2Tag) - || (t instanceof DefineEditTextTag)) { - texts.add((Tag) t); - } - } - } - - public static void getSprites(List list, List sprites) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getSprites(((Container) t).getSubItems(), sprites); - } - if (t instanceof DefineSpriteTag) { - sprites.add((Tag) t); - } - } - } - - public static void getButtons(List list, List buttons) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getButtons(((Container) t).getSubItems(), buttons); - } - if ((t instanceof DefineButtonTag) || (t instanceof DefineButton2Tag)) { - buttons.add((Tag) t); - } - } - } - - public List getSelectedNodes() { - List ret = new ArrayList<>(); - TreePath[] tps = tagTree.getSelectionPaths(); - if (tps == null) { - return ret; - } - for (TreePath tp : tps) { - TagNode te = (TagNode) tp.getLastPathComponent(); - ret.add(te); - } - return ret; - } - - public static TagType getTagType(Object t) { - if ((t instanceof DefineFontTag) - || (t instanceof DefineFont2Tag) - || (t instanceof DefineFont3Tag) - || (t instanceof DefineFont4Tag) - || (t instanceof DefineCompactedFont)) { - return TagType.FONT; - } - if ((t instanceof DefineTextTag) - || (t instanceof DefineText2Tag) - || (t instanceof DefineEditTextTag)) { - return TagType.TEXT; - } - - if ((t instanceof DefineBitsTag) - || (t instanceof DefineBitsJPEG2Tag) - || (t instanceof DefineBitsJPEG3Tag) - || (t instanceof DefineBitsJPEG4Tag) - || (t instanceof DefineBitsLosslessTag) - || (t instanceof DefineBitsLossless2Tag)) { - return TagType.IMAGE; - } - if ((t instanceof DefineShapeTag) - || (t instanceof DefineShape2Tag) - || (t instanceof DefineShape3Tag) - || (t instanceof DefineShape4Tag)) { - return TagType.SHAPE; - } - - if ((t instanceof DefineMorphShapeTag) || (t instanceof DefineMorphShape2Tag)) { - return TagType.MORPH_SHAPE; - } - - if (t instanceof DefineSpriteTag) { - return TagType.SPRITE; - } - if ((t instanceof DefineButtonTag) || (t instanceof DefineButton2Tag)) { - return TagType.BUTTON; - } - if (t instanceof ASMSource) { - return TagType.AS; - } - if (t instanceof TreeElement) { - TreeElement te = (TreeElement) t; - if (te.getItem() instanceof ScriptPack) { - return TagType.AS; - } else { - return TagType.PACKAGE; - } - } - if (t instanceof PackageNode) { - return TagType.PACKAGE; - } - if (t instanceof FrameNode) { - return TagType.FRAME; - } - if (t instanceof ShowFrameTag) { - return TagType.SHOW_FRAME; - } - - if (t instanceof DefineVideoStreamTag) { - return TagType.MOVIE; - } - - if ((t instanceof DefineSoundTag) || (t instanceof SoundStreamHeadTag) || (t instanceof SoundStreamHead2Tag)) { - return TagType.SOUND; - } - - if (t instanceof DefineBinaryDataTag) { - return TagType.BINARY_DATA; - } - - return TagType.FOLDER; - } - - public List getTagsWithType(List list, TagType type) { - List ret = new ArrayList<>(); - for (Object o : list) { - TagType ttype = getTagType(o); - if (type == ttype) { - ret.add(o); - } - } - return ret; - } - - public void renameIdentifier(SWF swf, String identifier) throws InterruptedException { - String oldName = identifier; - String newName = View.showInputDialog(translate("rename.enternew"), oldName); - if (newName != null) { - if (!oldName.equals(newName)) { - swf.renameAS2Identifier(oldName, newName); - View.showMessageDialog(null, translate("rename.finished.identifier")); - updateClassesList(); - reload(true); - } - } - } - - public void renameMultiname(List abcList, int multiNameIndex) { - String oldName = ""; - if (abcPanel.abc.constants.getMultiname(multiNameIndex).name_index > 0) { - oldName = abcPanel.abc.constants.getString(abcPanel.abc.constants.getMultiname(multiNameIndex).name_index); - } - String newName = View.showInputDialog(translate("rename.enternew"), oldName); - if (newName != null) { - if (!oldName.equals(newName)) { - int mulCount = 0; - for (ABCContainerTag cnt : abcList) { - ABC abc = cnt.getABC(); - for (int m = 1; m < abc.constants.getMultinameCount(); m++) { - int ni = abc.constants.getMultiname(m).name_index; - String n = ""; - if (ni > 0) { - n = abc.constants.getString(ni); - } - if (n.equals(oldName)) { - abc.renameMultiname(m, newName); - mulCount++; - } - } - } - View.showMessageDialog(null, translate("rename.finished.multiname").replace("%count%", "" + mulCount)); - if (abcPanel != null) { - abcPanel.reload(); - } - updateClassesList(); - reload(true); - abcPanel.hilightScript(abcPanel.decompiledTextArea.getScriptLeaf().getPath().toString()); - } - } - } - - public List getSelected(JTree tree) { - TreeSelectionModel tsm = tree.getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - Object o = tp.getLastPathComponent(); - ret.add(o); - } - return ret; - } - - public List getAllSubs(JTree tree, Object o) { - TreeModel tm = tree.getModel(); - List ret = new ArrayList<>(); - for (int i = 0; i < tm.getChildCount(o); i++) { - Object c = tm.getChild(o, i); - ret.add(c); - ret.addAll(getAllSubs(tree, c)); - } - return ret; - } - - public List getAllSelected(JTree tree) { - TreeSelectionModel tsm = tree.getSelectionModel(); - TreePath[] tps = tsm.getSelectionPaths(); - List ret = new ArrayList<>(); - if (tps == null) { - return ret; - } - - for (TreePath tp : tps) { - Object o = tp.getLastPathComponent(); - ret.add(o); - ret.addAll(getAllSubs(tree, o)); - } - return ret; - } - - public List getASTagNode(JTree tree) { - List result = new ArrayList<>(); - TagTreeModel tm = (TagTreeModel) tree.getModel(); - if (tm == null) { - return result; - } - TreeNode root = tm.getRoot(); - for (int j = 0; j < tm.getChildCount(root); j++) { - SWFRoot swfRoot = (SWFRoot) tm.getChild(root, j); - for (int i = 0; i < tm.getChildCount(swfRoot); i++) { - TreeNode node = tm.getChild(swfRoot, i); - if (node instanceof TagNode) { - TagNode tagNode = (TagNode) node; - TreeElementItem tag = tagNode.tag; - if (tag != null && "scripts".equals(tagNode.mark)) { - result.add((TagNode) node); - } - } - } - } - return result; - } - - public boolean confirmExperimental() { - return View.showConfirmDialog(null, translate("message.confirm.experimental"), translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION; - } - private SearchDialog searchDialog; - - public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException { - final ExportMode exportMode = ExportMode.get(export.getOption(ExportDialog.OPTION_ACTIONSCRIPT)); - final boolean isMp3OrWav = export.getOption(ExportDialog.OPTION_SOUNDS) == 0; - final boolean isFormatted = export.getOption(ExportDialog.OPTION_TEXTS) == 1; - - List ret = new ArrayList<>(); - List sel = getAllSelected(tagTree); - - for (SWF swf : swfs) { - List tlsList = new ArrayList<>(); - JPEGTablesTag jtt = null; - for (Tag t : swf.tags) { - if (t instanceof JPEGTablesTag) { - jtt = (JPEGTablesTag) t; - break; - } - } - List images = new ArrayList<>(); - List shapes = new ArrayList<>(); - List movies = new ArrayList<>(); - List sounds = new ArrayList<>(); - List texts = new ArrayList<>(); - List actionNodes = new ArrayList<>(); - List binaryData = new ArrayList<>(); - for (Object d : sel) { - if (d instanceof TagNode) { - TagNode n = (TagNode) d; - if (n.getSwf() != swf) { - continue; - } - if (getTagType(n.tag) == TagType.IMAGE) { - images.add((Tag) n.tag); - } - if (getTagType(n.tag) == TagType.SHAPE) { - shapes.add((Tag) n.tag); - } - if (getTagType(n.tag) == TagType.AS) { - actionNodes.add(n); - } - if (getTagType(n.tag) == TagType.MOVIE) { - movies.add((Tag) n.tag); - } - if (getTagType(n.tag) == TagType.SOUND) { - sounds.add((Tag) n.tag); - } - if (getTagType(n.tag) == TagType.BINARY_DATA) { - binaryData.add((Tag) n.tag); - } - if (getTagType(n.tag) == TagType.TEXT) { - texts.add((Tag) n.tag); - } - } - if (d instanceof TreeElement) { - if (((TreeElement) d).isLeaf()) { - TreeElement treeElement = (TreeElement) d; - if (treeElement.getSwf() == swf) { - tlsList.add((ScriptPack) treeElement.getItem()); - } - } - } - } - ret.addAll(swf.exportImages(handler, selFile + File.separator + "images", images)); - ret.addAll(SWF.exportShapes(handler, selFile + File.separator + "shapes", shapes)); - ret.addAll(swf.exportTexts(handler, selFile + File.separator + "texts", texts, isFormatted)); - ret.addAll(swf.exportMovies(handler, selFile + File.separator + "movies", movies)); - ret.addAll(swf.exportSounds(handler, selFile + File.separator + "sounds", sounds, isMp3OrWav, isMp3OrWav)); - ret.addAll(SWF.exportBinaryData(handler, selFile + File.separator + "binaryData", binaryData)); - List abcList = swf.abcList; - if (abcPanel != null) { - for (int i = 0; i < tlsList.size(); i++) { - ScriptPack tls = tlsList.get(i); - Main.startWork(translate("work.exporting") + " " + (i + 1) + "/" + tlsList.size() + " " + tls.getPath() + " ..."); - ret.add(tls.export(selFile, abcList, exportMode, Configuration.parallelSpeedUp.get())); - } - } else { - List allNodes = new ArrayList<>(); - List asNodes = getASTagNode(tagTree); - for (TagNode asn : asNodes) { - allNodes.add(asn); - TagNode.setExport(allNodes, false); - TagNode.setExport(actionNodes, true); - ret.addAll(TagNode.exportNodeAS(swf.tags, handler, allNodes, selFile, exportMode, null)); - } - } - } - return ret; - } - - public SWF getCurrentSwf() { - if (swfs == null || swfs.isEmpty()) { - return null; - } - - TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); - if (treeNode == null) { - return swfs.get(0); - } - - return treeNode.getSwf(); - } - - private void clearCache() { - if (abcPanel != null) { - abcPanel.decompiledTextArea.clearScriptCache(); - } - if (actionPanel != null) { - actionPanel.clearCache(); - } - } - - public void gotoDocumentClass(SWF swf) { - if (swf == null) { - return; - } - String documentClass = null; - loopdc: - for (Tag t : swf.tags) { - if (t instanceof SymbolClassTag) { - SymbolClassTag sc = (SymbolClassTag) t; - for (int i = 0; i < sc.tagIDs.length; i++) { - if (sc.tagIDs[i] == 0) { - documentClass = sc.classNames[i]; - break loopdc; - } - } - } - } - if (documentClass != null) { - showDetail(DETAILCARDAS3NAVIGATOR); - showCard(CARDACTIONSCRIPT3PANEL); - abcPanel.hilightScript(documentClass); - } - } - - public void disableDecompilationChanged() { - clearCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - reload(true); - updateClassesList(); - } - - public void searchAs() { - if (searchDialog == null) { - searchDialog = new SearchDialog(); - } - searchDialog.setVisible(true); - if (searchDialog.result) { - final String txt = searchDialog.searchField.getText(); - if (!txt.isEmpty()) { - if (abcPanel != null) { - new CancellableWorker() { - @Override - protected Void doInBackground() throws Exception { - if (abcPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - showDetail(DETAILCARDAS3NAVIGATOR); - showCard(CARDACTIONSCRIPT3PANEL); - } - }); - } else { - View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); - } - return null; - } - }.execute(); - } else { - new CancellableWorker() { - @Override - protected Void doInBackground() { - if (actionPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - showCard(CARDACTIONSCRIPTPANEL); - } - }); - } else { - View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); - } - return null; - } - }.execute(); - } - } - } - } - - public void autoDeobfuscateChanged() { - clearCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - reload(true); - updateClassesList(); - } - - public void renameOneIdentifier(final SWF swf) { - if (swf.fileAttributes.actionScript3) { - final int multiName = abcPanel.decompiledTextArea.getMultinameUnderCursor(); - final List abcList = swf.abcList; - if (multiName > 0) { - new CancellableWorker() { - @Override - public Void doInBackground() throws Exception { - Main.startWork(translate("work.renaming") + "..."); - renameMultiname(abcList, multiName); - return null; - } - - @Override - protected void done() { - Main.stopWork(); - } - }.execute(); - - } else { - View.showMessageDialog(null, translate("message.rename.notfound.multiname"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); - } - } else { - final String identifier = actionPanel.getStringUnderCursor(); - if (identifier != null) { - new CancellableWorker() { - @Override - public Void doInBackground() throws Exception { - Main.startWork(translate("work.renaming") + "..."); - try { - renameIdentifier(swf, identifier); - } catch (InterruptedException ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); - } - return null; - } - - @Override - protected void done() { - Main.stopWork(); - } - }.execute(); - } else { - View.showMessageDialog(null, translate("message.rename.notfound.identifier"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); - } - } - } - - public void exportFla(final SWF swf) { - JFileChooser fc = new JFileChooser(); - String selDir = Configuration.lastOpenDir.get(); - fc.setCurrentDirectory(new File(selDir)); - if (!selDir.endsWith(File.separator)) { - selDir += File.separator; - } - String fileName = (new File(swf.file).getName()); - fileName = fileName.substring(0, fileName.length() - 4) + ".fla"; - fc.setSelectedFile(new File(selDir + fileName)); - FileFilter fla = new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || (f.getName().toLowerCase().endsWith(".fla")); - } - - @Override - public String getDescription() { - return translate("filter.fla"); - } - }; - FileFilter xfl = new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || (f.getName().toLowerCase().endsWith(".xfl")); - } - - @Override - public String getDescription() { - return translate("filter.xfl"); - } - }; - fc.setFileFilter(fla); - fc.addChoosableFileFilter(xfl); - fc.setAcceptAllFileFilterUsed(false); - JFrame f = new JFrame(); - View.setWindowIcon(f); - int returnVal = fc.showSaveDialog(f); - if (returnVal == JFileChooser.APPROVE_OPTION) { - Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath()); - File sf = Helper.fixDialogFile(fc.getSelectedFile()); - - Main.startWork(translate("work.exporting.fla") + "..."); - final boolean compressed = fc.getFileFilter() == fla; - if (!compressed) { - if (sf.getName().endsWith(".fla")) { - sf = new File(sf.getAbsolutePath().substring(0, sf.getAbsolutePath().length() - 4) + ".xfl"); - } - } - final File selfile = sf; - new CancellableWorker() { - @Override - protected Void doInBackground() throws Exception { - Helper.freeMem(); - try { - if (compressed) { - swf.exportFla(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get()); - } else { - swf.exportXfl(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get()); - } - } catch (IOException ex) { - View.showMessageDialog(null, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE); - } - Helper.freeMem(); - return null; - } - - @Override - protected void done() { - Main.stopWork(); - } - }.execute(); - } - } - - public void export(final boolean onlySel) { - final ExportDialog export = new ExportDialog(); - export.setVisible(true); - if (!export.cancelled) { - JFileChooser chooser = new JFileChooser(); - chooser.setCurrentDirectory(new File(Configuration.lastExportDir.get())); - chooser.setDialogTitle(translate("export.select.directory")); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setAcceptAllFileFilterUsed(false); - if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { - final long timeBefore = System.currentTimeMillis(); - Main.startWork(translate("work.exporting") + "..."); - final String selFile = Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath(); - Configuration.lastExportDir.set(Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath()); - final ExportMode exportMode = ExportMode.get(export.getOption(ExportDialog.OPTION_ACTIONSCRIPT)); - final boolean isMp3OrWav = export.getOption(ExportDialog.OPTION_SOUNDS) == 0; - final boolean isFormatted = export.getOption(ExportDialog.OPTION_TEXTS) == 1; - final SWF swf = getCurrentSwf(); - new CancellableWorker() { - @Override - public Void doInBackground() throws Exception { - try { - if (onlySel) { - exportSelection(errorHandler, selFile, export); - } else { - swf.exportImages(errorHandler, selFile + File.separator + "images"); - swf.exportShapes(errorHandler, selFile + File.separator + "shapes"); - swf.exportTexts(errorHandler, selFile + File.separator + "texts", isFormatted); - swf.exportMovies(errorHandler, selFile + File.separator + "movies"); - swf.exportSounds(errorHandler, selFile + File.separator + "sounds", isMp3OrWav, isMp3OrWav); - swf.exportBinaryData(errorHandler, selFile + File.separator + "binaryData"); - swf.exportActionScript(errorHandler, selFile, exportMode, Configuration.parallelSpeedUp.get()); - } - } catch (Exception ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Error during export", ex); - View.showMessageDialog(null, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage()); - } - return null; - } - - @Override - protected void done() { - Main.stopWork(); - long timeAfter = System.currentTimeMillis(); - final long timeMs = timeAfter - timeBefore; - - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - setStatus(translate("export.finishedin").replace("%time%", Helper.formatTimeSec(timeMs))); - } - }); - } - }.execute(); - - } - } - } - - public void restoreControlFlow(final boolean all) { - Main.startWork(translate("work.restoringControlFlow")); - if ((!all) || confirmExperimental()) { - new CancellableWorker() { - @Override - protected Object doInBackground() throws Exception { - int cnt = 0; - if (all) { - for (ABCContainerTag tag : abcPanel.list) { - tag.getABC().restoreControlFlow(); - } - } else { - int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); - if (bi != -1) { - abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, abcPanel.decompiledTextArea.getCurrentTrait(), abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); - } - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, abcPanel.decompiledTextArea.getCurrentTrait()); - } - return true; - } - - @Override - protected void done() { - Main.stopWork(); - View.showMessageDialog(null, translate("work.restoringControlFlow.complete")); - - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - abcPanel.reload(); - updateClassesList(); - } - }); - } - }.execute(); - } - } - - public void renameIdentifiers(final SWF swf) { - if (confirmExperimental()) { - final RenameType renameType = new RenameDialog().display(); - if (renameType != null) { - Main.startWork(translate("work.renaming.identifiers") + "..."); - new CancellableWorker() { - @Override - protected Integer doInBackground() throws Exception { - int cnt = swf.deobfuscateIdentifiers(renameType); - return cnt; - } - - @Override - protected void done() { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - try { - int cnt = get(); - Main.stopWork(); - View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", "" + cnt)); - swf.assignClassesToSymbols(); - clearCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - updateClassesList(); - reload(true); - } catch (Exception ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Error during renaming identifiers", ex); - Main.stopWork(); - View.showMessageDialog(null, translate("error.occured").replace("%error%", ex.getClass().getSimpleName())); - } - } - }); - } - }.execute(); - } - } - } - - public void deobfuscate() { - if (deobfuscationDialog == null) { - deobfuscationDialog = new DeobfuscationDialog(); - } - deobfuscationDialog.setVisible(true); - if (deobfuscationDialog.ok) { - Main.startWork(translate("work.deobfuscating") + "..."); - new CancellableWorker() { - @Override - protected Object doInBackground() throws Exception { - try { - if (deobfuscationDialog.processAllCheckbox.isSelected()) { - for (ABCContainerTag tag : abcPanel.list) { - if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) { - tag.getABC().removeDeadCode(); - } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) { - tag.getABC().removeTraps(); - } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) { - tag.getABC().removeTraps(); - tag.getABC().restoreControlFlow(); - } - } - } else { - int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); - Trait t = abcPanel.decompiledTextArea.getCurrentTrait(); - if (bi != -1) { - if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) { - abcPanel.abc.bodies[bi].removeDeadCode(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); - } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) { - abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/); - } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) { - abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/); - abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); - } - } - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, t); - } - } catch (Exception ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Deobfuscation error", ex); - } - return true; - } - - @Override - protected void done() { - Main.stopWork(); - View.showMessageDialog(null, translate("work.deobfuscating.complete")); - - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - clearCache(); - abcPanel.reload(); - updateClassesList(); - } - }); - } - }.execute(); - } - } - - public void removeNonScripts(SWF swf) { - List tags = new ArrayList<>(swf.tags); - for (Tag tag : tags) { - System.out.println(tag.getClass()); - if (!(tag instanceof ABCContainerTag || tag instanceof ASMSource)) { - swf.removeTag(tag); - } - } - showCard(CARDEMPTYPANEL); - refreshTree(); - } - - public void refreshDecompiled() { - clearCache(); - if (abcPanel != null) { - abcPanel.reload(); - } - reload(true); - updateClassesList(); - } - - @Override - public void actionPerformed(ActionEvent e) { - switch (e.getActionCommand()) { - case ACTION_SELECT_COLOR: - Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectcolor.title"), View.swfBackgroundColor); - if (newColor != null) { - View.swfBackgroundColor = newColor; - reload(true); - } - break; - case ACTION_REPLACE_IMAGE: - { - Object tagObj = tagTree.getLastSelectedPathComponent(); - if (tagObj == null) { - return; - } - - if (tagObj instanceof TagNode) { - tagObj = ((TagNode) tagObj).tag; - } - if (tagObj instanceof ImageTag) { - ImageTag it = (ImageTag) tagObj; - if (it.importSupported()) { - JFileChooser fc = new JFileChooser(); - fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return (f.getName().toLowerCase().endsWith(".jpg")) - || (f.getName().toLowerCase().endsWith(".jpeg")) - || (f.getName().toLowerCase().endsWith(".gif")) - || (f.getName().toLowerCase().endsWith(".png")) - || (f.isDirectory()); - } - - @Override - public String getDescription() { - return translate("filter.images"); - } - }); - 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()); - byte[] data = Helper.readFile(selfile.getAbsolutePath()); - try { - it.setImage(data); - it.getSwf().clearImageCache(); - } catch (IOException ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Invalid image", ex); - View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); - } - reload(true); - } - } - } - } - break; - case ACTION_REPLACE_BINARY: - { - Object tagObj = tagTree.getLastSelectedPathComponent(); - if (tagObj == null) { - return; - } - - if (tagObj instanceof TagNode) { - tagObj = ((TagNode) tagObj).tag; - } - if (tagObj instanceof DefineBinaryDataTag) { - DefineBinaryDataTag bt = (DefineBinaryDataTag) tagObj; - JFileChooser fc = new JFileChooser(); - fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); - 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()); - byte[] data = Helper.readFile(selfile.getAbsolutePath()); - bt.binaryData = data; - reload(true); - } - } - } - break; - case ACTION_REMOVE_ITEM: - List sel = getSelected(tagTree); - - List tagsToRemove = new ArrayList<>(); - for (Object o : sel) { - Object tag = o; - if (o instanceof TagNode) { - tag = ((TagNode) o).tag; - } - if (tag instanceof Tag) { - tagsToRemove.add((Tag) tag); - } - } - - if (tagsToRemove.size() == 1) { - Tag tag = tagsToRemove.get(0); - if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tag.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { - tag.getSwf().removeTag(tag); - showCard(CARDEMPTYPANEL); - refreshTree(); - } - } else if (tagsToRemove.size() > 1) { - if (View.showConfirmDialog(this, translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { - for (Tag tag : tagsToRemove) { - tag.getSwf().removeTag(tag); - } - showCard(CARDEMPTYPANEL); - refreshTree(); - } - } - break; - case ACTION_EDIT_TEXT: - setEditText(true); - break; - case ACTION_CANCEL_TEXT: - setEditText(false); - break; - case ACTION_SAVE_TEXT: - if (oldValue instanceof TextTag) { - TextTag textTag = (TextTag) oldValue; - try { - if (textTag.setFormattedText(new MissingCharacterHandler() { - @Override - public boolean handle(FontTag font, List tags, char character) { - String fontName = fontPanel.sourceFontsMap.get(font.getFontId()); - if (fontName == null) { - fontName = font.getFontName(tags); - } - fontName = FontTag.findInstalledFontName(fontName); - Font f = new Font(fontName, font.getFontStyle(), 18); - if (!f.canDisplay(character)) { - View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); - return false; - } - font.addCharacter(tags, character, fontName); - return true; - - } - }, textTag.getSwf().tags, textValue.getText(), fontPanel.getSelectedFont())) { - setEditText(false); - } - } catch (ParseException ex) { - View.showMessageDialog(null, translate("error.text.invalid").replace("%text%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); - } - } - break; - case ACTION_CLOSE_SWF: - { - Main.closeFile(getCurrentSwf()); - } - } - if (Main.isWorking()) { - return; - } - - switch (e.getActionCommand()) { - - case MainFrameRibbon.ACTION_EXPORT_SEL: - export(true); - break; - } - } - - private int splitPos = 0; - - public void showDetailWithPreview(String card) { - CardLayout cl = (CardLayout) (displayWithPreview.getLayout()); - cl.show(displayWithPreview, card); - } - - public void showDetail(String card) { - CardLayout cl = (CardLayout) (detailPanel.getLayout()); - cl.show(detailPanel, card); - if (card.equals(DETAILCARDEMPTYPANEL)) { - if (detailPanel.isVisible()) { - splitPos = splitPane2.getDividerLocation(); - detailPanel.setVisible(false); - } - } else { - if (!detailPanel.isVisible()) { - detailPanel.setVisible(true); - splitPane2.setDividerLocation(splitPos); - } - } - - } - - public void showCard(String card) { - CardLayout cl = (CardLayout) (displayPanel.getLayout()); - cl.show(displayPanel, card); - } - - @Override - public void valueChanged(TreeSelectionEvent e) { - TreeNode treeNode = (TreeNode) e.getPath().getLastPathComponent(); - SWF swf = treeNode.getSwf(); - if (swfs.contains(swf)) { - updateUi(swf); - } else { - updateUi(); - } - setEditText(false, false); - reload(false); - } - - private void stopFlashPlayer() { - if (flashPanel != null) { - if (!flashPanel.isStopped()) { - flashPanel.stopSWF(); - } - } - } - - private static Tag classicTag(Tag t) { - if (t instanceof DefineCompactedFont) { - return ((DefineCompactedFont) t).toClassicFont(); - } - return t; - } - - public void reload(boolean forceReload) { - TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); - if (treeNode == null) { - return; - } - - if (!forceReload && (treeNode == oldValue)) { - return; - } - - oldValue = treeNode; - - TreeElementItem tagObj = null; - if (treeNode instanceof TagNode) { - tagObj = ((TagNode) treeNode).tag; - } - if (treeNode instanceof TreeElement) { - tagObj = ((TreeElement) treeNode).getItem(); - } - - - if (flashPanel != null) { - flashPanel.specialPlayback = false; - } - swfPreviewPanel.stop(); - stopFlashPlayer(); - if (tagObj instanceof ScriptPack) { - final ScriptPack scriptLeaf = (ScriptPack) tagObj; - final List abcList = scriptLeaf.abc.swf.abcList; - if (setSourceWorker != null) { - setSourceWorker.cancel(true); - } - if (!Main.isWorking()) { - CancellableWorker worker = new CancellableWorker() { - - @Override - protected Void doInBackground() throws Exception { - int classIndex = -1; - for (Trait t : scriptLeaf.abc.script_info[scriptLeaf.scriptIndex].traits.traits) { - if (t instanceof TraitClass) { - classIndex = ((TraitClass) t).class_info; - break; - } - } - abcPanel.detailPanel.methodTraitPanel.methodCodePanel.clear(); - abcPanel.navigator.setABC(abcList, scriptLeaf.abc); - abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex); - abcPanel.setAbc(scriptLeaf.abc); - abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList); - abcPanel.decompiledTextArea.setClassIndex(classIndex); - abcPanel.decompiledTextArea.setNoTrait(); - return null; - } - - @Override - protected void done() { - Main.stopWork(); - - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - try { - get(); - } catch (CancellationException ex) { - abcPanel.decompiledTextArea.setText("//" + AppStrings.translate("work.canceled")); - } catch (Exception ex) { - abcPanel.decompiledTextArea.setText("//Decompilation error: " + ex); - } - } - }); - } - }; - worker.execute(); - setSourceWorker = worker; - Main.startWork(translate("work.decompiling") + "...", worker); - } - - showDetail(DETAILCARDAS3NAVIGATOR); - showCard(CARDACTIONSCRIPT3PANEL); - return; - } else { - showDetail(DETAILCARDEMPTYPANEL); - } - - - if (treeNode instanceof SWFRoot) { - SWFRoot swfRoot = (SWFRoot) treeNode; - SWF swf = swfRoot.getSwf(); - if (mainRibbon.isInternalFlashViewerSelected()) { - showCard(CARDSWFPREVIEWPANEL); - swfPreviewPanel.load(swf); - swfPreviewPanel.play(); - } else { - showCard(CARDFLASHPANEL); - parametersPanel.setVisible(false); - if (flashPanel != null) { - Color backgroundColor = View.DEFAULT_BACKGROUND_COLOR; - for (Tag t : swf.tags) { - if (t instanceof SetBackgroundColorTag) { - backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); - break; - } - } - ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); - if (tempFile != null) { - tempFile.delete(); - } - try { - tempFile = File.createTempFile("temp", ".swf"); - tempFile.deleteOnExit(); - swf.saveTo(new BufferedOutputStream(new FileOutputStream(tempFile))); - flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, swf.frameRate); - } catch (IOException iex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex); - } - } - } - - } /*else if (tagObj instanceof DefineVideoStreamTag) { - showCard(CARDEMPTYPANEL); - } else if ((tagObj instanceof DefineSoundTag) || (tagObj instanceof SoundStreamHeadTag) || (tagObj instanceof SoundStreamHead2Tag)) { - showCard(CARDEMPTYPANEL); - } */ else if (tagObj instanceof DefineBinaryDataTag) { - showCard(CARDEMPTYPANEL); - } else if (tagObj instanceof ASMSource) { - showCard(CARDACTIONSCRIPTPANEL); - actionPanel.setSource((ASMSource) tagObj, !forceReload); - } else if (tagObj instanceof ImageTag) { - ImageTag imageTag = (ImageTag) tagObj; - showHideImageReplaceButton(imageTag.importSupported()); - showCard(CARDIMAGEPANEL); - imagePanel.setImage(imageTag.getImage(imageTag.getSwf().tags)); - } else if ((tagObj instanceof DrawableTag) && (!(tagObj instanceof TextTag)) && (!(tagObj instanceof FontTag)) && (mainRibbon.isInternalFlashViewerSelected())) { - Tag tag = (Tag) tagObj; - showCard(CARDDRAWPREVIEWPANEL); - previewImagePanel.setDrawable((DrawableTag) tag, tag.getSwf(), tag.getSwf().characters, 50/*FIXME*/); - } else if ((tagObj instanceof FontTag) && (mainRibbon.isInternalFlashViewerSelected())) { - Tag tag = (Tag) tagObj; - showCard(CARDFLASHPANEL); - previewImagePanel.setDrawable((DrawableTag) tag, tag.getSwf(), tag.getSwf().characters, 50/*FIXME*/); - showFontTag((FontTag) tagObj); - } else if (tagObj instanceof FrameNode && ((FrameNode) tagObj).isDisplayed() && (mainRibbon.isInternalFlashViewerSelected())) { - showCard(CARDDRAWPREVIEWPANEL); - FrameNode fn = (FrameNode) tagObj; - SWF swf = fn.getSwf(); - List controlTags = swf.tags; - int containerId = 0; - RECT rect = swf.displayRect; - int totalFrameCount = swf.frameCount; - if (fn.getParent() instanceof DefineSpriteTag) { - controlTags = ((DefineSpriteTag) fn.getParent()).subTags; - containerId = ((DefineSpriteTag) fn.getParent()).spriteId; - rect = ((DefineSpriteTag) fn.getParent()).getRect(swf.characters, new Stack()); - totalFrameCount = ((DefineSpriteTag) fn.getParent()).frameCount; - } - previewImagePanel.setImage(SWF.frameToImage(containerId, fn.getFrame() - 1, swf.tags, controlTags, rect, totalFrameCount, new Stack())); - } else if (((tagObj instanceof FrameNode) && ((FrameNode) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag)) { - ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); - createAndShowTempSwf(tagObj); - - if (tagObj instanceof TextTag) { - TextTag textTag = (TextTag) tagObj; - parametersPanel.setVisible(true); - previewSplitPane.setDividerLocation(previewSplitPane.getWidth() / 2); - showDetailWithPreview(CARDTEXTPANEL); - textValue.setText(textTag.getFormattedText(textTag.getSwf().tags)); - } else if (tagObj instanceof FontTag) { - showFontTag((FontTag) tagObj); - } else { - parametersPanel.setVisible(false); - } - - } else { - showCard(CARDEMPTYPANEL); - } - } - - private void createAndShowTempSwf(Object tagObj) { - SWF swf; - try { - if (tempFile != null) { - tempFile.delete(); - } - tempFile = File.createTempFile("temp", ".swf"); - tempFile.deleteOnExit(); - - Color backgroundColor = View.swfBackgroundColor; - - if (tagObj instanceof FontTag) { //Fonts are always black on white - backgroundColor = View.DEFAULT_BACKGROUND_COLOR; - } - - if (tagObj instanceof FrameNode) { - FrameNode fn = (FrameNode) tagObj; - swf = fn.getSwf(); - if (fn.getParent() == null) { - for (Tag t : swf.tags) { - if (t instanceof SetBackgroundColorTag) { - backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); - break; - } - } - } - } else { - Tag tag = (Tag) tagObj; - swf = tag.getSwf(); - } - - int frameCount = 1; - int frameRate = swf.frameRate; - HashMap videoFrames = new HashMap<>(); - DefineVideoStreamTag vs = null; - if (tagObj instanceof DefineVideoStreamTag) { - vs = (DefineVideoStreamTag) tagObj; - swf.populateVideoFrames(vs.getCharacterId(), swf.tags, videoFrames); - frameCount = videoFrames.size(); - } - - List soundFrames = new ArrayList<>(); - if (tagObj instanceof SoundStreamHeadTypeTag) { - SWF.populateSoundStreamBlocks(swf.tags, (Tag) tagObj, soundFrames); - frameCount = soundFrames.size(); - } - - if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { - frameCount = 100; - frameRate = 50; - } - - if (tagObj instanceof DefineSoundTag) { - frameCount = 1; - } - - byte[] data; - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - SWFOutputStream sos2 = new SWFOutputStream(baos, 10); - int width = swf.displayRect.Xmax - swf.displayRect.Xmin; - int height = swf.displayRect.Ymax - swf.displayRect.Ymin; - sos2.writeRECT(swf.displayRect); - sos2.writeUI8(0); - sos2.writeUI8(frameRate); - sos2.writeUI16(frameCount); //framecnt - - /*FileAttributesTag fa = new FileAttributesTag(); - sos2.writeTag(fa); - */ - sos2.writeTag(new SetBackgroundColorTag(null, new RGB(backgroundColor))); - - if (tagObj instanceof FrameNode) { - FrameNode fn = (FrameNode) tagObj; - Object parent = fn.getParent(); - List subs = new ArrayList<>(); - if (parent == null) { - subs.addAll(swf.tags); - } else { - if (parent instanceof Container) { - subs = ((Container) parent).getSubItems(); - } - } - List doneCharacters = new ArrayList<>(); - int frameCnt = 1; - for (Object o : subs) { - if (o instanceof ShowFrameTag) { - frameCnt++; - continue; - } - if (frameCnt > fn.getFrame()) { - break; - } - Tag t = (Tag) o; - Set needed = t.getDeepNeededCharacters(swf.characters, new ArrayList()); - for (int n : needed) { - if (!doneCharacters.contains(n)) { - sos2.writeTag(classicTag(swf.characters.get(n))); - doneCharacters.add(n); - } - } - if (t instanceof CharacterTag) { - doneCharacters.add(((CharacterTag) t).getCharacterId()); - } - sos2.writeTag(classicTag(t)); - - if (parent != null) { - if (t instanceof PlaceObjectTypeTag) { - PlaceObjectTypeTag pot = (PlaceObjectTypeTag) t; - int chid = pot.getCharacterId(); - int depth = pot.getDepth(); - MATRIX mat = pot.getMatrix(); - if (mat == null) { - mat = new MATRIX(); - } - mat = (MATRIX) Helper.deepCopy(mat); - if (parent instanceof BoundedTag) { - RECT r = ((BoundedTag) parent).getRect(swf.characters, new Stack()); - mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; - mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2; - } else { - mat.translateX += width / 2; - mat.translateY += height / 2; - } - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, false, false, true, false, true, depth, chid, mat, null, 0, null, 0, null)); - - } - } - } - sos2.writeTag(new ShowFrameTag(null)); - } else { - - if (tagObj instanceof DefineBitsTag) { - JPEGTablesTag jtt = swf.jtt; - if (jtt != null) { - sos2.writeTag(jtt); - } - } else if (tagObj instanceof AloneTag) { - } else { - Set needed = ((Tag) tagObj).getDeepNeededCharacters(swf.characters, new ArrayList()); - for (int n : needed) { - sos2.writeTag(classicTag(swf.characters.get(n))); - } - } - - sos2.writeTag(classicTag((Tag) tagObj)); - - int chtId = 0; - if (tagObj instanceof CharacterTag) { - chtId = ((CharacterTag) tagObj).getCharacterId(); - } - - MATRIX mat = new MATRIX(); - mat.hasRotate = false; - mat.hasScale = false; - mat.translateX = 0; - mat.translateY = 0; - if (tagObj instanceof BoundedTag) { - RECT r = ((BoundedTag) tagObj).getRect(swf.characters, new Stack()); - mat.translateX = -r.Xmin; - mat.translateY = -r.Ymin; - mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; - mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2; - } else { - mat.translateX = width / 4; - mat.translateY = height / 4; - } - if (tagObj instanceof FontTag) { - - int countGlyphs = ((FontTag) tagObj).getGlyphShapeTable().size(); - int fontId = ((FontTag) tagObj).getFontId(); - int sloupcu = (int) Math.ceil(Math.sqrt(countGlyphs)); - int radku = (int) Math.ceil(((float) countGlyphs) / ((float) sloupcu)); - int x = 0; - int y = 1; - for (int f = 0; f < countGlyphs; f++) { - if (x >= sloupcu) { - x = 0; - y++; - } - List rec = new ArrayList<>(); - TEXTRECORD tr = new TEXTRECORD(); - int textHeight = height / radku; - tr.fontId = fontId; - tr.styleFlagsHasFont = true; - tr.textHeight = textHeight; - tr.glyphEntries = new GLYPHENTRY[1]; - tr.styleFlagsHasColor = true; - tr.textColor = new RGB(0, 0, 0); - tr.glyphEntries[0] = new GLYPHENTRY(); - tr.glyphEntries[0].glyphAdvance = 0; - tr.glyphEntries[0].glyphIndex = f; - rec.add(tr); - mat.translateX = x * width / sloupcu; - mat.translateY = y * height / radku; - sos2.writeTag(new DefineTextTag(null, 999 + f, new RECT(0, width, 0, height), new MATRIX(), rec)); - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1 + f, 999 + f, mat, null, 0, null, 0, null)); - x++; - } - sos2.writeTag(new ShowFrameTag(null)); - } else if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); - sos2.writeTag(new ShowFrameTag(null)); - int numFrames = 100; - for (int ratio = 0; ratio < 65536; ratio += 65536 / numFrames) { - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, false, true, 1, chtId, mat, null, ratio, null, 0, null)); - sos2.writeTag(new ShowFrameTag(null)); - } - } else if (tagObj instanceof SoundStreamHeadTypeTag) { - for (SoundStreamBlockTag blk : soundFrames) { - sos2.writeTag(blk); - sos2.writeTag(new ShowFrameTag(null)); - } - } else if (tagObj instanceof DefineSoundTag) { - ExportAssetsTag ea = new ExportAssetsTag(); - DefineSoundTag ds = (DefineSoundTag) tagObj; - ea.tags.add(ds.soundId); - ea.names.add("my_define_sound"); - sos2.writeTag(ea); - List actions; - DoActionTag doa; - - - doa = new DoActionTag(null, new byte[]{}, SWF.DEFAULT_VERSION, 0); - actions = ASMParser.parse(0, 0, false, - "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\"\n" - + "Push \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\" 0.0 \"Sound\"\n" - + "NewObject\n" - + "SetMember\n" - + "Push \"my_define_sound\" 1 \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"attachSound\"\n" - + "CallMethod\n" - + "Pop\n" - + "Stop", SWF.DEFAULT_VERSION, false); - doa.setActions(actions, SWF.DEFAULT_VERSION); - sos2.writeTag(doa); - sos2.writeTag(new ShowFrameTag(null)); - - - actions = ASMParser.parse(0, 0, false, - "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n" - + "StopSounds\n" - + "Push \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\" 0.0 \"Sound\"\n" - + "NewObject\n" - + "SetMember\n" - + "Push \"my_define_sound\" 1 \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"attachSound\"\n" - + "CallMethod\n" - + "Pop\n" - + "Push 9999 0.0 2 \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"start\"\n" - + "CallMethod\n" - + "Pop\n" - + "Stop", SWF.DEFAULT_VERSION, false); - doa.setActions(actions, SWF.DEFAULT_VERSION); - sos2.writeTag(doa); - sos2.writeTag(new ShowFrameTag(null)); - - actions = ASMParser.parse(0, 0, false, - "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"onSoundComplete\" \"start\" \"execParam\"\n" - + "StopSounds\n" - + "Push \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\" 0.0 \"Sound\"\n" - + "NewObject\n" - + "SetMember\n" - + "Push \"my_define_sound\" 1 \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"attachSound\"\n" - + "CallMethod\n" - + "Pop\n" - + "Push \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"onSoundComplete\"\n" - + "DefineFunction2 \"\" 0 2 false true true false true false true false false {\n" - + "Push 0.0 register1 \"my_sound\"\n" - + "GetMember\n" - + "Push \"start\"\n" - + "CallMethod\n" - + "Pop\n" - + "}\n" - + "SetMember\n" - + "Push \"_root\"\n" - + "GetVariable\n" - + "Push \"execParam\"\n" - + "GetMember\n" - + "Push 1 \"_root\"\n" - + "GetVariable\n" - + "Push \"my_sound\"\n" - + "GetMember\n" - + "Push \"start\"\n" - + "CallMethod\n" - + "Pop\n" - + "Stop", SWF.DEFAULT_VERSION, false); - doa.setActions(actions, SWF.DEFAULT_VERSION); - sos2.writeTag(doa); - sos2.writeTag(new ShowFrameTag(null)); - - - actions = ASMParser.parse(0, 0, false, - "StopSounds\n" - + "Stop", SWF.DEFAULT_VERSION, false); - doa.setActions(actions, SWF.DEFAULT_VERSION); - sos2.writeTag(doa); - sos2.writeTag(new ShowFrameTag(null)); - - - sos2.writeTag(new ShowFrameTag(null)); - if (flashPanel != null) { - flashPanel.specialPlayback = true; - } - } else if (tagObj instanceof DefineVideoStreamTag) { - - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, false, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); - List frs = new ArrayList<>(videoFrames.values()); - Collections.sort(frs, new Comparator() { - @Override - public int compare(VideoFrameTag o1, VideoFrameTag o2) { - return o1.frameNum - o2.frameNum; - } - }); - boolean first = true; - int ratio = 0; - for (VideoFrameTag f : frs) { - if (!first) { - ratio++; - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, false, false, true, 1, 0, null, null, ratio, null, 0, null)); - } - sos2.writeTag(f); - sos2.writeTag(new ShowFrameTag(null)); - first = false; - } - } else { - sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); - sos2.writeTag(new ShowFrameTag(null)); - } - - - }//not showframe - - sos2.writeTag(new EndTag(null)); - data = baos.toByteArray(); - } - - try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { - SWFOutputStream sos = new SWFOutputStream(fos, 10); - sos.write("FWS".getBytes()); - sos.write(swf.version); - sos.writeUI32(sos.getPos() + data.length + 4); - sos.write(data); - fos.flush(); - } - - showCard(CARDFLASHPANEL); - if (flashPanel != null) { - flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, frameRate); - } - } catch (IOException | com.jpexs.decompiler.flash.action.parser.ParseException ex) { - Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private void showFontTag(FontTag ft) { - if (mainRibbon.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) { - ((CardLayout) viewerCards.getLayout()).show(viewerCards, INTERNAL_VIEWER_CARD); - internelViewerPanel.setDrawable(ft, ft.getSwf(), ft.getSwf().characters, 1); - } else { - ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); - } - - parametersPanel.setVisible(true); - previewSplitPane.setDividerLocation(previewSplitPane.getWidth() / 2); - fontPanel.showFontTag(ft); - showDetailWithPreview(CARDFONTPANEL); - } - - public void refreshTree() { - List> expandedNodes = getExpandedNodes(tagTree); - - tagTree.setModel(new TagTreeModel(this, swfs)); - - expandSwfRoots(); - expandTreeNodes(tagTree, expandedNodes); - } - - public void expandSwfRoots() { - TreeModel model = tagTree.getModel(); - Object node = model.getRoot(); - int childCount = model.getChildCount(node); - for (int j = 0; j < childCount; j++) { - Object child = model.getChild(node, j); - tagTree.expandPath(new TreePath(new Object[] {node, child})); - } - } - - private List> getExpandedNodes(JTree tree) { - List> expandedNodes = new ArrayList<>(); - int rowCount = tree.getRowCount(); - for (int i = 0; i < rowCount; i++) { - 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); - } - } - return expandedNodes; - } - - private void expandTreeNodes(JTree tree, List> pathsToExpand) { - for (List pathAsStringList : pathsToExpand) { - expandTreeNode(tree, pathAsStringList); - } - } - - private void expandTreeNode(JTree tree, List pathAsStringList) { - TreeModel model = tree.getModel(); - Object node = model.getRoot(); - - if (pathAsStringList.isEmpty()) { - return; - } - if (!pathAsStringList.get(0).equals(node.toString())) { - return; - } - - List path = new ArrayList<>(); - path.add(node); - - for (int i = 1; i < pathAsStringList.size(); i++) { - String name = pathAsStringList.get(i); - int childCount = model.getChildCount(node); - for (int j = 0; j < childCount; j++) { - Object child = model.getChild(node, j); - if (child.toString().equals(name)) { - node = child; - path.add(node); - break; - } - } - } - - TreePath tp = new TreePath(path.toArray(new Object[path.size()])); - tree.expandPath(tp); - } - - public void setEditText(boolean edit) { - setEditText(edit, true); - } - - public void setEditText(boolean edit, boolean reload) { - textValue.setEditable(edit); - textSaveButton.setVisible(edit); - textEditButton.setVisible(!edit); - textCancelButton.setVisible(edit); - if (!edit && reload) { - reload(true); - } - } - - private boolean isFreeing; - - @Override - public boolean isFreeing() { - return isFreeing; - } - - @Override - public void free() { - isFreeing = true; - Helper.emptyObject(mainRibbon); - Helper.emptyObject(statusPanel); - Helper.emptyObject(this); - } - - public void clearErrorState() { - statusPanel.clearErrorState(); - } - public void setErrorState() { - statusPanel.setErrorState(); - } + public void setTitle(String string); + public String translate(String key); + public MainFramePanel getPanel(); + public boolean isVisible(); + public void setVisible(boolean b); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java new file mode 100644 index 000000000..831528c1a --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassic.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; +import javax.swing.JFrame; + +/** + * + * @author JPEXS + */ +public final class MainFrameClassic extends AppFrame implements MainFrame { + + public MainFramePanel panel; + private MainFrameMenu mainMenu; + + public MainFrameClassic() { + super(); + + FlashPlayerPanel flashPanel = null; + try { + flashPanel = new FlashPlayerPanel(this); + } catch (FlashUnsupportedException fue) { + } + + boolean externalFlashPlayerUnavailable = flashPanel == null; + mainMenu = new MainFrameClassicMenu(this, externalFlashPlayerUnavailable); + + panel = new MainFramePanel(this, mainMenu, flashPanel); + + int w = Configuration.guiWindowWidth.get(); + int h = Configuration.guiWindowHeight.get(); + Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + if (w > dim.width) { + w = dim.width; + } + if (h > dim.height) { + h = dim.height; + } + setSize(w, h); + + boolean maximizedHorizontal = Configuration.guiWindowMaximizedHorizontal.get(); + boolean maximizedVertical = Configuration.guiWindowMaximizedVertical.get(); + + int state = 0; + if (maximizedHorizontal) { + state |= JFrame.MAXIMIZED_HORIZ; + } + if (maximizedVertical) { + state |= JFrame.MAXIMIZED_VERT; + } + setExtendedState(state); + + View.setWindowIcon(this); + addWindowStateListener(new WindowStateListener() { + @Override + public void windowStateChanged(WindowEvent e) { + int state = e.getNewState(); + Configuration.guiWindowMaximizedHorizontal.set((state & JFrame.MAXIMIZED_HORIZ) == JFrame.MAXIMIZED_HORIZ); + Configuration.guiWindowMaximizedVertical.set((state & JFrame.MAXIMIZED_VERT) == JFrame.MAXIMIZED_VERT); + } + }); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + int state = getExtendedState(); + if ((state & JFrame.MAXIMIZED_HORIZ) == 0) { + Configuration.guiWindowWidth.set(getWidth()); + } + if ((state & JFrame.MAXIMIZED_VERT) == 0) { + Configuration.guiWindowHeight.set(getHeight()); + } + } + }); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (Main.proxyFrame != null) { + if (Main.proxyFrame.isVisible()) { + return; + } + } + if (Main.loadFromMemoryFrame != null) { + if (Main.loadFromMemoryFrame.isVisible()) { + return; + } + } + if (Main.loadFromCacheFrame != null) { + if (Main.loadFromCacheFrame.isVisible()) { + return; + } + } + Main.exit(); + } + }); + + java.awt.Container cnt = getContentPane(); + cnt.setLayout(new BorderLayout()); + cnt.add(panel); + + View.centerScreen(this); + } + + @Override + public MainFramePanel getPanel() { + return panel; + } + } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java new file mode 100644 index 000000000..d3d2e67a0 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameClassicMenu.java @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2010-2013 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.ApplicationInfo; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.console.ContextMenuTools; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.helpers.Cache; +import com.sun.jna.Platform; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; + +/** + * + * @author JPEXS + */ +public class MainFrameClassicMenu implements MainFrameMenu, ActionListener { + + static final String ACTION_RELOAD = "RELOAD"; + static final String ACTION_ADVANCED_SETTINGS = "ADVANCEDSETTINGS"; + static final String ACTION_LOAD_MEMORY = "LOADMEMORY"; + static final String ACTION_LOAD_CACHE = "LOADCACHE"; + static final String ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP = "GOTODOCUMENTCLASSONSTARTUP"; + static final String ACTION_AUTO_RENAME_IDENTIFIERS = "AUTORENAMEIDENTIFIERS"; + static final String ACTION_CACHE_ON_DISK = "CACHEONDISK"; + static final String ACTION_SET_LANGUAGE = "SETLANGUAGE"; + static final String ACTION_DISABLE_DECOMPILATION = "DISABLEDECOMPILATION"; + static final String ACTION_ASSOCIATE = "ASSOCIATE"; + static final String ACTION_GOTO_DOCUMENT_CLASS = "GOTODOCUMENTCLASS"; + static final String ACTION_PARALLEL_SPEED_UP = "PARALLELSPEEDUP"; + static final String ACTION_INTERNAL_VIEWER_SWITCH = "INTERNALVIEWERSWITCH"; + static final String ACTION_SEARCH_AS = "SEARCHAS"; + static final String ACTION_AUTO_DEOBFUSCATE = "AUTODEOBFUSCATE"; + static final String ACTION_EXIT = "EXIT"; + + static final String ACTION_RENAME_ONE_IDENTIFIER = "RENAMEONEIDENTIFIER"; + static final String ACTION_ABOUT = "ABOUT"; + static final String ACTION_SHOW_PROXY = "SHOWPROXY"; + static final String ACTION_SUB_LIMITER = "SUBLIMITER"; + static final String ACTION_SAVE = "SAVE"; + static final String ACTION_SAVE_AS = "SAVEAS"; + static final String ACTION_SAVE_AS_EXE = "SAVEASEXE"; + static final String ACTION_OPEN = "OPEN"; + static final String ACTION_EXPORT_FLA = "EXPORTFLA"; + public static final String ACTION_EXPORT_SEL = "EXPORTSEL"; + static final String ACTION_EXPORT = "EXPORT"; + static final String ACTION_CHECK_UPDATES = "CHECKUPDATES"; + static final String ACTION_HELP_US = "HELPUS"; + static final String ACTION_HOMEPAGE = "HOMEPAGE"; + static final String ACTION_RESTORE_CONTROL_FLOW = "RESTORECONTROLFLOW"; + static final String ACTION_RESTORE_CONTROL_FLOW_ALL = "RESTORECONTROLFLOWALL"; + static final String ACTION_RENAME_IDENTIFIERS = "RENAMEIDENTIFIERS"; + static final String ACTION_DEOBFUSCATE = "DEOBFUSCATE"; + static final String ACTION_DEOBFUSCATE_ALL = "DEOBFUSCATEALL"; + static final String ACTION_REMOVE_NON_SCRIPTS = "REMOVENONSCRIPTS"; + static final String ACTION_REFRESH_DECOMPILED = "REFRESHDECOMPILED"; + + private MainFrameClassic mainFrame; + + private JCheckBoxMenuItem miAutoDeobfuscation; + private JCheckBoxMenuItem miInternalViewer; + private JCheckBoxMenuItem miParallelSpeedUp; + private JCheckBoxMenuItem miAssociate; + private JCheckBoxMenuItem miDecompile; + private JCheckBoxMenuItem miCacheDisk; + private JCheckBoxMenuItem miGotoMainClassOnStartup; + private JCheckBoxMenuItem miAutoRenameIdentifiers; + private JMenuItem saveCommandButton; + private JMenuItem saveasCommandButton; + private JMenuItem saveasexeCommandButton; + private JMenuItem exportAllCommandButton; + private JMenuItem exportFlaCommandButton; + private JMenuItem exportSelectionCommandButton; + + private JMenuItem reloadCommandButton; + private JMenuItem renameinvalidCommandButton; + private JMenuItem globalrenameCommandButton; + private JMenuItem deobfuscationCommandButton; + private JMenuItem searchCommandButton; + private JMenuItem gotoDocumentClassCommandButton; + + public MainFrameClassicMenu(MainFrameClassic mainFrame, boolean externalFlashPlayerUnavailable) { + this.mainFrame = mainFrame; + + createMenuBar(externalFlashPlayerUnavailable); + } + + @Override + public boolean isInternalFlashViewerSelected() { + return miInternalViewer.isSelected(); + } + + private String translate(String key) { + return mainFrame.translate(key); + } + + private void assignListener(JMenuItem b, final String command) { + final MainFrameClassicMenu t = this; + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + t.actionPerformed(new ActionEvent(e.getSource(), 0, command)); + } + }); + } + + private String fixCommandTitle(String title) { + if (title.length() > 2) { + if (title.charAt(1) == ' ') { + title = title.charAt(0) + "\u00A0" + title.substring(2); + } + } + return title; + } + + private void createMenuBar(boolean externalFlashPlayerUnavailable) { + JMenuBar menuBar = new JMenuBar(); + + JMenu menuFile = new JMenu(translate("menu.file")); + JMenuItem miOpen = new JMenuItem(translate("menu.file.open")); + miOpen.setIcon(View.getIcon("open16")); + miOpen.setActionCommand(ACTION_OPEN); + miOpen.addActionListener(this); + JMenuItem miSave = new JMenuItem(translate("menu.file.save")); + miSave.setIcon(View.getIcon("save16")); + miSave.setActionCommand(ACTION_SAVE); + miSave.addActionListener(this); + JMenuItem miSaveAs = new JMenuItem(translate("menu.file.saveas")); + miSaveAs.setIcon(View.getIcon("saveas16")); + miSaveAs.setActionCommand(ACTION_SAVE_AS); + miSaveAs.addActionListener(this); + JMenuItem miSaveAsExe = new JMenuItem(translate("menu.file.saveasexe")); + miSaveAsExe.setIcon(View.getIcon("saveas16")); + miSaveAsExe.setActionCommand(ACTION_SAVE_AS_EXE); + miSaveAsExe.addActionListener(this); + + JMenuItem menuExportFla = new JMenuItem(translate("menu.file.export.fla")); + menuExportFla.setActionCommand(ACTION_EXPORT_FLA); + menuExportFla.addActionListener(this); + menuExportFla.setIcon(View.getIcon("flash16")); + + JMenuItem menuExportAll = new JMenuItem(translate("menu.file.export.all")); + menuExportAll.setActionCommand(ACTION_EXPORT); + menuExportAll.addActionListener(this); + JMenuItem menuExportSel = new JMenuItem(translate("menu.file.export.selection")); + menuExportSel.setActionCommand(ACTION_EXPORT_SEL); + menuExportSel.addActionListener(this); + menuExportAll.setIcon(View.getIcon("export16")); + menuExportSel.setIcon(View.getIcon("exportsel16")); + + + + menuFile.add(miOpen); + menuFile.add(miSave); + menuFile.add(miSaveAs); + menuFile.add(miSaveAsExe); + menuFile.add(menuExportFla); + menuFile.add(menuExportAll); + menuFile.add(menuExportSel); + menuFile.addSeparator(); + JMenuItem miClose = new JMenuItem(translate("menu.file.exit")); + miClose.setIcon(View.getIcon("exit16")); + miClose.setActionCommand(ACTION_EXIT); + miClose.addActionListener(this); + menuFile.add(miClose); + menuBar.add(menuFile); + JMenu menuDeobfuscation = new JMenu(translate("menu.tools.deobfuscation")); + menuDeobfuscation.setIcon(View.getIcon("deobfuscate16")); + + JMenuItem miDeobfuscation = new JMenuItem(translate("menu.tools.deobfuscation.pcode")); + miDeobfuscation.setActionCommand(ACTION_DEOBFUSCATE); + miDeobfuscation.addActionListener(this); + + miAutoDeobfuscation = new JCheckBoxMenuItem(translate("menu.settings.autodeobfuscation")); + miAutoDeobfuscation.setSelected(Configuration.autoDeobfuscate.get()); + miAutoDeobfuscation.addActionListener(this); + miAutoDeobfuscation.setActionCommand(ACTION_AUTO_DEOBFUSCATE); + + JMenuItem miRenameOneIdentifier = new JMenuItem(translate("menu.tools.deobfuscation.globalrename")); + miRenameOneIdentifier.setActionCommand(ACTION_RENAME_ONE_IDENTIFIER); + miRenameOneIdentifier.addActionListener(this); + + JMenuItem miRenameIdentifiers = new JMenuItem(translate("menu.tools.deobfuscation.renameinvalid")); + miRenameIdentifiers.setActionCommand(ACTION_RENAME_IDENTIFIERS); + miRenameIdentifiers.addActionListener(this); + + + menuDeobfuscation.add(miRenameOneIdentifier); + menuDeobfuscation.add(miRenameIdentifiers); + menuDeobfuscation.add(miDeobfuscation); + JMenu menuTools = new JMenu(translate("menu.tools")); + JMenuItem miProxy = new JMenuItem(translate("menu.tools.proxy")); + miProxy.setActionCommand(ACTION_SHOW_PROXY); + miProxy.setIcon(View.getIcon("proxy16")); + miProxy.addActionListener(this); + + JMenuItem miSearchScript = new JMenuItem(translate("menu.tools.searchas")); + miSearchScript.addActionListener(this); + miSearchScript.setActionCommand(ACTION_SEARCH_AS); + miSearchScript.setIcon(View.getIcon("search16")); + + menuTools.add(miSearchScript); + + miInternalViewer = new JCheckBoxMenuItem(translate("menu.settings.internalflashviewer")); + miInternalViewer.setSelected(Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable); + if (externalFlashPlayerUnavailable) { + miInternalViewer.setEnabled(false); + } + miInternalViewer.setActionCommand(ACTION_INTERNAL_VIEWER_SWITCH); + miInternalViewer.addActionListener(this); + + miParallelSpeedUp = new JCheckBoxMenuItem(translate("menu.settings.parallelspeedup")); + miParallelSpeedUp.setSelected(Configuration.parallelSpeedUp.get()); + miParallelSpeedUp.setActionCommand(ACTION_PARALLEL_SPEED_UP); + miParallelSpeedUp.addActionListener(this); + + + menuTools.add(miProxy); + + menuTools.add(menuDeobfuscation); + + JMenuItem miGotoDocumentClass = new JMenuItem(translate("menu.tools.gotodocumentclass")); + miGotoDocumentClass.setActionCommand(ACTION_GOTO_DOCUMENT_CLASS); + miGotoDocumentClass.addActionListener(this); + menuBar.add(menuTools); + + miDecompile = new JCheckBoxMenuItem(translate("menu.settings.disabledecompilation")); + miDecompile.setSelected(!Configuration.decompile.get()); + miDecompile.setActionCommand(ACTION_DISABLE_DECOMPILATION); + miDecompile.addActionListener(this); + + miCacheDisk = new JCheckBoxMenuItem(translate("menu.settings.cacheOnDisk")); + miCacheDisk.setSelected(Configuration.cacheOnDisk.get()); + miCacheDisk.setActionCommand(ACTION_CACHE_ON_DISK); + miCacheDisk.addActionListener(this); + + miGotoMainClassOnStartup = new JCheckBoxMenuItem(translate("menu.settings.gotoMainClassOnStartup")); + miGotoMainClassOnStartup.setSelected(Configuration.gotoMainClassOnStartup.get()); + miGotoMainClassOnStartup.setActionCommand(ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP); + miGotoMainClassOnStartup.addActionListener(this); + + miAutoRenameIdentifiers = new JCheckBoxMenuItem(translate("menu.settings.autoRenameIdentifiers")); + miAutoRenameIdentifiers.setSelected(Configuration.autoRenameIdentifiers.get()); + miAutoRenameIdentifiers.setActionCommand(ACTION_AUTO_RENAME_IDENTIFIERS); + miAutoRenameIdentifiers.addActionListener(this); + + JMenu menuSettings = new JMenu(translate("menu.settings")); + menuSettings.add(miAutoDeobfuscation); + menuSettings.add(miInternalViewer); + menuSettings.add(miParallelSpeedUp); + menuSettings.add(miDecompile); + menuSettings.add(miCacheDisk); + menuSettings.add(miGotoMainClassOnStartup); + menuSettings.add(miAutoRenameIdentifiers); + + miAssociate = new JCheckBoxMenuItem(translate("menu.settings.addtocontextmenu")); + miAssociate.setActionCommand(ACTION_ASSOCIATE); + miAssociate.addActionListener(this); + miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); + + + JMenuItem miLanguage = new JMenuItem(translate("menu.settings.language")); + miLanguage.setActionCommand(ACTION_SET_LANGUAGE); + miLanguage.addActionListener(this); + + if (Platform.isWindows()) { + menuSettings.add(miAssociate); + } + menuSettings.add(miLanguage); + + menuBar.add(menuSettings); + JMenu menuHelp = new JMenu(translate("menu.help")); + JMenuItem miAbout = new JMenuItem(translate("menu.help.about")); + miAbout.setIcon(View.getIcon("about16")); + + miAbout.setActionCommand(ACTION_ABOUT); + miAbout.addActionListener(this); + + JMenuItem miCheckUpdates = new JMenuItem(translate("menu.help.checkupdates")); + miCheckUpdates.setActionCommand(ACTION_CHECK_UPDATES); + miCheckUpdates.setIcon(View.getIcon("update16")); + miCheckUpdates.addActionListener(this); + + JMenuItem miHelpUs = new JMenuItem(translate("menu.help.helpus")); + miHelpUs.setActionCommand(ACTION_HELP_US); + miHelpUs.setIcon(View.getIcon("donate16")); + miHelpUs.addActionListener(this); + + JMenuItem miHomepage = new JMenuItem(translate("menu.help.homepage")); + miHomepage.setActionCommand(ACTION_HOMEPAGE); + miHomepage.setIcon(View.getIcon("homepage16")); + miHomepage.addActionListener(this); + + + menuHelp.add(miCheckUpdates); + menuHelp.add(miHelpUs); + menuHelp.add(miHomepage); + menuHelp.add(miAbout); + menuBar.add(menuHelp); + + mainFrame.setJMenuBar(menuBar); + + //if (hasAbc) { + menuTools.add(miGotoDocumentClass); + //} + } + + @Override + public void updateComponets(SWF swf, List abcList) { + boolean swfLoaded = swf != null; + boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty(); + + /*saveCommandButton.setEnabled(swfLoaded); + saveasCommandButton.setEnabled(swfLoaded); + saveasexeCommandButton.setEnabled(swfLoaded); + exportAllCommandButton.setEnabled(swfLoaded); + exportFlaCommandButton.setEnabled(swfLoaded); + exportSelectionCommandButton.setEnabled(swfLoaded); + reloadCommandButton.setEnabled(swfLoaded); + + renameinvalidCommandButton.setEnabled(swfLoaded); + globalrenameCommandButton.setEnabled(swfLoaded); + deobfuscationCommandButton.setEnabled(swfLoaded); + searchCommandButton.setEnabled(swfLoaded); + + gotoDocumentClassCommandButton.setEnabled(hasAbc); + deobfuscationCommandButton.setEnabled(hasAbc);*/ + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand()) { + case ACTION_RELOAD: + if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) { + Main.reloadSWFs(); + } + break; + case ACTION_ADVANCED_SETTINGS: + Main.advancedSettings(); + break; + case ACTION_LOAD_MEMORY: + Main.loadFromMemory(); + break; + case ACTION_LOAD_CACHE: + Main.loadFromCache(); + break; + case ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP: + Configuration.gotoMainClassOnStartup.set(miGotoMainClassOnStartup.isSelected()); + break; + case ACTION_AUTO_RENAME_IDENTIFIERS: + Configuration.autoRenameIdentifiers.set(miAutoRenameIdentifiers.isSelected()); + break; + case ACTION_CACHE_ON_DISK: + Configuration.cacheOnDisk.set(miCacheDisk.isSelected()); + if (miCacheDisk.isSelected()) { + Cache.setStorageType(Cache.STORAGE_FILES); + } else { + Cache.setStorageType(Cache.STORAGE_MEMORY); + } + break; + case ACTION_SET_LANGUAGE: + new SelectLanguageDialog().display(); + break; + case ACTION_DISABLE_DECOMPILATION: + Configuration.decompile.set(!miDecompile.isSelected()); + mainFrame.panel.disableDecompilationChanged(); + break; + case ACTION_ASSOCIATE: + if (miAssociate.isSelected() == ContextMenuTools.isAddedToContextMenu()) { + return; + } + ContextMenuTools.addToContextMenu(miAssociate.isSelected()); + + //Update checkbox menuitem accordingly (User can cancel rights elevation) + new Timer().schedule(new TimerTask() { + @Override + public void run() { + miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); + } + }, 1000); //It takes some time registry change to apply + break; + case ACTION_GOTO_DOCUMENT_CLASS: + mainFrame.panel.gotoDocumentClass(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_PARALLEL_SPEED_UP: + String confStr = translate("message.confirm.parallel") + "\r\n"; + if (miParallelSpeedUp.isSelected()) { + 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((Boolean) miParallelSpeedUp.isSelected()); + } else { + miParallelSpeedUp.setSelected(!miParallelSpeedUp.isSelected()); + } + break; + case ACTION_INTERNAL_VIEWER_SWITCH: + Configuration.internalFlashViewer.set(miInternalViewer.isSelected()); + mainFrame.panel.reload(true); + break; + case ACTION_SEARCH_AS: + mainFrame.panel.searchAs(); + break; + case ACTION_AUTO_DEOBFUSCATE: + if (View.showConfirmDialog(mainFrame.panel, translate("message.confirm.autodeobfuscate") + "\r\n" + (miAutoDeobfuscation.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { + Configuration.autoDeobfuscate.set(miAutoDeobfuscation.isSelected()); + mainFrame.panel.autoDeobfuscateChanged(); + } else { + miAutoDeobfuscation.setSelected(!miAutoDeobfuscation.isSelected()); + } + break; + case ACTION_EXIT: + mainFrame.panel.setVisible(false); + if (Main.proxyFrame != null) { + if (Main.proxyFrame.isVisible()) { + return; + } + } + Main.exit(); + break; + } + + if (Main.isWorking()) { + return; + } + + switch (e.getActionCommand()) { + case ACTION_RENAME_ONE_IDENTIFIER: + mainFrame.panel.renameOneIdentifier(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_ABOUT: + Main.about(); + break; + case ACTION_SHOW_PROXY: + Main.showProxy(); + break; + case ACTION_SUB_LIMITER: + if (e.getSource() instanceof JCheckBoxMenuItem) { + Main.setSubLimiter(((JCheckBoxMenuItem) e.getSource()).getState()); + } + break; + case ACTION_SAVE: + try { + SWF swf = mainFrame.panel.getCurrentSwf(); + Main.saveFile(swf, swf.file); + } catch (IOException ex) { + Logger.getLogger(MainFrameClassicMenu.class.getName()).log(Level.SEVERE, null, ex); + View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE); + } + break; + case ACTION_SAVE_AS: + { + SWF swf = mainFrame.panel.getCurrentSwf(); + if (Main.saveFileDialog(swf)) { + mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); + saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null); + } + } + break; + case ACTION_SAVE_AS_EXE: + { + SWF swf = mainFrame.panel.getCurrentSwf(); + if (Main.saveFileDialog(swf, ".exe")) { + mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); + saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null); + } + } + break; + case ACTION_OPEN: + Main.openFileDialog(); + break; + case ACTION_EXPORT_FLA: + mainFrame.panel.exportFla(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_EXPORT_SEL: + case ACTION_EXPORT: + boolean onlySel = e.getActionCommand().endsWith("SEL"); + mainFrame.panel.export(onlySel); + break; + case ACTION_CHECK_UPDATES: + if (!Main.checkForUpdates()) { + View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE); + } + break; + case ACTION_HELP_US: + String helpUsURL = ApplicationInfo.PROJECT_PAGE + "/help_us.html"; + if (java.awt.Desktop.isDesktopSupported()) { + java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); + try { + java.net.URI uri = new java.net.URI(helpUsURL); + desktop.browse(uri); + } catch (URISyntaxException | IOException ex) { + } + } else { + View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL)); + } + break; + case ACTION_HOMEPAGE: + String homePageURL = ApplicationInfo.PROJECT_PAGE; + if (java.awt.Desktop.isDesktopSupported()) { + java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); + try { + java.net.URI uri = new java.net.URI(homePageURL); + desktop.browse(uri); + } catch (URISyntaxException | IOException ex) { + } + } else { + View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL)); + } + break; + case ACTION_RESTORE_CONTROL_FLOW: + case ACTION_RESTORE_CONTROL_FLOW_ALL: + boolean all = e.getActionCommand().endsWith("ALL"); + mainFrame.panel.restoreControlFlow(all); + break; + case ACTION_RENAME_IDENTIFIERS: + mainFrame.panel.renameIdentifiers(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_DEOBFUSCATE: + case ACTION_DEOBFUSCATE_ALL: + mainFrame.panel.deobfuscate(); + break; + case ACTION_REMOVE_NON_SCRIPTS: + mainFrame.panel.removeNonScripts(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_REFRESH_DECOMPILED: + mainFrame.panel.refreshDecompiled(); + break; + } + } + +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java new file mode 100644 index 000000000..668c1351f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010-2013 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.SWF; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import java.util.List; + +/** + * + * @author JPEXS + */ +public interface MainFrameMenu { + + public boolean isInternalFlashViewerSelected(); + + public void updateComponets(SWF swf, List abcList); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFramePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFramePanel.java new file mode 100644 index 000000000..659904344 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFramePanel.java @@ -0,0 +1,2864 @@ +/* + * Copyright (C) 2010-2013 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.AbortRetryIgnoreHandler; +import com.jpexs.decompiler.flash.ApplicationInfo; +import com.jpexs.decompiler.flash.FrameNode; +import com.jpexs.decompiler.flash.PackageNode; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.TagNode; +import com.jpexs.decompiler.flash.TreeElementItem; +import com.jpexs.decompiler.flash.TreeNode; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.RenameType; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.gui.abc.ABCPanel; +import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; +import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog; +import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane; +import com.jpexs.decompiler.flash.gui.abc.TreeElement; +import com.jpexs.decompiler.flash.gui.action.ActionPanel; +import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; +import com.jpexs.decompiler.flash.gui.player.PlayerControls; +import com.jpexs.decompiler.flash.helpers.Freed; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; +import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; +import com.jpexs.decompiler.flash.tags.DefineBitsTag; +import com.jpexs.decompiler.flash.tags.DefineButton2Tag; +import com.jpexs.decompiler.flash.tags.DefineButtonTag; +import com.jpexs.decompiler.flash.tags.DefineEditTextTag; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.DefineFont3Tag; +import com.jpexs.decompiler.flash.tags.DefineFont4Tag; +import com.jpexs.decompiler.flash.tags.DefineFontTag; +import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; +import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; +import com.jpexs.decompiler.flash.tags.DefineShape2Tag; +import com.jpexs.decompiler.flash.tags.DefineShape3Tag; +import com.jpexs.decompiler.flash.tags.DefineShape4Tag; +import com.jpexs.decompiler.flash.tags.DefineShapeTag; +import com.jpexs.decompiler.flash.tags.DefineSoundTag; +import com.jpexs.decompiler.flash.tags.DefineSpriteTag; +import com.jpexs.decompiler.flash.tags.DefineText2Tag; +import com.jpexs.decompiler.flash.tags.DefineTextTag; +import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; +import com.jpexs.decompiler.flash.tags.DoActionTag; +import com.jpexs.decompiler.flash.tags.EndTag; +import com.jpexs.decompiler.flash.tags.ExportAssetsTag; +import com.jpexs.decompiler.flash.tags.JPEGTablesTag; +import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; +import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; +import com.jpexs.decompiler.flash.tags.ShowFrameTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; +import com.jpexs.decompiler.flash.tags.SymbolClassTag; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.AloneTag; +import com.jpexs.decompiler.flash.tags.base.BoundedTag; +import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.Container; +import com.jpexs.decompiler.flash.tags.base.ContainerItem; +import com.jpexs.decompiler.flash.tags.base.DrawableTag; +import com.jpexs.decompiler.flash.tags.base.FontTag; +import com.jpexs.decompiler.flash.tags.base.ImageTag; +import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; +import com.jpexs.decompiler.flash.tags.base.TextTag; +import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; +import com.jpexs.decompiler.flash.tags.text.ParseException; +import com.jpexs.decompiler.flash.types.GLYPHENTRY; +import com.jpexs.decompiler.flash.types.MATRIX; +import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.RGB; +import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.jpexs.decompiler.graph.ExportMode; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.Stack; +import java.util.concurrent.CancellationException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +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.JProgressBar; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.plaf.basic.BasicLabelUI; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import org.pushingpixels.flamingo.api.common.AbstractCommandButton; +import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState; +import org.pushingpixels.flamingo.api.common.CommandButtonLayoutManager; +import org.pushingpixels.flamingo.api.common.icon.ResizableIcon; +import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton; + +/** + * + * @author JPEXS + */ +public class MainFramePanel extends JPanel implements ActionListener, TreeSelectionListener, Freed { + + private MainFrame mainFrame; + private List swfs; + private ABCPanel abcPanel; + private ActionPanel actionPanel; + private JPanel welcomePanel; + private MainFrameStatusPanel statusPanel; + private MainFrameMenu mainMenu; + private FontPanel fontPanel; + private JProgressBar progressBar = new JProgressBar(0, 100); + private DeobfuscationDialog deobfuscationDialog; + public JTree tagTree; + private FlashPlayerPanel flashPanel; + private JPanel contentPanel; + private JPanel displayPanel; + private ImagePanel imagePanel; + private ImagePanel previewImagePanel; + private SWFPreviwPanel swfPreviewPanel; + private boolean isWelcomeScreen = true; + private static final String CARDFLASHPANEL = "Flash card"; + private static final String CARDSWFPREVIEWPANEL = "SWF card"; + private static final String CARDDRAWPREVIEWPANEL = "Draw card"; + private static final String CARDIMAGEPANEL = "Image card"; + private static final String CARDEMPTYPANEL = "Empty card"; + private static final String CARDACTIONSCRIPTPANEL = "ActionScript card"; + private static final String CARDACTIONSCRIPT3PANEL = "ActionScript3 card"; + private static final String DETAILCARDAS3NAVIGATOR = "Traits list"; + private static final String DETAILCARDEMPTYPANEL = "Empty card"; + private static final String CARDTEXTPANEL = "Text card"; + private static final String CARDFONTPANEL = "Font card"; + private static final String FLASH_VIEWER_CARD = "FLASHVIEWER"; + private static final String INTERNAL_VIEWER_CARD = "INTERNALVIEWER"; + private static final String SPLIT_PANE1 = "SPLITPANE1"; + private static final String WELCOME_PANEL = "WELCOMEPANEL"; + private LineMarkedEditorPane textValue; + private JSplitPane splitPane1; + private JSplitPane splitPane2; + private boolean splitsInited = false; + private JPanel detailPanel; + private JTextField filterField = new MyTextField(""); + private JPanel searchPanel; + private JPanel displayWithPreview; + private JButton textSaveButton; + private JButton textEditButton; + private JButton textCancelButton; + private JPanel parametersPanel; + private JSplitPane previewSplitPane; + private JButton imageReplaceButton; + private JPanel imageButtonsPanel; + private PlayerControls flashControls; + private ImagePanel internelViewerPanel; + private JPanel viewerCards; + private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler(); + private CancellableWorker setSourceWorker; + public TreeNode oldValue; + private File tempFile; + + private static final String ACTION_SELECT_COLOR = "SELECTCOLOR"; + private static final String ACTION_REPLACE_IMAGE = "REPLACEIMAGE"; + private static final String ACTION_REPLACE_BINARY = "REPLACEBINARY"; + private static final String ACTION_REMOVE_ITEM = "REMOVEITEM"; + private static final String ACTION_EDIT_TEXT = "EDITTEXT"; + private static final String ACTION_CANCEL_TEXT = "CANCELTEXT"; + private static final String ACTION_SAVE_TEXT = "SAVETEXT"; + private static final String ACTION_CLOSE_SWF = "CLOSESWF"; + + public void setPercent(int percent) { + progressBar.setValue(percent); + progressBar.setVisible(true); + } + + public void hidePercent() { + if (progressBar.isVisible()) { + progressBar.setVisible(false); + } + } + + static { + try { + File.createTempFile("temp", ".swf").delete(); //First call to this is slow, so make it first + } catch (IOException ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private static void addTab(JTabbedPane tabbedPane, Component tab, String title, Icon icon) { + tabbedPane.add(tab); + + JLabel lbl = new JLabel(title); + lbl.setIcon(icon); + lbl.setIconTextGap(5); + lbl.setHorizontalTextPosition(SwingConstants.RIGHT); + + tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, lbl); + } + + public void setStatus(String s) { + statusPanel.setStatus(s); + } + + public void setWorkStatus(String s, CancellableWorker worker) { + statusPanel.setWorkStatus(s, worker); + } + + private void createContextMenu() { + final JPopupMenu contextPopupMenu = new JPopupMenu(); + final JMenuItem removeMenuItem = new JMenuItem(translate("contextmenu.remove")); + removeMenuItem.addActionListener(this); + removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM); + final JMenuItem exportSelectionMenuItem = new JMenuItem(translate("menu.file.export.selection")); + exportSelectionMenuItem.setActionCommand(MainFrameRibbonMenu.ACTION_EXPORT_SEL); + exportSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(exportSelectionMenuItem); + final JMenuItem replaceImageSelectionMenuItem = new JMenuItem(translate("button.replace")); + replaceImageSelectionMenuItem.setActionCommand(ACTION_REPLACE_IMAGE); + replaceImageSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(replaceImageSelectionMenuItem); + final JMenuItem replaceBinarySelectionMenuItem = new JMenuItem(translate("button.replace")); + replaceBinarySelectionMenuItem.setActionCommand(ACTION_REPLACE_BINARY); + replaceBinarySelectionMenuItem.addActionListener(this); + contextPopupMenu.add(replaceBinarySelectionMenuItem); + final JMenuItem closeSelectionMenuItem = new JMenuItem(translate("contextmenu.closeSwf")); + closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF); + closeSelectionMenuItem.addActionListener(this); + contextPopupMenu.add(closeSelectionMenuItem); + + contextPopupMenu.add(removeMenuItem); + tagTree.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + + int row = tagTree.getClosestRowForLocation(e.getX(), e.getY()); + int[] selectionRows = tagTree.getSelectionRows(); + if (!Helper.contains(selectionRows, row)) { + tagTree.setSelectionRow(row); + } + + TreePath[] paths = tagTree.getSelectionPaths(); + if (paths == null || paths.length == 0) { + return; + } + boolean allSelectedIsTag = true; + for (TreePath treePath : paths) { + Object tagObj = treePath.getLastPathComponent(); + + if (tagObj instanceof TagNode) { + Object tag = ((TagNode) tagObj).tag; + if (!(tag instanceof Tag)) { + allSelectedIsTag = false; + break; + } + } else { + allSelectedIsTag = false; + } + } + + replaceImageSelectionMenuItem.setVisible(false); + replaceBinarySelectionMenuItem.setVisible(false); + closeSelectionMenuItem.setVisible(false); + + if (paths.length == 1) { + Object tagObj = paths[0].getLastPathComponent(); + + if (tagObj instanceof TagNode) { + Object tag = ((TagNode) tagObj).tag; + + if (tag instanceof ImageTag && ((ImageTag) tag).importSupported()) { + replaceImageSelectionMenuItem.setVisible(true); + } + if (tag instanceof DefineBinaryDataTag) { + replaceBinarySelectionMenuItem.setVisible(true); + } + } + + if (tagObj instanceof SWFRoot) { + closeSelectionMenuItem.setVisible(true); + } + } + + removeMenuItem.setVisible(allSelectedIsTag); + contextPopupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + } + + private JPanel createWelcomePanel() { + JPanel welcomePanel = new JPanel(); + welcomePanel.setLayout(new BoxLayout(welcomePanel, BoxLayout.Y_AXIS)); + JLabel welcomeToLabel = new JLabel(translate("startup.welcometo")); + welcomeToLabel.setFont(welcomeToLabel.getFont().deriveFont(40)); + welcomeToLabel.setAlignmentX(0.5f); + JPanel appNamePanel = new JPanel(new FlowLayout()); + JLabel jpLabel = new JLabel("JPEXS "); + jpLabel.setAlignmentX(0.5f); + jpLabel.setForeground(new Color(0, 0, 160)); + jpLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); + jpLabel.setHorizontalAlignment(SwingConstants.CENTER); + appNamePanel.add(jpLabel); + + JLabel ffLabel = new JLabel("Free Flash "); + ffLabel.setAlignmentX(0.5f); + ffLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); + ffLabel.setHorizontalAlignment(SwingConstants.CENTER); + appNamePanel.add(ffLabel); + + JLabel decLabel = new JLabel("Decompiler"); + decLabel.setAlignmentX(0.5f); + decLabel.setForeground(Color.red); + decLabel.setFont(new Font("Tahoma", Font.BOLD, 50)); + decLabel.setHorizontalAlignment(SwingConstants.CENTER); + appNamePanel.add(decLabel); + appNamePanel.setAlignmentX(0.5f); + welcomePanel.add(Box.createGlue()); + welcomePanel.add(welcomeToLabel); + welcomePanel.add(appNamePanel); + JLabel startLabel = new JLabel(translate("startup.selectopen")); + startLabel.setAlignmentX(0.5f); + startLabel.setFont(startLabel.getFont().deriveFont(30)); + welcomePanel.add(startLabel); + welcomePanel.add(Box.createGlue()); + return welcomePanel; + } + + private JPanel createImagesCard() { + JPanel imagesCard = new JPanel(new BorderLayout()); + imagePanel = new ImagePanel(); + imagesCard.add(imagePanel, BorderLayout.CENTER); + + imageReplaceButton = new JButton(translate("button.replace"), View.getIcon("edit16")); + imageReplaceButton.setMargin(new Insets(3, 3, 3, 10)); + imageReplaceButton.setActionCommand(ACTION_REPLACE_IMAGE); + imageReplaceButton.addActionListener(this); + imageButtonsPanel = new JPanel(new FlowLayout()); + imageButtonsPanel.add(imageReplaceButton); + + imagesCard.add(imageButtonsPanel, BorderLayout.SOUTH); + return imagesCard; + } + + private void showHideImageReplaceButton(boolean show) { + imageReplaceButton.setVisible(show); + setImageButtonPanelVisibility(); + } + + private void setImageButtonPanelVisibility() { + // hide button panel when no button is visible + // now there is only one button, later add here the other buttons + boolean visible = imageReplaceButton.isVisible(); + imageButtonsPanel.setVisible(visible); + } + + public String translate(String key) { + return mainFrame.translate(key); + } + + public MainFramePanel(MainFrame mainFrame, MainFrameMenu mainMenu, FlashPlayerPanel flashPanel) { + super(); + + this.mainFrame = mainFrame; + this.mainMenu = mainMenu; + + mainFrame.setTitle(ApplicationInfo.applicationVerName); + + setLayout(new BorderLayout()); + swfs = new ArrayList<>(); + + detailPanel = new JPanel(); + detailPanel.setLayout(new CardLayout()); + JPanel whitePanel = new JPanel(); + whitePanel.setBackground(Color.white); + detailPanel.add(whitePanel, DETAILCARDEMPTYPANEL); + CardLayout cl2 = (CardLayout) (detailPanel.getLayout()); + cl2.show(detailPanel, DETAILCARDEMPTYPANEL); + + UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName()); + tagTree = new JTree((TreeModel) null); + tagTree.setRootVisible(false); + tagTree.addTreeSelectionListener(this); + tagTree.setBackground(Color.white); + tagTree.setUI(new BasicTreeUI() { + @Override + public void paint(Graphics g, JComponent c) { + setHashColor(Color.gray); + super.paint(g, c); + } + }); + + + + DragSource dragSource = DragSource.getDefaultDragSource(); + dragSource.createDefaultDragGestureRecognizer(tagTree, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() { + @Override + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(DragSource.DefaultCopyDrop, new Transferable() { + @Override + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{DataFlavor.javaFileListFlavor}; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.javaFileListFlavor); + } + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (flavor.equals(DataFlavor.javaFileListFlavor)) { + List files = new ArrayList<>(); + String tempDir = System.getProperty("java.io.tmpdir"); + if (!tempDir.endsWith(File.separator)) { + tempDir += File.separator; + } + Random rnd = new Random(); + tempDir += "ffdec" + File.separator + "export" + File.separator + System.currentTimeMillis() + "_" + rnd.nextInt(1000); + File fTempDir = new File(tempDir); + if (!fTempDir.exists()) { + if (!fTempDir.mkdirs()) { + if (!fTempDir.exists()) { + throw new IOException("cannot create directory " + fTempDir); + } + } + } + final ExportDialog export = new ExportDialog(); + + try { + File ftemp = new File(tempDir); + files = exportSelection(errorHandler, tempDir, export); + files.clear(); + + File[] fs = ftemp.listFiles(); + files.addAll(Arrays.asList(fs)); + + Main.stopWork(); + } catch (IOException ex) { + return null; + } + for (File f : files) { + f.deleteOnExit(); + } + new File(tempDir).deleteOnExit(); + return files; + + } + return null; + } + }, new DragSourceListener() { + @Override + public void dragEnter(DragSourceDragEvent dsde) { + enableDrop(false); + } + + @Override + public void dragOver(DragSourceDragEvent dsde) { + } + + @Override + public void dropActionChanged(DragSourceDragEvent dsde) { + } + + @Override + public void dragExit(DragSourceEvent dse) { + } + + @Override + public void dragDropEnd(DragSourceDropEvent dsde) { + enableDrop(true); + } + }); + } + }); + + createContextMenu(); + + TreeCellRenderer tcr = new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + super.getTreeCellRendererComponent( + tree, value, sel, + expanded, leaf, row, + hasFocus); + Object val = value; + if (val instanceof TagNode) { + val = ((TagNode) val).tag; + } + TagType type = getTagType(val); + if (val instanceof SWFRoot) { + setIcon(View.getIcon("flash16")); + } else if (type != null) { + if (type == TagType.FOLDER && expanded) { + type = TagType.FOLDER_OPEN; + } + String tagTypeStr = type.toString().toLowerCase().replace("_", ""); + setIcon(View.getIcon(tagTypeStr + "16")); + //setToolTipText("This book is in the Tutorial series."); + } else { + //setToolTipText(null); //no tool tip + } + + String tos = value.toString(); + int sw = getFontMetrics(getFont()).stringWidth(tos); + setPreferredSize(new Dimension(18 + sw, getPreferredSize().height)); + setUI(new BasicLabelUI()); + setOpaque(false); + //setBackground(Color.green); + setBackgroundNonSelectionColor(Color.white); + //setBackgroundSelectionColor(Color.ORANGE); + return this; + } + }; + + tagTree.setCellRenderer(tcr); + + statusPanel = new MainFrameStatusPanel(this); + add(statusPanel, BorderLayout.SOUTH); + + JPanel textTopPanel = new JPanel(new BorderLayout()); + textValue = new LineMarkedEditorPane(); + textTopPanel.add(new JScrollPane(textValue), BorderLayout.CENTER); + textValue.setEditable(false); + //textValue.setFont(UIManager.getFont("TextField.font")); + + + + JPanel textButtonsPanel = new JPanel(); + textButtonsPanel.setLayout(new FlowLayout()); + + + textSaveButton = new JButton(translate("button.save"), View.getIcon("save16")); + textSaveButton.setMargin(new Insets(3, 3, 3, 10)); + textSaveButton.setActionCommand(ACTION_SAVE_TEXT); + textSaveButton.addActionListener(this); + + textEditButton = new JButton(translate("button.edit"), View.getIcon("edit16")); + textEditButton.setMargin(new Insets(3, 3, 3, 10)); + textEditButton.setActionCommand(ACTION_EDIT_TEXT); + textEditButton.addActionListener(this); + + textCancelButton = new JButton(translate("button.cancel"), View.getIcon("cancel16")); + textCancelButton.setMargin(new Insets(3, 3, 3, 10)); + textCancelButton.setActionCommand(ACTION_CANCEL_TEXT); + textCancelButton.addActionListener(this); + + textButtonsPanel.add(textEditButton); + textButtonsPanel.add(textSaveButton); + textButtonsPanel.add(textCancelButton); + + textSaveButton.setVisible(false); + textCancelButton.setVisible(false); + + textTopPanel.add(textButtonsPanel, BorderLayout.SOUTH); + + displayWithPreview = new JPanel(new CardLayout()); + + displayWithPreview.add(textTopPanel, CARDTEXTPANEL); + + fontPanel = new FontPanel(this); + displayWithPreview.add(fontPanel, CARDFONTPANEL); + + + Component leftComponent; + + + displayPanel = new JPanel(new CardLayout()); + + if (flashPanel != null) { + JPanel flashPlayPanel = new JPanel(new BorderLayout()); + flashPlayPanel.add(flashPanel, BorderLayout.CENTER); + flashPlayPanel.add(flashControls = new PlayerControls(flashPanel), BorderLayout.SOUTH); + leftComponent = flashPlayPanel; + } else { + JPanel swtPanel = new JPanel(new BorderLayout()); + swtPanel.add(new JLabel("
" + translate("notavailonthisplatform") + "
", JLabel.CENTER), BorderLayout.CENTER); + swtPanel.setBackground(View.DEFAULT_BACKGROUND_COLOR); + leftComponent = swtPanel; + } + + textValue.setContentType("text/swf_text"); + + previewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + previewSplitPane.setDividerLocation(300); + JPanel pan = new JPanel(new BorderLayout()); + JLabel prevLabel = new HeaderLabel(translate("swfpreview")); + prevLabel.setHorizontalAlignment(SwingConstants.CENTER); + //prevLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); + + JLabel paramsLabel = new HeaderLabel(translate("parameters")); + paramsLabel.setHorizontalAlignment(SwingConstants.CENTER); + //paramsLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); + pan.add(prevLabel, BorderLayout.NORTH); + + viewerCards = new JPanel(); + viewerCards.setLayout(new CardLayout()); + //viewerCards.add(leftComponent,FLASH_VIEWER_CARD); + + internelViewerPanel = new ImagePanel(); + JPanel ivPanel = new JPanel(new BorderLayout()); + ivPanel.add(new HeaderLabel(translate("swfpreview.internal")), BorderLayout.NORTH); + ivPanel.add(internelViewerPanel, BorderLayout.CENTER); + viewerCards.add(ivPanel, INTERNAL_VIEWER_CARD); + + ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); + + if (flashPanel != null) { + JPanel bottomPanel = new JPanel(new BorderLayout()); + JPanel buttonsPanel = new JPanel(new FlowLayout()); + JButton selectColorButton = new JButton(View.getIcon("color16")); + selectColorButton.addActionListener(this); + selectColorButton.setActionCommand(ACTION_SELECT_COLOR); + selectColorButton.setToolTipText(AppStrings.translate("button.selectcolor.hint")); + buttonsPanel.add(selectColorButton); + bottomPanel.add(buttonsPanel, BorderLayout.EAST); + pan.add(bottomPanel, BorderLayout.SOUTH); + } + pan.add(leftComponent, BorderLayout.CENTER); + viewerCards.add(pan, FLASH_VIEWER_CARD); + previewSplitPane.setLeftComponent(viewerCards); + + parametersPanel = new JPanel(new BorderLayout()); + parametersPanel.add(paramsLabel, BorderLayout.NORTH); + parametersPanel.add(displayWithPreview, BorderLayout.CENTER); + previewSplitPane.setRightComponent(parametersPanel); + parametersPanel.setVisible(false); + displayPanel.add(previewSplitPane, CARDFLASHPANEL); + + displayPanel.add(createImagesCard(), CARDIMAGEPANEL); + + JPanel shapesCard = new JPanel(new BorderLayout()); + + JPanel previewPanel = new JPanel(new BorderLayout()); + + previewImagePanel = new ImagePanel(); + + JPanel previewCnt = new JPanel(new BorderLayout()); + previewCnt.add(previewImagePanel, BorderLayout.CENTER); + previewCnt.add(new PlayerControls(previewImagePanel), BorderLayout.SOUTH); + previewPanel.add(previewCnt, BorderLayout.CENTER); + JLabel prevIntLabel = new HeaderLabel(translate("swfpreview.internal")); + prevIntLabel.setHorizontalAlignment(SwingConstants.CENTER); + //prevIntLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); + previewPanel.add(prevIntLabel, BorderLayout.NORTH); + shapesCard.add(previewPanel, BorderLayout.CENTER); + displayPanel.add(shapesCard, CARDDRAWPREVIEWPANEL); + + swfPreviewPanel = new SWFPreviwPanel(); + displayPanel.add(swfPreviewPanel, CARDSWFPREVIEWPANEL); + + + displayPanel.add(new JPanel(), CARDEMPTYPANEL); + CardLayout cl = (CardLayout) (displayPanel.getLayout()); + cl.show(displayPanel, CARDEMPTYPANEL); + + searchPanel = new JPanel(); + searchPanel.setLayout(new BorderLayout()); + searchPanel.add(filterField, BorderLayout.CENTER); + searchPanel.add(new JLabel(View.getIcon("search16")), BorderLayout.WEST); + JLabel closeSearchButton = new JLabel(View.getIcon("cancel16")); + closeSearchButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + filterField.setText(""); + doFilter(); + searchPanel.setVisible(false); + } + }); + searchPanel.add(closeSearchButton, BorderLayout.EAST); + JPanel pan1 = new JPanel(new BorderLayout()); + pan1.add(new JScrollPane(tagTree), BorderLayout.CENTER); + pan1.add(searchPanel, BorderLayout.SOUTH); + + filterField.setActionCommand(ABCPanel.ACTION_FILTER_SCRIPT); + filterField.addActionListener(this); + + searchPanel.setVisible(false); + + filterField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + warn(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + warn(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + warn(); + } + + public void warn() { + doFilter(); + } + }); + + //displayPanel.setBorder(BorderFactory.createLineBorder(Color.black)); + splitPane2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pan1, detailPanel); + splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitPane2, displayPanel); + + + welcomePanel = createWelcomePanel(); + add(welcomePanel, BorderLayout.CENTER); + //splitPane1.setDividerLocation(0.5); + + splitPane1.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent pce) { + if (splitsInited) { + Configuration.guiSplitPane1DividerLocation.set((int) pce.getNewValue()); + } + } + }); + + splitPane2.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent pce) { + if (detailPanel.isVisible()) { + Configuration.guiSplitPane2DividerLocation.set((int) pce.getNewValue()); + } + } + }); + + CardLayout cl3 = new CardLayout(); + contentPanel = new JPanel(cl3); + contentPanel.add(welcomePanel, WELCOME_PANEL); + contentPanel.add(splitPane1, SPLIT_PANE1); + add(contentPanel); + cl3.show(contentPanel, WELCOME_PANEL); + + tagTree.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if ((e.getKeyCode() == 'F') && (e.isControlDown())) { + searchPanel.setVisible(true); + filterField.requestFocusInWindow(); + } + } + }); + detailPanel.setVisible(false); + + updateUi(); + + //Opening files with drag&drop to main window + enableDrop(true); + } + + public void load(SWF swf) { + List objs = new ArrayList<>(); + if (swf != null) { + objs.addAll(swf.tags); + } + + ArrayList abcList = new ArrayList<>(); + getActionScript3(objs, abcList); + + swfs.add(swf); + swf.abcList = abcList; + + boolean hasAbc = !abcList.isEmpty(); + + if (hasAbc) { + if (abcPanel == null) { + abcPanel = new ABCPanel(this); + displayPanel.add(abcPanel, CARDACTIONSCRIPT3PANEL); + detailPanel.add(abcPanel.tabbedPane, DETAILCARDAS3NAVIGATOR); + } + abcPanel.setSwf(abcList, swf); + } else { + if (actionPanel == null) { + actionPanel = new ActionPanel(this); + displayPanel.add(actionPanel, CARDACTIONSCRIPTPANEL); + } + } + + tagTree.setModel(new TagTreeModel(mainFrame, swfs)); + expandSwfRoots(); + + for (Tag t : swf.tags) { + if (t instanceof JPEGTablesTag) { + swf.jtt = (JPEGTablesTag) t; + } + } + + List list2 = new ArrayList<>(); + list2.addAll(swf.tags); + swf.characters = new HashMap<>(); + parseCharacters(swf, list2); + + if (Configuration.autoRenameIdentifiers.get()) { + try { + swf.deobfuscateIdentifiers(RenameType.TYPENUMBER); + swf.assignClassesToSymbols(); + clearCache(); + if (abcPanel != null) { + abcPanel.reload(); + } + updateClassesList(); + } catch (InterruptedException ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + showDetail(DETAILCARDEMPTYPANEL); + showCard(CARDEMPTYPANEL); + updateUi(swf); + } + + private void updateUi(final SWF swf) { + + mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); + + List abcList = swf.abcList; + + boolean hasAbc = !abcList.isEmpty(); + + if (hasAbc) { + abcPanel.setSwf(abcList, swf); + } + + if (isWelcomeScreen) { + CardLayout cl = (CardLayout) (contentPanel.getLayout()); + cl.show(contentPanel, SPLIT_PANE1); + isWelcomeScreen = false; + } + + mainMenu.updateComponets(swf, abcList); + } + + private void updateUi() { + if (!isWelcomeScreen) { + CardLayout cl = (CardLayout) (contentPanel.getLayout()); + cl.show(contentPanel, WELCOME_PANEL); + isWelcomeScreen = true; + } + + if (swfs.isEmpty()) { + mainMenu.updateComponets(null, null); + } else { + SWF swf = swfs.get(0); + updateUi(swf); + } + } + + public void closeAll() { + swfs.clear(); + oldValue = null; + if (abcPanel != null) { + abcPanel.clearSwf(); + } + if (actionPanel != null) { + actionPanel.clearSource(); + } + updateUi(); + updateTagTree(); + } + + public void close(SWF swf) { + swfs.remove(swf); + if (abcPanel != null && abcPanel.swf == swf) { + abcPanel.clearSwf(); + } + if (actionPanel != null) { + actionPanel.clearSource(); + } + oldValue = null; + updateUi(); + updateTagTree(); + } + + private void updateTagTree() { + tagTree.setModel(new TagTreeModel(mainFrame, swfs)); + expandSwfRoots(); + } + + public void enableDrop(boolean value) { + if (value) { + setDropTarget(new DropTarget() { + @Override + public synchronized void drop(DropTargetDropEvent dtde) { + try { + dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + @SuppressWarnings("unchecked") + List droppedFiles = (List) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); + if (!droppedFiles.isEmpty()) { + String path = droppedFiles.get(0).getAbsolutePath(); + Main.openFile(path, null); + } + } catch (UnsupportedFlavorException | IOException ex) { + } + } + }); + } else { + setDropTarget(null); + } + } + + public void updateClassesList() { + List nodes = getASTagNode(tagTree); + boolean updateNeeded = false; + for (TagNode n : nodes) { + if (n.tag instanceof ClassesListTreeModel) { + ((ClassesListTreeModel) n.tag).update(); + updateNeeded = true; + } + } + + refreshTree(); + + if (updateNeeded) { + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + tagTree.updateUI(); + } + }); + } + } + + public void doFilter() { + List nodes = getASTagNode(tagTree); + boolean updateNeeded = false; + for (TagNode n : nodes) { + if (n.tag instanceof ClassesListTreeModel) { + ((ClassesListTreeModel) n.tag).setFilter(filterField.getText()); + updateNeeded = true; + } + } + + if (updateNeeded) { + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + tagTree.updateUI(); + } + }); + } + } + + @Override + public void setVisible(boolean b) { + super.setVisible(b); + if (b) { + if (abcPanel != null) { + abcPanel.initSplits(); + } + if (actionPanel != null) { + actionPanel.initSplits(); + } + + final MainFramePanel t = this; + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + splitPane1.setDividerLocation(Configuration.guiSplitPane1DividerLocation.get(getWidth() / 3)); + int confDivLoc = Configuration.guiSplitPane2DividerLocation.get(splitPane2.getHeight() * 3 / 5); + if (confDivLoc > splitPane2.getHeight() - 10) { //In older releases, divider location was saved when detailPanel was invisible too + confDivLoc = splitPane2.getHeight() * 3 / 5; + } + splitPane2.setDividerLocation(confDivLoc); + + splitPos = splitPane2.getDividerLocation(); + splitsInited = true; + if (Configuration.gotoMainClassOnStartup.get()) { + gotoDocumentClass(getCurrentSwf()); + } + } + }); + + + } + } + + private void parseCharacters(SWF swf, List list) { + for (ContainerItem t : list) { + if (t instanceof CharacterTag) { + swf.characters.put(((CharacterTag) t).getCharacterId(), (CharacterTag) t); + } + if (t instanceof Container) { + parseCharacters(swf, ((Container) t).getSubItems()); + } + } + } + + public static void getShapes(List list, List shapes) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getShapes(((Container) t).getSubItems(), shapes); + } + if ((t instanceof DefineShapeTag) + || (t instanceof DefineShape2Tag) + || (t instanceof DefineShape3Tag) + || (t instanceof DefineShape4Tag)) { + shapes.add((Tag) t); + } + } + } + + public static void getFonts(List list, List fonts) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getFonts(((Container) t).getSubItems(), fonts); + } + if ((t instanceof DefineFontTag) + || (t instanceof DefineFont2Tag) + || (t instanceof DefineFont3Tag) + || (t instanceof DefineFont4Tag)) { + fonts.add((Tag) t); + } + } + } + + public static void getActionScript3(List list, List actionScripts) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getActionScript3(((Container) t).getSubItems(), actionScripts); + } + if (t instanceof ABCContainerTag) { + actionScripts.add((ABCContainerTag) t); + } + } + } + + public static void getMorphShapes(List list, List morphShapes) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getMorphShapes(((Container) t).getSubItems(), morphShapes); + } + if ((t instanceof DefineMorphShapeTag) || (t instanceof DefineMorphShape2Tag)) { + morphShapes.add((Tag) t); + } + } + } + + public static void getImages(List list, List images) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getImages(((Container) t).getSubItems(), images); + } + if ((t instanceof DefineBitsTag) + || (t instanceof DefineBitsJPEG2Tag) + || (t instanceof DefineBitsJPEG3Tag) + || (t instanceof DefineBitsJPEG4Tag) + || (t instanceof DefineBitsLosslessTag) + || (t instanceof DefineBitsLossless2Tag)) { + images.add((Tag) t); + } + } + } + + public static void getTexts(List list, List texts) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getTexts(((Container) t).getSubItems(), texts); + } + if ((t instanceof DefineTextTag) + || (t instanceof DefineText2Tag) + || (t instanceof DefineEditTextTag)) { + texts.add((Tag) t); + } + } + } + + public static void getSprites(List list, List sprites) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getSprites(((Container) t).getSubItems(), sprites); + } + if (t instanceof DefineSpriteTag) { + sprites.add((Tag) t); + } + } + } + + public static void getButtons(List list, List buttons) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getButtons(((Container) t).getSubItems(), buttons); + } + if ((t instanceof DefineButtonTag) || (t instanceof DefineButton2Tag)) { + buttons.add((Tag) t); + } + } + } + + public List getSelectedNodes() { + List ret = new ArrayList<>(); + TreePath[] tps = tagTree.getSelectionPaths(); + if (tps == null) { + return ret; + } + for (TreePath tp : tps) { + TagNode te = (TagNode) tp.getLastPathComponent(); + ret.add(te); + } + return ret; + } + + public static TagType getTagType(Object t) { + if ((t instanceof DefineFontTag) + || (t instanceof DefineFont2Tag) + || (t instanceof DefineFont3Tag) + || (t instanceof DefineFont4Tag) + || (t instanceof DefineCompactedFont)) { + return TagType.FONT; + } + if ((t instanceof DefineTextTag) + || (t instanceof DefineText2Tag) + || (t instanceof DefineEditTextTag)) { + return TagType.TEXT; + } + + if ((t instanceof DefineBitsTag) + || (t instanceof DefineBitsJPEG2Tag) + || (t instanceof DefineBitsJPEG3Tag) + || (t instanceof DefineBitsJPEG4Tag) + || (t instanceof DefineBitsLosslessTag) + || (t instanceof DefineBitsLossless2Tag)) { + return TagType.IMAGE; + } + if ((t instanceof DefineShapeTag) + || (t instanceof DefineShape2Tag) + || (t instanceof DefineShape3Tag) + || (t instanceof DefineShape4Tag)) { + return TagType.SHAPE; + } + + if ((t instanceof DefineMorphShapeTag) || (t instanceof DefineMorphShape2Tag)) { + return TagType.MORPH_SHAPE; + } + + if (t instanceof DefineSpriteTag) { + return TagType.SPRITE; + } + if ((t instanceof DefineButtonTag) || (t instanceof DefineButton2Tag)) { + return TagType.BUTTON; + } + if (t instanceof ASMSource) { + return TagType.AS; + } + if (t instanceof TreeElement) { + TreeElement te = (TreeElement) t; + if (te.getItem() instanceof ScriptPack) { + return TagType.AS; + } else { + return TagType.PACKAGE; + } + } + if (t instanceof PackageNode) { + return TagType.PACKAGE; + } + if (t instanceof FrameNode) { + return TagType.FRAME; + } + if (t instanceof ShowFrameTag) { + return TagType.SHOW_FRAME; + } + + if (t instanceof DefineVideoStreamTag) { + return TagType.MOVIE; + } + + if ((t instanceof DefineSoundTag) || (t instanceof SoundStreamHeadTag) || (t instanceof SoundStreamHead2Tag)) { + return TagType.SOUND; + } + + if (t instanceof DefineBinaryDataTag) { + return TagType.BINARY_DATA; + } + + return TagType.FOLDER; + } + + public List getTagsWithType(List list, TagType type) { + List ret = new ArrayList<>(); + for (Object o : list) { + TagType ttype = getTagType(o); + if (type == ttype) { + ret.add(o); + } + } + return ret; + } + + public void renameIdentifier(SWF swf, String identifier) throws InterruptedException { + String oldName = identifier; + String newName = View.showInputDialog(translate("rename.enternew"), oldName); + if (newName != null) { + if (!oldName.equals(newName)) { + swf.renameAS2Identifier(oldName, newName); + View.showMessageDialog(null, translate("rename.finished.identifier")); + updateClassesList(); + reload(true); + } + } + } + + public void renameMultiname(List abcList, int multiNameIndex) { + String oldName = ""; + if (abcPanel.abc.constants.getMultiname(multiNameIndex).name_index > 0) { + oldName = abcPanel.abc.constants.getString(abcPanel.abc.constants.getMultiname(multiNameIndex).name_index); + } + String newName = View.showInputDialog(translate("rename.enternew"), oldName); + if (newName != null) { + if (!oldName.equals(newName)) { + int mulCount = 0; + for (ABCContainerTag cnt : abcList) { + ABC abc = cnt.getABC(); + for (int m = 1; m < abc.constants.getMultinameCount(); m++) { + int ni = abc.constants.getMultiname(m).name_index; + String n = ""; + if (ni > 0) { + n = abc.constants.getString(ni); + } + if (n.equals(oldName)) { + abc.renameMultiname(m, newName); + mulCount++; + } + } + } + View.showMessageDialog(null, translate("rename.finished.multiname").replace("%count%", "" + mulCount)); + if (abcPanel != null) { + abcPanel.reload(); + } + updateClassesList(); + reload(true); + abcPanel.hilightScript(abcPanel.decompiledTextArea.getScriptLeaf().getPath().toString()); + } + } + } + + public List getSelected(JTree tree) { + TreeSelectionModel tsm = tree.getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + Object o = tp.getLastPathComponent(); + ret.add(o); + } + return ret; + } + + public List getAllSubs(JTree tree, Object o) { + TreeModel tm = tree.getModel(); + List ret = new ArrayList<>(); + for (int i = 0; i < tm.getChildCount(o); i++) { + Object c = tm.getChild(o, i); + ret.add(c); + ret.addAll(getAllSubs(tree, c)); + } + return ret; + } + + public List getAllSelected(JTree tree) { + TreeSelectionModel tsm = tree.getSelectionModel(); + TreePath[] tps = tsm.getSelectionPaths(); + List ret = new ArrayList<>(); + if (tps == null) { + return ret; + } + + for (TreePath tp : tps) { + Object o = tp.getLastPathComponent(); + ret.add(o); + ret.addAll(getAllSubs(tree, o)); + } + return ret; + } + + public List getASTagNode(JTree tree) { + List result = new ArrayList<>(); + TagTreeModel tm = (TagTreeModel) tree.getModel(); + if (tm == null) { + return result; + } + TreeNode root = tm.getRoot(); + for (int j = 0; j < tm.getChildCount(root); j++) { + SWFRoot swfRoot = (SWFRoot) tm.getChild(root, j); + for (int i = 0; i < tm.getChildCount(swfRoot); i++) { + TreeNode node = tm.getChild(swfRoot, i); + if (node instanceof TagNode) { + TagNode tagNode = (TagNode) node; + TreeElementItem tag = tagNode.tag; + if (tag != null && "scripts".equals(tagNode.mark)) { + result.add((TagNode) node); + } + } + } + } + return result; + } + + public boolean confirmExperimental() { + return View.showConfirmDialog(null, translate("message.confirm.experimental"), translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION; + } + private SearchDialog searchDialog; + + public List exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException { + final ExportMode exportMode = ExportMode.get(export.getOption(ExportDialog.OPTION_ACTIONSCRIPT)); + final boolean isMp3OrWav = export.getOption(ExportDialog.OPTION_SOUNDS) == 0; + final boolean isFormatted = export.getOption(ExportDialog.OPTION_TEXTS) == 1; + + List ret = new ArrayList<>(); + List sel = getAllSelected(tagTree); + + for (SWF swf : swfs) { + List tlsList = new ArrayList<>(); + JPEGTablesTag jtt = null; + for (Tag t : swf.tags) { + if (t instanceof JPEGTablesTag) { + jtt = (JPEGTablesTag) t; + break; + } + } + List images = new ArrayList<>(); + List shapes = new ArrayList<>(); + List movies = new ArrayList<>(); + List sounds = new ArrayList<>(); + List texts = new ArrayList<>(); + List actionNodes = new ArrayList<>(); + List binaryData = new ArrayList<>(); + for (Object d : sel) { + if (d instanceof TagNode) { + TagNode n = (TagNode) d; + if (n.getSwf() != swf) { + continue; + } + if (getTagType(n.tag) == TagType.IMAGE) { + images.add((Tag) n.tag); + } + if (getTagType(n.tag) == TagType.SHAPE) { + shapes.add((Tag) n.tag); + } + if (getTagType(n.tag) == TagType.AS) { + actionNodes.add(n); + } + if (getTagType(n.tag) == TagType.MOVIE) { + movies.add((Tag) n.tag); + } + if (getTagType(n.tag) == TagType.SOUND) { + sounds.add((Tag) n.tag); + } + if (getTagType(n.tag) == TagType.BINARY_DATA) { + binaryData.add((Tag) n.tag); + } + if (getTagType(n.tag) == TagType.TEXT) { + texts.add((Tag) n.tag); + } + } + if (d instanceof TreeElement) { + if (((TreeElement) d).isLeaf()) { + TreeElement treeElement = (TreeElement) d; + if (treeElement.getSwf() == swf) { + tlsList.add((ScriptPack) treeElement.getItem()); + } + } + } + } + ret.addAll(swf.exportImages(handler, selFile + File.separator + "images", images)); + ret.addAll(SWF.exportShapes(handler, selFile + File.separator + "shapes", shapes)); + ret.addAll(swf.exportTexts(handler, selFile + File.separator + "texts", texts, isFormatted)); + ret.addAll(swf.exportMovies(handler, selFile + File.separator + "movies", movies)); + ret.addAll(swf.exportSounds(handler, selFile + File.separator + "sounds", sounds, isMp3OrWav, isMp3OrWav)); + ret.addAll(SWF.exportBinaryData(handler, selFile + File.separator + "binaryData", binaryData)); + List abcList = swf.abcList; + if (abcPanel != null) { + for (int i = 0; i < tlsList.size(); i++) { + ScriptPack tls = tlsList.get(i); + Main.startWork(translate("work.exporting") + " " + (i + 1) + "/" + tlsList.size() + " " + tls.getPath() + " ..."); + ret.add(tls.export(selFile, abcList, exportMode, Configuration.parallelSpeedUp.get())); + } + } else { + List allNodes = new ArrayList<>(); + List asNodes = getASTagNode(tagTree); + for (TagNode asn : asNodes) { + allNodes.add(asn); + TagNode.setExport(allNodes, false); + TagNode.setExport(actionNodes, true); + ret.addAll(TagNode.exportNodeAS(swf.tags, handler, allNodes, selFile, exportMode, null)); + } + } + } + return ret; + } + + public SWF getCurrentSwf() { + if (swfs == null || swfs.isEmpty()) { + return null; + } + + TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); + if (treeNode == null) { + return swfs.get(0); + } + + return treeNode.getSwf(); + } + + private void clearCache() { + if (abcPanel != null) { + abcPanel.decompiledTextArea.clearScriptCache(); + } + if (actionPanel != null) { + actionPanel.clearCache(); + } + } + + public void gotoDocumentClass(SWF swf) { + if (swf == null) { + return; + } + String documentClass = null; + loopdc: + for (Tag t : swf.tags) { + if (t instanceof SymbolClassTag) { + SymbolClassTag sc = (SymbolClassTag) t; + for (int i = 0; i < sc.tagIDs.length; i++) { + if (sc.tagIDs[i] == 0) { + documentClass = sc.classNames[i]; + break loopdc; + } + } + } + } + if (documentClass != null) { + showDetail(DETAILCARDAS3NAVIGATOR); + showCard(CARDACTIONSCRIPT3PANEL); + abcPanel.hilightScript(documentClass); + } + } + + public void disableDecompilationChanged() { + clearCache(); + if (abcPanel != null) { + abcPanel.reload(); + } + reload(true); + updateClassesList(); + } + + public void searchAs() { + if (searchDialog == null) { + searchDialog = new SearchDialog(); + } + searchDialog.setVisible(true); + if (searchDialog.result) { + final String txt = searchDialog.searchField.getText(); + if (!txt.isEmpty()) { + if (abcPanel != null) { + new CancellableWorker() { + @Override + protected Void doInBackground() throws Exception { + if (abcPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + showDetail(DETAILCARDAS3NAVIGATOR); + showCard(CARDACTIONSCRIPT3PANEL); + } + }); + } else { + View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + } + return null; + } + }.execute(); + } else { + new CancellableWorker() { + @Override + protected Void doInBackground() { + if (actionPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + showCard(CARDACTIONSCRIPTPANEL); + } + }); + } else { + View.showMessageDialog(null, translate("message.search.notfound").replace("%searchtext%", txt), translate("message.search.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + } + return null; + } + }.execute(); + } + } + } + } + + public void autoDeobfuscateChanged() { + clearCache(); + if (abcPanel != null) { + abcPanel.reload(); + } + reload(true); + updateClassesList(); + } + + public void renameOneIdentifier(final SWF swf) { + if (swf.fileAttributes.actionScript3) { + final int multiName = abcPanel.decompiledTextArea.getMultinameUnderCursor(); + final List abcList = swf.abcList; + if (multiName > 0) { + new CancellableWorker() { + @Override + public Void doInBackground() throws Exception { + Main.startWork(translate("work.renaming") + "..."); + renameMultiname(abcList, multiName); + return null; + } + + @Override + protected void done() { + Main.stopWork(); + } + }.execute(); + + } else { + View.showMessageDialog(null, translate("message.rename.notfound.multiname"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + } + } else { + final String identifier = actionPanel.getStringUnderCursor(); + if (identifier != null) { + new CancellableWorker() { + @Override + public Void doInBackground() throws Exception { + Main.startWork(translate("work.renaming") + "..."); + try { + renameIdentifier(swf, identifier); + } catch (InterruptedException ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + + @Override + protected void done() { + Main.stopWork(); + } + }.execute(); + } else { + View.showMessageDialog(null, translate("message.rename.notfound.identifier"), translate("message.rename.notfound.title"), JOptionPane.INFORMATION_MESSAGE); + } + } + } + + public void exportFla(final SWF swf) { + JFileChooser fc = new JFileChooser(); + String selDir = Configuration.lastOpenDir.get(); + fc.setCurrentDirectory(new File(selDir)); + if (!selDir.endsWith(File.separator)) { + selDir += File.separator; + } + String fileName = (new File(swf.file).getName()); + fileName = fileName.substring(0, fileName.length() - 4) + ".fla"; + fc.setSelectedFile(new File(selDir + fileName)); + FileFilter fla = new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || (f.getName().toLowerCase().endsWith(".fla")); + } + + @Override + public String getDescription() { + return translate("filter.fla"); + } + }; + FileFilter xfl = new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || (f.getName().toLowerCase().endsWith(".xfl")); + } + + @Override + public String getDescription() { + return translate("filter.xfl"); + } + }; + fc.setFileFilter(fla); + fc.addChoosableFileFilter(xfl); + fc.setAcceptAllFileFilterUsed(false); + JFrame f = new JFrame(); + View.setWindowIcon(f); + int returnVal = fc.showSaveDialog(f); + if (returnVal == JFileChooser.APPROVE_OPTION) { + Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath()); + File sf = Helper.fixDialogFile(fc.getSelectedFile()); + + Main.startWork(translate("work.exporting.fla") + "..."); + final boolean compressed = fc.getFileFilter() == fla; + if (!compressed) { + if (sf.getName().endsWith(".fla")) { + sf = new File(sf.getAbsolutePath().substring(0, sf.getAbsolutePath().length() - 4) + ".xfl"); + } + } + final File selfile = sf; + new CancellableWorker() { + @Override + protected Void doInBackground() throws Exception { + Helper.freeMem(); + try { + if (compressed) { + swf.exportFla(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get()); + } else { + swf.exportXfl(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get()); + } + } catch (IOException ex) { + View.showMessageDialog(null, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE); + } + Helper.freeMem(); + return null; + } + + @Override + protected void done() { + Main.stopWork(); + } + }.execute(); + } + } + + public void export(final boolean onlySel) { + final ExportDialog export = new ExportDialog(); + export.setVisible(true); + if (!export.cancelled) { + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new File(Configuration.lastExportDir.get())); + chooser.setDialogTitle(translate("export.select.directory")); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + final long timeBefore = System.currentTimeMillis(); + Main.startWork(translate("work.exporting") + "..."); + final String selFile = Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath(); + Configuration.lastExportDir.set(Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath()); + final ExportMode exportMode = ExportMode.get(export.getOption(ExportDialog.OPTION_ACTIONSCRIPT)); + final boolean isMp3OrWav = export.getOption(ExportDialog.OPTION_SOUNDS) == 0; + final boolean isFormatted = export.getOption(ExportDialog.OPTION_TEXTS) == 1; + final SWF swf = getCurrentSwf(); + new CancellableWorker() { + @Override + public Void doInBackground() throws Exception { + try { + if (onlySel) { + exportSelection(errorHandler, selFile, export); + } else { + swf.exportImages(errorHandler, selFile + File.separator + "images"); + swf.exportShapes(errorHandler, selFile + File.separator + "shapes"); + swf.exportTexts(errorHandler, selFile + File.separator + "texts", isFormatted); + swf.exportMovies(errorHandler, selFile + File.separator + "movies"); + swf.exportSounds(errorHandler, selFile + File.separator + "sounds", isMp3OrWav, isMp3OrWav); + swf.exportBinaryData(errorHandler, selFile + File.separator + "binaryData"); + swf.exportActionScript(errorHandler, selFile, exportMode, Configuration.parallelSpeedUp.get()); + } + } catch (Exception ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, "Error during export", ex); + View.showMessageDialog(null, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage()); + } + return null; + } + + @Override + protected void done() { + Main.stopWork(); + long timeAfter = System.currentTimeMillis(); + final long timeMs = timeAfter - timeBefore; + + View.execInEventDispatchLater(new Runnable() { + + @Override + public void run() { + setStatus(translate("export.finishedin").replace("%time%", Helper.formatTimeSec(timeMs))); + } + }); + } + }.execute(); + + } + } + } + + public void restoreControlFlow(final boolean all) { + Main.startWork(translate("work.restoringControlFlow")); + if ((!all) || confirmExperimental()) { + new CancellableWorker() { + @Override + protected Object doInBackground() throws Exception { + int cnt = 0; + if (all) { + for (ABCContainerTag tag : abcPanel.list) { + tag.getABC().restoreControlFlow(); + } + } else { + int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); + if (bi != -1) { + abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, abcPanel.decompiledTextArea.getCurrentTrait(), abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); + } + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, abcPanel.decompiledTextArea.getCurrentTrait()); + } + return true; + } + + @Override + protected void done() { + Main.stopWork(); + View.showMessageDialog(null, translate("work.restoringControlFlow.complete")); + + View.execInEventDispatch(new Runnable() { + + @Override + public void run() { + abcPanel.reload(); + updateClassesList(); + } + }); + } + }.execute(); + } + } + + public void renameIdentifiers(final SWF swf) { + if (confirmExperimental()) { + final RenameType renameType = new RenameDialog().display(); + if (renameType != null) { + Main.startWork(translate("work.renaming.identifiers") + "..."); + new CancellableWorker() { + @Override + protected Integer doInBackground() throws Exception { + int cnt = swf.deobfuscateIdentifiers(renameType); + return cnt; + } + + @Override + protected void done() { + View.execInEventDispatch(new Runnable() { + + @Override + public void run() { + try { + int cnt = get(); + Main.stopWork(); + View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", "" + cnt)); + swf.assignClassesToSymbols(); + clearCache(); + if (abcPanel != null) { + abcPanel.reload(); + } + updateClassesList(); + reload(true); + } catch (Exception ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, "Error during renaming identifiers", ex); + Main.stopWork(); + View.showMessageDialog(null, translate("error.occured").replace("%error%", ex.getClass().getSimpleName())); + } + } + }); + } + }.execute(); + } + } + } + + public void deobfuscate() { + if (deobfuscationDialog == null) { + deobfuscationDialog = new DeobfuscationDialog(); + } + deobfuscationDialog.setVisible(true); + if (deobfuscationDialog.ok) { + Main.startWork(translate("work.deobfuscating") + "..."); + new CancellableWorker() { + @Override + protected Object doInBackground() throws Exception { + try { + if (deobfuscationDialog.processAllCheckbox.isSelected()) { + for (ABCContainerTag tag : abcPanel.list) { + if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) { + tag.getABC().removeDeadCode(); + } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) { + tag.getABC().removeTraps(); + } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) { + tag.getABC().removeTraps(); + tag.getABC().restoreControlFlow(); + } + } + } else { + int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex(); + Trait t = abcPanel.decompiledTextArea.getCurrentTrait(); + if (bi != -1) { + if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) { + abcPanel.abc.bodies[bi].removeDeadCode(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); + } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) { + abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/); + } else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) { + abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/); + abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]); + } + } + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, t); + } + } catch (Exception ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, "Deobfuscation error", ex); + } + return true; + } + + @Override + protected void done() { + Main.stopWork(); + View.showMessageDialog(null, translate("work.deobfuscating.complete")); + + View.execInEventDispatch(new Runnable() { + + @Override + public void run() { + clearCache(); + abcPanel.reload(); + updateClassesList(); + } + }); + } + }.execute(); + } + } + + public void removeNonScripts(SWF swf) { + List tags = new ArrayList<>(swf.tags); + for (Tag tag : tags) { + System.out.println(tag.getClass()); + if (!(tag instanceof ABCContainerTag || tag instanceof ASMSource)) { + swf.removeTag(tag); + } + } + showCard(CARDEMPTYPANEL); + refreshTree(); + } + + public void refreshDecompiled() { + clearCache(); + if (abcPanel != null) { + abcPanel.reload(); + } + reload(true); + updateClassesList(); + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand()) { + case ACTION_SELECT_COLOR: + Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectcolor.title"), View.swfBackgroundColor); + if (newColor != null) { + View.swfBackgroundColor = newColor; + reload(true); + } + break; + case ACTION_REPLACE_IMAGE: + { + Object tagObj = tagTree.getLastSelectedPathComponent(); + if (tagObj == null) { + return; + } + + if (tagObj instanceof TagNode) { + tagObj = ((TagNode) tagObj).tag; + } + if (tagObj instanceof ImageTag) { + ImageTag it = (ImageTag) tagObj; + if (it.importSupported()) { + JFileChooser fc = new JFileChooser(); + fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return (f.getName().toLowerCase().endsWith(".jpg")) + || (f.getName().toLowerCase().endsWith(".jpeg")) + || (f.getName().toLowerCase().endsWith(".gif")) + || (f.getName().toLowerCase().endsWith(".png")) + || (f.isDirectory()); + } + + @Override + public String getDescription() { + return translate("filter.images"); + } + }); + 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()); + byte[] data = Helper.readFile(selfile.getAbsolutePath()); + try { + it.setImage(data); + it.getSwf().clearImageCache(); + } catch (IOException ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, "Invalid image", ex); + View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); + } + reload(true); + } + } + } + } + break; + case ACTION_REPLACE_BINARY: + { + Object tagObj = tagTree.getLastSelectedPathComponent(); + if (tagObj == null) { + return; + } + + if (tagObj instanceof TagNode) { + tagObj = ((TagNode) tagObj).tag; + } + if (tagObj instanceof DefineBinaryDataTag) { + DefineBinaryDataTag bt = (DefineBinaryDataTag) tagObj; + JFileChooser fc = new JFileChooser(); + fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); + 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()); + byte[] data = Helper.readFile(selfile.getAbsolutePath()); + bt.binaryData = data; + reload(true); + } + } + } + break; + case ACTION_REMOVE_ITEM: + List sel = getSelected(tagTree); + + List tagsToRemove = new ArrayList<>(); + for (Object o : sel) { + Object tag = o; + if (o instanceof TagNode) { + tag = ((TagNode) o).tag; + } + if (tag instanceof Tag) { + tagsToRemove.add((Tag) tag); + } + } + + if (tagsToRemove.size() == 1) { + Tag tag = tagsToRemove.get(0); + if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tag.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + tag.getSwf().removeTag(tag); + showCard(CARDEMPTYPANEL); + refreshTree(); + } + } else if (tagsToRemove.size() > 1) { + if (View.showConfirmDialog(this, translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + for (Tag tag : tagsToRemove) { + tag.getSwf().removeTag(tag); + } + showCard(CARDEMPTYPANEL); + refreshTree(); + } + } + break; + case ACTION_EDIT_TEXT: + setEditText(true); + break; + case ACTION_CANCEL_TEXT: + setEditText(false); + break; + case ACTION_SAVE_TEXT: + if (oldValue instanceof TextTag) { + TextTag textTag = (TextTag) oldValue; + try { + if (textTag.setFormattedText(new MissingCharacterHandler() { + @Override + public boolean handle(FontTag font, List tags, char character) { + String fontName = fontPanel.sourceFontsMap.get(font.getFontId()); + if (fontName == null) { + fontName = font.getFontName(tags); + } + fontName = FontTag.findInstalledFontName(fontName); + Font f = new Font(fontName, font.getFontStyle(), 18); + if (!f.canDisplay(character)) { + View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); + return false; + } + font.addCharacter(tags, character, fontName); + return true; + + } + }, textTag.getSwf().tags, textValue.getText(), fontPanel.getSelectedFont())) { + setEditText(false); + } + } catch (ParseException ex) { + View.showMessageDialog(null, translate("error.text.invalid").replace("%text%", ex.text).replace("%line%", "" + ex.line), translate("error"), JOptionPane.ERROR_MESSAGE); + } + } + break; + case ACTION_CLOSE_SWF: + { + Main.closeFile(getCurrentSwf()); + } + } + if (Main.isWorking()) { + return; + } + + switch (e.getActionCommand()) { + + case MainFrameRibbonMenu.ACTION_EXPORT_SEL: + export(true); + break; + } + } + + private int splitPos = 0; + + public void showDetailWithPreview(String card) { + CardLayout cl = (CardLayout) (displayWithPreview.getLayout()); + cl.show(displayWithPreview, card); + } + + public void showDetail(String card) { + CardLayout cl = (CardLayout) (detailPanel.getLayout()); + cl.show(detailPanel, card); + if (card.equals(DETAILCARDEMPTYPANEL)) { + if (detailPanel.isVisible()) { + splitPos = splitPane2.getDividerLocation(); + detailPanel.setVisible(false); + } + } else { + if (!detailPanel.isVisible()) { + detailPanel.setVisible(true); + splitPane2.setDividerLocation(splitPos); + } + } + + } + + public void showCard(String card) { + CardLayout cl = (CardLayout) (displayPanel.getLayout()); + cl.show(displayPanel, card); + } + + @Override + public void valueChanged(TreeSelectionEvent e) { + TreeNode treeNode = (TreeNode) e.getPath().getLastPathComponent(); + SWF swf = treeNode.getSwf(); + if (swfs.contains(swf)) { + updateUi(swf); + } else { + updateUi(); + } + setEditText(false, false); + reload(false); + } + + private void stopFlashPlayer() { + if (flashPanel != null) { + if (!flashPanel.isStopped()) { + flashPanel.stopSWF(); + } + } + } + + private static Tag classicTag(Tag t) { + if (t instanceof DefineCompactedFont) { + return ((DefineCompactedFont) t).toClassicFont(); + } + return t; + } + + public void reload(boolean forceReload) { + TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); + if (treeNode == null) { + return; + } + + if (!forceReload && (treeNode == oldValue)) { + return; + } + + oldValue = treeNode; + + TreeElementItem tagObj = null; + if (treeNode instanceof TagNode) { + tagObj = ((TagNode) treeNode).tag; + } + if (treeNode instanceof TreeElement) { + tagObj = ((TreeElement) treeNode).getItem(); + } + + + if (flashPanel != null) { + flashPanel.specialPlayback = false; + } + swfPreviewPanel.stop(); + stopFlashPlayer(); + if (tagObj instanceof ScriptPack) { + final ScriptPack scriptLeaf = (ScriptPack) tagObj; + final List abcList = scriptLeaf.abc.swf.abcList; + if (setSourceWorker != null) { + setSourceWorker.cancel(true); + } + if (!Main.isWorking()) { + CancellableWorker worker = new CancellableWorker() { + + @Override + protected Void doInBackground() throws Exception { + int classIndex = -1; + for (Trait t : scriptLeaf.abc.script_info[scriptLeaf.scriptIndex].traits.traits) { + if (t instanceof TraitClass) { + classIndex = ((TraitClass) t).class_info; + break; + } + } + abcPanel.detailPanel.methodTraitPanel.methodCodePanel.clear(); + abcPanel.navigator.setABC(abcList, scriptLeaf.abc); + abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex); + abcPanel.setAbc(scriptLeaf.abc); + abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList); + abcPanel.decompiledTextArea.setClassIndex(classIndex); + abcPanel.decompiledTextArea.setNoTrait(); + return null; + } + + @Override + protected void done() { + Main.stopWork(); + + View.execInEventDispatch(new Runnable() { + + @Override + public void run() { + try { + get(); + } catch (CancellationException ex) { + abcPanel.decompiledTextArea.setText("//" + AppStrings.translate("work.canceled")); + } catch (Exception ex) { + abcPanel.decompiledTextArea.setText("//Decompilation error: " + ex); + } + } + }); + } + }; + worker.execute(); + setSourceWorker = worker; + Main.startWork(translate("work.decompiling") + "...", worker); + } + + showDetail(DETAILCARDAS3NAVIGATOR); + showCard(CARDACTIONSCRIPT3PANEL); + return; + } else { + showDetail(DETAILCARDEMPTYPANEL); + } + + + if (treeNode instanceof SWFRoot) { + SWFRoot swfRoot = (SWFRoot) treeNode; + SWF swf = swfRoot.getSwf(); + if (mainMenu.isInternalFlashViewerSelected()) { + showCard(CARDSWFPREVIEWPANEL); + swfPreviewPanel.load(swf); + swfPreviewPanel.play(); + } else { + showCard(CARDFLASHPANEL); + parametersPanel.setVisible(false); + if (flashPanel != null) { + Color backgroundColor = View.DEFAULT_BACKGROUND_COLOR; + for (Tag t : swf.tags) { + if (t instanceof SetBackgroundColorTag) { + backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); + break; + } + } + ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); + if (tempFile != null) { + tempFile.delete(); + } + try { + tempFile = File.createTempFile("temp", ".swf"); + tempFile.deleteOnExit(); + swf.saveTo(new BufferedOutputStream(new FileOutputStream(tempFile))); + flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, swf.frameRate); + } catch (IOException iex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex); + } + } + } + + } /*else if (tagObj instanceof DefineVideoStreamTag) { + showCard(CARDEMPTYPANEL); + } else if ((tagObj instanceof DefineSoundTag) || (tagObj instanceof SoundStreamHeadTag) || (tagObj instanceof SoundStreamHead2Tag)) { + showCard(CARDEMPTYPANEL); + } */ else if (tagObj instanceof DefineBinaryDataTag) { + showCard(CARDEMPTYPANEL); + } else if (tagObj instanceof ASMSource) { + showCard(CARDACTIONSCRIPTPANEL); + actionPanel.setSource((ASMSource) tagObj, !forceReload); + } else if (tagObj instanceof ImageTag) { + ImageTag imageTag = (ImageTag) tagObj; + showHideImageReplaceButton(imageTag.importSupported()); + showCard(CARDIMAGEPANEL); + imagePanel.setImage(imageTag.getImage(imageTag.getSwf().tags)); + } else if ((tagObj instanceof DrawableTag) && (!(tagObj instanceof TextTag)) && (!(tagObj instanceof FontTag)) && (mainMenu.isInternalFlashViewerSelected())) { + Tag tag = (Tag) tagObj; + showCard(CARDDRAWPREVIEWPANEL); + previewImagePanel.setDrawable((DrawableTag) tag, tag.getSwf(), tag.getSwf().characters, 50/*FIXME*/); + } else if ((tagObj instanceof FontTag) && (mainMenu.isInternalFlashViewerSelected())) { + Tag tag = (Tag) tagObj; + showCard(CARDFLASHPANEL); + previewImagePanel.setDrawable((DrawableTag) tag, tag.getSwf(), tag.getSwf().characters, 50/*FIXME*/); + showFontTag((FontTag) tagObj); + } else if (tagObj instanceof FrameNode && ((FrameNode) tagObj).isDisplayed() && (mainMenu.isInternalFlashViewerSelected())) { + showCard(CARDDRAWPREVIEWPANEL); + FrameNode fn = (FrameNode) tagObj; + SWF swf = fn.getSwf(); + List controlTags = swf.tags; + int containerId = 0; + RECT rect = swf.displayRect; + int totalFrameCount = swf.frameCount; + if (fn.getParent() instanceof DefineSpriteTag) { + controlTags = ((DefineSpriteTag) fn.getParent()).subTags; + containerId = ((DefineSpriteTag) fn.getParent()).spriteId; + rect = ((DefineSpriteTag) fn.getParent()).getRect(swf.characters, new Stack()); + totalFrameCount = ((DefineSpriteTag) fn.getParent()).frameCount; + } + previewImagePanel.setImage(SWF.frameToImage(containerId, fn.getFrame() - 1, swf.tags, controlTags, rect, totalFrameCount, new Stack())); + } else if (((tagObj instanceof FrameNode) && ((FrameNode) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag)) { + ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); + createAndShowTempSwf(tagObj); + + if (tagObj instanceof TextTag) { + TextTag textTag = (TextTag) tagObj; + parametersPanel.setVisible(true); + previewSplitPane.setDividerLocation(previewSplitPane.getWidth() / 2); + showDetailWithPreview(CARDTEXTPANEL); + textValue.setText(textTag.getFormattedText(textTag.getSwf().tags)); + } else if (tagObj instanceof FontTag) { + showFontTag((FontTag) tagObj); + } else { + parametersPanel.setVisible(false); + } + + } else { + showCard(CARDEMPTYPANEL); + } + } + + private void createAndShowTempSwf(Object tagObj) { + SWF swf; + try { + if (tempFile != null) { + tempFile.delete(); + } + tempFile = File.createTempFile("temp", ".swf"); + tempFile.deleteOnExit(); + + Color backgroundColor = View.swfBackgroundColor; + + if (tagObj instanceof FontTag) { //Fonts are always black on white + backgroundColor = View.DEFAULT_BACKGROUND_COLOR; + } + + if (tagObj instanceof FrameNode) { + FrameNode fn = (FrameNode) tagObj; + swf = fn.getSwf(); + if (fn.getParent() == null) { + for (Tag t : swf.tags) { + if (t instanceof SetBackgroundColorTag) { + backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor(); + break; + } + } + } + } else { + Tag tag = (Tag) tagObj; + swf = tag.getSwf(); + } + + int frameCount = 1; + int frameRate = swf.frameRate; + HashMap videoFrames = new HashMap<>(); + DefineVideoStreamTag vs = null; + if (tagObj instanceof DefineVideoStreamTag) { + vs = (DefineVideoStreamTag) tagObj; + swf.populateVideoFrames(vs.getCharacterId(), swf.tags, videoFrames); + frameCount = videoFrames.size(); + } + + List soundFrames = new ArrayList<>(); + if (tagObj instanceof SoundStreamHeadTypeTag) { + SWF.populateSoundStreamBlocks(swf.tags, (Tag) tagObj, soundFrames); + frameCount = soundFrames.size(); + } + + if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { + frameCount = 100; + frameRate = 50; + } + + if (tagObj instanceof DefineSoundTag) { + frameCount = 1; + } + + byte[] data; + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + SWFOutputStream sos2 = new SWFOutputStream(baos, 10); + int width = swf.displayRect.Xmax - swf.displayRect.Xmin; + int height = swf.displayRect.Ymax - swf.displayRect.Ymin; + sos2.writeRECT(swf.displayRect); + sos2.writeUI8(0); + sos2.writeUI8(frameRate); + sos2.writeUI16(frameCount); //framecnt + + /*FileAttributesTag fa = new FileAttributesTag(); + sos2.writeTag(fa); + */ + sos2.writeTag(new SetBackgroundColorTag(null, new RGB(backgroundColor))); + + if (tagObj instanceof FrameNode) { + FrameNode fn = (FrameNode) tagObj; + Object parent = fn.getParent(); + List subs = new ArrayList<>(); + if (parent == null) { + subs.addAll(swf.tags); + } else { + if (parent instanceof Container) { + subs = ((Container) parent).getSubItems(); + } + } + List doneCharacters = new ArrayList<>(); + int frameCnt = 1; + for (Object o : subs) { + if (o instanceof ShowFrameTag) { + frameCnt++; + continue; + } + if (frameCnt > fn.getFrame()) { + break; + } + Tag t = (Tag) o; + Set needed = t.getDeepNeededCharacters(swf.characters, new ArrayList()); + for (int n : needed) { + if (!doneCharacters.contains(n)) { + sos2.writeTag(classicTag(swf.characters.get(n))); + doneCharacters.add(n); + } + } + if (t instanceof CharacterTag) { + doneCharacters.add(((CharacterTag) t).getCharacterId()); + } + sos2.writeTag(classicTag(t)); + + if (parent != null) { + if (t instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag pot = (PlaceObjectTypeTag) t; + int chid = pot.getCharacterId(); + int depth = pot.getDepth(); + MATRIX mat = pot.getMatrix(); + if (mat == null) { + mat = new MATRIX(); + } + mat = (MATRIX) Helper.deepCopy(mat); + if (parent instanceof BoundedTag) { + RECT r = ((BoundedTag) parent).getRect(swf.characters, new Stack()); + mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; + mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2; + } else { + mat.translateX += width / 2; + mat.translateY += height / 2; + } + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, false, false, true, false, true, depth, chid, mat, null, 0, null, 0, null)); + + } + } + } + sos2.writeTag(new ShowFrameTag(null)); + } else { + + if (tagObj instanceof DefineBitsTag) { + JPEGTablesTag jtt = swf.jtt; + if (jtt != null) { + sos2.writeTag(jtt); + } + } else if (tagObj instanceof AloneTag) { + } else { + Set needed = ((Tag) tagObj).getDeepNeededCharacters(swf.characters, new ArrayList()); + for (int n : needed) { + sos2.writeTag(classicTag(swf.characters.get(n))); + } + } + + sos2.writeTag(classicTag((Tag) tagObj)); + + int chtId = 0; + if (tagObj instanceof CharacterTag) { + chtId = ((CharacterTag) tagObj).getCharacterId(); + } + + MATRIX mat = new MATRIX(); + mat.hasRotate = false; + mat.hasScale = false; + mat.translateX = 0; + mat.translateY = 0; + if (tagObj instanceof BoundedTag) { + RECT r = ((BoundedTag) tagObj).getRect(swf.characters, new Stack()); + mat.translateX = -r.Xmin; + mat.translateY = -r.Ymin; + mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; + mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2; + } else { + mat.translateX = width / 4; + mat.translateY = height / 4; + } + if (tagObj instanceof FontTag) { + + int countGlyphs = ((FontTag) tagObj).getGlyphShapeTable().size(); + int fontId = ((FontTag) tagObj).getFontId(); + int sloupcu = (int) Math.ceil(Math.sqrt(countGlyphs)); + int radku = (int) Math.ceil(((float) countGlyphs) / ((float) sloupcu)); + int x = 0; + int y = 1; + for (int f = 0; f < countGlyphs; f++) { + if (x >= sloupcu) { + x = 0; + y++; + } + List rec = new ArrayList<>(); + TEXTRECORD tr = new TEXTRECORD(); + int textHeight = height / radku; + tr.fontId = fontId; + tr.styleFlagsHasFont = true; + tr.textHeight = textHeight; + tr.glyphEntries = new GLYPHENTRY[1]; + tr.styleFlagsHasColor = true; + tr.textColor = new RGB(0, 0, 0); + tr.glyphEntries[0] = new GLYPHENTRY(); + tr.glyphEntries[0].glyphAdvance = 0; + tr.glyphEntries[0].glyphIndex = f; + rec.add(tr); + mat.translateX = x * width / sloupcu; + mat.translateY = y * height / radku; + sos2.writeTag(new DefineTextTag(null, 999 + f, new RECT(0, width, 0, height), new MATRIX(), rec)); + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1 + f, 999 + f, mat, null, 0, null, 0, null)); + x++; + } + sos2.writeTag(new ShowFrameTag(null)); + } else if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) { + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); + sos2.writeTag(new ShowFrameTag(null)); + int numFrames = 100; + for (int ratio = 0; ratio < 65536; ratio += 65536 / numFrames) { + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, false, true, 1, chtId, mat, null, ratio, null, 0, null)); + sos2.writeTag(new ShowFrameTag(null)); + } + } else if (tagObj instanceof SoundStreamHeadTypeTag) { + for (SoundStreamBlockTag blk : soundFrames) { + sos2.writeTag(blk); + sos2.writeTag(new ShowFrameTag(null)); + } + } else if (tagObj instanceof DefineSoundTag) { + ExportAssetsTag ea = new ExportAssetsTag(); + DefineSoundTag ds = (DefineSoundTag) tagObj; + ea.tags.add(ds.soundId); + ea.names.add("my_define_sound"); + sos2.writeTag(ea); + List actions; + DoActionTag doa; + + + doa = new DoActionTag(null, new byte[]{}, SWF.DEFAULT_VERSION, 0); + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\"\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n" + + "NewObject\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"attachSound\"\n" + + "CallMethod\n" + + "Pop\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n" + + "StopSounds\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n" + + "NewObject\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"attachSound\"\n" + + "CallMethod\n" + + "Pop\n" + + "Push 9999 0.0 2 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"start\"\n" + + "CallMethod\n" + + "Pop\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"onSoundComplete\" \"start\" \"execParam\"\n" + + "StopSounds\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n" + + "NewObject\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"attachSound\"\n" + + "CallMethod\n" + + "Pop\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"onSoundComplete\"\n" + + "DefineFunction2 \"\" 0 2 false true true false true false true false false {\n" + + "Push 0.0 register1 \"my_sound\"\n" + + "GetMember\n" + + "Push \"start\"\n" + + "CallMethod\n" + + "Pop\n" + + "}\n" + + "SetMember\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"execParam\"\n" + + "GetMember\n" + + "Push 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"start\"\n" + + "CallMethod\n" + + "Pop\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + + actions = ASMParser.parse(0, 0, false, + "StopSounds\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + + sos2.writeTag(new ShowFrameTag(null)); + if (flashPanel != null) { + flashPanel.specialPlayback = true; + } + } else if (tagObj instanceof DefineVideoStreamTag) { + + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, false, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); + List frs = new ArrayList<>(videoFrames.values()); + Collections.sort(frs, new Comparator() { + @Override + public int compare(VideoFrameTag o1, VideoFrameTag o2) { + return o1.frameNum - o2.frameNum; + } + }); + boolean first = true; + int ratio = 0; + for (VideoFrameTag f : frs) { + if (!first) { + ratio++; + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, false, false, true, 1, 0, null, null, ratio, null, 0, null)); + } + sos2.writeTag(f); + sos2.writeTag(new ShowFrameTag(null)); + first = false; + } + } else { + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); + sos2.writeTag(new ShowFrameTag(null)); + } + + + }//not showframe + + sos2.writeTag(new EndTag(null)); + data = baos.toByteArray(); + } + + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { + SWFOutputStream sos = new SWFOutputStream(fos, 10); + sos.write("FWS".getBytes()); + sos.write(swf.version); + sos.writeUI32(sos.getPos() + data.length + 4); + sos.write(data); + fos.flush(); + } + + showCard(CARDFLASHPANEL); + if (flashPanel != null) { + flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, frameRate); + } + } catch (IOException | com.jpexs.decompiler.flash.action.parser.ParseException ex) { + Logger.getLogger(MainFramePanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private void showFontTag(FontTag ft) { + if (mainMenu.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) { + ((CardLayout) viewerCards.getLayout()).show(viewerCards, INTERNAL_VIEWER_CARD); + internelViewerPanel.setDrawable(ft, ft.getSwf(), ft.getSwf().characters, 1); + } else { + ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); + } + + parametersPanel.setVisible(true); + previewSplitPane.setDividerLocation(previewSplitPane.getWidth() / 2); + fontPanel.showFontTag(ft); + showDetailWithPreview(CARDFONTPANEL); + } + + public void refreshTree() { + List> expandedNodes = getExpandedNodes(tagTree); + + tagTree.setModel(new TagTreeModel(mainFrame, swfs)); + + expandSwfRoots(); + expandTreeNodes(tagTree, expandedNodes); + } + + public void expandSwfRoots() { + TreeModel model = tagTree.getModel(); + Object node = model.getRoot(); + int childCount = model.getChildCount(node); + for (int j = 0; j < childCount; j++) { + Object child = model.getChild(node, j); + tagTree.expandPath(new TreePath(new Object[] {node, child})); + } + } + + private List> getExpandedNodes(JTree tree) { + List> expandedNodes = new ArrayList<>(); + int rowCount = tree.getRowCount(); + for (int i = 0; i < rowCount; i++) { + 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); + } + } + return expandedNodes; + } + + private void expandTreeNodes(JTree tree, List> pathsToExpand) { + for (List pathAsStringList : pathsToExpand) { + expandTreeNode(tree, pathAsStringList); + } + } + + private void expandTreeNode(JTree tree, List pathAsStringList) { + TreeModel model = tree.getModel(); + Object node = model.getRoot(); + + if (pathAsStringList.isEmpty()) { + return; + } + if (!pathAsStringList.get(0).equals(node.toString())) { + return; + } + + List path = new ArrayList<>(); + path.add(node); + + for (int i = 1; i < pathAsStringList.size(); i++) { + String name = pathAsStringList.get(i); + int childCount = model.getChildCount(node); + for (int j = 0; j < childCount; j++) { + Object child = model.getChild(node, j); + if (child.toString().equals(name)) { + node = child; + path.add(node); + break; + } + } + } + + TreePath tp = new TreePath(path.toArray(new Object[path.size()])); + tree.expandPath(tp); + } + + public void setEditText(boolean edit) { + setEditText(edit, true); + } + + public void setEditText(boolean edit, boolean reload) { + textValue.setEditable(edit); + textSaveButton.setVisible(edit); + textEditButton.setVisible(!edit); + textCancelButton.setVisible(edit); + if (!edit && reload) { + reload(true); + } + } + + private boolean isFreeing; + + @Override + public boolean isFreeing() { + return isFreeing; + } + + @Override + public void free() { + isFreeing = true; + Helper.emptyObject(mainMenu); + Helper.emptyObject(statusPanel); + Helper.emptyObject(this); + } + + public void clearErrorState() { + statusPanel.clearErrorState(); + } + public void setErrorState() { + statusPanel.setErrorState(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java index eebd75621..6b43e6cef 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbon.java @@ -16,820 +16,221 @@ */ package com.jpexs.decompiler.flash.gui; -import com.jpexs.decompiler.flash.ApplicationInfo; -import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.console.ContextMenuTools; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.helpers.Cache; -import com.jpexs.process.ProcessTools; -import com.sun.jna.Platform; +import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.net.URISyntaxException; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; +import java.beans.PropertyChangeEvent; import java.util.ArrayList; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.JCheckBox; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; +import javax.swing.JFrame; import javax.swing.SwingUtilities; +import org.pushingpixels.flamingo.api.common.AbstractCommandButton; import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState; -import org.pushingpixels.flamingo.api.common.JCommandButton; -import org.pushingpixels.flamingo.api.common.JCommandButtonPanel; +import org.pushingpixels.flamingo.api.common.CommandButtonLayoutManager; +import org.pushingpixels.flamingo.api.common.icon.ResizableIcon; 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.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; +import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton; /** * * @author JPEXS */ -public class MainFrameRibbon implements ActionListener { +public final class MainFrameRibbon extends AppRibbonFrame implements MainFrame { - static final String ACTION_RELOAD = "RELOAD"; - static final String ACTION_ADVANCED_SETTINGS = "ADVANCEDSETTINGS"; - static final String ACTION_LOAD_MEMORY = "LOADMEMORY"; - static final String ACTION_LOAD_CACHE = "LOADCACHE"; - static final String ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP = "GOTODOCUMENTCLASSONSTARTUP"; - static final String ACTION_AUTO_RENAME_IDENTIFIERS = "AUTORENAMEIDENTIFIERS"; - static final String ACTION_CACHE_ON_DISK = "CACHEONDISK"; - static final String ACTION_SET_LANGUAGE = "SETLANGUAGE"; - static final String ACTION_DISABLE_DECOMPILATION = "DISABLEDECOMPILATION"; - static final String ACTION_ASSOCIATE = "ASSOCIATE"; - static final String ACTION_GOTO_DOCUMENT_CLASS = "GOTODOCUMENTCLASS"; - static final String ACTION_PARALLEL_SPEED_UP = "PARALLELSPEEDUP"; - static final String ACTION_INTERNAL_VIEWER_SWITCH = "INTERNALVIEWERSWITCH"; - static final String ACTION_SEARCH_AS = "SEARCHAS"; - static final String ACTION_AUTO_DEOBFUSCATE = "AUTODEOBFUSCATE"; - static final String ACTION_EXIT = "EXIT"; - - static final String ACTION_RENAME_ONE_IDENTIFIER = "RENAMEONEIDENTIFIER"; - static final String ACTION_ABOUT = "ABOUT"; - static final String ACTION_SHOW_PROXY = "SHOWPROXY"; - static final String ACTION_SUB_LIMITER = "SUBLIMITER"; - static final String ACTION_SAVE = "SAVE"; - static final String ACTION_SAVE_AS = "SAVEAS"; - static final String ACTION_SAVE_AS_EXE = "SAVEASEXE"; - static final String ACTION_OPEN = "OPEN"; - static final String ACTION_EXPORT_FLA = "EXPORTFLA"; - public static final String ACTION_EXPORT_SEL = "EXPORTSEL"; - static final String ACTION_EXPORT = "EXPORT"; - static final String ACTION_CHECK_UPDATES = "CHECKUPDATES"; - static final String ACTION_HELP_US = "HELPUS"; - static final String ACTION_HOMEPAGE = "HOMEPAGE"; - static final String ACTION_RESTORE_CONTROL_FLOW = "RESTORECONTROLFLOW"; - static final String ACTION_RESTORE_CONTROL_FLOW_ALL = "RESTORECONTROLFLOWALL"; - static final String ACTION_RENAME_IDENTIFIERS = "RENAMEIDENTIFIERS"; - static final String ACTION_DEOBFUSCATE = "DEOBFUSCATE"; - static final String ACTION_DEOBFUSCATE_ALL = "DEOBFUSCATEALL"; - static final String ACTION_REMOVE_NON_SCRIPTS = "REMOVENONSCRIPTS"; - static final String ACTION_REFRESH_DECOMPILED = "REFRESHDECOMPILED"; - - private MainFrame mainFrame; - - private JCheckBox miAutoDeobfuscation; - private JCheckBox miInternalViewer; - private JCheckBox miParallelSpeedUp; - private JCheckBox miAssociate; - private JCheckBox miDecompile; - private JCheckBox miCacheDisk; - private JCheckBox miGotoMainClassOnStartup; - private JCheckBox miAutoRenameIdentifiers; - private JCommandButton saveCommandButton; - private JCommandButton saveasCommandButton; - private JCommandButton saveasexeCommandButton; - private JCommandButton exportAllCommandButton; - private JCommandButton exportFlaCommandButton; - private JCommandButton exportSelectionCommandButton; + public MainFramePanel panel; + private MainFrameMenu mainMenu; - private JCommandButton reloadCommandButton; - private JCommandButton renameinvalidCommandButton; - private JCommandButton globalrenameCommandButton; - private JCommandButton deobfuscationCommandButton; - private JCommandButton searchCommandButton; - private JCommandButton gotoDocumentClassCommandButton; + public MainFrameRibbon() { + super(); - RibbonApplicationMenuEntryPrimary exportFlaMenu; - RibbonApplicationMenuEntryPrimary exportAllMenu; - RibbonApplicationMenuEntryPrimary exportSelMenu; - - public MainFrameRibbon(MainFrame mainFrame, JRibbon ribbon, boolean externalFlashPlayerUnavailable) { - this.mainFrame = mainFrame; - - ribbon.addTask(createFileRibbonTask()); - ribbon.addTask(createToolsRibbonTask()); - ribbon.addTask(createSettingsRibbonTask()); - ribbon.addTask(createHelpRibbonTask()); - - if (Configuration.debugMode.get()) { - ribbon.addTask(createDebugRibbonTask()); + FlashPlayerPanel flashPanel = null; + try { + flashPanel = new FlashPlayerPanel(this); + } catch (FlashUnsupportedException fue) { } - ribbon.setApplicationMenu(createMainMenu()); + java.awt.Container cnt = getContentPane(); + cnt.setLayout(new BorderLayout()); + JRibbon ribbon = getRibbon(); + cnt.add(ribbon, BorderLayout.NORTH); - createMenuBar(externalFlashPlayerUnavailable); - } + boolean externalFlashPlayerUnavailable = flashPanel == null; + mainMenu = new MainFrameRibbonMenu(this, ribbon, externalFlashPlayerUnavailable); - public boolean isInternalFlashViewerSelected() { - return miInternalViewer.isSelected(); - } - - private String translate(String key) { - return mainFrame.translate(key); - } + panel = new MainFramePanel(this, mainMenu, flashPanel); + panel.setBackground(Color.yellow); + cnt.add(panel, BorderLayout.CENTER); - private void assignListener(JCommandButton b, final String command) { - final MainFrameRibbon t = this; - b.addActionListener(new ActionListener() { + int w = Configuration.guiWindowWidth.get(); + int h = Configuration.guiWindowHeight.get(); + Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + if (w > dim.width) { + w = dim.width; + } + if (h > dim.height) { + h = dim.height; + } + setSize(w, h); + + boolean maximizedHorizontal = Configuration.guiWindowMaximizedHorizontal.get(); + boolean maximizedVertical = Configuration.guiWindowMaximizedVertical.get(); + + int state = 0; + if (maximizedHorizontal) { + state |= JFrame.MAXIMIZED_HORIZ; + } + if (maximizedVertical) { + state |= JFrame.MAXIMIZED_VERT; + } + setExtendedState(state); + + View.setWindowIcon(this); + addWindowStateListener(new WindowStateListener() { @Override - public void actionPerformed(ActionEvent e) { - t.actionPerformed(new ActionEvent(e.getSource(), 0, command)); + public void windowStateChanged(WindowEvent e) { + int state = e.getNewState(); + Configuration.guiWindowMaximizedHorizontal.set((state & JFrame.MAXIMIZED_HORIZ) == JFrame.MAXIMIZED_HORIZ); + Configuration.guiWindowMaximizedVertical.set((state & JFrame.MAXIMIZED_VERT) == JFrame.MAXIMIZED_VERT); } }); - } - - private String fixCommandTitle(String title) { - if (title.length() > 2) { - if (title.charAt(1) == ' ') { - title = title.charAt(0) + "\u00A0" + title.substring(2); - } - } - return title; - } - - private void createMenuBar(boolean externalFlashPlayerUnavailable) { - JMenuBar menuBar = new JMenuBar(); - - JMenu menuFile = new JMenu(translate("menu.file")); - JMenuItem miOpen = new JMenuItem(translate("menu.file.open")); - miOpen.setIcon(View.getIcon("open16")); - miOpen.setActionCommand(ACTION_OPEN); - miOpen.addActionListener(this); - JMenuItem miSave = new JMenuItem(translate("menu.file.save")); - miSave.setIcon(View.getIcon("save16")); - miSave.setActionCommand(ACTION_SAVE); - miSave.addActionListener(this); - JMenuItem miSaveAs = new JMenuItem(translate("menu.file.saveas")); - miSaveAs.setIcon(View.getIcon("saveas16")); - miSaveAs.setActionCommand(ACTION_SAVE_AS); - miSaveAs.addActionListener(this); - JMenuItem miSaveAsExe = new JMenuItem(translate("menu.file.saveasexe")); - miSaveAsExe.setIcon(View.getIcon("saveas16")); - miSaveAsExe.setActionCommand(ACTION_SAVE_AS_EXE); - miSaveAsExe.addActionListener(this); - - JMenuItem menuExportFla = new JMenuItem(translate("menu.file.export.fla")); - menuExportFla.setActionCommand(ACTION_EXPORT_FLA); - menuExportFla.addActionListener(this); - menuExportFla.setIcon(View.getIcon("flash16")); - - JMenuItem menuExportAll = new JMenuItem(translate("menu.file.export.all")); - menuExportAll.setActionCommand(ACTION_EXPORT); - menuExportAll.addActionListener(this); - JMenuItem menuExportSel = new JMenuItem(translate("menu.file.export.selection")); - menuExportSel.setActionCommand(ACTION_EXPORT_SEL); - menuExportSel.addActionListener(this); - menuExportAll.setIcon(View.getIcon("export16")); - menuExportSel.setIcon(View.getIcon("exportsel16")); - - - - menuFile.add(miOpen); - menuFile.add(miSave); - menuFile.add(miSaveAs); - menuFile.add(miSaveAsExe); - menuFile.add(menuExportFla); - menuFile.add(menuExportAll); - menuFile.add(menuExportSel); - menuFile.addSeparator(); - JMenuItem miClose = new JMenuItem(translate("menu.file.exit")); - miClose.setIcon(View.getIcon("exit16")); - miClose.setActionCommand(ACTION_EXIT); - miClose.addActionListener(this); - menuFile.add(miClose); - menuBar.add(menuFile); - JMenu menuDeobfuscation = new JMenu(translate("menu.tools.deobfuscation")); - menuDeobfuscation.setIcon(View.getIcon("deobfuscate16")); - - JMenuItem miDeobfuscation = new JMenuItem(translate("menu.tools.deobfuscation.pcode")); - miDeobfuscation.setActionCommand(ACTION_DEOBFUSCATE); - miDeobfuscation.addActionListener(this); - - miAutoDeobfuscation.setSelected(Configuration.autoDeobfuscate.get()); - miAutoDeobfuscation.addActionListener(this); - miAutoDeobfuscation.setActionCommand(ACTION_AUTO_DEOBFUSCATE); - - JMenuItem miRenameOneIdentifier = new JMenuItem(translate("menu.tools.deobfuscation.globalrename")); - miRenameOneIdentifier.setActionCommand(ACTION_RENAME_ONE_IDENTIFIER); - miRenameOneIdentifier.addActionListener(this); - - JMenuItem miRenameIdentifiers = new JMenuItem(translate("menu.tools.deobfuscation.renameinvalid")); - miRenameIdentifiers.setActionCommand(ACTION_RENAME_IDENTIFIERS); - miRenameIdentifiers.addActionListener(this); - - - menuDeobfuscation.add(miRenameOneIdentifier); - menuDeobfuscation.add(miRenameIdentifiers); - menuDeobfuscation.add(miDeobfuscation); - JMenu menuTools = new JMenu(translate("menu.tools")); - JMenuItem miProxy = new JMenuItem(translate("menu.tools.proxy")); - miProxy.setActionCommand(ACTION_SHOW_PROXY); - miProxy.setIcon(View.getIcon("proxy16")); - miProxy.addActionListener(this); - - JMenuItem miSearchScript = new JMenuItem(translate("menu.tools.searchas")); - miSearchScript.addActionListener(this); - miSearchScript.setActionCommand(ACTION_SEARCH_AS); - miSearchScript.setIcon(View.getIcon("search16")); - - menuTools.add(miSearchScript); - - miInternalViewer.setSelected(Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable); - if (externalFlashPlayerUnavailable) { - miInternalViewer.setEnabled(false); - } - miInternalViewer.setActionCommand(ACTION_INTERNAL_VIEWER_SWITCH); - miInternalViewer.addActionListener(this); - - miParallelSpeedUp.setSelected(Configuration.parallelSpeedUp.get()); - miParallelSpeedUp.setActionCommand(ACTION_PARALLEL_SPEED_UP); - miParallelSpeedUp.addActionListener(this); - - - menuTools.add(miProxy); - - menuTools.add(menuDeobfuscation); - - JMenuItem miGotoDocumentClass = new JMenuItem(translate("menu.tools.gotodocumentclass")); - miGotoDocumentClass.setActionCommand(ACTION_GOTO_DOCUMENT_CLASS); - miGotoDocumentClass.addActionListener(this); - menuBar.add(menuTools); - - miDecompile.setSelected(!Configuration.decompile.get()); - miDecompile.setActionCommand(ACTION_DISABLE_DECOMPILATION); - miDecompile.addActionListener(this); - - - miCacheDisk.setSelected(Configuration.cacheOnDisk.get()); - miCacheDisk.setActionCommand(ACTION_CACHE_ON_DISK); - miCacheDisk.addActionListener(this); - - miGotoMainClassOnStartup.setSelected(Configuration.gotoMainClassOnStartup.get()); - miGotoMainClassOnStartup.setActionCommand(ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP); - miGotoMainClassOnStartup.addActionListener(this); - - miAutoRenameIdentifiers.setSelected(Configuration.autoRenameIdentifiers.get()); - miAutoRenameIdentifiers.setActionCommand(ACTION_AUTO_RENAME_IDENTIFIERS); - miAutoRenameIdentifiers.addActionListener(this); - - /*JMenu menuSettings = new JMenu(translate("menu.settings")); - menuSettings.add(autoDeobfuscateMenuItem); - menuSettings.add(miInternalViewer); - menuSettings.add(miParallelSpeedUp); - menuSettings.add(miDecompile); - menuSettings.add(miCacheDisk); - menuSettings.add(miGotoMainClassOnStartup); - menuSettings.add(miAutoRenameIdentifiers);*/ - - miAssociate.setActionCommand(ACTION_ASSOCIATE); - miAssociate.addActionListener(this); - miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); - - - JMenuItem miLanguage = new JMenuItem(translate("menu.settings.language")); - miLanguage.setActionCommand(ACTION_SET_LANGUAGE); - miLanguage.addActionListener(this); - - /* if (Platform.isWindows()) { - menuSettings.add(miAssociate); - } - menuSettings.add(miLanguage); - - menuBar.add(menuSettings);*/ - JMenu menuHelp = new JMenu(translate("menu.help")); - JMenuItem miAbout = new JMenuItem(translate("menu.help.about")); - miAbout.setIcon(View.getIcon("about16")); - - miAbout.setActionCommand(ACTION_ABOUT); - miAbout.addActionListener(this); - - JMenuItem miCheckUpdates = new JMenuItem(translate("menu.help.checkupdates")); - miCheckUpdates.setActionCommand(ACTION_CHECK_UPDATES); - miCheckUpdates.setIcon(View.getIcon("update16")); - miCheckUpdates.addActionListener(this); - - JMenuItem miHelpUs = new JMenuItem(translate("menu.help.helpus")); - miHelpUs.setActionCommand(ACTION_HELP_US); - miHelpUs.setIcon(View.getIcon("donate16")); - miHelpUs.addActionListener(this); - - JMenuItem miHomepage = new JMenuItem(translate("menu.help.homepage")); - miHomepage.setActionCommand(ACTION_HOMEPAGE); - miHomepage.setIcon(View.getIcon("homepage16")); - miHomepage.addActionListener(this); - - - menuHelp.add(miCheckUpdates); - menuHelp.add(miHelpUs); - menuHelp.add(miHomepage); - menuHelp.add(miAbout); - menuBar.add(menuHelp); - - //setJMenuBar(menuBar); - - //if (hasAbc) { - menuTools.add(miGotoDocumentClass); - //} - } - - private RibbonApplicationMenu createMainMenu() { - RibbonApplicationMenu mainMenu = new RibbonApplicationMenu(); - exportFlaMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("exportfla32"), translate("menu.file.export.fla"), new ActionRedirector(this, ACTION_EXPORT_FLA), JCommandButton.CommandButtonKind.ACTION_ONLY); - exportAllMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("export32"), translate("menu.file.export.all"), new ActionRedirector(this, ACTION_EXPORT), JCommandButton.CommandButtonKind.ACTION_ONLY); - exportSelMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("exportsel32"), translate("menu.file.export.selection"), new ActionRedirector(this, ACTION_EXPORT_SEL), JCommandButton.CommandButtonKind.ACTION_ONLY); - RibbonApplicationMenuEntryPrimary checkUpdatesMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("update32"), translate("menu.help.checkupdates"), new ActionRedirector(this, ACTION_CHECK_UPDATES), JCommandButton.CommandButtonKind.ACTION_ONLY); - RibbonApplicationMenuEntryPrimary aboutMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("about32"), translate("menu.help.about"), new ActionRedirector(this, ACTION_ABOUT), JCommandButton.CommandButtonKind.ACTION_ONLY); - RibbonApplicationMenuEntryPrimary openFileMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("open32"), translate("menu.file.open"), new ActionRedirector(this, ACTION_OPEN), JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION); - openFileMenu.setRolloverCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() { + addComponentListener(new ComponentAdapter() { @Override - public void menuEntryActivated(JPanel targetPanel) { - 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(new ActionListener() { - - @Override - public void actionPerformed(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); - } - openHistoryPanel.setMaxButtonColumns(1); - targetPanel.setLayout(new BorderLayout()); - targetPanel.add(openHistoryPanel, BorderLayout.CENTER); + public void componentResized(ComponentEvent e) { + int state = getExtendedState(); + if ((state & JFrame.MAXIMIZED_HORIZ) == 0) { + Configuration.guiWindowWidth.set(getWidth()); + } + if ((state & JFrame.MAXIMIZED_VERT) == 0) { + Configuration.guiWindowHeight.set(getHeight()); + } } }); - - RibbonApplicationMenuEntryFooter exitMenu = new RibbonApplicationMenuEntryFooter(View.getResizableIcon("exit32"), translate("menu.file.exit"), new ActionRedirector(this, "EXIT")); - - mainMenu.addMenuEntry(openFileMenu); - mainMenu.addMenuSeparator(); - mainMenu.addMenuEntry(exportFlaMenu); - mainMenu.addMenuEntry(exportAllMenu); - mainMenu.addMenuEntry(exportSelMenu); - mainMenu.addMenuSeparator(); - mainMenu.addMenuEntry(checkUpdatesMenu); - mainMenu.addMenuEntry(aboutMenu); - mainMenu.addFooterEntry(exitMenu); - mainMenu.addMenuSeparator(); - - return mainMenu; - } - - private List getResizePolicies(JRibbonBand ribbonBand) { - List resizePolicies = new ArrayList<>(); - resizePolicies.add(new CoreRibbonResizePolicies.Mirror(ribbonBand.getControlPanel())); - resizePolicies.add(new IconRibbonBandResizePolicy(ribbonBand.getControlPanel())); - return resizePolicies; - } - - private RibbonTask createFileRibbonTask() { - JRibbonBand editBand = new JRibbonBand(translate("menu.general"), null); - editBand.setResizePolicies(getResizePolicies(editBand)); - JCommandButton openCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.open")), View.getResizableIcon("open32")); - assignListener(openCommandButton, ACTION_OPEN); - saveCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.save")), View.getResizableIcon("save32")); - assignListener(saveCommandButton, ACTION_SAVE); - saveasCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.saveas")), View.getResizableIcon("saveas16")); - assignListener(saveasCommandButton, ACTION_SAVE_AS); - saveasexeCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.saveasexe")), View.getResizableIcon("saveas16")); - assignListener(saveasexeCommandButton, ACTION_SAVE_AS_EXE); - - reloadCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.reload")), View.getResizableIcon("reload16")); - assignListener(reloadCommandButton, ACTION_RELOAD); - - editBand.addCommandButton(openCommandButton, RibbonElementPriority.TOP); - editBand.addCommandButton(saveCommandButton, RibbonElementPriority.TOP); - editBand.addCommandButton(saveasCommandButton, RibbonElementPriority.MEDIUM); - editBand.addCommandButton(saveasexeCommandButton, RibbonElementPriority.MEDIUM); - editBand.addCommandButton(reloadCommandButton, RibbonElementPriority.MEDIUM); - - JRibbonBand exportBand = new JRibbonBand(translate("menu.export"), null); - exportBand.setResizePolicies(getResizePolicies(exportBand)); - exportFlaCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.fla")), View.getResizableIcon("exportfla32")); - assignListener(exportFlaCommandButton, ACTION_EXPORT_FLA); - exportAllCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.all")), View.getResizableIcon("export16")); - assignListener(exportAllCommandButton, ACTION_EXPORT); - exportSelectionCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.selection")), View.getResizableIcon("exportsel16")); - assignListener(exportSelectionCommandButton, ACTION_EXPORT_SEL); - - exportBand.addCommandButton(exportFlaCommandButton, RibbonElementPriority.TOP); - exportBand.addCommandButton(exportAllCommandButton, RibbonElementPriority.MEDIUM); - exportBand.addCommandButton(exportSelectionCommandButton, RibbonElementPriority.MEDIUM); - - return new RibbonTask(translate("menu.file"), editBand, exportBand); - } - - private RibbonTask createToolsRibbonTask() { - //----------------------------------------- TOOLS ----------------------------------- - - JRibbonBand toolsBand = new JRibbonBand(translate("menu.tools"), null); - toolsBand.setResizePolicies(getResizePolicies(toolsBand)); - - searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchas")), View.getResizableIcon("search32")); - assignListener(searchCommandButton, ACTION_SEARCH_AS); - gotoDocumentClassCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.gotodocumentclass")), View.getResizableIcon("gotomainclass32")); - assignListener(gotoDocumentClassCommandButton, ACTION_GOTO_DOCUMENT_CLASS); - - JCommandButton proxyCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.proxy")), View.getResizableIcon("proxy16")); - assignListener(proxyCommandButton, ACTION_SHOW_PROXY); - - JCommandButton loadMemoryCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchmemory")), View.getResizableIcon("loadmemory16")); - assignListener(loadMemoryCommandButton, ACTION_LOAD_MEMORY); - - JCommandButton loadCacheCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchcache")), View.getResizableIcon("loadcache16")); - assignListener(loadCacheCommandButton, ACTION_LOAD_CACHE); - - toolsBand.addCommandButton(searchCommandButton, RibbonElementPriority.TOP); - toolsBand.addCommandButton(gotoDocumentClassCommandButton, RibbonElementPriority.TOP); - toolsBand.addCommandButton(proxyCommandButton, RibbonElementPriority.MEDIUM); - toolsBand.addCommandButton(loadMemoryCommandButton, RibbonElementPriority.MEDIUM); - toolsBand.addCommandButton(loadCacheCommandButton, RibbonElementPriority.MEDIUM); - if (!ProcessTools.toolsAvailable()) { - loadMemoryCommandButton.setEnabled(false); - } - JRibbonBand deobfuscationBand = new JRibbonBand(translate("menu.tools.deobfuscation"), null); - deobfuscationBand.setResizePolicies(getResizePolicies(deobfuscationBand)); - - deobfuscationCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.pcode")), View.getResizableIcon("deobfuscate32")); - assignListener(deobfuscationCommandButton, ACTION_DEOBFUSCATE); - globalrenameCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.globalrename")), View.getResizableIcon("rename16")); - assignListener(globalrenameCommandButton, ACTION_RENAME_ONE_IDENTIFIER); - renameinvalidCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.renameinvalid")), View.getResizableIcon("renameall16")); - assignListener(renameinvalidCommandButton, ACTION_RENAME_IDENTIFIERS); - - deobfuscationBand.addCommandButton(deobfuscationCommandButton, RibbonElementPriority.TOP); - deobfuscationBand.addCommandButton(globalrenameCommandButton, RibbonElementPriority.MEDIUM); - deobfuscationBand.addCommandButton(renameinvalidCommandButton, RibbonElementPriority.MEDIUM); - - return new RibbonTask(translate("menu.tools"), toolsBand, deobfuscationBand); - } - - private RibbonTask createSettingsRibbonTask() { - //----------------------------------------- SETTINGS ----------------------------------- - - JRibbonBand settingsBand = new JRibbonBand(translate("menu.settings"), null); - settingsBand.setResizePolicies(getResizePolicies(settingsBand)); - - miAutoDeobfuscation = new JCheckBox(translate("menu.settings.autodeobfuscation")); - - miInternalViewer = new JCheckBox(translate("menu.settings.internalflashviewer")); - miParallelSpeedUp = new JCheckBox(translate("menu.settings.parallelspeedup")); - miDecompile = new JCheckBox(translate("menu.settings.disabledecompilation")); - miAssociate = new JCheckBox(translate("menu.settings.addtocontextmenu")); - miCacheDisk = new JCheckBox(translate("menu.settings.cacheOnDisk")); - miGotoMainClassOnStartup = new JCheckBox(translate("menu.settings.gotoMainClassOnStartup")); - miAutoRenameIdentifiers = new JCheckBox(translate("menu.settings.autoRenameIdentifiers")); - - settingsBand.addRibbonComponent(new JRibbonComponent(miAutoDeobfuscation)); - settingsBand.addRibbonComponent(new JRibbonComponent(miInternalViewer)); - settingsBand.addRibbonComponent(new JRibbonComponent(miParallelSpeedUp)); - settingsBand.addRibbonComponent(new JRibbonComponent(miDecompile)); - if (Platform.isWindows()) { - settingsBand.addRibbonComponent(new JRibbonComponent(miAssociate)); - } - settingsBand.addRibbonComponent(new JRibbonComponent(miCacheDisk)); - settingsBand.addRibbonComponent(new JRibbonComponent(miGotoMainClassOnStartup)); - settingsBand.addRibbonComponent(new JRibbonComponent(miAutoRenameIdentifiers)); - - JRibbonBand languageBand = new JRibbonBand(translate("menu.language"), null); - List languageBandResizePolicies = new ArrayList<>(); - languageBandResizePolicies.add(new BaseRibbonBandResizePolicy(languageBand.getControlPanel()) { + addWindowListener(new WindowAdapter() { @Override - public int getPreferredWidth(int i, int i1) { - return 105; - } - - @Override - public void install(int i, int i1) { - } - }); - languageBandResizePolicies.add(new IconRibbonBandResizePolicy(languageBand.getControlPanel())); - languageBand.setResizePolicies(languageBandResizePolicies); - JCommandButton setLanguageCommandButton = new JCommandButton(fixCommandTitle(translate("menu.settings.language")), View.getResizableIcon("setlanguage32")); - assignListener(setLanguageCommandButton, ACTION_SET_LANGUAGE); - languageBand.addCommandButton(setLanguageCommandButton, RibbonElementPriority.TOP); - - JRibbonBand advancedSettingsBand = new JRibbonBand(translate("menu.advancedsettings.advancedsettings"), null); - advancedSettingsBand.setResizePolicies(getResizePolicies(advancedSettingsBand)); - JCommandButton advancedSettingsCommandButton = new JCommandButton(fixCommandTitle(translate("menu.advancedsettings.advancedsettings")), View.getResizableIcon("settings16")); - assignListener(advancedSettingsCommandButton, ACTION_ADVANCED_SETTINGS); - - advancedSettingsBand.addCommandButton(advancedSettingsCommandButton, RibbonElementPriority.MEDIUM); - - return new RibbonTask(translate("menu.settings"), settingsBand, languageBand, advancedSettingsBand); - } - - private RibbonTask createHelpRibbonTask() { - //----------------------------------------- HELP ----------------------------------- - - JRibbonBand helpBand = new JRibbonBand(translate("menu.help"), null); - helpBand.setResizePolicies(getResizePolicies(helpBand)); - - JCommandButton checkForUpdatesCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.checkupdates")), View.getResizableIcon("update16")); - assignListener(checkForUpdatesCommandButton, ACTION_CHECK_UPDATES); - JCommandButton helpUsUpdatesCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.helpus")), View.getResizableIcon("donate32")); - assignListener(helpUsUpdatesCommandButton, ACTION_HELP_US); - JCommandButton homepageCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.homepage")), View.getResizableIcon("homepage16")); - assignListener(homepageCommandButton, ACTION_HOMEPAGE); - JCommandButton aboutCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.about")), View.getResizableIcon("about32")); - assignListener(aboutCommandButton, ACTION_ABOUT); - - helpBand.addCommandButton(aboutCommandButton, RibbonElementPriority.TOP); - helpBand.addCommandButton(checkForUpdatesCommandButton, RibbonElementPriority.MEDIUM); - helpBand.addCommandButton(homepageCommandButton, RibbonElementPriority.MEDIUM); - helpBand.addCommandButton(helpUsUpdatesCommandButton, RibbonElementPriority.TOP); - return new RibbonTask(translate("menu.help"), helpBand); - } - - private RibbonTask createDebugRibbonTask() { - //----------------------------------------- DEBUG ----------------------------------- - - JRibbonBand debugBand = new JRibbonBand("Debug", null); - debugBand.setResizePolicies(getResizePolicies(debugBand)); - - JCommandButton removeNonScriptsCommandButton = new JCommandButton(fixCommandTitle("Remove non scripts"), View.getResizableIcon("update16")); - assignListener(removeNonScriptsCommandButton, ACTION_REMOVE_NON_SCRIPTS); - - JCommandButton refreshDecompiledCommandButton = new JCommandButton(fixCommandTitle("Refresh decompiled script"), View.getResizableIcon("update16")); - assignListener(refreshDecompiledCommandButton, ACTION_REFRESH_DECOMPILED); - - debugBand.addCommandButton(removeNonScriptsCommandButton, RibbonElementPriority.MEDIUM); - debugBand.addCommandButton(refreshDecompiledCommandButton, RibbonElementPriority.MEDIUM); - return new RibbonTask("Debug", debugBand); - } - - public void updateComponets(SWF swf, List abcList) { - boolean swfLoaded = swf != null; - boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty(); - - exportAllMenu.setEnabled(swfLoaded); - exportFlaMenu.setEnabled(swfLoaded); - exportSelMenu.setEnabled(swfLoaded); - - saveCommandButton.setEnabled(swfLoaded); - saveasCommandButton.setEnabled(swfLoaded); - saveasexeCommandButton.setEnabled(swfLoaded); - exportAllCommandButton.setEnabled(swfLoaded); - exportFlaCommandButton.setEnabled(swfLoaded); - exportSelectionCommandButton.setEnabled(swfLoaded); - reloadCommandButton.setEnabled(swfLoaded); - - renameinvalidCommandButton.setEnabled(swfLoaded); - globalrenameCommandButton.setEnabled(swfLoaded); - deobfuscationCommandButton.setEnabled(swfLoaded); - searchCommandButton.setEnabled(swfLoaded); - - gotoDocumentClassCommandButton.setEnabled(hasAbc); - deobfuscationCommandButton.setEnabled(hasAbc); - } - - @Override - public void actionPerformed(ActionEvent e) { - switch (e.getActionCommand()) { - case ACTION_RELOAD: - if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) { - Main.reloadSWFs(); - } - break; - case ACTION_ADVANCED_SETTINGS: - Main.advancedSettings(); - break; - case ACTION_LOAD_MEMORY: - Main.loadFromMemory(); - break; - case ACTION_LOAD_CACHE: - Main.loadFromCache(); - break; - case ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP: - Configuration.gotoMainClassOnStartup.set(miGotoMainClassOnStartup.isSelected()); - break; - case ACTION_AUTO_RENAME_IDENTIFIERS: - Configuration.autoRenameIdentifiers.set(miAutoRenameIdentifiers.isSelected()); - break; - case ACTION_CACHE_ON_DISK: - Configuration.cacheOnDisk.set(miCacheDisk.isSelected()); - if (miCacheDisk.isSelected()) { - Cache.setStorageType(Cache.STORAGE_FILES); - } else { - Cache.setStorageType(Cache.STORAGE_MEMORY); - } - break; - case ACTION_SET_LANGUAGE: - new SelectLanguageDialog().display(); - break; - case ACTION_DISABLE_DECOMPILATION: - Configuration.decompile.set(!miDecompile.isSelected()); - mainFrame.disableDecompilationChanged(); - break; - case ACTION_ASSOCIATE: - if (miAssociate.isSelected() == ContextMenuTools.isAddedToContextMenu()) { - return; - } - ContextMenuTools.addToContextMenu(miAssociate.isSelected()); - - //Update checkbox menuitem accordingly (User can cancel rights elevation) - new Timer().schedule(new TimerTask() { - @Override - public void run() { - miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); - } - }, 1000); //It takes some time registry change to apply - break; - case ACTION_GOTO_DOCUMENT_CLASS: - mainFrame.gotoDocumentClass(mainFrame.getCurrentSwf()); - break; - case ACTION_PARALLEL_SPEED_UP: - String confStr = translate("message.confirm.parallel") + "\r\n"; - if (miParallelSpeedUp.isSelected()) { - 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((Boolean) miParallelSpeedUp.isSelected()); - } else { - miParallelSpeedUp.setSelected(!miParallelSpeedUp.isSelected()); - } - break; - case ACTION_INTERNAL_VIEWER_SWITCH: - Configuration.internalFlashViewer.set(miInternalViewer.isSelected()); - mainFrame.reload(true); - break; - case ACTION_SEARCH_AS: - mainFrame.searchAs(); - break; - case ACTION_AUTO_DEOBFUSCATE: - if (View.showConfirmDialog(mainFrame, translate("message.confirm.autodeobfuscate") + "\r\n" + (miAutoDeobfuscation.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { - Configuration.autoDeobfuscate.set(miAutoDeobfuscation.isSelected()); - mainFrame.autoDeobfuscateChanged(); - } else { - miAutoDeobfuscation.setSelected(!miAutoDeobfuscation.isSelected()); - } - break; - case ACTION_EXIT: - mainFrame.setVisible(false); + public void windowClosing(WindowEvent e) { if (Main.proxyFrame != null) { if (Main.proxyFrame.isVisible()) { return; } } + if (Main.loadFromMemoryFrame != null) { + if (Main.loadFromMemoryFrame.isVisible()) { + return; + } + } + if (Main.loadFromCacheFrame != null) { + if (Main.loadFromCacheFrame.isVisible()) { + return; + } + } Main.exit(); - break; - } + } + }); - if (Main.isWorking()) { + View.centerScreen(this); + } + + private static void getApplicationMenuButtons(Component comp, List ret) { + if (comp instanceof JRibbonApplicationMenuButton) { + ret.add((JRibbonApplicationMenuButton) comp); return; } - - switch (e.getActionCommand()) { - case ACTION_RENAME_ONE_IDENTIFIER: - mainFrame.renameOneIdentifier(mainFrame.getCurrentSwf()); - break; - case ACTION_ABOUT: - Main.about(); - break; - case ACTION_SHOW_PROXY: - Main.showProxy(); - break; - case ACTION_SUB_LIMITER: - if (e.getSource() instanceof JCheckBoxMenuItem) { - Main.setSubLimiter(((JCheckBoxMenuItem) e.getSource()).getState()); - } - break; - case ACTION_SAVE: - try { - SWF swf = mainFrame.getCurrentSwf(); - Main.saveFile(swf, swf.file); - } catch (IOException ex) { - Logger.getLogger(MainFrameRibbon.class.getName()).log(Level.SEVERE, null, ex); - View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE); - } - break; - case ACTION_SAVE_AS: - { - SWF swf = mainFrame.getCurrentSwf(); - if (Main.saveFileDialog(swf)) { - mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); - saveCommandButton.setEnabled(mainFrame.getCurrentSwf() != null); - } - } - break; - case ACTION_SAVE_AS_EXE: - { - SWF swf = mainFrame.getCurrentSwf(); - if (Main.saveFileDialog(swf, ".exe")) { - mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); - saveCommandButton.setEnabled(mainFrame.getCurrentSwf() != null); - } - } - break; - case ACTION_OPEN: - Main.openFileDialog(); - break; - case ACTION_EXPORT_FLA: - mainFrame.exportFla(mainFrame.getCurrentSwf()); - break; - case ACTION_EXPORT_SEL: - case ACTION_EXPORT: - boolean onlySel = e.getActionCommand().endsWith("SEL"); - mainFrame.export(onlySel); - break; - case ACTION_CHECK_UPDATES: - if (!Main.checkForUpdates()) { - View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE); - } - break; - case ACTION_HELP_US: - String helpUsURL = ApplicationInfo.PROJECT_PAGE + "/help_us.html"; - if (java.awt.Desktop.isDesktopSupported()) { - java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); - try { - java.net.URI uri = new java.net.URI(helpUsURL); - desktop.browse(uri); - } catch (URISyntaxException | IOException ex) { - } - } else { - View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL)); - } - break; - case ACTION_HOMEPAGE: - String homePageURL = ApplicationInfo.PROJECT_PAGE; - if (java.awt.Desktop.isDesktopSupported()) { - java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); - try { - java.net.URI uri = new java.net.URI(homePageURL); - desktop.browse(uri); - } catch (URISyntaxException | IOException ex) { - } - } else { - View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL)); - } - break; - case ACTION_RESTORE_CONTROL_FLOW: - case ACTION_RESTORE_CONTROL_FLOW_ALL: - boolean all = e.getActionCommand().endsWith("ALL"); - mainFrame.restoreControlFlow(all); - break; - case ACTION_RENAME_IDENTIFIERS: - mainFrame.renameIdentifiers(mainFrame.getCurrentSwf()); - break; - case ACTION_DEOBFUSCATE: - case ACTION_DEOBFUSCATE_ALL: - mainFrame.deobfuscate(); - break; - case ACTION_REMOVE_NON_SCRIPTS: - mainFrame.removeNonScripts(mainFrame.getCurrentSwf()); - break; - case ACTION_REFRESH_DECOMPILED: - mainFrame.refreshDecompiled(); - break; + if (comp instanceof java.awt.Container) { + java.awt.Container cont = (java.awt.Container) comp; + for (int i = 0; i < cont.getComponentCount(); i++) { + getApplicationMenuButtons(cont.getComponent(i), ret); + } } } -} + @Override + public void setVisible(boolean b) { + super.setVisible(b); + + final MainFrameRibbon t = this; + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + List mbuttons = new ArrayList<>(); + getApplicationMenuButtons(t, mbuttons); + + for (final JRibbonApplicationMenuButton mbutton : mbuttons) { + mbutton.setIcon(View.getResizableIcon("buttonicon_256")); + mbutton.setDisplayState(new CommandButtonDisplayState( + "My Ribbon Application Menu Button", mbutton.getSize().width) { + @Override + public CommandButtonLayoutManager createLayoutManager( + AbstractCommandButton commandButton) { + return new CommandButtonLayoutManager() { + @Override + public int getPreferredIconSize() { + return mbutton.getSize().width; + } + + @Override + public CommandButtonLayoutManager.CommandButtonLayoutInfo getLayoutInfo( + AbstractCommandButton commandButton, Graphics g) { + CommandButtonLayoutManager.CommandButtonLayoutInfo result = new CommandButtonLayoutManager.CommandButtonLayoutInfo(); + result.actionClickArea = new Rectangle(0, 0, 0, 0); + result.popupClickArea = new Rectangle(0, 0, commandButton + .getWidth(), commandButton.getHeight()); + result.popupActionRect = new Rectangle(0, 0, 0, 0); + ResizableIcon icon = commandButton.getIcon(); + icon.setDimension(new Dimension(commandButton.getWidth(), commandButton.getHeight())); + result.iconRect = new Rectangle( + 0, + 0, + commandButton.getWidth(), commandButton.getHeight()); + result.isTextInActionArea = false; + return result; + } + + @Override + public Dimension getPreferredSize( + AbstractCommandButton commandButton) { + return new Dimension(40, 40); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + } + + @Override + public Point getKeyTipAnchorCenterPoint( + AbstractCommandButton commandButton) { + // dead center + return new Point(commandButton.getWidth() / 2, + commandButton.getHeight() / 2); + } + }; + } + }); + + MyRibbonApplicationMenuButtonUI mui = (MyRibbonApplicationMenuButtonUI) mbutton.getUI(); + mui.setHoverIcon(View.getResizableIcon("buttonicon_hover_256")); + mui.setNormalIcon(View.getResizableIcon("buttonicon_256")); + mui.setClickIcon(View.getResizableIcon("buttonicon_down_256")); + } + } + }); + + panel.setVisible(b); + } + + @Override + public MainFramePanel getPanel() { + return panel; + } + } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java new file mode 100644 index 000000000..4101a722f --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java @@ -0,0 +1,680 @@ +/* + * Copyright (C) 2010-2013 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.ApplicationInfo; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.console.ContextMenuTools; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.helpers.Cache; +import com.jpexs.process.ProcessTools; +import com.sun.jna.Platform; +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState; +import org.pushingpixels.flamingo.api.common.JCommandButton; +import org.pushingpixels.flamingo.api.common.JCommandButtonPanel; +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.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 implements MainFrameMenu, ActionListener { + + static final String ACTION_RELOAD = "RELOAD"; + static final String ACTION_ADVANCED_SETTINGS = "ADVANCEDSETTINGS"; + static final String ACTION_LOAD_MEMORY = "LOADMEMORY"; + static final String ACTION_LOAD_CACHE = "LOADCACHE"; + static final String ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP = "GOTODOCUMENTCLASSONSTARTUP"; + static final String ACTION_AUTO_RENAME_IDENTIFIERS = "AUTORENAMEIDENTIFIERS"; + static final String ACTION_CACHE_ON_DISK = "CACHEONDISK"; + static final String ACTION_SET_LANGUAGE = "SETLANGUAGE"; + static final String ACTION_DISABLE_DECOMPILATION = "DISABLEDECOMPILATION"; + static final String ACTION_ASSOCIATE = "ASSOCIATE"; + static final String ACTION_GOTO_DOCUMENT_CLASS = "GOTODOCUMENTCLASS"; + static final String ACTION_PARALLEL_SPEED_UP = "PARALLELSPEEDUP"; + static final String ACTION_INTERNAL_VIEWER_SWITCH = "INTERNALVIEWERSWITCH"; + static final String ACTION_SEARCH_AS = "SEARCHAS"; + static final String ACTION_AUTO_DEOBFUSCATE = "AUTODEOBFUSCATE"; + static final String ACTION_EXIT = "EXIT"; + + static final String ACTION_RENAME_ONE_IDENTIFIER = "RENAMEONEIDENTIFIER"; + static final String ACTION_ABOUT = "ABOUT"; + static final String ACTION_SHOW_PROXY = "SHOWPROXY"; + static final String ACTION_SUB_LIMITER = "SUBLIMITER"; + static final String ACTION_SAVE = "SAVE"; + static final String ACTION_SAVE_AS = "SAVEAS"; + static final String ACTION_SAVE_AS_EXE = "SAVEASEXE"; + static final String ACTION_OPEN = "OPEN"; + static final String ACTION_EXPORT_FLA = "EXPORTFLA"; + public static final String ACTION_EXPORT_SEL = "EXPORTSEL"; + static final String ACTION_EXPORT = "EXPORT"; + static final String ACTION_CHECK_UPDATES = "CHECKUPDATES"; + static final String ACTION_HELP_US = "HELPUS"; + static final String ACTION_HOMEPAGE = "HOMEPAGE"; + static final String ACTION_RESTORE_CONTROL_FLOW = "RESTORECONTROLFLOW"; + static final String ACTION_RESTORE_CONTROL_FLOW_ALL = "RESTORECONTROLFLOWALL"; + static final String ACTION_RENAME_IDENTIFIERS = "RENAMEIDENTIFIERS"; + static final String ACTION_DEOBFUSCATE = "DEOBFUSCATE"; + static final String ACTION_DEOBFUSCATE_ALL = "DEOBFUSCATEALL"; + static final String ACTION_REMOVE_NON_SCRIPTS = "REMOVENONSCRIPTS"; + static final String ACTION_REFRESH_DECOMPILED = "REFRESHDECOMPILED"; + + private MainFrameRibbon mainFrame; + + private JCheckBox miAutoDeobfuscation; + private JCheckBox miInternalViewer; + private JCheckBox miParallelSpeedUp; + private JCheckBox miAssociate; + private JCheckBox miDecompile; + private JCheckBox miCacheDisk; + private JCheckBox miGotoMainClassOnStartup; + private JCheckBox miAutoRenameIdentifiers; + private JCommandButton saveCommandButton; + private JCommandButton saveasCommandButton; + private JCommandButton saveasexeCommandButton; + private JCommandButton exportAllCommandButton; + private JCommandButton exportFlaCommandButton; + private JCommandButton exportSelectionCommandButton; + + private JCommandButton reloadCommandButton; + private JCommandButton renameinvalidCommandButton; + private JCommandButton globalrenameCommandButton; + private JCommandButton deobfuscationCommandButton; + private JCommandButton searchCommandButton; + private JCommandButton gotoDocumentClassCommandButton; + + RibbonApplicationMenuEntryPrimary exportFlaMenu; + RibbonApplicationMenuEntryPrimary exportAllMenu; + RibbonApplicationMenuEntryPrimary exportSelMenu; + + public MainFrameRibbonMenu(MainFrameRibbon mainFrame, JRibbon ribbon, boolean externalFlashPlayerUnavailable) { + this.mainFrame = mainFrame; + + ribbon.addTask(createFileRibbonTask()); + ribbon.addTask(createToolsRibbonTask()); + ribbon.addTask(createSettingsRibbonTask(externalFlashPlayerUnavailable)); + ribbon.addTask(createHelpRibbonTask()); + + if (Configuration.debugMode.get()) { + ribbon.addTask(createDebugRibbonTask()); + } + + ribbon.setApplicationMenu(createMainMenu()); + } + + @Override + public boolean isInternalFlashViewerSelected() { + return miInternalViewer.isSelected(); + } + + private String translate(String key) { + return mainFrame.translate(key); + } + + private void assignListener(JCommandButton b, final String command) { + final MainFrameRibbonMenu t = this; + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + t.actionPerformed(new ActionEvent(e.getSource(), 0, command)); + } + }); + } + + private String fixCommandTitle(String title) { + if (title.length() > 2) { + if (title.charAt(1) == ' ') { + title = title.charAt(0) + "\u00A0" + title.substring(2); + } + } + return title; + } + + private RibbonApplicationMenu createMainMenu() { + RibbonApplicationMenu mainMenu = new RibbonApplicationMenu(); + exportFlaMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("exportfla32"), translate("menu.file.export.fla"), new ActionRedirector(this, ACTION_EXPORT_FLA), JCommandButton.CommandButtonKind.ACTION_ONLY); + exportAllMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("export32"), translate("menu.file.export.all"), new ActionRedirector(this, ACTION_EXPORT), JCommandButton.CommandButtonKind.ACTION_ONLY); + exportSelMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("exportsel32"), translate("menu.file.export.selection"), new ActionRedirector(this, ACTION_EXPORT_SEL), JCommandButton.CommandButtonKind.ACTION_ONLY); + RibbonApplicationMenuEntryPrimary checkUpdatesMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("update32"), translate("menu.help.checkupdates"), new ActionRedirector(this, ACTION_CHECK_UPDATES), JCommandButton.CommandButtonKind.ACTION_ONLY); + RibbonApplicationMenuEntryPrimary aboutMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("about32"), translate("menu.help.about"), new ActionRedirector(this, ACTION_ABOUT), JCommandButton.CommandButtonKind.ACTION_ONLY); + RibbonApplicationMenuEntryPrimary openFileMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("open32"), translate("menu.file.open"), new ActionRedirector(this, ACTION_OPEN), JCommandButton.CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION); + openFileMenu.setRolloverCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() { + @Override + public void menuEntryActivated(JPanel targetPanel) { + 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(new ActionListener() { + + @Override + public void actionPerformed(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); + } + openHistoryPanel.setMaxButtonColumns(1); + targetPanel.setLayout(new BorderLayout()); + targetPanel.add(openHistoryPanel, BorderLayout.CENTER); + } + }); + + RibbonApplicationMenuEntryFooter exitMenu = new RibbonApplicationMenuEntryFooter(View.getResizableIcon("exit32"), translate("menu.file.exit"), new ActionRedirector(this, "EXIT")); + + mainMenu.addMenuEntry(openFileMenu); + mainMenu.addMenuSeparator(); + mainMenu.addMenuEntry(exportFlaMenu); + mainMenu.addMenuEntry(exportAllMenu); + mainMenu.addMenuEntry(exportSelMenu); + mainMenu.addMenuSeparator(); + mainMenu.addMenuEntry(checkUpdatesMenu); + mainMenu.addMenuEntry(aboutMenu); + mainMenu.addFooterEntry(exitMenu); + mainMenu.addMenuSeparator(); + + return mainMenu; + } + + private List getResizePolicies(JRibbonBand ribbonBand) { + List resizePolicies = new ArrayList<>(); + resizePolicies.add(new CoreRibbonResizePolicies.Mirror(ribbonBand.getControlPanel())); + resizePolicies.add(new IconRibbonBandResizePolicy(ribbonBand.getControlPanel())); + return resizePolicies; + } + + private RibbonTask createFileRibbonTask() { + JRibbonBand editBand = new JRibbonBand(translate("menu.general"), null); + editBand.setResizePolicies(getResizePolicies(editBand)); + JCommandButton openCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.open")), View.getResizableIcon("open32")); + assignListener(openCommandButton, ACTION_OPEN); + saveCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.save")), View.getResizableIcon("save32")); + assignListener(saveCommandButton, ACTION_SAVE); + saveasCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.saveas")), View.getResizableIcon("saveas16")); + assignListener(saveasCommandButton, ACTION_SAVE_AS); + saveasexeCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.saveasexe")), View.getResizableIcon("saveas16")); + assignListener(saveasexeCommandButton, ACTION_SAVE_AS_EXE); + + reloadCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.reload")), View.getResizableIcon("reload16")); + assignListener(reloadCommandButton, ACTION_RELOAD); + + editBand.addCommandButton(openCommandButton, RibbonElementPriority.TOP); + editBand.addCommandButton(saveCommandButton, RibbonElementPriority.TOP); + editBand.addCommandButton(saveasCommandButton, RibbonElementPriority.MEDIUM); + editBand.addCommandButton(saveasexeCommandButton, RibbonElementPriority.MEDIUM); + editBand.addCommandButton(reloadCommandButton, RibbonElementPriority.MEDIUM); + + JRibbonBand exportBand = new JRibbonBand(translate("menu.export"), null); + exportBand.setResizePolicies(getResizePolicies(exportBand)); + exportFlaCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.fla")), View.getResizableIcon("exportfla32")); + assignListener(exportFlaCommandButton, ACTION_EXPORT_FLA); + exportAllCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.all")), View.getResizableIcon("export16")); + assignListener(exportAllCommandButton, ACTION_EXPORT); + exportSelectionCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.export.selection")), View.getResizableIcon("exportsel16")); + assignListener(exportSelectionCommandButton, ACTION_EXPORT_SEL); + + exportBand.addCommandButton(exportFlaCommandButton, RibbonElementPriority.TOP); + exportBand.addCommandButton(exportAllCommandButton, RibbonElementPriority.MEDIUM); + exportBand.addCommandButton(exportSelectionCommandButton, RibbonElementPriority.MEDIUM); + + return new RibbonTask(translate("menu.file"), editBand, exportBand); + } + + private RibbonTask createToolsRibbonTask() { + //----------------------------------------- TOOLS ----------------------------------- + + JRibbonBand toolsBand = new JRibbonBand(translate("menu.tools"), null); + toolsBand.setResizePolicies(getResizePolicies(toolsBand)); + + searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchas")), View.getResizableIcon("search32")); + assignListener(searchCommandButton, ACTION_SEARCH_AS); + gotoDocumentClassCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.gotodocumentclass")), View.getResizableIcon("gotomainclass32")); + assignListener(gotoDocumentClassCommandButton, ACTION_GOTO_DOCUMENT_CLASS); + + JCommandButton proxyCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.proxy")), View.getResizableIcon("proxy16")); + assignListener(proxyCommandButton, ACTION_SHOW_PROXY); + + JCommandButton loadMemoryCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchmemory")), View.getResizableIcon("loadmemory16")); + assignListener(loadMemoryCommandButton, ACTION_LOAD_MEMORY); + + JCommandButton loadCacheCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.searchcache")), View.getResizableIcon("loadcache16")); + assignListener(loadCacheCommandButton, ACTION_LOAD_CACHE); + + toolsBand.addCommandButton(searchCommandButton, RibbonElementPriority.TOP); + toolsBand.addCommandButton(gotoDocumentClassCommandButton, RibbonElementPriority.TOP); + toolsBand.addCommandButton(proxyCommandButton, RibbonElementPriority.MEDIUM); + toolsBand.addCommandButton(loadMemoryCommandButton, RibbonElementPriority.MEDIUM); + toolsBand.addCommandButton(loadCacheCommandButton, RibbonElementPriority.MEDIUM); + if (!ProcessTools.toolsAvailable()) { + loadMemoryCommandButton.setEnabled(false); + } + JRibbonBand deobfuscationBand = new JRibbonBand(translate("menu.tools.deobfuscation"), null); + deobfuscationBand.setResizePolicies(getResizePolicies(deobfuscationBand)); + + deobfuscationCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.pcode")), View.getResizableIcon("deobfuscate32")); + assignListener(deobfuscationCommandButton, ACTION_DEOBFUSCATE); + globalrenameCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.globalrename")), View.getResizableIcon("rename16")); + assignListener(globalrenameCommandButton, ACTION_RENAME_ONE_IDENTIFIER); + renameinvalidCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.deobfuscation.renameinvalid")), View.getResizableIcon("renameall16")); + assignListener(renameinvalidCommandButton, ACTION_RENAME_IDENTIFIERS); + + deobfuscationBand.addCommandButton(deobfuscationCommandButton, RibbonElementPriority.TOP); + deobfuscationBand.addCommandButton(globalrenameCommandButton, RibbonElementPriority.MEDIUM); + deobfuscationBand.addCommandButton(renameinvalidCommandButton, RibbonElementPriority.MEDIUM); + + return new RibbonTask(translate("menu.tools"), toolsBand, deobfuscationBand); + } + + private RibbonTask createSettingsRibbonTask(boolean externalFlashPlayerUnavailable) { + //----------------------------------------- SETTINGS ----------------------------------- + + JRibbonBand settingsBand = new JRibbonBand(translate("menu.settings"), null); + settingsBand.setResizePolicies(getResizePolicies(settingsBand)); + + miAutoDeobfuscation = new JCheckBox(translate("menu.settings.autodeobfuscation")); + miAutoDeobfuscation.setSelected(Configuration.autoDeobfuscate.get()); + miAutoDeobfuscation.addActionListener(this); + miAutoDeobfuscation.setActionCommand(ACTION_AUTO_DEOBFUSCATE); + + miInternalViewer = new JCheckBox(translate("menu.settings.internalflashviewer")); + miInternalViewer.setSelected(Configuration.internalFlashViewer.get() || externalFlashPlayerUnavailable); + if (externalFlashPlayerUnavailable) { + miInternalViewer.setEnabled(false); + } + miInternalViewer.setActionCommand(ACTION_INTERNAL_VIEWER_SWITCH); + miInternalViewer.addActionListener(this); + + miParallelSpeedUp = new JCheckBox(translate("menu.settings.parallelspeedup")); + miParallelSpeedUp.setSelected(Configuration.parallelSpeedUp.get()); + miParallelSpeedUp.setActionCommand(ACTION_PARALLEL_SPEED_UP); + miParallelSpeedUp.addActionListener(this); + + miDecompile = new JCheckBox(translate("menu.settings.disabledecompilation")); + miDecompile.setSelected(!Configuration.decompile.get()); + miDecompile.setActionCommand(ACTION_DISABLE_DECOMPILATION); + miDecompile.addActionListener(this); + + miAssociate = new JCheckBox(translate("menu.settings.addtocontextmenu")); + miAssociate.setActionCommand(ACTION_ASSOCIATE); + miAssociate.addActionListener(this); + miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); + + miCacheDisk = new JCheckBox(translate("menu.settings.cacheOnDisk")); + miCacheDisk.setSelected(Configuration.cacheOnDisk.get()); + miCacheDisk.setActionCommand(ACTION_CACHE_ON_DISK); + miCacheDisk.addActionListener(this); + + miGotoMainClassOnStartup = new JCheckBox(translate("menu.settings.gotoMainClassOnStartup")); + miGotoMainClassOnStartup.setSelected(Configuration.gotoMainClassOnStartup.get()); + miGotoMainClassOnStartup.setActionCommand(ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP); + miGotoMainClassOnStartup.addActionListener(this); + + miAutoRenameIdentifiers = new JCheckBox(translate("menu.settings.autoRenameIdentifiers")); + miAutoRenameIdentifiers.setSelected(Configuration.autoRenameIdentifiers.get()); + miAutoRenameIdentifiers.setActionCommand(ACTION_AUTO_RENAME_IDENTIFIERS); + miAutoRenameIdentifiers.addActionListener(this); + + settingsBand.addRibbonComponent(new JRibbonComponent(miAutoDeobfuscation)); + settingsBand.addRibbonComponent(new JRibbonComponent(miInternalViewer)); + settingsBand.addRibbonComponent(new JRibbonComponent(miParallelSpeedUp)); + settingsBand.addRibbonComponent(new JRibbonComponent(miDecompile)); + if (Platform.isWindows()) { + settingsBand.addRibbonComponent(new JRibbonComponent(miAssociate)); + } + settingsBand.addRibbonComponent(new JRibbonComponent(miCacheDisk)); + settingsBand.addRibbonComponent(new JRibbonComponent(miGotoMainClassOnStartup)); + settingsBand.addRibbonComponent(new JRibbonComponent(miAutoRenameIdentifiers)); + + JRibbonBand languageBand = new JRibbonBand(translate("menu.language"), null); + List languageBandResizePolicies = new ArrayList<>(); + languageBandResizePolicies.add(new BaseRibbonBandResizePolicy(languageBand.getControlPanel()) { + @Override + public int getPreferredWidth(int i, int i1) { + return 105; + } + + @Override + public void install(int i, int i1) { + } + }); + languageBandResizePolicies.add(new IconRibbonBandResizePolicy(languageBand.getControlPanel())); + languageBand.setResizePolicies(languageBandResizePolicies); + JCommandButton setLanguageCommandButton = new JCommandButton(fixCommandTitle(translate("menu.settings.language")), View.getResizableIcon("setlanguage32")); + assignListener(setLanguageCommandButton, ACTION_SET_LANGUAGE); + languageBand.addCommandButton(setLanguageCommandButton, RibbonElementPriority.TOP); + + JRibbonBand advancedSettingsBand = new JRibbonBand(translate("menu.advancedsettings.advancedsettings"), null); + advancedSettingsBand.setResizePolicies(getResizePolicies(advancedSettingsBand)); + JCommandButton advancedSettingsCommandButton = new JCommandButton(fixCommandTitle(translate("menu.advancedsettings.advancedsettings")), View.getResizableIcon("settings16")); + assignListener(advancedSettingsCommandButton, ACTION_ADVANCED_SETTINGS); + + advancedSettingsBand.addCommandButton(advancedSettingsCommandButton, RibbonElementPriority.MEDIUM); + + return new RibbonTask(translate("menu.settings"), settingsBand, languageBand, advancedSettingsBand); + } + + private RibbonTask createHelpRibbonTask() { + //----------------------------------------- HELP ----------------------------------- + + JRibbonBand helpBand = new JRibbonBand(translate("menu.help"), null); + helpBand.setResizePolicies(getResizePolicies(helpBand)); + + JCommandButton checkForUpdatesCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.checkupdates")), View.getResizableIcon("update16")); + assignListener(checkForUpdatesCommandButton, ACTION_CHECK_UPDATES); + JCommandButton helpUsUpdatesCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.helpus")), View.getResizableIcon("donate32")); + assignListener(helpUsUpdatesCommandButton, ACTION_HELP_US); + JCommandButton homepageCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.homepage")), View.getResizableIcon("homepage16")); + assignListener(homepageCommandButton, ACTION_HOMEPAGE); + JCommandButton aboutCommandButton = new JCommandButton(fixCommandTitle(translate("menu.help.about")), View.getResizableIcon("about32")); + assignListener(aboutCommandButton, ACTION_ABOUT); + + helpBand.addCommandButton(aboutCommandButton, RibbonElementPriority.TOP); + helpBand.addCommandButton(checkForUpdatesCommandButton, RibbonElementPriority.MEDIUM); + helpBand.addCommandButton(homepageCommandButton, RibbonElementPriority.MEDIUM); + helpBand.addCommandButton(helpUsUpdatesCommandButton, RibbonElementPriority.TOP); + return new RibbonTask(translate("menu.help"), helpBand); + } + + private RibbonTask createDebugRibbonTask() { + //----------------------------------------- DEBUG ----------------------------------- + + JRibbonBand debugBand = new JRibbonBand("Debug", null); + debugBand.setResizePolicies(getResizePolicies(debugBand)); + + JCommandButton removeNonScriptsCommandButton = new JCommandButton(fixCommandTitle("Remove non scripts"), View.getResizableIcon("update16")); + assignListener(removeNonScriptsCommandButton, ACTION_REMOVE_NON_SCRIPTS); + + JCommandButton refreshDecompiledCommandButton = new JCommandButton(fixCommandTitle("Refresh decompiled script"), View.getResizableIcon("update16")); + assignListener(refreshDecompiledCommandButton, ACTION_REFRESH_DECOMPILED); + + debugBand.addCommandButton(removeNonScriptsCommandButton, RibbonElementPriority.MEDIUM); + debugBand.addCommandButton(refreshDecompiledCommandButton, RibbonElementPriority.MEDIUM); + return new RibbonTask("Debug", debugBand); + } + + @Override + public void updateComponets(SWF swf, List abcList) { + boolean swfLoaded = swf != null; + boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty(); + + exportAllMenu.setEnabled(swfLoaded); + exportFlaMenu.setEnabled(swfLoaded); + exportSelMenu.setEnabled(swfLoaded); + + saveCommandButton.setEnabled(swfLoaded); + saveasCommandButton.setEnabled(swfLoaded); + saveasexeCommandButton.setEnabled(swfLoaded); + exportAllCommandButton.setEnabled(swfLoaded); + exportFlaCommandButton.setEnabled(swfLoaded); + exportSelectionCommandButton.setEnabled(swfLoaded); + reloadCommandButton.setEnabled(swfLoaded); + + renameinvalidCommandButton.setEnabled(swfLoaded); + globalrenameCommandButton.setEnabled(swfLoaded); + deobfuscationCommandButton.setEnabled(swfLoaded); + searchCommandButton.setEnabled(swfLoaded); + + gotoDocumentClassCommandButton.setEnabled(hasAbc); + deobfuscationCommandButton.setEnabled(hasAbc); + } + + @Override + public void actionPerformed(ActionEvent e) { + switch (e.getActionCommand()) { + case ACTION_RELOAD: + if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) { + Main.reloadSWFs(); + } + break; + case ACTION_ADVANCED_SETTINGS: + Main.advancedSettings(); + break; + case ACTION_LOAD_MEMORY: + Main.loadFromMemory(); + break; + case ACTION_LOAD_CACHE: + Main.loadFromCache(); + break; + case ACTION_GOTO_DOCUMENT_CLASS_ON_STARTUP: + Configuration.gotoMainClassOnStartup.set(miGotoMainClassOnStartup.isSelected()); + break; + case ACTION_AUTO_RENAME_IDENTIFIERS: + Configuration.autoRenameIdentifiers.set(miAutoRenameIdentifiers.isSelected()); + break; + case ACTION_CACHE_ON_DISK: + Configuration.cacheOnDisk.set(miCacheDisk.isSelected()); + if (miCacheDisk.isSelected()) { + Cache.setStorageType(Cache.STORAGE_FILES); + } else { + Cache.setStorageType(Cache.STORAGE_MEMORY); + } + break; + case ACTION_SET_LANGUAGE: + new SelectLanguageDialog().display(); + break; + case ACTION_DISABLE_DECOMPILATION: + Configuration.decompile.set(!miDecompile.isSelected()); + mainFrame.panel.disableDecompilationChanged(); + break; + case ACTION_ASSOCIATE: + if (miAssociate.isSelected() == ContextMenuTools.isAddedToContextMenu()) { + return; + } + ContextMenuTools.addToContextMenu(miAssociate.isSelected()); + + //Update checkbox menuitem accordingly (User can cancel rights elevation) + new Timer().schedule(new TimerTask() { + @Override + public void run() { + miAssociate.setSelected(ContextMenuTools.isAddedToContextMenu()); + } + }, 1000); //It takes some time registry change to apply + break; + case ACTION_GOTO_DOCUMENT_CLASS: + mainFrame.panel.gotoDocumentClass(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_PARALLEL_SPEED_UP: + String confStr = translate("message.confirm.parallel") + "\r\n"; + if (miParallelSpeedUp.isSelected()) { + 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((Boolean) miParallelSpeedUp.isSelected()); + } else { + miParallelSpeedUp.setSelected(!miParallelSpeedUp.isSelected()); + } + break; + case ACTION_INTERNAL_VIEWER_SWITCH: + Configuration.internalFlashViewer.set(miInternalViewer.isSelected()); + mainFrame.panel.reload(true); + break; + case ACTION_SEARCH_AS: + mainFrame.panel.searchAs(); + break; + case ACTION_AUTO_DEOBFUSCATE: + if (View.showConfirmDialog(mainFrame.panel, translate("message.confirm.autodeobfuscate") + "\r\n" + (miAutoDeobfuscation.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { + Configuration.autoDeobfuscate.set(miAutoDeobfuscation.isSelected()); + mainFrame.panel.autoDeobfuscateChanged(); + } else { + miAutoDeobfuscation.setSelected(!miAutoDeobfuscation.isSelected()); + } + break; + case ACTION_EXIT: + mainFrame.panel.setVisible(false); + if (Main.proxyFrame != null) { + if (Main.proxyFrame.isVisible()) { + return; + } + } + Main.exit(); + break; + } + + if (Main.isWorking()) { + return; + } + + switch (e.getActionCommand()) { + case ACTION_RENAME_ONE_IDENTIFIER: + mainFrame.panel.renameOneIdentifier(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_ABOUT: + Main.about(); + break; + case ACTION_SHOW_PROXY: + Main.showProxy(); + break; + case ACTION_SUB_LIMITER: + if (e.getSource() instanceof JCheckBoxMenuItem) { + Main.setSubLimiter(((JCheckBoxMenuItem) e.getSource()).getState()); + } + break; + case ACTION_SAVE: + try { + SWF swf = mainFrame.panel.getCurrentSwf(); + Main.saveFile(swf, swf.file); + } catch (IOException ex) { + Logger.getLogger(MainFrameRibbonMenu.class.getName()).log(Level.SEVERE, null, ex); + View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE); + } + break; + case ACTION_SAVE_AS: + { + SWF swf = mainFrame.panel.getCurrentSwf(); + if (Main.saveFileDialog(swf)) { + mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); + saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null); + } + } + break; + case ACTION_SAVE_AS_EXE: + { + SWF swf = mainFrame.panel.getCurrentSwf(); + if (Main.saveFileDialog(swf, ".exe")) { + mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : "")); + saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null); + } + } + break; + case ACTION_OPEN: + Main.openFileDialog(); + break; + case ACTION_EXPORT_FLA: + mainFrame.panel.exportFla(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_EXPORT_SEL: + case ACTION_EXPORT: + boolean onlySel = e.getActionCommand().endsWith("SEL"); + mainFrame.panel.export(onlySel); + break; + case ACTION_CHECK_UPDATES: + if (!Main.checkForUpdates()) { + View.showMessageDialog(null, translate("update.check.nonewversion"), translate("update.check.title"), JOptionPane.INFORMATION_MESSAGE); + } + break; + case ACTION_HELP_US: + String helpUsURL = ApplicationInfo.PROJECT_PAGE + "/help_us.html"; + if (java.awt.Desktop.isDesktopSupported()) { + java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); + try { + java.net.URI uri = new java.net.URI(helpUsURL); + desktop.browse(uri); + } catch (URISyntaxException | IOException ex) { + } + } else { + View.showMessageDialog(null, translate("message.helpus").replace("%url%", helpUsURL)); + } + break; + case ACTION_HOMEPAGE: + String homePageURL = ApplicationInfo.PROJECT_PAGE; + if (java.awt.Desktop.isDesktopSupported()) { + java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); + try { + java.net.URI uri = new java.net.URI(homePageURL); + desktop.browse(uri); + } catch (URISyntaxException | IOException ex) { + } + } else { + View.showMessageDialog(null, translate("message.homepage").replace("%url%", homePageURL)); + } + break; + case ACTION_RESTORE_CONTROL_FLOW: + case ACTION_RESTORE_CONTROL_FLOW_ALL: + boolean all = e.getActionCommand().endsWith("ALL"); + mainFrame.panel.restoreControlFlow(all); + break; + case ACTION_RENAME_IDENTIFIERS: + mainFrame.panel.renameIdentifiers(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_DEOBFUSCATE: + case ACTION_DEOBFUSCATE_ALL: + mainFrame.panel.deobfuscate(); + break; + case ACTION_REMOVE_NON_SCRIPTS: + mainFrame.panel.removeNonScripts(mainFrame.panel.getCurrentSwf()); + break; + case ACTION_REFRESH_DECOMPILED: + mainFrame.panel.refreshDecompiled(); + break; + } + } + +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java index be37e63be..6ad0aebad 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java @@ -39,7 +39,7 @@ public class MainFrameStatusPanel extends JPanel implements ActionListener { static final String ACTION_SHOW_ERROR_LOG = "SHOWERRORLOG"; - private MainFrame mainFrame; + private MainFramePanel mainFramePanel; private LoadingPanel loadingPanel = new LoadingPanel(20, 20); private JLabel statusLabel = new JLabel(""); @@ -51,8 +51,8 @@ public class MainFrameStatusPanel extends JPanel implements ActionListener { private CancellableWorker currentWorker; - public MainFrameStatusPanel(MainFrame mainFrame) { - this.mainFrame = mainFrame; + public MainFrameStatusPanel(MainFramePanel mainFramePanel) { + this.mainFramePanel = mainFramePanel; createStatusPanel(); } @@ -108,7 +108,7 @@ public class MainFrameStatusPanel extends JPanel implements ActionListener { } private String translate(String key) { - return mainFrame.translate(key); + return mainFramePanel.translate(key); } public void setStatus(String s) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java index 50fd05b71..c914ae711 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java @@ -64,7 +64,7 @@ public class TagTreeModel implements TreeModel { List ret = new ArrayList<>(); int frameCnt = 0; for (ContainerItem o : list) { - TagType ttype = MainFrame.getTagType(o); + TagType ttype = MainFramePanel.getTagType(o); if (ttype == TagType.SHOW_FRAME && type == TagType.FRAME) { frameCnt++; ret.add(new TagNode(new FrameNode(o.getSwf(), frameCnt, parent, display), o.getSwf())); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index f716575e1..71d853383 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -39,7 +39,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.HeaderLabel; import com.jpexs.decompiler.flash.gui.Main; -import com.jpexs.decompiler.flash.gui.MainFrame; +import com.jpexs.decompiler.flash.gui.MainFramePanel; import com.jpexs.decompiler.flash.gui.MyTextField; import com.jpexs.decompiler.flash.gui.TagTreeModel; import com.jpexs.decompiler.flash.gui.View; @@ -80,7 +80,7 @@ import jsyntaxpane.actions.DocumentSearchData; public class ABCPanel extends JPanel implements ItemListener, ActionListener, Freed { - private MainFrame mainFrame; + private MainFramePanel mainFramePanel; public TraitsList navigator; public ClassesListTree classTree; public ABC abc; @@ -336,10 +336,10 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr } @SuppressWarnings("unchecked") - public ABCPanel(MainFrame mainFrame) { + public ABCPanel(MainFramePanel mainFramePanel) { DefaultSyntaxKit.initKit(); - this.mainFrame = mainFrame; + this.mainFramePanel = mainFramePanel; setLayout(new BorderLayout()); decompiledTextArea = new DecompiledEditorPane(this); @@ -586,13 +586,13 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr } public void hilightScript(ScriptPack pack) { - TagTreeModel ttm = (TagTreeModel) mainFrame.tagTree.getModel(); + TagTreeModel ttm = (TagTreeModel) mainFramePanel.tagTree.getModel(); final TreePath tp = ttm.getTagPath(pack); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - mainFrame.tagTree.setSelectionPath(tp); - mainFrame.tagTree.scrollPathToVisible(tp); + mainFramePanel.tagTree.setSelectionPath(tp); + mainFramePanel.tagTree.scrollPathToVisible(tp); } }); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java index 52e451c0f..d6eb54b5a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java @@ -23,7 +23,6 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.View; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.helpers.CancellableWorker; import java.util.ArrayList; import java.util.List; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 16723f55f..0fa7666b7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -31,7 +31,7 @@ import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.GraphFrame; import com.jpexs.decompiler.flash.gui.HeaderLabel; import com.jpexs.decompiler.flash.gui.Main; -import com.jpexs.decompiler.flash.gui.MainFrame; +import com.jpexs.decompiler.flash.gui.MainFramePanel; import com.jpexs.decompiler.flash.gui.TagTreeModel; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane; @@ -93,7 +93,7 @@ public class ActionPanel extends JPanel implements ActionListener { static final String ACTION_EDIT_DECOMPILED = "EDITDECOMPILED"; static final String ACTION_CANCEL_DECOMPILED = "CANCELDECOMPILED"; - private MainFrame mainFrame; + private MainFramePanel mainFramePanel; public LineMarkedEditorPane editor; public LineMarkedEditorPane decompiledEditor; public JSplitPane splitPane; @@ -232,7 +232,7 @@ public class ActionPanel extends JPanel implements ActionListener { if ((txt != null) && (!txt.isEmpty())) { searchIgnoreCase = ignoreCase; searchRegexp = regexp; - List list = SWF.createASTagList(mainFrame.getCurrentSwf().tags, null); + List list = SWF.createASTagList(mainFramePanel.getCurrentSwf().tags, null); Map asms = getASMs("", list); found = new ArrayList<>(); Pattern pat = null; @@ -435,9 +435,9 @@ public class ActionPanel extends JPanel implements ActionListener { public void hilightOffset(long offset) { } - public ActionPanel(MainFrame mainFrame) { + public ActionPanel(MainFramePanel mainFramePanel) { DefaultSyntaxKit.initKit(); - this.mainFrame = mainFrame; + this.mainFramePanel = mainFramePanel; editor = new LineMarkedEditorPane(); editor.setEditable(false); decompiledEditor = new LineMarkedEditorPane(); @@ -824,10 +824,10 @@ public class ActionPanel extends JPanel implements ActionListener { public void updateSearchPos() { searchPos.setText((foundPos + 1) + "/" + found.size()); setSource(found.get(foundPos), true); - TagTreeModel ttm = (TagTreeModel) mainFrame.tagTree.getModel(); + TagTreeModel ttm = (TagTreeModel) mainFramePanel.tagTree.getModel(); TreePath tp = ttm.getTagPath(found.get(foundPos)); - mainFrame.tagTree.setSelectionPath(tp); - mainFrame.tagTree.scrollPathToVisible(tp); + mainFramePanel.tagTree.setSelectionPath(tp); + mainFramePanel.tagTree.scrollPathToVisible(tp); decompiledEditor.setCaretPosition(0); java.util.Timer t = new java.util.Timer(); SwingUtilities.invokeLater(new Runnable() { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index fc4e5fdd9..21f5e11c0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -29,6 +29,7 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser; import com.sun.jna.ptr.IntByReference; import java.awt.Color; +import java.awt.Component; import java.awt.Graphics; import java.awt.Panel; import java.awt.event.ComponentEvent; @@ -38,7 +39,6 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JFrame; /** * @@ -51,7 +51,7 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private HANDLE pipe; private static List processes = new ArrayList<>(); private static List pipes = new ArrayList<>(); - private JFrame frame; + private Component frame; private boolean stopped = true; private static final int CMD_PLAY = 1; private static final int CMD_RESIZE = 2; @@ -193,7 +193,7 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}, 3, ibr, null); } - public FlashPlayerPanel(JFrame frame) { + public FlashPlayerPanel(Component frame) { if (!Platform.isWindows()) { throw new FlashUnsupportedException(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java index 9d6c46cd6..5239d5e33 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.AppFrame; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.MainFrame; +import com.jpexs.decompiler.flash.gui.MainFrameRibbon; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.proxy.CatchedListener; import com.jpexs.proxy.ReplacedListener;