mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 06:21:16 +00:00
Added Set AS1/2 linkage dialog (uses ExportAssets tag) in the context menu for characters
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2024 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.abc.*;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont4Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class AsLinkageDialog extends AppDialog {
|
||||
|
||||
private final JButton proceedButton = new JButton(translate("button.proceed"));
|
||||
private final JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
|
||||
private final JTextField identifierTextField = new JTextField(30);
|
||||
private final JTextField classNameTextField = new JTextField(30);
|
||||
private final JTextField parentClassNameTextField = new JTextField(30);
|
||||
private String selectedIdentifier = null;
|
||||
private String selectedClass = null;
|
||||
private String selectedParentClass = null;
|
||||
private ExportAssetsTag originalExportAssetsTag;
|
||||
private ExportAssetsTag selectedExportAssetsTag;
|
||||
private String originalClassName;
|
||||
private Tag selectedPosition;
|
||||
private Timelined selectedTimelined;
|
||||
private int result = ERROR_OPTION;
|
||||
|
||||
private final SWF swf;
|
||||
|
||||
private final int characterId;
|
||||
|
||||
private int characterFrame = -1;
|
||||
|
||||
private int exportAssetsCount = 0;
|
||||
|
||||
private final JLabel errorLabel = new JLabel();
|
||||
|
||||
private final JLabel parentClassNameLabel = new JLabel(translate("class.parentname"));
|
||||
|
||||
private final JRadioButton existingExportAssetsTagRadioButton = new JRadioButton(translate("linkage.notfound.exportAssets.where.existing"));
|
||||
private final JRadioButton newExportAssetsTagRadioButton = new JRadioButton(translate("linkage.notfound.exportAssets.where.new"));
|
||||
|
||||
private static final Map<Class<?>, String> tagTypeToParentClass = new HashMap<>();
|
||||
|
||||
static {
|
||||
tagTypeToParentClass.put(SoundTag.class, "flash.media.Sound");
|
||||
tagTypeToParentClass.put(ImageTag.class, "flash.display.Bitmap");
|
||||
tagTypeToParentClass.put(FontTag.class, "flash.text.Font");
|
||||
tagTypeToParentClass.put(DefineFont4Tag.class, "flash.text.Font");
|
||||
tagTypeToParentClass.put(DefineBinaryDataTag.class, "flash.utils.ByteArray");
|
||||
tagTypeToParentClass.put(DefineSpriteTag.class, "flash.display.Sprite");
|
||||
}
|
||||
|
||||
public static String getParentClassFromCharacter(CharacterTag ch) {
|
||||
for (Class<?> cls : tagTypeToParentClass.keySet()) {
|
||||
if (cls.isAssignableFrom(ch.getClass())) {
|
||||
return tagTypeToParentClass.get(cls);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AsLinkageDialog(Window owner, SWF swf, int characterId) {
|
||||
super(owner);
|
||||
|
||||
this.swf = swf;
|
||||
this.characterId = characterId;
|
||||
|
||||
CharacterTag ch = swf.getCharacter(characterId);
|
||||
if (ch == null) {
|
||||
throw new RuntimeException("Character " + characterId + " not found");
|
||||
}
|
||||
|
||||
//parentClassNameTextField.setText(getParentClassFromCharacter(ch));
|
||||
|
||||
int frame = 1;
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t == ch) {
|
||||
characterFrame = frame;
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
frame++;
|
||||
}
|
||||
}
|
||||
frame = 1;
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (frame >= characterFrame) {
|
||||
if (t instanceof ExportAssetsTag) {
|
||||
ExportAssetsTag ea = (ExportAssetsTag) t;
|
||||
if (ea.tags.contains(characterId)) {
|
||||
originalExportAssetsTag = ea;
|
||||
}
|
||||
exportAssetsCount++;
|
||||
}
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
frame++;
|
||||
}
|
||||
}
|
||||
|
||||
String originalIdentifier = ch.getExportName();
|
||||
|
||||
identifierTextField.setText(originalIdentifier);
|
||||
|
||||
originalClassName = ch.getAs2ClassName();
|
||||
|
||||
if (originalClassName != null) {
|
||||
classNameTextField.setText(originalClassName);
|
||||
classNameTextField.setEnabled(false);
|
||||
identifierTextField.setEnabled(false);
|
||||
}
|
||||
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setTitle(translate("dialog.title"));
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
|
||||
|
||||
cnt.add(new JLabel(translate("identifier")));
|
||||
cnt.add(identifierTextField);
|
||||
|
||||
cnt.add(new JLabel(translate("classname")));
|
||||
cnt.add(classNameTextField);
|
||||
if (originalClassName == null) {
|
||||
cnt.add(parentClassNameLabel);
|
||||
cnt.add(parentClassNameTextField);
|
||||
}
|
||||
cnt.add(errorLabel);
|
||||
|
||||
if (originalClassName == null && originalExportAssetsTag == null) {
|
||||
ButtonGroup whereToStoreMappingButtonGroup = new ButtonGroup();
|
||||
whereToStoreMappingButtonGroup.add(existingExportAssetsTagRadioButton);
|
||||
whereToStoreMappingButtonGroup.add(newExportAssetsTagRadioButton);
|
||||
cnt.add(new JLabel(translate("linkage.notfound.exportAssets.where")));
|
||||
|
||||
JPanel whereToStoreMappingPanel = new JPanel(new FlowLayout());
|
||||
whereToStoreMappingPanel.add(existingExportAssetsTagRadioButton);
|
||||
whereToStoreMappingPanel.add(newExportAssetsTagRadioButton);
|
||||
cnt.add(whereToStoreMappingPanel);
|
||||
existingExportAssetsTagRadioButton.setSelected(true);
|
||||
}
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
proceedButton.addActionListener(this::okButtonActionPerformed);
|
||||
cancelButton.addActionListener(this::cancelButtonActionPerformed);
|
||||
buttonsPanel.add(proceedButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
|
||||
cnt.add(buttonsPanel);
|
||||
|
||||
setCentralAlignment((JComponent) cnt);
|
||||
|
||||
if (exportAssetsCount == 0) {
|
||||
newExportAssetsTagRadioButton.setSelected(true);
|
||||
newExportAssetsTagRadioButton.setEnabled(false);
|
||||
existingExportAssetsTagRadioButton.setEnabled(false);
|
||||
}
|
||||
|
||||
existingExportAssetsTagRadioButton.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
checkEnabled();
|
||||
}
|
||||
});
|
||||
newExportAssetsTagRadioButton.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
checkEnabled();
|
||||
}
|
||||
});
|
||||
|
||||
classNameTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
checkEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
checkEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
checkEnabled();
|
||||
}
|
||||
});
|
||||
|
||||
classNameTextField.addActionListener(this::okButtonActionPerformed);
|
||||
checkEnabled();
|
||||
pack();
|
||||
setModal(true);
|
||||
setResizable(false);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
private void setCentralAlignment(JComponent container) {
|
||||
Component[] components = container.getComponents();
|
||||
for (Component component : components) {
|
||||
if (component instanceof JComponent) {
|
||||
((JComponent) component).setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEnabled() {
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
String newIdentifier = identifierTextField.getText();
|
||||
String newClassName = classNameTextField.getText();
|
||||
|
||||
if (originalClassName != null) {
|
||||
ok = false;
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
errorLabel.setText("");
|
||||
}
|
||||
|
||||
if (!classNameTextField.isEnabled() && newIdentifier.isEmpty()) {
|
||||
ok = false;
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
errorLabel.setText(translate("error.cannotRemoveIdentifierClassExists"));
|
||||
}
|
||||
|
||||
if (newClassName.endsWith(".")) {
|
||||
ok = false;
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
errorLabel.setText("");
|
||||
}
|
||||
|
||||
if (newIdentifier.isEmpty() && !newClassName.isEmpty()) {
|
||||
ok = false;
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
errorLabel.setText("");
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
CharacterTag ch = swf.getCharacter(characterId);
|
||||
String oldClassName = ch.getAs2ClassName();
|
||||
if (oldClassName == null && newClassName != null && ch.getSwf().getCharacterByExportName("__Packages." + newClassName) != null) {
|
||||
ok = false;
|
||||
errorLabel.setText(translate("error.alreadyExistsClass"));
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (originalExportAssetsTag != null) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
} else if (existingExportAssetsTagRadioButton.isSelected() && exportAssetsCount == 1) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
} else {
|
||||
proceedButton.setText(translate("button.proceed"));
|
||||
}
|
||||
} else {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
}
|
||||
|
||||
proceedButton.setEnabled(ok);
|
||||
}
|
||||
|
||||
private void okButtonActionPerformed(ActionEvent evt) {
|
||||
if (!proceedButton.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
setVisible(false);
|
||||
if (originalExportAssetsTag != null) {
|
||||
selectedExportAssetsTag = originalExportAssetsTag;
|
||||
} else {
|
||||
if (existingExportAssetsTagRadioButton.isSelected()) {
|
||||
SelectTagOfTypeDialog selectExportAssetsDialog = new SelectTagOfTypeDialog(owner, swf, ExportAssetsTag.class, "ExportAssets", characterFrame);
|
||||
selectedExportAssetsTag = (ExportAssetsTag) selectExportAssetsDialog.showDialog();
|
||||
if (selectedExportAssetsTag == null) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (newExportAssetsTagRadioButton.isSelected()) {
|
||||
SelectTagPositionDialog selectTagPositionDialog = new SelectTagPositionDialog(owner, swf, false, "ExportAssets", characterFrame);
|
||||
if (selectTagPositionDialog.showDialog() != OK_OPTION) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
selectedPosition = selectTagPositionDialog.getSelectedTag();
|
||||
selectedTimelined = selectTagPositionDialog.getSelectedTimelined();
|
||||
}
|
||||
}
|
||||
result = OK_OPTION;
|
||||
selectedIdentifier = identifierTextField.getText();
|
||||
selectedClass = classNameTextField.getText();
|
||||
selectedParentClass = parentClassNameTextField.getText();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
private void cancelButtonActionPerformed(ActionEvent evt) {
|
||||
selectedIdentifier = null;
|
||||
selectedClass = null;
|
||||
selectedParentClass = null;
|
||||
selectedPosition = null;
|
||||
selectedTimelined = null;
|
||||
selectedExportAssetsTag = null;
|
||||
characterFrame = -1;
|
||||
result = CANCEL_OPTION;
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public int showDialog() {
|
||||
selectedIdentifier = null;
|
||||
selectedClass = null;
|
||||
selectedParentClass = null;
|
||||
selectedPosition = null;
|
||||
selectedTimelined = null;
|
||||
selectedExportAssetsTag = null;
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Tag getSelectedPosition() {
|
||||
return selectedPosition;
|
||||
}
|
||||
|
||||
public String getSelectedClass() {
|
||||
return selectedClass;
|
||||
}
|
||||
|
||||
public String getSelectedParentClass() {
|
||||
return selectedParentClass;
|
||||
}
|
||||
|
||||
public ExportAssetsTag getSelectedExportAssetsTag() {
|
||||
return selectedExportAssetsTag;
|
||||
}
|
||||
|
||||
public Timelined getSelectedTimelined() {
|
||||
return selectedTimelined;
|
||||
}
|
||||
|
||||
public int getCharacterFrame() {
|
||||
return characterFrame;
|
||||
}
|
||||
|
||||
public String getSelectedIdentifier() {
|
||||
return selectedIdentifier;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,6 +73,7 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
private String selectedParentClass = null;
|
||||
private ABCContainerTag selectedAbcContainer;
|
||||
private SymbolClassTag selectedSymbolClassTag;
|
||||
private SymbolClassTag originalSymbolClassTag;
|
||||
private Tag selectedPosition;
|
||||
private Timelined selectedTimelined;
|
||||
private int result = ERROR_OPTION;
|
||||
@@ -165,6 +166,10 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
abcContainers.add((ABCContainerTag) t);
|
||||
}
|
||||
if (t instanceof SymbolClassTag) {
|
||||
SymbolClassTag sc = (SymbolClassTag) t;
|
||||
if (sc.tags.contains(characterId)) {
|
||||
originalSymbolClassTag = sc;
|
||||
}
|
||||
symbolClassCount++;
|
||||
}
|
||||
}
|
||||
@@ -240,12 +245,15 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
ButtonGroup whereToStoreMappingButtonGroup = new ButtonGroup();
|
||||
whereToStoreMappingButtonGroup.add(existingSymbolClassTagRadioButton);
|
||||
whereToStoreMappingButtonGroup.add(newSymbolClassTagRadioButton);
|
||||
doNotCreateNewClassPanel.add(new JLabel(translate("class.notfound.onlySetClassName.symbolClass.where")));
|
||||
|
||||
if (originalSymbolClassTag == null) {
|
||||
doNotCreateNewClassPanel.add(new JLabel(translate("class.notfound.onlySetClassName.symbolClass.where")));
|
||||
|
||||
JPanel whereToStoreMappingPanel = new JPanel(new FlowLayout());
|
||||
whereToStoreMappingPanel.add(existingSymbolClassTagRadioButton);
|
||||
whereToStoreMappingPanel.add(newSymbolClassTagRadioButton);
|
||||
doNotCreateNewClassPanel.add(whereToStoreMappingPanel);
|
||||
JPanel whereToStoreMappingPanel = new JPanel(new FlowLayout());
|
||||
whereToStoreMappingPanel.add(existingSymbolClassTagRadioButton);
|
||||
whereToStoreMappingPanel.add(newSymbolClassTagRadioButton);
|
||||
doNotCreateNewClassPanel.add(whereToStoreMappingPanel);
|
||||
}
|
||||
existingSymbolClassTagRadioButton.setSelected(true);
|
||||
|
||||
setCentralAlignment(doNotCreateNewClassPanel);
|
||||
@@ -381,10 +389,10 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
|
||||
String newClassName = classNameTextField.getText();
|
||||
|
||||
if (newClassName.isEmpty()) {
|
||||
/*if (newClassName.isEmpty()) {
|
||||
ok = false;
|
||||
errorLabel.setText("");
|
||||
}
|
||||
}*/
|
||||
|
||||
if (newClassName.endsWith(".")) {
|
||||
ok = false;
|
||||
@@ -400,7 +408,7 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
} else if (oldClassNames.size() == 1 && newClassName.equals(oldClassNames.iterator().next())) {
|
||||
ok = false;
|
||||
errorLabel.setText(translate("error.needToModify"));
|
||||
} else if (swf.getCharacterByClass(newClassName) != null) {
|
||||
} else if (!newClassName.isEmpty() && swf.getCharacterByClass(newClassName) != null) {
|
||||
ok = false;
|
||||
errorLabel.setText(translate("error.alreadyAssignedClass"));
|
||||
}
|
||||
@@ -409,42 +417,48 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
CardLayout cl = (CardLayout) classFoundOrNotOrErrorPanel.getLayout();
|
||||
|
||||
if (ok) {
|
||||
List<String> classNames = new ArrayList<>();
|
||||
classNames.add(newClassName);
|
||||
foundInAbcContainer = null;
|
||||
try {
|
||||
List<ScriptPack> scriptPacks = swf.getScriptPacksByClassNames(classNames);
|
||||
if (!scriptPacks.isEmpty()) {
|
||||
ABC foundInAbc = scriptPacks.get(0).abc; //Assume there is only single pack with the class
|
||||
if (newClassName.isEmpty()) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
cl.show(classFoundOrNotOrErrorPanel, ERROR_CARD);
|
||||
errorLabel.setText("");
|
||||
} else {
|
||||
List<String> classNames = new ArrayList<>();
|
||||
classNames.add(newClassName);
|
||||
foundInAbcContainer = null;
|
||||
try {
|
||||
List<ScriptPack> scriptPacks = swf.getScriptPacksByClassNames(classNames);
|
||||
if (!scriptPacks.isEmpty()) {
|
||||
ABC foundInAbc = scriptPacks.get(0).abc; //Assume there is only single pack with the class
|
||||
|
||||
boolean foundContainer = false;
|
||||
for (ABCContainerTag cnt : abcContainers) {
|
||||
if (cnt.getABC() == foundInAbc) {
|
||||
foundInAbcContainer = cnt;
|
||||
break;
|
||||
boolean foundContainer = false;
|
||||
for (ABCContainerTag cnt : abcContainers) {
|
||||
if (cnt.getABC() == foundInAbc) {
|
||||
foundInAbcContainer = cnt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
if (foundInAbcContainer != null) {
|
||||
cl.show(classFoundOrNotOrErrorPanel, CLASS_FOUND_CARD);
|
||||
} else {
|
||||
cl.show(classFoundOrNotOrErrorPanel, CLASS_NOT_FOUND_CARD);
|
||||
|
||||
if (createClassRadioButton.isSelected()) {
|
||||
if (existingAbcTagRadioButton.isSelected() && abcCount == 1) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
} else {
|
||||
proceedButton.setText(translate("button.proceed"));
|
||||
}
|
||||
if (foundInAbcContainer != null) {
|
||||
cl.show(classFoundOrNotOrErrorPanel, CLASS_FOUND_CARD);
|
||||
} else {
|
||||
if (existingSymbolClassTagRadioButton.isSelected() && symbolClassCount == 1) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
cl.show(classFoundOrNotOrErrorPanel, CLASS_NOT_FOUND_CARD);
|
||||
|
||||
if (createClassRadioButton.isSelected()) {
|
||||
if (existingAbcTagRadioButton.isSelected() && abcCount == 1) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
} else {
|
||||
proceedButton.setText(translate("button.proceed"));
|
||||
}
|
||||
} else {
|
||||
proceedButton.setText(translate("button.proceed"));
|
||||
if (originalSymbolClassTag != null || (existingSymbolClassTagRadioButton.isSelected() && symbolClassCount == 1)) {
|
||||
proceedButton.setText(translate("button.ok"));
|
||||
} else {
|
||||
proceedButton.setText(translate("button.proceed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -461,46 +475,55 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
return;
|
||||
}
|
||||
setVisible(false);
|
||||
if (foundInAbcContainer == null) {
|
||||
if (createClassRadioButton.isSelected()) {
|
||||
if (existingAbcTagRadioButton.isSelected()) {
|
||||
SelectTagOfTypeDialog selectDoABCDialog = new SelectTagOfTypeDialog(owner, swf, ABCContainerTag.class, "DoABC", characterFrame);
|
||||
selectedAbcContainer = (ABCContainerTag) selectDoABCDialog.showDialog();
|
||||
if (selectedAbcContainer == null) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
boolean emptyClassName = classNameTextField.getText().isEmpty();
|
||||
if (emptyClassName) {
|
||||
selectedSymbolClassTag = originalSymbolClassTag;
|
||||
} else {
|
||||
if (foundInAbcContainer == null) {
|
||||
if (createClassRadioButton.isSelected()) {
|
||||
if (existingAbcTagRadioButton.isSelected()) {
|
||||
SelectTagOfTypeDialog selectDoABCDialog = new SelectTagOfTypeDialog(owner, swf, ABCContainerTag.class, "DoABC", characterFrame);
|
||||
selectedAbcContainer = (ABCContainerTag) selectDoABCDialog.showDialog();
|
||||
if (selectedAbcContainer == null) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newAbcTagRadioButton.isSelected()) {
|
||||
SelectTagPositionDialog selectTagPositionDialog = new SelectTagPositionDialog(owner, swf, false, "DoABC", characterFrame);
|
||||
if (selectTagPositionDialog.showDialog() != OK_OPTION) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
if (newAbcTagRadioButton.isSelected()) {
|
||||
SelectTagPositionDialog selectTagPositionDialog = new SelectTagPositionDialog(owner, swf, false, "DoABC", characterFrame);
|
||||
if (selectTagPositionDialog.showDialog() != OK_OPTION) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
selectedPosition = selectTagPositionDialog.getSelectedTag();
|
||||
selectedTimelined = selectTagPositionDialog.getSelectedTimelined();
|
||||
}
|
||||
} else {
|
||||
if (originalSymbolClassTag != null) {
|
||||
selectedSymbolClassTag = originalSymbolClassTag;
|
||||
} else {
|
||||
if (existingSymbolClassTagRadioButton.isSelected()) {
|
||||
SelectTagOfTypeDialog selectSymbolClassDialog = new SelectTagOfTypeDialog(owner, swf, SymbolClassTag.class, "SymbolClass", characterFrame);
|
||||
selectedSymbolClassTag = (SymbolClassTag) selectSymbolClassDialog.showDialog();
|
||||
if (selectedSymbolClassTag == null) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (newSymbolClassTagRadioButton.isSelected()) {
|
||||
SelectTagPositionDialog selectTagPositionDialog = new SelectTagPositionDialog(owner, swf, false, "SymbolClass", characterFrame);
|
||||
if (selectTagPositionDialog.showDialog() != OK_OPTION) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
selectedPosition = selectTagPositionDialog.getSelectedTag();
|
||||
selectedTimelined = selectTagPositionDialog.getSelectedTimelined();
|
||||
}
|
||||
}
|
||||
selectedPosition = selectTagPositionDialog.getSelectedTag();
|
||||
selectedTimelined = selectTagPositionDialog.getSelectedTimelined();
|
||||
}
|
||||
} else {
|
||||
if (existingSymbolClassTagRadioButton.isSelected()) {
|
||||
SelectTagOfTypeDialog selectSymbolClassDialog = new SelectTagOfTypeDialog(owner, swf, SymbolClassTag.class, "SymbolClass", characterFrame);
|
||||
selectedSymbolClassTag = (SymbolClassTag) selectSymbolClassDialog.showDialog();
|
||||
if (selectedSymbolClassTag == null) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (newSymbolClassTagRadioButton.isSelected()) {
|
||||
SelectTagPositionDialog selectTagPositionDialog = new SelectTagPositionDialog(owner, swf, false, "SymbolClass", characterFrame);
|
||||
if (selectTagPositionDialog.showDialog() != OK_OPTION) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
return;
|
||||
}
|
||||
selectedPosition = selectTagPositionDialog.getSelectedTag();
|
||||
selectedTimelined = selectTagPositionDialog.getSelectedTimelined();
|
||||
}
|
||||
selectedAbcContainer = foundInAbcContainer;
|
||||
}
|
||||
} else {
|
||||
selectedAbcContainer = foundInAbcContainer;
|
||||
}
|
||||
|
||||
if (selectedAbcContainer != null) {
|
||||
@@ -516,7 +539,7 @@ public class As3ClassLinkageDialog extends AppDialog {
|
||||
}
|
||||
}
|
||||
|
||||
createClass = foundInAbcContainer == null && createClassRadioButton.isSelected();
|
||||
createClass = !emptyClassName && foundInAbcContainer == null && createClassRadioButton.isSelected();
|
||||
|
||||
result = OK_OPTION;
|
||||
selectedClass = classNameTextField.getText();
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = AS linkage
|
||||
button.ok = OK
|
||||
button.proceed = Proceed
|
||||
button.cancel = Cancel
|
||||
|
||||
identifier = ActionScript identifier:
|
||||
classname = ActionScript2 class (fully qualified):
|
||||
class.parentname = Parent class name (fully qualified):
|
||||
|
||||
error.alreadyExistsClass = Error: This class is already exists
|
||||
error.cannotRemoveIdentifierClassExists = Error: Cannot remove identifier, class already exists
|
||||
|
||||
linkage.notfound.exportAssets.where = Where to store the linkage data:
|
||||
linkage.notfound.exportAssets.where.existing = Existing ExportAssets tag
|
||||
linkage.notfound.exportAssets.where.new = New ExportAssets tag
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = AS vazba
|
||||
button.ok = OK
|
||||
button.proceed = Pokra\u010dovat
|
||||
button.cancel = Storno
|
||||
|
||||
identifier = ActionScript identifik\u00e1tor:
|
||||
classname = ActionScript2 t\u0159\u00edda (pln\u011b kvalifikovan\u00e1):
|
||||
class.parentname = N\u00e1zev rodi\u010dovsk\u00e9 t\u0159\u00eddy (pln\u011b kvalifikovan\u00fd):
|
||||
|
||||
error.alreadyExistsClass = Chyba: Tato t\u0159\u00edda ji\u017e existuje
|
||||
error.cannotRemoveIdentifierClassExists = Chyba: Nelze odstranit idenitifik\u00e1tor, t\u0159\u00edda ji\u017e existuje
|
||||
|
||||
linkage.notfound.exportAssets.where = Kam um\u00edstit data o vazb\u011b:
|
||||
linkage.notfound.exportAssets.where.existing = Existuj\u00edc\u00ed ExportAssets tag
|
||||
linkage.notfound.exportAssets.where.new = Nov\u00fd ExportAssets tag
|
||||
@@ -1271,4 +1271,6 @@ warning.cleanAbc = This action will remove items from ABC which have zero usages
|
||||
|
||||
tagInfo.idType = Type of the id
|
||||
|
||||
contextmenu.configurePathResolving = Configure path resolving...
|
||||
contextmenu.configurePathResolving = Configure path resolving...
|
||||
|
||||
contextmenu.setAsLinkage = Set AS linkage
|
||||
@@ -1246,4 +1246,6 @@ warning.cleanAbc = Tato akce odstran\u00ed z ABC polo\u017eky, kter\u00e9 maj\u0
|
||||
|
||||
tagInfo.idType = Typ id
|
||||
|
||||
contextmenu.configurePathResolving = Nastavit resolvov\u00e1n\u00ed cest...
|
||||
contextmenu.configurePathResolving = Nastavit resolvov\u00e1n\u00ed cest...
|
||||
|
||||
contextmenu.setAsLinkage = Nastavit AS vazbu
|
||||
@@ -38,6 +38,6 @@ class.notfound.create.abc.where.existing = Existing DoABC tag
|
||||
class.notfound.create.abc.where.new = New DoABC tag
|
||||
|
||||
class.notfound.onlySetClassName = No, just assign class name
|
||||
class.notfound.onlySetClassName.symbolClass.where = Where to store the mapping:
|
||||
class.notfound.onlySetClassName.symbolClass.where = Where to store the linkage data:
|
||||
class.notfound.onlySetClassName.symbolClass.where.existing = Existing SymbolClass tag
|
||||
class.notfound.onlySetClassName.symbolClass.where.new = New SymbolClass tag
|
||||
@@ -38,6 +38,6 @@ class.notfound.create.abc.where.existing = Existuj\u00edc\u00ed DoABC tag
|
||||
class.notfound.create.abc.where.new = Nov\u00fd DoABC tag
|
||||
|
||||
class.notfound.onlySetClassName = Ne, jen p\u0159i\u0159adit n\u00e1zev t\u0159\u00eddy
|
||||
class.notfound.onlySetClassName.symbolClass.where = Kam um\u00edstit mapov\u00e1n\u00ed:
|
||||
class.notfound.onlySetClassName.symbolClass.where = Kam um\u00edstit data o vazb\u011b:
|
||||
class.notfound.onlySetClassName.symbolClass.where.existing = Existuj\u00edc\u00ed SymbolClass tag
|
||||
class.notfound.onlySetClassName.symbolClass.where.new = Nov\u00fd SymbolClass tag
|
||||
@@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.configuration.CustomConfigurationKeys;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.AsLinkageDialog;
|
||||
import com.jpexs.decompiler.flash.gui.ClipboardType;
|
||||
import com.jpexs.decompiler.flash.gui.CollectDepthAsSpritesDialog;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
@@ -174,6 +175,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
private JMenuItem configurePathResolvingMenuItem;
|
||||
|
||||
private JMenuItem setAsLinkageMenuItem;
|
||||
|
||||
private JMenuItem setAs3ClassLinkageMenuItem;
|
||||
|
||||
private JMenuItem expandRecursiveMenuItem;
|
||||
@@ -451,7 +454,12 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
replaceRefsWithTagMenuItem.setIcon(View.getIcon("replacewithtag16"));
|
||||
add(replaceRefsWithTagMenuItem);
|
||||
|
||||
setAs3ClassLinkageMenuItem = new JMenuItem(mainPanel.translate("contextmenu.setAs3ClassLinkage")); //FIXME
|
||||
setAsLinkageMenuItem = new JMenuItem(mainPanel.translate("contextmenu.setAsLinkage"));
|
||||
setAsLinkageMenuItem.addActionListener(this::setAsLinkageActionPerformed);
|
||||
setAsLinkageMenuItem.setIcon(View.getIcon("asclass16"));
|
||||
add(setAsLinkageMenuItem);
|
||||
|
||||
setAs3ClassLinkageMenuItem = new JMenuItem(mainPanel.translate("contextmenu.setAs3ClassLinkage"));
|
||||
setAs3ClassLinkageMenuItem.addActionListener(this::setAs3ClassLinkageActionPerformed);
|
||||
setAs3ClassLinkageMenuItem.setIcon(View.getIcon("asclass16"));
|
||||
add(setAs3ClassLinkageMenuItem);
|
||||
@@ -1126,6 +1134,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
boolean hasExportableNodes = tree.hasExportableNodes();
|
||||
|
||||
setAsLinkageMenuItem.setVisible(false);
|
||||
setAs3ClassLinkageMenuItem.setVisible(false);
|
||||
expandRecursiveMenuItem.setVisible(false);
|
||||
collapseRecursiveMenuItem.setVisible(false);
|
||||
@@ -1372,6 +1381,12 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
if (cht.getSwf().isAS3() && As3ClassLinkageDialog.getParentClassFromCharacter(cht) != null) {
|
||||
setAs3ClassLinkageMenuItem.setVisible(true);
|
||||
}
|
||||
if (!cht.getSwf().isAS3()) {
|
||||
String ename = cht.getExportName();
|
||||
if (ename == null || !ename.startsWith("__Packages.")) {
|
||||
setAsLinkageMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tree.getModel().getChildCount(firstItem) > 0) {
|
||||
@@ -2546,13 +2561,175 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), ((SWF) itemj.getOpenable()).getCharacter(hasCharacterId.getCharacterId()));
|
||||
}
|
||||
|
||||
/*
|
||||
How setting AS linkage should work:
|
||||
User selects linkage identifier (the one really stored in ExportAssets of the character)
|
||||
If the file is AS1/2:
|
||||
If exists DoInitAction tag for that character, that has Object.registerClass("oldLinkageIdentifier", cls)
|
||||
readonly class name is displayed
|
||||
readonly identifier is displayed
|
||||
exit
|
||||
else
|
||||
(optional) User selects desired AS2 classname and parent class name to be created
|
||||
If the linkage did not exist before (no ExportAssets had such id) and linkage identifier is not empty,
|
||||
user can select whether to use existing ExportAssets tag (if some exists) or to create new
|
||||
|
||||
On pressing OK:
|
||||
If the linkage did not exist before (no ExportAssets had such id) and the new identifier is not empty,
|
||||
user selects existing ExportAssets tag via dialog or selects position for new
|
||||
if the dialog is cancelled, exit
|
||||
If the file is AS1/2:
|
||||
If the user choosed to create new class (cls is its fully qualified name)
|
||||
Frame of Exportassets is determined
|
||||
New DoInitAction for the character is created in the EA frame which has Object.registerClass("linkageIdentifier", cls) in code
|
||||
New empty DefineSprite is created in frame 1, and its name in ExportAssets tag is set to "__Packages." + cls
|
||||
New DoInitAction for the DefineSprite in frame 1 is created and it's filled with new cls Class code
|
||||
The Exportassets tag is modified with the new linkage identifier
|
||||
*/
|
||||
private void setAsLinkageActionPerformed(ActionEvent evt) {
|
||||
CharacterTag ch = (CharacterTag) getCurrentItem();
|
||||
SWF swf = ch.getSwf();
|
||||
AsLinkageDialog d = new AsLinkageDialog(Main.getDefaultDialogsOwner(), swf, ch.getCharacterId());
|
||||
if (d.showDialog() != AppDialog.OK_OPTION) {
|
||||
return;
|
||||
}
|
||||
String identifier = d.getSelectedIdentifier();
|
||||
String className = d.getSelectedClass();
|
||||
String classParent = d.getSelectedParentClass();
|
||||
ExportAssetsTag ea = d.getSelectedExportAssetsTag();
|
||||
|
||||
if (ea == null) {
|
||||
ea = new ExportAssetsTag(swf);
|
||||
ea.setTimelined(swf);
|
||||
if (d.getSelectedPosition() == null) {
|
||||
swf.addTag(ea);
|
||||
} else {
|
||||
swf.addTag(swf.indexOfTag(d.getSelectedPosition()), ea);
|
||||
}
|
||||
}
|
||||
|
||||
if (!className.isEmpty()) {
|
||||
int frame = 1;
|
||||
int eaFrame = -1;
|
||||
int regInsertPos = -1;
|
||||
ReadOnlyTagList tags = swf.getTags();
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t == ea) {
|
||||
eaFrame = frame;
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
if (frame == eaFrame) {
|
||||
regInsertPos = i;
|
||||
break;
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
}
|
||||
|
||||
DoInitActionTag regDoInit = new DoInitActionTag(swf);
|
||||
regDoInit.spriteId = ch.getCharacterId();
|
||||
regDoInit.setTimelined(swf);
|
||||
|
||||
ActionScript2Parser regParser = new ActionScript2Parser(swf, regDoInit);
|
||||
|
||||
String[] parts = className.contains(".") ? className.split("\\.") : new String[]{className};
|
||||
DottedChain classDottedChain = new DottedChain(parts);
|
||||
|
||||
try {
|
||||
List<Action> regActions = regParser.actionsFromString("Object.registerClass(\"" + Helper.escapePCodeString(identifier) + "\"," + classDottedChain.toPrintableString(false) + ");", swf.getCharset());
|
||||
regDoInit.setActions(regActions);
|
||||
} catch (ActionParseException | IOException | CompilationException | InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
swf.addTag(regInsertPos, regDoInit);
|
||||
|
||||
int insertPos = 0;
|
||||
|
||||
tags = swf.getTags();
|
||||
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof ShowFrameTag) {
|
||||
insertPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int classCharacterId = swf.getNextCharacterId();
|
||||
DefineSpriteTag classSprite = new DefineSpriteTag(swf);
|
||||
classSprite.spriteId = classCharacterId;
|
||||
classSprite.hasEndTag = true;
|
||||
classSprite.setTimelined(swf);
|
||||
|
||||
String exportName = "__Packages." + className;
|
||||
|
||||
ExportAssetsTag classExportAssets = new ExportAssetsTag(swf);
|
||||
classExportAssets.names = new ArrayList<>();
|
||||
classExportAssets.names.add(exportName);
|
||||
classExportAssets.tags = new ArrayList<>();
|
||||
classExportAssets.tags.add(classCharacterId);
|
||||
classExportAssets.setTimelined(swf);
|
||||
|
||||
DoInitActionTag classDoInit = new DoInitActionTag(swf);
|
||||
classDoInit.spriteId = classCharacterId;
|
||||
classDoInit.setTimelined(swf);
|
||||
|
||||
ActionScript2Parser parser = new ActionScript2Parser(swf, classDoInit);
|
||||
|
||||
String[] partsParent = classParent.contains(".") ? classParent.split("\\.") : new String[]{classParent};
|
||||
DottedChain dcParent = new DottedChain(partsParent);
|
||||
|
||||
try {
|
||||
List<Action> actions = parser.actionsFromString("class " + classDottedChain.toPrintableString(false) + (classParent.isEmpty() ? "" : " extends " + dcParent.toPrintableString(false)) + "{}", swf.getCharset());
|
||||
classDoInit.setActions(actions);
|
||||
} catch (ActionParseException | IOException | CompilationException | InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
classSprite.setExportName(exportName);
|
||||
|
||||
swf.addTag(insertPos, classSprite);
|
||||
swf.addTag(insertPos + 1, classExportAssets);
|
||||
swf.addTag(insertPos + 2, classDoInit);
|
||||
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (int i = ea.names.size() - 1; i >= 0; i--) {
|
||||
if (ea.tags.get(i) == ch.getCharacterId()) {
|
||||
if (identifier.isEmpty()) {
|
||||
ea.tags.remove(i);
|
||||
ea.names.remove(i);
|
||||
} else {
|
||||
ea.names.set(i, identifier);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!identifier.isEmpty() && !found) {
|
||||
ea.tags.add(ch.getCharacterId());
|
||||
ea.names.add(identifier);
|
||||
}
|
||||
ea.setModified(true);
|
||||
if (ea.names.isEmpty()) {
|
||||
swf.removeTag(ea);
|
||||
}
|
||||
|
||||
swf.clearAllCache();
|
||||
swf.assignExportNamesToSymbols();
|
||||
swf.setModified(true);
|
||||
mainPanel.refreshTree(swf);
|
||||
}
|
||||
/*
|
||||
How set class to character mapping work in AS3:
|
||||
a) a character is selected
|
||||
b) if the character already has assigned more than 1 class then exit with a message that user must do this manually
|
||||
c) new class name is entered, must be different than previous
|
||||
d) if new class name is already assigned to different character, exit
|
||||
e) find the ABC, where class with that name is defined
|
||||
e) if the classname is not empty find the ABC, where class with that name is defined
|
||||
if found
|
||||
determine its frame
|
||||
find nearest frame >= ABC frame, such that the character is defined in it (or is defined earlier in the file)
|
||||
@@ -2569,14 +2746,15 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
otherwise create new SymbolClass in that frame
|
||||
|
||||
or suggest not creating class, set only its name
|
||||
choose whether to use existing Symbolclass or add new
|
||||
AFTER PRESSING OK:
|
||||
select existing SymbolClass or add new SymbolClass (on selected position).
|
||||
(Selected frame for target SymbolClass must have defined the character in it or earlier in the file)
|
||||
if the character did not have assigned name before (= no SymbolClass used)
|
||||
choose whether to use existing Symbolclass or add new
|
||||
AFTER PRESSING OK:
|
||||
select existing SymbolClass or add new SymbolClass (on selected position).
|
||||
(Selected frame for target SymbolClass must have defined the character in it or earlier in the file)
|
||||
AFTER PRESSING OK:
|
||||
I. if there is previously assigned classname, find associated SymbolClass and remove the mapping from it
|
||||
II. if the previous Symbolclass is empty, remove it
|
||||
III. add new character mapping to new SymbolClass determined
|
||||
II. if the previous Symbolclass is empty and is not target SymbolClass, remove it
|
||||
III. if the new classname is not empty, add new character mapping to new SymbolClass determined
|
||||
*/
|
||||
private void setAs3ClassLinkageActionPerformed(ActionEvent evt) {
|
||||
CharacterTag ch = (CharacterTag) getCurrentItem();
|
||||
@@ -2592,59 +2770,73 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
SymbolClassTag selectedSymbolClass = d.getSelectedSymbolClassTag();
|
||||
ABCContainerTag selectedAbcContainer = d.getSelectedAbcContainer();
|
||||
String className = d.getSelectedClass();
|
||||
String parentClassName = d.getSelectedParentClass();
|
||||
|
||||
if (!d.isClassFound() && !d.doCreateClass() && selectedSymbolClass == null) { //we selected position of new SymbolClass
|
||||
selectedSymbolClass = new SymbolClassTag(swf);
|
||||
selectedSymbolClass.setTimelined(swf);
|
||||
Tag pos = d.getSelectedPosition();
|
||||
if (pos == null) {
|
||||
swf.addTag(selectedSymbolClass);
|
||||
} else {
|
||||
swf.addTag(swf.indexOfTag(pos), selectedSymbolClass);
|
||||
|
||||
if (className.isEmpty() && !ch.getClassNames().isEmpty()) {
|
||||
SymbolClassTag sct = d.getSelectedSymbolClassTag();
|
||||
for (int i = sct.tags.size() - 1; i >= 0; i--) {
|
||||
if (sct.tags.get(i) == ch.getCharacterId()) {
|
||||
sct.names.remove(i);
|
||||
sct.tags.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sct.names.isEmpty()) {
|
||||
swf.removeTag(sct);
|
||||
}
|
||||
} else {
|
||||
String parentClassName = d.getSelectedParentClass();
|
||||
|
||||
if (!d.isClassFound() && d.doCreateClass()) {
|
||||
if (d.getSelectedAbcContainer() == null) {
|
||||
selectedAbcContainer = new DoABC2Tag(swf);
|
||||
((Tag) selectedAbcContainer).setTimelined(swf);
|
||||
if (!d.isClassFound() && !d.doCreateClass() && selectedSymbolClass == null) { //we selected position of new SymbolClass
|
||||
selectedSymbolClass = new SymbolClassTag(swf);
|
||||
selectedSymbolClass.setTimelined(swf);
|
||||
Tag pos = d.getSelectedPosition();
|
||||
if (pos == null) {
|
||||
swf.addTag((Tag) selectedAbcContainer);
|
||||
swf.addTag(selectedSymbolClass);
|
||||
} else {
|
||||
swf.addTag(swf.indexOfTag(pos), (Tag) selectedAbcContainer);
|
||||
swf.addTag(swf.indexOfTag(pos), selectedSymbolClass);
|
||||
}
|
||||
}
|
||||
|
||||
String pkg = className.contains(".") ? className.substring(0, className.lastIndexOf(".")) : "";
|
||||
String classSimpleName = className.contains(".") ? className.substring(className.lastIndexOf(".") + 1) : className;
|
||||
String fileName = className.replace(".", "/");
|
||||
String[] pkgParts = new String[0];
|
||||
if (!pkg.isEmpty()) {
|
||||
if (pkg.contains(".")) {
|
||||
pkgParts = pkg.split("\\.");
|
||||
} else {
|
||||
pkgParts = new String[]{pkg};
|
||||
if (!d.isClassFound() && d.doCreateClass()) {
|
||||
if (d.getSelectedAbcContainer() == null) {
|
||||
selectedAbcContainer = new DoABC2Tag(swf);
|
||||
((Tag) selectedAbcContainer).setTimelined(swf);
|
||||
Tag pos = d.getSelectedPosition();
|
||||
if (pos == null) {
|
||||
swf.addTag((Tag) selectedAbcContainer);
|
||||
} else {
|
||||
swf.addTag(swf.indexOfTag(pos), (Tag) selectedAbcContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
AbcIndexing abcIndex = swf.getAbcIndex();
|
||||
abcIndex.selectAbc(selectedAbcContainer.getABC());
|
||||
ActionScript3Parser parser = new ActionScript3Parser(abcIndex);
|
||||
|
||||
DottedChain dc = new DottedChain(pkgParts);
|
||||
String script = "package " + dc.toPrintableString(true) + " {"
|
||||
+ (parentClassName.isEmpty() ? "" : "import " + parentClassName + ";")
|
||||
+ "public class " + IdentifiersDeobfuscation.printIdentifier(true, classSimpleName) + (parentClassName.isEmpty() ? "" : " extends " + parentClassName) + " {"
|
||||
+ " }"
|
||||
+ "}";
|
||||
parser.addScript(script, fileName, 0, 0, swf.getDocumentClass());
|
||||
} catch (IOException | InterruptedException | AVM2ParseException | CompilationException ex) {
|
||||
Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, "Error during script compilation", ex);
|
||||
}
|
||||
String pkg = className.contains(".") ? className.substring(0, className.lastIndexOf(".")) : "";
|
||||
String classSimpleName = className.contains(".") ? className.substring(className.lastIndexOf(".") + 1) : className;
|
||||
String fileName = className.replace(".", "/");
|
||||
String[] pkgParts = new String[0];
|
||||
if (!pkg.isEmpty()) {
|
||||
if (pkg.contains(".")) {
|
||||
pkgParts = pkg.split("\\.");
|
||||
} else {
|
||||
pkgParts = new String[]{pkg};
|
||||
}
|
||||
}
|
||||
try {
|
||||
AbcIndexing abcIndex = swf.getAbcIndex();
|
||||
abcIndex.selectAbc(selectedAbcContainer.getABC());
|
||||
ActionScript3Parser parser = new ActionScript3Parser(abcIndex);
|
||||
|
||||
((Tag) selectedAbcContainer).setModified(true);
|
||||
DottedChain dc = new DottedChain(pkgParts);
|
||||
String script = "package " + dc.toPrintableString(true) + " {"
|
||||
+ (parentClassName.isEmpty() ? "" : "import " + parentClassName + ";")
|
||||
+ "public class " + IdentifiersDeobfuscation.printIdentifier(true, classSimpleName) + (parentClassName.isEmpty() ? "" : " extends " + parentClassName) + " {"
|
||||
+ " }"
|
||||
+ "}";
|
||||
parser.addScript(script, fileName, 0, 0, swf.getDocumentClass());
|
||||
} catch (IOException | InterruptedException | AVM2ParseException | CompilationException ex) {
|
||||
Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, "Error during script compilation", ex);
|
||||
}
|
||||
|
||||
((Tag) selectedAbcContainer).setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedSymbolClass == null) {
|
||||
|
||||
Reference in New Issue
Block a user