diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f9a3e6a..5e9b43abf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. - #1202 Check for modifications outside FFDec and ask user to reload - #1155, #1602 AS3 remove trait button - #1260, #1438 AS1/2 direct editing on(xxx), onClipEvent(xxx) handlers +- AS1/2 Add new frame script ### Fixed - #1298 AS1/2 properly decompiled setProperty/getProperty diff --git a/src/com/jpexs/decompiler/flash/gui/AppDialog.java b/src/com/jpexs/decompiler/flash/gui/AppDialog.java index 86ed8eef5..bb1100e6d 100644 --- a/src/com/jpexs/decompiler/flash/gui/AppDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/AppDialog.java @@ -59,6 +59,10 @@ public abstract class AppDialog extends JDialog { return resourceBundle.getString(key); } + public static String translateForDialog(String key, Class cls) { + return ResourceBundle.getBundle(AppStrings.getResourcePath(cls)).getString(key); + } + public void updateLanguage() { resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass())); } diff --git a/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java b/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java new file mode 100644 index 000000000..87101a22e --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2021 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.action; + +import com.jpexs.decompiler.flash.gui.AppDialog; +import com.jpexs.decompiler.flash.gui.Main; +import com.jpexs.decompiler.flash.gui.View; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; + +/** + * + * @author JPEXS + */ +public class AddScriptDialog extends AppDialog { + + private final JButton okButton = new JButton(translate("button.ok")); + + private final JButton cancelButton = new JButton(translate("button.cancel")); + private JTextField frameTextField; + + private int frame = -1; + + private int result = ERROR_OPTION; + + public AddScriptDialog() { + setDefaultCloseOperation(HIDE_ON_CLOSE); + setTitle(translate("dialog.title")); + + Container cnt = getContentPane(); + cnt.setLayout(new BorderLayout()); + + JPanel panButtons = new JPanel(new FlowLayout()); + okButton.addActionListener(this::okButtonActionPerformed); + cancelButton.addActionListener(this::cancelButtonActionPerformed); + panButtons.add(okButton); + panButtons.add(cancelButton); + + JPanel centerPanel = new JPanel(new FlowLayout()); + JLabel frameLabel = new JLabel(translate("framenum")); + frameTextField = new JTextField(4); + frameTextField.addActionListener(this::okButtonActionPerformed); + frameLabel.setLabelFor(frameTextField); + centerPanel.add(frameLabel); + centerPanel.add(frameTextField); + cnt.add(centerPanel, BorderLayout.CENTER); + + cnt.add(panButtons, BorderLayout.SOUTH); + + setModal(true); + setResizable(true); + pack(); + View.centerScreen(this); + } + + private void okButtonActionPerformed(ActionEvent evt) { + boolean invalid = false; + try { + frame = Integer.parseInt(frameTextField.getText()); + if (frame <= 0) { + invalid = true; + } + + } catch (NumberFormatException nfe) { + invalid = true; + } + + if (invalid) { + View.showMessageDialog(this, translate("message.framenum.invalid"), Main.getMainFrame().translate("error"), JOptionPane.ERROR_MESSAGE); + frame = -1; + } else { + result = OK_OPTION; + setVisible(false); + } + } + + public int getFrame() { + return frame; + } + + + private void cancelButtonActionPerformed(ActionEvent evt) { + result = CANCEL_OPTION; + setVisible(false); + } + + public int showDialog() { + setVisible(true); + return result; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 696f03f36..ea4bc2cd3 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -781,4 +781,6 @@ script.seemsBroken = WARNING: The code decompilation contains sel = tagTree.getSelected(); + if (!sel.isEmpty()) { + if (sel.get(0) instanceof FolderItem) { + + FolderItem folder = (FolderItem) sel.get(0); + SWF swf = folder.getSwf(); + + DoActionTag doAction = new DoActionTag(swf); + + ReadOnlyTagList tagList = swf.getTags(); + int frame = 1; + boolean frameFound = false; + for (int i = 0; i < tagList.size(); i++) { + Tag t = tagList.get(i); + if (frame == targetFrame && t instanceof DoActionTag) { + View.showMessageDialog(mainPanel, AppDialog.translateForDialog("message.alreadyhasscript", AddScriptDialog.class), + mainPanel.getMainFrame().translate("error"), JOptionPane.ERROR_MESSAGE + ); + addScriptActionPerformed(evt); + return; + } + if (t instanceof ShowFrameTag) { + if (frame == targetFrame) { + swf.addTag(i, doAction); + frameFound = true; + break; + } + frame++; + } + } + if (!frameFound) { + for (; frame < targetFrame; frame++) { + swf.addTag(new ShowFrameTag(swf)); + } + swf.addTag(doAction); + swf.addTag(new ShowFrameTag(swf)); + } + + TreePath selection = mainPanel.tagTree.getSelectionPath(); + TreePath swfPath = selection.getParentPath(); + swf.resetTimeline(); + mainPanel.refreshTree(swf); + + FolderItem scriptsNode = (FolderItem) mainPanel.tagTree.getModel().getScriptsNode(swf); + TreePath scriptsPath = swfPath.pathByAddingChild(scriptsNode); + for (TreeItem subItem : scriptsNode.subItems) { + if (subItem instanceof FrameScript) { + if (((FrameScript) subItem).getFrame().frame + 1 == targetFrame) { + TreePath framePath = scriptsPath.pathByAddingChild(subItem); + TreeItem doActionTag = mainPanel.tagTree.getModel().getChild(subItem, 0); + TreePath doActionPath = framePath.pathByAddingChild(doActionTag); + mainPanel.tagTree.setSelectionPath(doActionPath); + break; + } + } + } + //tagTree.getSelectionPath(); + /*mainPanel.tagTree.setSelectionPath(new TreePath(new Object[]{ + mainPanel.tagTree.getModel().getRoot() + }));*/ + } + } + } + } + private void removeItemActionPerformed(ActionEvent evt, boolean removeDependencies) { List sel = tagTree.getSelected();