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();