mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 04:01:25 +00:00
trunk contents moved to root
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.ApplicationInfo;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class AboutDialog extends AppDialog {
|
||||
|
||||
private static final String[] CONTRIBUTORS = new String[]{
|
||||
"Paolo Cancedda",
|
||||
"Capasha",
|
||||
"focus",
|
||||
"honfika",
|
||||
"Krock",
|
||||
"Laurent LOUVET",
|
||||
"MaGiC",
|
||||
"pepka",
|
||||
"poxyran",
|
||||
"Rtsjx"};
|
||||
private static final String AUTHOR = "JPEXS";
|
||||
|
||||
public AboutDialog() {
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setSize(new Dimension(300, 320));
|
||||
setTitle(translate("dialog.title"));
|
||||
|
||||
Container cnt = getContentPane();
|
||||
JPanel cp = new JPanel();
|
||||
cp.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(cp, BorderLayout.CENTER);
|
||||
cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
|
||||
|
||||
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, 25));
|
||||
jpLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
appNamePanel.add(jpLabel);
|
||||
|
||||
JLabel ffLabel = new JLabel("Free Flash");
|
||||
ffLabel.setAlignmentX(0.5f);
|
||||
ffLabel.setFont(new Font("Tahoma", Font.BOLD, 25));
|
||||
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, 25));
|
||||
decLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
appNamePanel.add(decLabel);
|
||||
appNamePanel.setAlignmentX(0.5f);
|
||||
cp.add(appNamePanel);
|
||||
|
||||
JLabel verLabel = new JLabel(translate("version") + " " + ApplicationInfo.version);
|
||||
verLabel.setAlignmentX(0.5f);
|
||||
//verLabel.setPreferredSize(new Dimension(300, 15));
|
||||
verLabel.setFont(new Font("Tahoma", Font.BOLD, 15));
|
||||
verLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(verLabel);
|
||||
|
||||
JLabel byLabel = new JLabel(translate("by"));
|
||||
byLabel.setAlignmentX(0.5f);
|
||||
byLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(byLabel);
|
||||
|
||||
JLabel authorLabel = new JLabel(AUTHOR);
|
||||
authorLabel.setAlignmentX(0.5f);
|
||||
authorLabel.setForeground(new Color(0, 0, 160));
|
||||
authorLabel.setFont(new Font("Tahoma", Font.BOLD, 20));
|
||||
//jpexsLabel.setPreferredSize(new Dimension(300, 25));
|
||||
authorLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(authorLabel);
|
||||
|
||||
JLabel dateLabel = new JLabel("2010-2014");
|
||||
dateLabel.setAlignmentX(0.5f);
|
||||
//dateLabel.setPreferredSize(new Dimension(300, 10));
|
||||
dateLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(dateLabel);
|
||||
|
||||
JLabel transAuthorLabel = new JLabel(translate("translation.author.label"));
|
||||
transAuthorLabel.setAlignmentX(0.5f);
|
||||
//transAuthorLabel.setPreferredSize(new Dimension(300, 20));
|
||||
transAuthorLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
JLabel transAuthor = new JLabel(translate("translation.author"));
|
||||
transAuthor.setAlignmentX(0.5f);
|
||||
//transAuthor.setPreferredSize(new Dimension(300, 20));
|
||||
transAuthor.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(transAuthorLabel);
|
||||
cp.add(transAuthor);
|
||||
|
||||
JLabel contributorsLabel = new JLabel(translate("contributors"));
|
||||
contributorsLabel.setAlignmentX(0.5f);
|
||||
contributorsLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
contributorsLabel.setFont(contributorsLabel.getFont().deriveFont(Font.BOLD));
|
||||
cp.add(contributorsLabel);
|
||||
|
||||
for (String c : CONTRIBUTORS) {
|
||||
JLabel contributorLabel = new JLabel(c);
|
||||
contributorLabel.setAlignmentX(0.5f);
|
||||
contributorLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(contributorLabel);
|
||||
}
|
||||
|
||||
cp.add(Box.createVerticalStrut(10));
|
||||
|
||||
LinkLabel wwwLabel = new LinkLabel(ApplicationInfo.PROJECT_PAGE);
|
||||
wwwLabel.setAlignmentX(0.5f);
|
||||
wwwLabel.setForeground(Color.blue);
|
||||
//wwwLabel.setPreferredSize(new Dimension(300, 25));
|
||||
wwwLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
cp.add(wwwLabel);
|
||||
cp.add(Box.createVerticalStrut(10));
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.setAlignmentX(0.5f);
|
||||
cp.add(okButton);
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
setModal(true);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
setResizable(false);
|
||||
pack();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionRedirector implements ActionListener {
|
||||
|
||||
ActionListener target;
|
||||
String actionCommand;
|
||||
|
||||
public ActionRedirector(ActionListener target, String actionCommand) {
|
||||
this.target = target;
|
||||
this.actionCommand = actionCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
e = new ActionEvent(e.getSource(), e.getID(), actionCommand);
|
||||
target.actionPerformed(e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.ConfigurationCategory;
|
||||
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
|
||||
import com.jpexs.decompiler.flash.gui.helpers.SpringUtilities;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class AdvancedSettingsDialog extends AppDialog implements ActionListener {
|
||||
|
||||
private Map<String, Component> componentsMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates new form AdvancedSettingsDialog
|
||||
*/
|
||||
public AdvancedSettingsDialog() {
|
||||
initComponents();
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
|
||||
//configurationTable.setCellEditor(configurationTable.getDefaultEditor(null));
|
||||
pack();
|
||||
}
|
||||
|
||||
private DefaultTableModel getModel() {
|
||||
return new javax.swing.table.DefaultTableModel(
|
||||
new Object[][]{},
|
||||
new String[]{
|
||||
translate("advancedSettings.columns.name"),
|
||||
translate("advancedSettings.columns.value"),
|
||||
translate("advancedSettings.columns.description")
|
||||
}
|
||||
) {
|
||||
Class[] types = new Class[]{
|
||||
String.class, Object.class, String.class
|
||||
};
|
||||
boolean[] canEdit = new boolean[]{
|
||||
false, true, false
|
||||
};
|
||||
|
||||
@Override
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
return types[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return canEdit[columnIndex];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
okButton = new JButton();
|
||||
cancelButton = new JButton();
|
||||
resetButton = new JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle(translate("advancedSettings.dialog.title"));
|
||||
setModal(true);
|
||||
setPreferredSize(new java.awt.Dimension(800, 500));
|
||||
|
||||
okButton.setText(AppStrings.translate("button.ok"));
|
||||
okButton.addActionListener(this);
|
||||
okButton.setActionCommand("OK");
|
||||
|
||||
cancelButton.setText(AppStrings.translate("button.cancel"));
|
||||
cancelButton.addActionListener(this);
|
||||
cancelButton.setActionCommand("CANCEL");
|
||||
|
||||
resetButton.setText(AppStrings.translate("button.reset"));
|
||||
resetButton.addActionListener(this);
|
||||
resetButton.setActionCommand("RESET");
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
//cnt.add(new JScrollPane(configurationTable),BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel buttonsLeftPanel = new JPanel(new FlowLayout());
|
||||
buttonsLeftPanel.add(resetButton, BorderLayout.WEST);
|
||||
|
||||
buttonsPanel.add(buttonsLeftPanel, BorderLayout.WEST);
|
||||
|
||||
JPanel buttonsRightPanel = new JPanel(new FlowLayout());
|
||||
buttonsRightPanel.add(cancelButton);
|
||||
buttonsRightPanel.add(okButton);
|
||||
buttonsPanel.add(buttonsRightPanel, BorderLayout.EAST);
|
||||
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
Map<String, Field> fields = Configuration.getConfigurationFields();
|
||||
String[] keys = new String[fields.size()];
|
||||
keys = fields.keySet().toArray(keys);
|
||||
Arrays.sort(keys);
|
||||
|
||||
Map<String, Map<String, Field>> categorized = new HashMap<>();
|
||||
|
||||
for (String name : keys) {
|
||||
Field field = fields.get(name);
|
||||
ConfigurationCategory cat = field.getAnnotation(ConfigurationCategory.class);
|
||||
String scat = cat == null?"other":cat.value();
|
||||
if (!categorized.containsKey(scat)) {
|
||||
categorized.put(scat, new HashMap<String, Field>());
|
||||
}
|
||||
categorized.get(scat).put(name, field);
|
||||
}
|
||||
|
||||
JTabbedPane tabPane = new JTabbedPane();
|
||||
Map<String,Component> tabs=new HashMap<>();
|
||||
for (String cat : categorized.keySet()) {
|
||||
JPanel configPanel = new JPanel(new SpringLayout());
|
||||
for (String name : categorized.get(cat).keySet()) {
|
||||
Field field = categorized.get(cat).get(name);
|
||||
|
||||
String locName = translate("config.name." + name);
|
||||
|
||||
try {
|
||||
|
||||
ConfigurationItem item = (ConfigurationItem) field.get(null);
|
||||
|
||||
ParameterizedType listType = (ParameterizedType) field.getGenericType();
|
||||
Class itemType = (Class<?>) listType.getActualTypeArguments()[0];
|
||||
/*String description = Configuration.getDescription(field);
|
||||
if (description == null) {
|
||||
description = "";
|
||||
}*/
|
||||
String description = translate("config.description." + name);
|
||||
|
||||
Object defaultValue = Configuration.getDefaultValue(field);
|
||||
if (defaultValue != null) {
|
||||
description += " (" + translate("default") + ": " + defaultValue + ")";
|
||||
}
|
||||
//model.addRow(new Object[]{locName, item.get(), description});
|
||||
|
||||
JLabel l = new JLabel(locName, JLabel.TRAILING);
|
||||
l.setToolTipText(description);
|
||||
configPanel.add(l);
|
||||
Component c = null;
|
||||
if ((itemType == String.class) || (itemType == Integer.class) || (itemType == Long.class) || (itemType == Double.class) || (itemType == Float.class) || (itemType == Calendar.class)) {
|
||||
JTextField tf = new JTextField();
|
||||
Object val = item.get();
|
||||
if (val == null) {
|
||||
val = "";
|
||||
}
|
||||
if (itemType == Calendar.class) {
|
||||
|
||||
tf.setText(new SimpleDateFormat().format(((Calendar) item.get()).getTime()));
|
||||
} else {
|
||||
tf.setText(val.toString());
|
||||
}
|
||||
tf.setToolTipText(description);
|
||||
tf.setMaximumSize(new Dimension(Integer.MAX_VALUE,tf.getPreferredSize().height));
|
||||
c = tf;
|
||||
}
|
||||
if (itemType == Boolean.class) {
|
||||
JCheckBox cb = new JCheckBox();
|
||||
cb.setSelected((Boolean) item.get());
|
||||
cb.setToolTipText(description);
|
||||
c = cb;
|
||||
}
|
||||
componentsMap.put(name, c);
|
||||
l.setLabelFor(c);
|
||||
configPanel.add(c);
|
||||
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// Reflection exceptions. This should never happen
|
||||
throw new Error(ex.getMessage());
|
||||
}
|
||||
}
|
||||
SpringUtilities.makeCompactGrid(configPanel,
|
||||
categorized.get(cat).size(), 2, //rows, cols
|
||||
6, 6, //initX, initY
|
||||
6, 6); //xPad, yPad
|
||||
tabs.put(cat,new JScrollPane(configPanel));
|
||||
}
|
||||
|
||||
|
||||
String catOrder[] = new String[]{"ui","display","decompilation","script","format","export","limit","update","debug","other"};
|
||||
|
||||
for(String cat:catOrder){
|
||||
if(!tabs.containsKey(cat)){
|
||||
continue;
|
||||
}
|
||||
tabPane.add(translate("config.group.name."+cat),tabs.get(cat));
|
||||
tabPane.setToolTipTextAt(tabPane.getTabCount()-1, translate("config.group.description."+cat));
|
||||
}
|
||||
|
||||
|
||||
|
||||
cnt.add(tabPane, BorderLayout.CENTER);
|
||||
pack();
|
||||
}
|
||||
|
||||
private void showRestartConfirmDialod() {
|
||||
if (View.showConfirmDialog(this, translate("advancedSettings.restartConfirmation"), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(AdvancedSettingsDialog.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
SelectLanguageDialog.reloadUi();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private JButton cancelButton;
|
||||
private JButton okButton;
|
||||
private JButton resetButton;
|
||||
//private EachRowRendererEditor configurationTable;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case "OK":
|
||||
boolean modified = false;
|
||||
Map<String, Field> fields = Configuration.getConfigurationFields();
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
for (String name : fields.keySet()) {
|
||||
Component c = componentsMap.get(name);
|
||||
Object value = null;
|
||||
|
||||
ParameterizedType listType = (ParameterizedType) fields.get(name).getGenericType();
|
||||
Class itemType = (Class<?>) listType.getActualTypeArguments()[0];
|
||||
if (itemType == String.class) {
|
||||
value = ((JTextField) c).getText();
|
||||
}
|
||||
if (itemType == Boolean.class) {
|
||||
value = ((JCheckBox) c).isSelected();
|
||||
}
|
||||
|
||||
if (itemType == Calendar.class) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
try {
|
||||
cal.setTime(new SimpleDateFormat().parse(((JTextField) c).getText()));
|
||||
} catch (ParseException ex) {
|
||||
c.requestFocusInWindow();
|
||||
return;
|
||||
}
|
||||
value = cal;
|
||||
}
|
||||
|
||||
try {
|
||||
if (itemType == Integer.class) {
|
||||
value = Integer.parseInt(((JTextField) c).getText());
|
||||
}
|
||||
if (itemType == Long.class) {
|
||||
value = Long.parseLong(((JTextField) c).getText());
|
||||
}
|
||||
if (itemType == Double.class) {
|
||||
value = Double.parseDouble(((JTextField) c).getText());
|
||||
}
|
||||
if (itemType == Float.class) {
|
||||
value = Float.parseFloat(((JTextField) c).getText());
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
if (!((JTextField) c).getText().equals("")) {
|
||||
c.requestFocusInWindow();
|
||||
return;
|
||||
}//else null
|
||||
}
|
||||
values.put(name, value);
|
||||
}
|
||||
|
||||
for (String name : fields.keySet()) {
|
||||
Component c = componentsMap.get(name);
|
||||
Object value = values.get(name);
|
||||
|
||||
Field field = fields.get(name);
|
||||
ConfigurationItem item = null;
|
||||
try {
|
||||
item = (ConfigurationItem) field.get(null);
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// Reflection exceptions. This should never happen
|
||||
throw new Error(ex.getMessage());
|
||||
}
|
||||
if (item.get() != null && !item.get().equals(value)) {
|
||||
item.set(value);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
Configuration.saveConfig();
|
||||
setVisible(false);
|
||||
if (modified) {
|
||||
showRestartConfirmDialod();
|
||||
}
|
||||
break;
|
||||
case "CANCEL":
|
||||
setVisible(false);
|
||||
break;
|
||||
case "RESET":
|
||||
|
||||
Map<String, Field> rfields = Configuration.getConfigurationFields();
|
||||
for (Entry<String, Field> entry : rfields.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
Field field = entry.getValue();
|
||||
try {
|
||||
ConfigurationItem item = (ConfigurationItem) field.get(null);
|
||||
item.unset();
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
// Reflection exceptions. This should never happen
|
||||
throw new Error(ex.getMessage());
|
||||
}
|
||||
}
|
||||
Configuration.saveConfig();
|
||||
setVisible(false);
|
||||
showRestartConfirmDialod();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JRootPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AppDialog extends JDialog {
|
||||
|
||||
private ResourceBundle resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass()));
|
||||
|
||||
public AppDialog() {
|
||||
View.installEscapeCloseOperation(this);
|
||||
if (Configuration.useRibbonInterface.get()) {
|
||||
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||
}
|
||||
}
|
||||
|
||||
public String translate(String key) {
|
||||
return resourceBundle.getString(key);
|
||||
}
|
||||
|
||||
public void updateLanguage() {
|
||||
resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AppFrame extends JFrame {
|
||||
|
||||
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) {
|
||||
return resourceBundle.getString(key);
|
||||
}
|
||||
|
||||
public void updateLanguage() {
|
||||
resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import java.util.ResourceBundle;
|
||||
import org.pushingpixels.flamingo.api.ribbon.JRibbonFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AppRibbonFrame extends JRibbonFrame {
|
||||
|
||||
private final 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) {
|
||||
return resourceBundle.getString(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public final class BinaryPanel extends JPanel implements ComponentListener {
|
||||
|
||||
public LineMarkedEditorPane hexEditor = new LineMarkedEditorPane();
|
||||
private byte[] data;
|
||||
|
||||
public BinaryPanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
add(new JScrollPane(hexEditor), BorderLayout.CENTER);
|
||||
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
addComponentListener(this);
|
||||
}
|
||||
|
||||
public void setBinaryData(byte[] data) {
|
||||
this.data = data;
|
||||
hexEditor.setEditable(false);
|
||||
if (data != null) {
|
||||
int widthInChars = getWidth() / 7 - 3 - 11; // -3: scrollbar, -11: address in hex format
|
||||
int blockCount = widthInChars / 34;
|
||||
hexEditor.setFont(new Font("Monospaced", Font.PLAIN, hexEditor.getFont().getSize()));
|
||||
hexEditor.setContentType("text/plain");
|
||||
int limit = Configuration.binaryDataDisplayLimit.get();
|
||||
hexEditor.setText(Helper.byteArrayToHex(data, blockCount * 8, limit));
|
||||
hexEditor.setCaretPosition(0);
|
||||
} else {
|
||||
hexEditor.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
setBinaryData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent ce) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent ce) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent ce) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.ContainerListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ButtonsPanel extends JPanel {
|
||||
|
||||
private ComponentListener listener;
|
||||
|
||||
public ButtonsPanel() {
|
||||
super(new FlowLayout());
|
||||
|
||||
listener = new ComponentListener() {
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
updateVisibility();
|
||||
}
|
||||
};
|
||||
|
||||
this.addContainerListener(new ContainerListener() {
|
||||
|
||||
@Override
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
e.getComponent().addComponentListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
e.getComponent().removeComponentListener(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateVisibility() {
|
||||
|
||||
// hide button panel when no button is visible
|
||||
boolean visible = false;
|
||||
for (Component component : getComponents()) {
|
||||
if (component instanceof JButton) {
|
||||
JButton button = (JButton) component;
|
||||
if (button.isVisible()) {
|
||||
visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
setVisible(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 javax.swing.JTable;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class EachRowRendererEditor extends JTable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Class editingClass;
|
||||
|
||||
@Override
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
editingClass = null;
|
||||
int modelColumn = convertColumnIndexToModel(column);
|
||||
if (modelColumn == 1) {
|
||||
Object value = getModel().getValueAt(row, modelColumn);
|
||||
Class rowClass = value == null ? String.class : value.getClass();
|
||||
return getDefaultRenderer(rowClass);
|
||||
} else {
|
||||
return super.getCellRenderer(row, column);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellEditor getCellEditor(int row, int column) {
|
||||
editingClass = null;
|
||||
int modelColumn = convertColumnIndexToModel(column);
|
||||
if (modelColumn == 1) {
|
||||
Object value = getModel().getValueAt(row, modelColumn);
|
||||
editingClass = value == null ? String.class : value.getClass();
|
||||
return getDefaultEditor(editingClass);
|
||||
} else {
|
||||
return super.getCellEditor(row, column);
|
||||
}
|
||||
}
|
||||
|
||||
// This method is also invoked by the editor when the value in the editor
|
||||
// component is saved in the TableModel. The class was saved when the
|
||||
// editor was invoked so the proper class can be created.
|
||||
@Override
|
||||
public Class getColumnClass(int column) {
|
||||
return editingClass != null ? editingClass : super.getColumnClass(column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ErrorLogFrame extends AppFrame {
|
||||
|
||||
private static ErrorLogFrame instance;
|
||||
|
||||
private final JPanel logView = new JPanel();
|
||||
private JPanel logViewInner = new JPanel();
|
||||
private final Handler handler;
|
||||
private final ImageIcon expandIcon;
|
||||
private final ImageIcon collapseIcon;
|
||||
private ErrorState errorState = ErrorState.NO_ERROR;
|
||||
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public static ErrorLogFrame getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ErrorLogFrame();
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Logger logger = Logger.getLogger("");
|
||||
logger.addHandler(instance.getHandler());
|
||||
}
|
||||
});
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static ErrorLogFrame createNewInstance() {
|
||||
if (instance != null) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Logger logger = Logger.getLogger("");
|
||||
logger.removeHandler(instance.getHandler());
|
||||
}
|
||||
});
|
||||
instance.setVisible(false);
|
||||
instance.dispose();
|
||||
instance = null;
|
||||
}
|
||||
return getInstance();
|
||||
}
|
||||
|
||||
public ErrorState getErrorState() {
|
||||
return errorState;
|
||||
}
|
||||
|
||||
public ErrorLogFrame() {
|
||||
setTitle(translate("dialog.title"));
|
||||
setSize(700, 400);
|
||||
setBackground(Color.white);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
logView.setBackground(Color.white);
|
||||
logView.setLayout(new BorderLayout());
|
||||
cnt.setBackground(Color.white);
|
||||
|
||||
logViewInner.setLayout(new BoxLayout(logViewInner, BoxLayout.Y_AXIS));
|
||||
logView.add(logViewInner, BorderLayout.NORTH);
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton clearButton = new JButton(translate("clear"));
|
||||
clearButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
logViewInner.removeAll();
|
||||
Main.clearLogFile();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
buttonsPanel.add(clearButton);
|
||||
|
||||
expandIcon = View.getIcon("expand16");
|
||||
collapseIcon = View.getIcon("collapse16");
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
cnt.add(new JScrollPane(logView), BorderLayout.CENTER);
|
||||
handler = new Handler() {
|
||||
SimpleFormatter formatter = new SimpleFormatter();
|
||||
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
if (getLevel().intValue() <= record.getLevel().intValue()) {
|
||||
log(record.getLevel(), formatter.formatMessage(record), record.getThrown());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException {
|
||||
}
|
||||
};
|
||||
handler.setLevel(Level.WARNING);
|
||||
}
|
||||
|
||||
public void clearErrorState() {
|
||||
errorState = ErrorState.NO_ERROR;
|
||||
MainFrame mainFrame = Main.getMainFrame();
|
||||
if (mainFrame != null) {
|
||||
mainFrame.getPanel().setErrorState(errorState);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyMainFrame(Level level) {
|
||||
boolean stateChanged = false;
|
||||
if (level.intValue() >= Level.SEVERE.intValue()) {
|
||||
if (errorState != ErrorState.ERROR) {
|
||||
errorState = ErrorState.ERROR;
|
||||
stateChanged = true;
|
||||
}
|
||||
} else if (level.intValue() >= Level.WARNING.intValue()) {
|
||||
if (errorState != ErrorState.ERROR && errorState != ErrorState.WARNING) {
|
||||
errorState = ErrorState.WARNING;
|
||||
stateChanged = true;
|
||||
}
|
||||
} else if (level.intValue() >= Level.INFO.intValue()) {
|
||||
if (errorState == ErrorState.NO_ERROR) {
|
||||
errorState = ErrorState.INFO;
|
||||
stateChanged = true;
|
||||
}
|
||||
}
|
||||
if (stateChanged) {
|
||||
MainFrame mainFrame = Main.getMainFrame();
|
||||
if (mainFrame != null) {
|
||||
mainFrame.getPanel().setErrorState(errorState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void log(final Level level, final String msg, final String detail) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyMainFrame(level);
|
||||
|
||||
JPanel pan = new JPanel();
|
||||
pan.setBackground(Color.white);
|
||||
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
|
||||
|
||||
JComponent detailComponent;
|
||||
if (detail == null) {
|
||||
detailComponent = null;
|
||||
} else {
|
||||
final JTextArea detailTextArea = new JTextArea(detail);
|
||||
detailTextArea.setEditable(false);
|
||||
detailTextArea.setOpaque(false);
|
||||
detailTextArea.setFont(new JLabel().getFont());
|
||||
detailTextArea.setBackground(Color.white);
|
||||
detailComponent = detailTextArea;
|
||||
}
|
||||
JPanel header = new JPanel();
|
||||
header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS));
|
||||
header.setBackground(Color.white);
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss");
|
||||
final String dateStr = format.format(new Date());
|
||||
|
||||
JToggleButton copyButton = new JToggleButton(View.getIcon("copy16"));
|
||||
copyButton.setFocusPainted(false);
|
||||
copyButton.setBorderPainted(false);
|
||||
copyButton.setFocusable(false);
|
||||
copyButton.setContentAreaFilled(false);
|
||||
copyButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
copyButton.setMargin(new Insets(2, 2, 2, 2));
|
||||
copyButton.setToolTipText(translate("copy"));
|
||||
copyButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
StringSelection stringSelection = new StringSelection(dateStr + " " + level.toString() + " " + msg + "\r\n" + detail);
|
||||
clipboard.setContents(stringSelection, null);
|
||||
}
|
||||
});
|
||||
|
||||
final JToggleButton expandButton = new JToggleButton(collapseIcon);
|
||||
expandButton.setFocusPainted(false);
|
||||
expandButton.setBorderPainted(false);
|
||||
expandButton.setFocusable(false);
|
||||
expandButton.setContentAreaFilled(false);
|
||||
expandButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
expandButton.setMargin(new Insets(2, 2, 2, 2));
|
||||
expandButton.setToolTipText(translate("details"));
|
||||
|
||||
final JScrollPane scrollPane;
|
||||
if (detailComponent != null) {
|
||||
scrollPane = new JScrollPane(detailComponent);
|
||||
scrollPane.setAlignmentX(0f);
|
||||
} else {
|
||||
scrollPane = null;
|
||||
}
|
||||
|
||||
if (detailComponent != null) {
|
||||
expandButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
expandButton.setIcon(expandButton.isSelected() ? expandIcon : collapseIcon);
|
||||
scrollPane.setVisible(expandButton.isSelected());
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (detailComponent != null) {
|
||||
header.add(expandButton);
|
||||
}
|
||||
JLabel dateLabel = new JLabel(dateStr);
|
||||
dateLabel.setPreferredSize(new Dimension(200, (int) dateLabel.getPreferredSize().getHeight()));
|
||||
dateLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
header.add(dateLabel);
|
||||
|
||||
JLabel levelLabel = new JLabel(level.getName());
|
||||
levelLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
header.add(levelLabel);
|
||||
JTextArea msgLabel = new JTextArea(msg);
|
||||
msgLabel.setEditable(false);
|
||||
msgLabel.setOpaque(false);
|
||||
msgLabel.setFont(levelLabel.getFont());
|
||||
|
||||
msgLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
header.add(msgLabel);
|
||||
header.setAlignmentX(0f);
|
||||
|
||||
header.add(copyButton);
|
||||
pan.add(header);
|
||||
if (detailComponent != null) {
|
||||
pan.add(scrollPane);
|
||||
scrollPane.setVisible(false);
|
||||
}
|
||||
pan.setAlignmentX(0f);
|
||||
logViewInner.add(pan);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void log(Level level, String msg) {
|
||||
log(level, msg, (String) null);
|
||||
}
|
||||
|
||||
public void log(Level level, String msg, Throwable ex) {
|
||||
StringWriter sw = new StringWriter();
|
||||
if (ex != null) {
|
||||
ex.printStackTrace(new PrintWriter(sw));
|
||||
}
|
||||
log(level, msg, sw.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum ErrorState {
|
||||
|
||||
NO_ERROR, INFO, WARNING, ERROR
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.MorphShapeExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ExportDialog extends AppDialog {
|
||||
|
||||
boolean cancelled = false;
|
||||
|
||||
String[] optionNames = {
|
||||
"shapes",
|
||||
"texts",
|
||||
"images",
|
||||
"movies",
|
||||
"sounds",
|
||||
"scripts",
|
||||
"binaryData",
|
||||
"frames",
|
||||
"fonts",
|
||||
"morphshapes"
|
||||
};
|
||||
|
||||
//Display options only when these classes found
|
||||
Class[][] objClasses = {
|
||||
{ShapeTag.class},
|
||||
{TextTag.class},
|
||||
{ImageTag.class},
|
||||
{DefineVideoStreamTag.class},
|
||||
{SoundTag.class},
|
||||
{TreeNode.class, ScriptPack.class},
|
||||
{DefineBinaryDataTag.class},
|
||||
{FrameNodeItem.class},
|
||||
{FontTag.class},
|
||||
{MorphShapeTag.class}
|
||||
};
|
||||
|
||||
//Enum classes for values
|
||||
Class[] optionClasses = {
|
||||
ShapeExportMode.class,
|
||||
TextExportMode.class,
|
||||
ImageExportMode.class,
|
||||
MovieExportMode.class,
|
||||
SoundExportMode.class,
|
||||
ScriptExportMode.class,
|
||||
BinaryDataExportMode.class,
|
||||
FramesExportMode.class,
|
||||
FontExportMode.class,
|
||||
MorphShapeExportMode.class
|
||||
};
|
||||
|
||||
private final JComboBox[] combos;
|
||||
|
||||
public <E> E getValue(Class<E> option) {
|
||||
for (int i = 0; i < optionClasses.length; i++) {
|
||||
if (option == optionClasses[i]) {
|
||||
E values[] = option.getEnumConstants();
|
||||
return values[combos[i].getSelectedIndex()];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void saveConfig() {
|
||||
String cfg = "";
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
int selIndex = combos[i].getSelectedIndex();
|
||||
Class c = optionClasses[i];
|
||||
Object vals[] = c.getEnumConstants();
|
||||
String key = optionNames[i] + "." + vals[selIndex].toString().toLowerCase();
|
||||
if (i > 0) {
|
||||
cfg += ",";
|
||||
}
|
||||
cfg += key;
|
||||
}
|
||||
Configuration.lastSelectedExportFormats.set(cfg);
|
||||
}
|
||||
|
||||
public ExportDialog(List<Object> exportables) {
|
||||
setTitle(translate("dialog.title"));
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
cancelled = true;
|
||||
}
|
||||
});
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
JPanel comboPanel = new JPanel(null);
|
||||
combos = new JComboBox[optionNames.length];
|
||||
JLabel[] labels = new JLabel[optionNames.length];
|
||||
int labWidth = 0;
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
labels[i] = new JLabel(optionNames[i]);
|
||||
if (labels[i].getPreferredSize().width > labWidth) {
|
||||
labWidth = labels[i].getPreferredSize().width;
|
||||
}
|
||||
}
|
||||
String exportFormatsStr = Configuration.lastSelectedExportFormats.get();
|
||||
if ("".equals(exportFormatsStr)) {
|
||||
exportFormatsStr = null;
|
||||
}
|
||||
String exportFormatsArr[] = new String[0];
|
||||
if (exportFormatsStr != null) {
|
||||
if (exportFormatsStr.contains(",")) {
|
||||
exportFormatsArr = exportFormatsStr.split(",");
|
||||
} else {
|
||||
exportFormatsArr = new String[]{exportFormatsStr};
|
||||
}
|
||||
|
||||
}
|
||||
List<String> exportFormats = Arrays.asList(exportFormatsArr);
|
||||
int comboWidth = 200;
|
||||
int top = 10;
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
Class c = optionClasses[i];
|
||||
Object vals[] = c.getEnumConstants();
|
||||
String names[] = new String[vals.length];
|
||||
int itemIndex = -1;
|
||||
for (int j = 0; j < vals.length; j++) {
|
||||
|
||||
String key = optionNames[i] + "." + vals[j].toString().toLowerCase();
|
||||
if (exportFormats.contains(key)) {
|
||||
itemIndex = j;
|
||||
}
|
||||
names[j] = translate(key);
|
||||
}
|
||||
|
||||
combos[i] = new JComboBox<>(names);
|
||||
if (itemIndex > -1) {
|
||||
combos[i].setSelectedIndex(itemIndex);
|
||||
}
|
||||
combos[i].setBounds(10 + labWidth + 10, top, comboWidth, combos[i].getPreferredSize().height);
|
||||
boolean exportableExists = false;
|
||||
if (exportables == null) {
|
||||
exportableExists = true;
|
||||
} else {
|
||||
for (Object e : exportables) {
|
||||
for (int j = 0; j < objClasses[i].length; j++) {
|
||||
if (objClasses[i][j].isInstance(e)) {
|
||||
exportableExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exportableExists) {
|
||||
continue;
|
||||
}
|
||||
JLabel lab = new JLabel(translate(optionNames[i]));
|
||||
lab.setBounds(10, top, lab.getPreferredSize().width, lab.getPreferredSize().height);
|
||||
comboPanel.add(lab);
|
||||
comboPanel.add(combos[i]);
|
||||
top += combos[i].getHeight();
|
||||
}
|
||||
Dimension dim = new Dimension(10 + labWidth + 10 + comboWidth + 10, top + 10);
|
||||
comboPanel.setMinimumSize(dim);
|
||||
comboPanel.setPreferredSize(dim);
|
||||
cnt.add(comboPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
saveConfig();
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
cancelled = true;
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
pack();
|
||||
//setSize(245, top + getInsets().top);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
cancelled = false;
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FlashUnsupportedException extends RuntimeException {
|
||||
|
||||
public FlashUnsupportedException() {
|
||||
super("Flash Unsupported");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.font.CharacterRanges;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FontEmbedDialog extends AppDialog implements ActionListener {
|
||||
|
||||
private static final String ACTION_OK = "OK";
|
||||
private static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
private static final int SAMPLE_MAX_LENGTH = 50;
|
||||
|
||||
private final JComboBox<String> sourceFont;
|
||||
private final JCheckBox[] rangeCheckboxes;
|
||||
private final String rangeNames[];
|
||||
private final JLabel[] rangeSamples;
|
||||
private final JTextField individualCharsField;
|
||||
private boolean result = false;
|
||||
private JLabel individialSample;
|
||||
private final int style;
|
||||
|
||||
public String getSelectedFont() {
|
||||
return sourceFont.getSelectedItem().toString();
|
||||
}
|
||||
|
||||
public Set<Integer> getSelectedChars() {
|
||||
Set<Integer> chars = new TreeSet<>();
|
||||
Font f = new Font(getSelectedFont(), style, new JLabel().getFont().getSize());
|
||||
for (int i = 0; i < rangeCheckboxes.length; i++) {
|
||||
if (rangeCheckboxes[i].isSelected()) {
|
||||
int codes[] = CharacterRanges.rangeCodes(i);
|
||||
for (int c : codes) {
|
||||
if (f.canDisplay(c)) {
|
||||
chars.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String indStr = individualCharsField.getText();
|
||||
for (int i = 0; i < indStr.length(); i++) {
|
||||
if (f.canDisplay(indStr.codePointAt(i))) {
|
||||
chars.add(indStr.codePointAt(i));
|
||||
}
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
|
||||
public FontEmbedDialog(String selectedFont, String selectedChars, int style) {
|
||||
setSize(900, 600);
|
||||
this.style = style;
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setTitle(translate("dialog.title"));
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
|
||||
|
||||
individialSample = new JLabel();
|
||||
sourceFont = new JComboBox<>(new Vector<>(FontTag.fontNames));
|
||||
sourceFont.setSelectedItem(selectedFont);
|
||||
cnt.add(sourceFont);
|
||||
JPanel rangesPanel = new JPanel();
|
||||
rangesPanel.setLayout(new BoxLayout(rangesPanel, BoxLayout.Y_AXIS));
|
||||
int rc = CharacterRanges.rangeCount();
|
||||
rangeCheckboxes = new JCheckBox[rc];
|
||||
rangeSamples = new JLabel[rc];
|
||||
rangeNames = new String[rc];
|
||||
for (int i = 0; i < rc; i++) {
|
||||
rangeNames[i] = CharacterRanges.rangeName(i);
|
||||
rangeSamples[i] = new JLabel("");
|
||||
rangeCheckboxes[i] = new JCheckBox(rangeNames[i]);
|
||||
JPanel rangeRowPanel = new JPanel();
|
||||
rangeRowPanel.setLayout(new BoxLayout(rangeRowPanel, BoxLayout.X_AXIS));
|
||||
rangeRowPanel.add(rangeCheckboxes[i]);
|
||||
rangeRowPanel.add(Box.createHorizontalGlue());
|
||||
rangeRowPanel.add(rangeSamples[i]);
|
||||
rangeRowPanel.setAlignmentX(0);
|
||||
rangesPanel.add(rangeRowPanel);
|
||||
}
|
||||
cnt.add(new JScrollPane(rangesPanel));
|
||||
|
||||
JPanel specialPanel = new JPanel();
|
||||
specialPanel.setLayout(new BoxLayout(specialPanel, BoxLayout.X_AXIS));
|
||||
specialPanel.add(new JLabel(translate("label.individual")));
|
||||
individualCharsField = new JTextField();
|
||||
individualCharsField.setPreferredSize(new Dimension(100, individualCharsField.getPreferredSize().height));
|
||||
individialSample = new JLabel();
|
||||
specialPanel.add(individualCharsField);
|
||||
cnt.add(specialPanel);
|
||||
cnt.add(individialSample);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton okButton = new JButton(AppStrings.translate("button.ok"));
|
||||
okButton.setActionCommand(ACTION_OK);
|
||||
okButton.addActionListener(this);
|
||||
JButton cancelButton = new JButton(AppStrings.translate("button.cancel"));
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
cnt.add(buttonsPanel);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
individualCharsField.setText(selectedChars);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
sourceFont.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateCheckboxes();
|
||||
}
|
||||
});
|
||||
updateCheckboxes();
|
||||
individualCharsField.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
updateIndividual();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateIndividual() {
|
||||
String chars = individualCharsField.getText();
|
||||
Font f = new Font(getSelectedFont(), style, new JLabel().getFont().getSize());
|
||||
String visibleChars = "";
|
||||
for (int i = 0; i < chars.length(); i++) {
|
||||
if (f.canDisplay(chars.codePointAt(i))) {
|
||||
visibleChars += "" + chars.charAt(i);
|
||||
}
|
||||
}
|
||||
individialSample.setText(visibleChars);
|
||||
}
|
||||
|
||||
private void updateCheckboxes() {
|
||||
String fontStr = sourceFont.getSelectedItem().toString();
|
||||
Font f = new Font(fontStr, style, new JLabel().getFont().getSize());
|
||||
int rc = CharacterRanges.rangeCount();
|
||||
for (int i = 0; i < rc; i++) {
|
||||
rangeNames[i] = CharacterRanges.rangeName(i);
|
||||
int codes[] = CharacterRanges.rangeCodes(i);
|
||||
int avail = 0;
|
||||
String sample = "";
|
||||
for (int c = 0; c < codes.length; c++) {
|
||||
if (f.canDisplay(codes[c])) {
|
||||
if (avail < SAMPLE_MAX_LENGTH) {
|
||||
sample += "" + (char) codes[c];
|
||||
}
|
||||
avail++;
|
||||
}
|
||||
}
|
||||
rangeSamples[i].setText(sample);
|
||||
rangeSamples[i].setFont(f);
|
||||
rangeCheckboxes[i].setText(translate("range.description").replace("%available%", "" + avail).replace("%name%", rangeNames[i]).replace("%total%", "" + codes.length));
|
||||
}
|
||||
individialSample.setFont(f);
|
||||
updateIndividual();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OK:
|
||||
result = true;
|
||||
setVisible(false);
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
result = false;
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean display() {
|
||||
result = false;
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,591 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.8" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Events>
|
||||
<EventHandler event="componentResized" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="formComponentResized"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="473" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="415" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<Properties>
|
||||
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="463" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel11" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="fontSelection" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="fontAddCharactersField" min="-2" pref="150" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="fontEmbedButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="buttonEdit" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="buttonSave" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="buttonCancel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="100" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="fontAddCharsButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="updateTextsCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="buttonPreviewFont" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="315" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="415" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel10" alignment="3" max="32767" attributes="0"/>
|
||||
<Component id="fontAddCharactersField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="fontAddCharsButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="updateTextsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fontSelection" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="buttonPreviewFont" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fontEmbedButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="78" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="buttonEdit" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="buttonSave" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="buttonCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.name" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fontNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 14]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 14]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 14]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="fontName.name" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="8" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="fontDisplayNameScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
|
||||
<Property name="horizontalScrollBar" type="javax.swing.JScrollBar" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="fontDisplayNameTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new JLabel().getFont()" type="code"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 16]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="fontName.copyright" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="fontCopyrightScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
|
||||
<Property name="horizontalScrollBar" type="javax.swing.JScrollBar" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="fontCopyrightTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new JLabel().getFont()" type="code"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 16]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.isbold" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="fontIsBoldCheckBox">
|
||||
<Properties>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.isitalic" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="fontIsItalicCheckBox">
|
||||
<Properties>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.ascent" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fontAscentLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.descent" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fontDescentLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel8">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.leading" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="7" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fontLeadingLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="value.unknown" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="7" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel9">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.characters" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="23" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="fontCharactersScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
|
||||
<Property name="horizontalScrollBar" type="javax.swing.JScrollBar" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="8" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="0" insetsRight="6" anchor="23" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="fontCharactersTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new JLabel().getFont()" type="code"/>
|
||||
</Property>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[250, 16]"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel10">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.characters.add" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="fontAddCharactersField">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="fontAddCharsButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.ok" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fontAddCharsButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="updateTextsCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.updateTexts" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel11">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.source" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="fontSelection">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="getModel()" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectedItem" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="FontTag.defaultFontName" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="fontSelectionItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="fontEmbedButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.font.embed" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fontEmbedButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="buttonEdit">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/com/jpexs/decompiler/flash/gui/graphics/edit16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.edit" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonEditActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="buttonSave">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/com/jpexs/decompiler/flash/gui/graphics/save16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.save" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonSaveActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="buttonCancel">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/com/jpexs/decompiler/flash/gui/graphics/cancel16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.cancel" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="buttonPreviewFont">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="button.preview" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonPreviewFontActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,679 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFontNameTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import java.awt.Font;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FontPanel extends javax.swing.JPanel {
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
private FontTag fontTag;
|
||||
|
||||
/**
|
||||
* Creates new form FontPanel
|
||||
*
|
||||
* @param mainPanel
|
||||
*/
|
||||
public FontPanel(MainPanel mainPanel) {
|
||||
this.mainPanel = mainPanel;
|
||||
initComponents();
|
||||
}
|
||||
|
||||
public FontTag getFontTag() {
|
||||
return fontTag;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
fontTag = null;
|
||||
}
|
||||
|
||||
private ComboBoxModel<String> getModel() {
|
||||
return new DefaultComboBoxModel<>(FontTag.fontNamesArray);
|
||||
}
|
||||
|
||||
private void setEditable(boolean editable) {
|
||||
if (editable) {
|
||||
buttonEdit.setVisible(false);
|
||||
buttonSave.setVisible(true);
|
||||
buttonCancel.setVisible(true);
|
||||
if (fontTag.isBoldEditable()) {
|
||||
fontIsBoldCheckBox.setEnabled(true);
|
||||
}
|
||||
if (fontTag.isItalicEditable()) {
|
||||
fontIsItalicCheckBox.setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
buttonEdit.setVisible(true);
|
||||
buttonSave.setVisible(false);
|
||||
buttonCancel.setVisible(false);
|
||||
fontIsBoldCheckBox.setEnabled(false);
|
||||
fontIsItalicCheckBox.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private String translate(String key) {
|
||||
return mainPanel.translate(key);
|
||||
}
|
||||
|
||||
private void fontAddChars(FontTag ft, Set<Integer> selChars, String selFont) {
|
||||
FontTag f = (FontTag) mainPanel.tagTree.getCurrentTreeItem();
|
||||
SWF swf = ft.getSwf();
|
||||
String oldchars = f.getCharacters(swf.tags);
|
||||
for (int ic : selChars) {
|
||||
char c = (char) ic;
|
||||
if (oldchars.indexOf((int) c) == -1) {
|
||||
Font font = new Font(selFont, f.getFontStyle(), 1024);
|
||||
if (!font.canDisplay(c)) {
|
||||
View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + c), translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String[] yesno = new String[]{translate("button.yes"), translate("button.no"), translate("button.yes.all"), translate("button.no.all")};
|
||||
boolean yestoall = false;
|
||||
boolean notoall = false;
|
||||
for (int ic : selChars) {
|
||||
char c = (char) ic;
|
||||
if (oldchars.indexOf((int) c) > -1) {
|
||||
int opt; //yes
|
||||
if (!(yestoall || notoall)) {
|
||||
opt = View.showOptionDialog(null, translate("message.font.add.exists").replace("%char%", "" + c), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, translate("button.yes"));
|
||||
if (opt == 2) {
|
||||
yestoall = true;
|
||||
}
|
||||
if (opt == 3) {
|
||||
notoall = true;
|
||||
}
|
||||
}
|
||||
if (yestoall) {
|
||||
opt = 0; //yes
|
||||
} else if (notoall) {
|
||||
opt = 1; //no
|
||||
} else {
|
||||
opt = 1;
|
||||
}
|
||||
|
||||
if (opt == 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f.addCharacter(c, fontSelection.getSelectedItem().toString());
|
||||
oldchars += c;
|
||||
}
|
||||
|
||||
int fontId = ft.getFontId();
|
||||
if (updateTextsCheckBox.isSelected()) {
|
||||
for (Tag tag : swf.tags) {
|
||||
if (tag instanceof TextTag) {
|
||||
TextTag textTag = (TextTag) tag;
|
||||
if (textTag.getFontIds().contains(fontId)) {
|
||||
String text = textTag.getFormattedText();
|
||||
mainPanel.saveText(textTag, text, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ft.setModified(true);
|
||||
SWF.clearImageCache();
|
||||
}
|
||||
|
||||
public void showFontTag(FontTag ft) {
|
||||
SWF swf = ft.getSwf();
|
||||
fontTag = ft;
|
||||
DefineFontNameTag fontNameTag = null;
|
||||
for (Tag tag : swf.tags) {
|
||||
if (tag instanceof DefineFontNameTag) {
|
||||
DefineFontNameTag dfnt = (DefineFontNameTag) tag;
|
||||
if (dfnt.fontId == ft.getFontId()) {
|
||||
fontNameTag = dfnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fontNameLabel.setText(ft.getFontName());
|
||||
if (fontNameTag != null) {
|
||||
fontDisplayNameTextArea.setText(fontNameTag.fontName);
|
||||
fontCopyrightTextArea.setText(fontNameTag.fontCopyright);
|
||||
}
|
||||
|
||||
fontIsBoldCheckBox.setSelected(ft.isBold());
|
||||
fontIsItalicCheckBox.setSelected(ft.isItalic());
|
||||
fontDescentLabel.setText(ft.getDescent() == -1 ? translate("value.unknown") : "" + ft.getDescent());
|
||||
fontAscentLabel.setText(ft.getAscent() == -1 ? translate("value.unknown") : "" + ft.getAscent());
|
||||
fontLeadingLabel.setText(ft.getLeading() == -1 ? translate("value.unknown") : "" + ft.getLeading());
|
||||
String chars = ft.getCharacters(swf.tags);
|
||||
fontCharactersTextArea.setText(chars);
|
||||
String key = swf.getShortFileName() + "_" + ft.getFontId() + "_" + ft.getFontName();
|
||||
if (swf.sourceFontsMap.containsKey(ft.getFontId())) {
|
||||
fontSelection.setSelectedItem(swf.sourceFontsMap.get(ft.getFontId()));
|
||||
} else if (Configuration.getFontPairs().containsKey(key)) {
|
||||
fontSelection.setSelectedItem(Configuration.getFontPairs().get(key));
|
||||
} else if (Configuration.getFontPairs().containsKey(ft.getFontName())) {
|
||||
fontSelection.setSelectedItem(Configuration.getFontPairs().get(ft.getFontName()));
|
||||
} else {
|
||||
fontSelection.setSelectedItem(FontTag.findInstalledFontName(ft.getFontName()));
|
||||
}
|
||||
setEditable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
|
||||
fontNameLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
|
||||
javax.swing.JScrollPane fontDisplayNameScrollPane = new javax.swing.JScrollPane();
|
||||
fontDisplayNameTextArea = new javax.swing.JTextArea();
|
||||
javax.swing.JLabel jLabel3 = new javax.swing.JLabel();
|
||||
javax.swing.JScrollPane fontCopyrightScrollPane = new javax.swing.JScrollPane();
|
||||
fontCopyrightTextArea = new javax.swing.JTextArea();
|
||||
javax.swing.JLabel jLabel4 = new javax.swing.JLabel();
|
||||
fontIsBoldCheckBox = new javax.swing.JCheckBox();
|
||||
javax.swing.JLabel jLabel5 = new javax.swing.JLabel();
|
||||
fontIsItalicCheckBox = new javax.swing.JCheckBox();
|
||||
javax.swing.JLabel jLabel6 = new javax.swing.JLabel();
|
||||
fontAscentLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel jLabel7 = new javax.swing.JLabel();
|
||||
fontDescentLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel jLabel8 = new javax.swing.JLabel();
|
||||
fontLeadingLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel jLabel9 = new javax.swing.JLabel();
|
||||
fontCharactersScrollPane = new javax.swing.JScrollPane();
|
||||
fontCharactersTextArea = new javax.swing.JTextArea();
|
||||
javax.swing.JLabel jLabel10 = new javax.swing.JLabel();
|
||||
fontAddCharactersField = new javax.swing.JTextField();
|
||||
fontAddCharsButton = new javax.swing.JButton();
|
||||
updateTextsCheckBox = new javax.swing.JCheckBox();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
fontSelection = new javax.swing.JComboBox();
|
||||
fontEmbedButton = new javax.swing.JButton();
|
||||
buttonEdit = new javax.swing.JButton();
|
||||
buttonSave = new javax.swing.JButton();
|
||||
buttonCancel = new javax.swing.JButton();
|
||||
buttonPreviewFont = new javax.swing.JButton();
|
||||
|
||||
addComponentListener(new java.awt.event.ComponentAdapter() {
|
||||
public void componentResized(java.awt.event.ComponentEvent evt) {
|
||||
formComponentResized(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
jPanel1.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("com/jpexs/decompiler/flash/gui/locales/MainFrame"); // NOI18N
|
||||
jLabel1.setText(bundle.getString("font.name")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel1, gridBagConstraints);
|
||||
|
||||
fontNameLabel.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
fontNameLabel.setMaximumSize(new java.awt.Dimension(250, 14));
|
||||
fontNameLabel.setMinimumSize(new java.awt.Dimension(250, 14));
|
||||
fontNameLabel.setPreferredSize(new java.awt.Dimension(250, 14));
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontNameLabel, gridBagConstraints);
|
||||
|
||||
jLabel2.setText(bundle.getString("fontName.name")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.ipadx = 8;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel2, gridBagConstraints);
|
||||
|
||||
fontDisplayNameScrollPane.setBorder(null);
|
||||
fontDisplayNameScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
fontDisplayNameScrollPane.setHorizontalScrollBar(null);
|
||||
|
||||
fontDisplayNameTextArea.setEditable(false);
|
||||
fontDisplayNameTextArea.setColumns(20);
|
||||
fontDisplayNameTextArea.setFont(new JLabel().getFont());
|
||||
fontDisplayNameTextArea.setLineWrap(true);
|
||||
fontDisplayNameTextArea.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
fontDisplayNameTextArea.setWrapStyleWord(true);
|
||||
fontDisplayNameTextArea.setMinimumSize(new java.awt.Dimension(250, 16));
|
||||
fontDisplayNameTextArea.setOpaque(false);
|
||||
fontDisplayNameScrollPane.setViewportView(fontDisplayNameTextArea);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontDisplayNameScrollPane, gridBagConstraints);
|
||||
|
||||
jLabel3.setText(bundle.getString("fontName.copyright")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel3, gridBagConstraints);
|
||||
|
||||
fontCopyrightScrollPane.setBorder(null);
|
||||
fontCopyrightScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
fontCopyrightScrollPane.setHorizontalScrollBar(null);
|
||||
|
||||
fontCopyrightTextArea.setEditable(false);
|
||||
fontCopyrightTextArea.setColumns(20);
|
||||
fontCopyrightTextArea.setFont(new JLabel().getFont());
|
||||
fontCopyrightTextArea.setLineWrap(true);
|
||||
fontCopyrightTextArea.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
fontCopyrightTextArea.setWrapStyleWord(true);
|
||||
fontCopyrightTextArea.setMinimumSize(new java.awt.Dimension(250, 16));
|
||||
fontCopyrightTextArea.setOpaque(false);
|
||||
fontCopyrightScrollPane.setViewportView(fontCopyrightTextArea);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontCopyrightScrollPane, gridBagConstraints);
|
||||
|
||||
jLabel4.setText(bundle.getString("font.isbold")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel4, gridBagConstraints);
|
||||
|
||||
fontIsBoldCheckBox.setEnabled(false);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontIsBoldCheckBox, gridBagConstraints);
|
||||
|
||||
jLabel5.setText(bundle.getString("font.isitalic")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel5, gridBagConstraints);
|
||||
|
||||
fontIsItalicCheckBox.setEnabled(false);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontIsItalicCheckBox, gridBagConstraints);
|
||||
|
||||
jLabel6.setText(bundle.getString("font.ascent")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel6, gridBagConstraints);
|
||||
|
||||
fontAscentLabel.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontAscentLabel, gridBagConstraints);
|
||||
|
||||
jLabel7.setText(bundle.getString("font.descent")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel7, gridBagConstraints);
|
||||
|
||||
fontDescentLabel.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontDescentLabel, gridBagConstraints);
|
||||
|
||||
jLabel8.setText(bundle.getString("font.leading")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 7;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel8, gridBagConstraints);
|
||||
|
||||
fontLeadingLabel.setText(bundle.getString("value.unknown")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 7;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontLeadingLabel, gridBagConstraints);
|
||||
|
||||
jLabel9.setText(bundle.getString("font.characters")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jLabel9, gridBagConstraints);
|
||||
|
||||
fontCharactersScrollPane.setBorder(null);
|
||||
fontCharactersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
fontCharactersScrollPane.setHorizontalScrollBar(null);
|
||||
|
||||
fontCharactersTextArea.setEditable(false);
|
||||
fontCharactersTextArea.setColumns(20);
|
||||
fontCharactersTextArea.setFont(new JLabel().getFont());
|
||||
fontCharactersTextArea.setLineWrap(true);
|
||||
fontCharactersTextArea.setWrapStyleWord(true);
|
||||
fontCharactersTextArea.setMinimumSize(new java.awt.Dimension(250, 16));
|
||||
fontCharactersTextArea.setOpaque(false);
|
||||
fontCharactersScrollPane.setViewportView(fontCharactersTextArea);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 6, 0, 6);
|
||||
jPanel1.add(fontCharactersScrollPane, gridBagConstraints);
|
||||
|
||||
jLabel10.setText(bundle.getString("font.characters.add")); // NOI18N
|
||||
|
||||
fontAddCharsButton.setText(bundle.getString("button.ok")); // NOI18N
|
||||
fontAddCharsButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
fontAddCharsButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
updateTextsCheckBox.setText(bundle.getString("font.updateTexts")); // NOI18N
|
||||
|
||||
jLabel11.setText(bundle.getString("font.source")); // NOI18N
|
||||
|
||||
fontSelection.setModel(getModel());
|
||||
fontSelection.setSelectedItem(FontTag.defaultFontName);
|
||||
fontSelection.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
fontSelectionItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
fontEmbedButton.setText(bundle.getString("button.font.embed")); // NOI18N
|
||||
fontEmbedButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
fontEmbedButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jpexs/decompiler/flash/gui/graphics/edit16.png"))); // NOI18N
|
||||
buttonEdit.setText(bundle.getString("button.edit")); // NOI18N
|
||||
buttonEdit.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonEditActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jpexs/decompiler/flash/gui/graphics/save16.png"))); // NOI18N
|
||||
buttonSave.setText(bundle.getString("button.save")); // NOI18N
|
||||
buttonSave.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonSaveActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonCancel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jpexs/decompiler/flash/gui/graphics/cancel16.png"))); // NOI18N
|
||||
buttonCancel.setText(bundle.getString("button.cancel")); // NOI18N
|
||||
buttonCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonPreviewFont.setText(bundle.getString("button.preview")); // NOI18N
|
||||
buttonPreviewFont.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonPreviewFontActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
|
||||
jPanel2.setLayout(jPanel2Layout);
|
||||
jPanel2Layout.setHorizontalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 463, Short.MAX_VALUE)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(jLabel11)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(fontSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(jLabel10)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(fontAddCharactersField, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(fontEmbedButton))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(buttonEdit)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(buttonSave)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(buttonCancel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(fontAddCharsButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(updateTextsCheckBox))
|
||||
.addComponent(buttonPreviewFont))
|
||||
.addGap(315, 315, 315)))
|
||||
.addContainerGap()))
|
||||
);
|
||||
jPanel2Layout.setVerticalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 415, Short.MAX_VALUE)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(fontAddCharactersField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(fontAddCharsButton)
|
||||
.addComponent(updateTextsCheckBox))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(fontSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(buttonPreviewFont)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(fontEmbedButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 78, Short.MAX_VALUE)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(buttonEdit)
|
||||
.addComponent(buttonSave)
|
||||
.addComponent(buttonCancel))
|
||||
.addContainerGap()))
|
||||
);
|
||||
|
||||
jScrollPane1.setViewportView(jPanel2);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 415, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void fontAddCharsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fontAddCharsButtonActionPerformed
|
||||
String newchars = fontAddCharactersField.getText();
|
||||
|
||||
TreeItem item = mainPanel.tagTree.getCurrentTreeItem();
|
||||
if (item instanceof FontTag) {
|
||||
Set<Integer> selChars = new TreeSet<>();
|
||||
for (int c = 0; c < newchars.length(); c++) {
|
||||
selChars.add(newchars.codePointAt(c));
|
||||
}
|
||||
fontAddChars((FontTag) item, selChars, fontSelection.getSelectedItem().toString());
|
||||
fontAddCharactersField.setText("");
|
||||
mainPanel.reload(true);
|
||||
}
|
||||
}//GEN-LAST:event_fontAddCharsButtonActionPerformed
|
||||
|
||||
private void fontEmbedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fontEmbedButtonActionPerformed
|
||||
TreeItem item = mainPanel.tagTree.getCurrentTreeItem();
|
||||
if (item instanceof FontTag) {
|
||||
FontTag fontTag = (FontTag) item;
|
||||
FontEmbedDialog fed = new FontEmbedDialog(fontSelection.getSelectedItem().toString(), fontAddCharactersField.getText(), fontTag.getFontStyle());
|
||||
if (fed.display()) {
|
||||
Set<Integer> selChars = fed.getSelectedChars();
|
||||
if (!selChars.isEmpty()) {
|
||||
String selFont = fed.getSelectedFont();
|
||||
fontSelection.setSelectedItem(selFont);
|
||||
fontAddChars(fontTag, selChars, selFont);
|
||||
fontAddCharactersField.setText("");
|
||||
mainPanel.reload(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_fontEmbedButtonActionPerformed
|
||||
|
||||
private void fontSelectionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_fontSelectionItemStateChanged
|
||||
TreeItem item = mainPanel.tagTree.getCurrentTreeItem();
|
||||
if (item instanceof FontTag) {
|
||||
FontTag f = (FontTag) item;
|
||||
SWF swf = f.getSwf();
|
||||
String selectedSystemFont = (String) fontSelection.getSelectedItem();
|
||||
swf.sourceFontsMap.put(f.getFontId(), selectedSystemFont);
|
||||
Configuration.addFontPair(swf.getShortFileName(), f.getFontId(), f.getFontName(), selectedSystemFont);
|
||||
}
|
||||
}//GEN-LAST:event_fontSelectionItemStateChanged
|
||||
|
||||
private void buttonEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEditActionPerformed
|
||||
setEditable(true);
|
||||
}//GEN-LAST:event_buttonEditActionPerformed
|
||||
|
||||
private void buttonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSaveActionPerformed
|
||||
if (fontTag.isBoldEditable()) {
|
||||
fontTag.setBold(fontIsBoldCheckBox.isSelected());
|
||||
}
|
||||
if (fontTag.isItalicEditable()) {
|
||||
fontTag.setItalic(fontIsItalicCheckBox.isSelected());
|
||||
}
|
||||
setEditable(false);
|
||||
}//GEN-LAST:event_buttonSaveActionPerformed
|
||||
|
||||
private void buttonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCancelActionPerformed
|
||||
showFontTag(fontTag);
|
||||
setEditable(false);
|
||||
}//GEN-LAST:event_buttonCancelActionPerformed
|
||||
|
||||
private void buttonPreviewFontActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPreviewFontActionPerformed
|
||||
String selectedSystemFont = (String) fontSelection.getSelectedItem();
|
||||
new FontPreviewDialog(null, true, new Font(selectedSystemFont, fontTag.getFontStyle(), 1024)).setVisible(true);
|
||||
}//GEN-LAST:event_buttonPreviewFontActionPerformed
|
||||
|
||||
private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
|
||||
jPanel1.updateUI();
|
||||
}//GEN-LAST:event_formComponentResized
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton buttonCancel;
|
||||
private javax.swing.JButton buttonEdit;
|
||||
private javax.swing.JButton buttonPreviewFont;
|
||||
private javax.swing.JButton buttonSave;
|
||||
private javax.swing.JTextField fontAddCharactersField;
|
||||
private javax.swing.JButton fontAddCharsButton;
|
||||
private javax.swing.JLabel fontAscentLabel;
|
||||
private javax.swing.JScrollPane fontCharactersScrollPane;
|
||||
private javax.swing.JTextArea fontCharactersTextArea;
|
||||
private javax.swing.JTextArea fontCopyrightTextArea;
|
||||
private javax.swing.JLabel fontDescentLabel;
|
||||
private javax.swing.JTextArea fontDisplayNameTextArea;
|
||||
private javax.swing.JButton fontEmbedButton;
|
||||
private javax.swing.JCheckBox fontIsBoldCheckBox;
|
||||
private javax.swing.JCheckBox fontIsItalicCheckBox;
|
||||
private javax.swing.JLabel fontLeadingLabel;
|
||||
private javax.swing.JLabel fontNameLabel;
|
||||
private javax.swing.JComboBox fontSelection;
|
||||
private javax.swing.JLabel jLabel11;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JCheckBox updateTextsCheckBox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/FontPreviewDialog.properties" key="fontPreview.dialog.title" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="default"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1024, 512]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="componentMoved" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="formComponentMoved"/>
|
||||
<EventHandler event="componentResized" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="formComponentResized"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="comboBoxSampleTexts" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="labelFontName" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="519" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="comboBoxSampleTexts" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelFontName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="431" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="labelSample72" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample18" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample12" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample24" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample36" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample48" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="labelSample60" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="692" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample12" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample18" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample24" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample36" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample48" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample60" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="labelSample72" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="labelSample72">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="72" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample60">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="60" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample12">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="12" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample24">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="24" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample48">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="48" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample36">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="36" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelSample18">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="18" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="---"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="12"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="18"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="24"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="36"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="48"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="60"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel8">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="72"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JComboBox" name="comboBoxSampleTexts">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="getModel()" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="comboBoxSampleTextsItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/MainFrame.properties" key="font.name" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="labelFontName">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="-"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.configuration.Configuration;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.awt.Font;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FontPreviewDialog extends AppDialog {
|
||||
|
||||
/**
|
||||
* Creates new form FontPreviewDialog
|
||||
*
|
||||
* @param parent
|
||||
* @param font
|
||||
* @param modal
|
||||
*/
|
||||
public FontPreviewDialog(java.awt.Frame parent, boolean modal, Font font) {
|
||||
super();
|
||||
setModal(true);
|
||||
initComponents();
|
||||
View.setWindowIcon(this);
|
||||
|
||||
labelSample12.setFont(font.deriveFont(Font.PLAIN, 12));
|
||||
labelSample18.setFont(font.deriveFont(Font.PLAIN, 18));
|
||||
labelSample24.setFont(font.deriveFont(Font.PLAIN, 24));
|
||||
labelSample36.setFont(font.deriveFont(Font.PLAIN, 36));
|
||||
labelSample48.setFont(font.deriveFont(Font.PLAIN, 48));
|
||||
labelSample60.setFont(font.deriveFont(Font.PLAIN, 60));
|
||||
labelSample72.setFont(font.deriveFont(Font.PLAIN, 72));
|
||||
comboBoxSampleTexts.setSelectedIndex(Configuration.guiFontPreviewSampleText.get(0));
|
||||
if (Configuration.guiFontPreviewWidth.hasValue()) {
|
||||
int width = Configuration.guiFontPreviewWidth.get();
|
||||
int height = Configuration.guiFontPreviewHeight.get();
|
||||
setSize(width, height);
|
||||
}
|
||||
if (Configuration.guiFontPreviewPosX.hasValue()) {
|
||||
int posX = Configuration.guiFontPreviewPosX.get();
|
||||
int posY = Configuration.guiFontPreviewPosY.get();
|
||||
setLocation(posX, posY);
|
||||
}
|
||||
setText((String) comboBoxSampleTexts.getSelectedItem());
|
||||
labelFontName.setText(font.getFontName());
|
||||
}
|
||||
|
||||
private void setText(String text) {
|
||||
labelSample12.setText(text);
|
||||
labelSample18.setText(text);
|
||||
labelSample24.setText(text);
|
||||
labelSample36.setText(text);
|
||||
labelSample48.setText(text);
|
||||
labelSample60.setText(text);
|
||||
labelSample72.setText(text);
|
||||
}
|
||||
|
||||
private ComboBoxModel<String> getModel() {
|
||||
List<String> sampleTexts = new ArrayList<>();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(FontPreviewDialog.class.getResourceAsStream("/com/jpexs/decompiler/flash/tags/font/font_preview_samples.txt"), Utf8Helper.charset));
|
||||
String s;
|
||||
try {
|
||||
while ((s = br.readLine()) != null) {
|
||||
sampleTexts.add(s);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(FontPreviewDialog.class.getName()).log(Level.SEVERE, "Cannot read font preview dialog sample texts", ex);
|
||||
}
|
||||
return new DefaultComboBoxModel<>(sampleTexts.toArray(new String[sampleTexts.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
labelSample72 = new javax.swing.JLabel();
|
||||
labelSample60 = new javax.swing.JLabel();
|
||||
labelSample12 = new javax.swing.JLabel();
|
||||
labelSample24 = new javax.swing.JLabel();
|
||||
labelSample48 = new javax.swing.JLabel();
|
||||
labelSample36 = new javax.swing.JLabel();
|
||||
labelSample18 = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
jLabel5 = new javax.swing.JLabel();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
jLabel8 = new javax.swing.JLabel();
|
||||
comboBoxSampleTexts = new javax.swing.JComboBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
labelFontName = new javax.swing.JLabel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("com/jpexs/decompiler/flash/gui/locales/FontPreviewDialog"); // NOI18N
|
||||
setTitle(bundle.getString("fontPreview.dialog.title")); // NOI18N
|
||||
setPreferredSize(new java.awt.Dimension(1024, 512));
|
||||
addComponentListener(new java.awt.event.ComponentAdapter() {
|
||||
public void componentMoved(java.awt.event.ComponentEvent evt) {
|
||||
formComponentMoved(evt);
|
||||
}
|
||||
public void componentResized(java.awt.event.ComponentEvent evt) {
|
||||
formComponentResized(evt);
|
||||
}
|
||||
});
|
||||
|
||||
labelSample72.setFont(new java.awt.Font("Tahoma", 0, 72)); // NOI18N
|
||||
labelSample72.setText("---");
|
||||
|
||||
labelSample60.setFont(new java.awt.Font("Tahoma", 0, 60)); // NOI18N
|
||||
labelSample60.setText("---");
|
||||
|
||||
labelSample12.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
|
||||
labelSample12.setText("---");
|
||||
|
||||
labelSample24.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
|
||||
labelSample24.setText("---");
|
||||
|
||||
labelSample48.setFont(new java.awt.Font("Tahoma", 0, 48)); // NOI18N
|
||||
labelSample48.setText("---");
|
||||
|
||||
labelSample36.setFont(new java.awt.Font("Tahoma", 0, 36)); // NOI18N
|
||||
labelSample36.setText("---");
|
||||
|
||||
labelSample18.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
|
||||
labelSample18.setText("---");
|
||||
|
||||
jLabel2.setText("12");
|
||||
|
||||
jLabel3.setText("18");
|
||||
|
||||
jLabel4.setText("24");
|
||||
|
||||
jLabel5.setText("36");
|
||||
|
||||
jLabel6.setText("48");
|
||||
|
||||
jLabel7.setText("60");
|
||||
|
||||
jLabel8.setText("72");
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(jLabel3)
|
||||
.addComponent(jLabel4)
|
||||
.addComponent(jLabel5)
|
||||
.addComponent(jLabel6)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(jLabel8))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(labelSample72)
|
||||
.addComponent(labelSample18)
|
||||
.addComponent(labelSample12)
|
||||
.addComponent(labelSample24)
|
||||
.addComponent(labelSample36)
|
||||
.addComponent(labelSample48)
|
||||
.addComponent(labelSample60))
|
||||
.addContainerGap(692, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample12)
|
||||
.addComponent(jLabel2))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample18)
|
||||
.addComponent(jLabel3))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample24)
|
||||
.addComponent(jLabel4))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample36)
|
||||
.addComponent(jLabel5))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample48)
|
||||
.addComponent(jLabel6))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample60)
|
||||
.addComponent(jLabel7))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(labelSample72)
|
||||
.addComponent(jLabel8))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
jScrollPane1.setViewportView(jPanel1);
|
||||
|
||||
comboBoxSampleTexts.setModel(getModel());
|
||||
comboBoxSampleTexts.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
comboBoxSampleTextsItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
java.util.ResourceBundle bundle1 = java.util.ResourceBundle.getBundle("com/jpexs/decompiler/flash/gui/locales/MainFrame"); // NOI18N
|
||||
jLabel1.setText(bundle1.getString("font.name")); // NOI18N
|
||||
|
||||
labelFontName.setText("-");
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(comboBoxSampleTexts, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(labelFontName)
|
||||
.addGap(519, 519, 519)))
|
||||
.addContainerGap())
|
||||
.addComponent(jScrollPane1)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(comboBoxSampleTexts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(labelFontName))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 431, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void comboBoxSampleTextsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboBoxSampleTextsItemStateChanged
|
||||
Configuration.guiFontPreviewSampleText.set(comboBoxSampleTexts.getSelectedIndex());
|
||||
setText((String) comboBoxSampleTexts.getSelectedItem());
|
||||
}//GEN-LAST:event_comboBoxSampleTextsItemStateChanged
|
||||
|
||||
private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
|
||||
Configuration.guiFontPreviewWidth.set(getWidth());
|
||||
Configuration.guiFontPreviewHeight.set(getHeight());
|
||||
}//GEN-LAST:event_formComponentResized
|
||||
|
||||
private void formComponentMoved(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentMoved
|
||||
Configuration.guiFontPreviewPosX.set(getX());
|
||||
Configuration.guiFontPreviewPosY.set(getY());
|
||||
}//GEN-LAST:event_formComponentMoved
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JComboBox comboBoxSampleTexts;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
private javax.swing.JLabel jLabel5;
|
||||
private javax.swing.JLabel jLabel6;
|
||||
private javax.swing.JLabel jLabel7;
|
||||
private javax.swing.JLabel jLabel8;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel labelFontName;
|
||||
private javax.swing.JLabel labelSample12;
|
||||
private javax.swing.JLabel labelSample18;
|
||||
private javax.swing.JLabel labelSample24;
|
||||
private javax.swing.JLabel labelSample36;
|
||||
private javax.swing.JLabel labelSample48;
|
||||
private javax.swing.JLabel labelSample60;
|
||||
private javax.swing.JLabel labelSample72;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.ChangeListener;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.ReflectionTools;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor;
|
||||
import com.jpexs.decompiler.flash.gui.helpers.SpringUtilities;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.types.ARGB;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Calculated;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Multiline;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Optional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator;
|
||||
import com.jpexs.decompiler.flash.types.annotations.parser.ParseException;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SpringLayout;
|
||||
|
||||
/**
|
||||
* Old Generic Tag editor
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GenericTagPanel extends JPanel implements ChangeListener {
|
||||
|
||||
private final JEditorPane genericTagPropertiesEditorPane;
|
||||
private final JPanel genericTagPropertiesEditPanel;
|
||||
private final JScrollPane genericTagPropertiesEditorPaneScrollPanel;
|
||||
private final JScrollPane genericTagPropertiesEditPanelScrollPanel;
|
||||
private Tag tag;
|
||||
private Tag editedTag;
|
||||
|
||||
private List<String> keys = new ArrayList<>();
|
||||
private Map<String, GenericTagEditor> editors = new HashMap<>();
|
||||
private Map<String, Component> labels = new HashMap<>();
|
||||
private Map<String, Component> types = new HashMap<>();
|
||||
private Map<String, List<Field>> fieldPaths = new HashMap<>();
|
||||
private Map<String, List<Integer>> fieldIndices = new HashMap<>();
|
||||
private HeaderLabel hdr;
|
||||
private Set<String> addKeys = new HashSet<>();
|
||||
private Map<String, Component> addButtons = new HashMap<>();
|
||||
private Map<String, Component> removeButtons = new HashMap<>();
|
||||
|
||||
public GenericTagPanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
hdr = new HeaderLabel("");
|
||||
add(hdr, BorderLayout.NORTH);
|
||||
genericTagPropertiesEditorPane = new JEditorPane() {
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
genericTagPropertiesEditorPane.setEditable(false);
|
||||
genericTagPropertiesEditorPaneScrollPanel = new JScrollPane(genericTagPropertiesEditorPane);
|
||||
add(genericTagPropertiesEditorPaneScrollPanel, BorderLayout.CENTER);
|
||||
|
||||
genericTagPropertiesEditPanel = new JPanel();
|
||||
genericTagPropertiesEditPanel.setLayout(new SpringLayout());
|
||||
JPanel edPanel = new JPanel(new BorderLayout());
|
||||
edPanel.add(genericTagPropertiesEditPanel, BorderLayout.NORTH);
|
||||
genericTagPropertiesEditPanelScrollPanel = new JScrollPane(edPanel);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
editors.clear();
|
||||
fieldPaths.clear();
|
||||
fieldIndices.clear();
|
||||
labels.clear();
|
||||
types.clear();
|
||||
keys.clear();
|
||||
addKeys.clear();
|
||||
addButtons.clear();
|
||||
removeButtons.clear();
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
}
|
||||
|
||||
public void setEditMode(boolean edit, Tag tag) {
|
||||
if (tag == null) {
|
||||
tag = this.tag;
|
||||
}
|
||||
|
||||
this.tag = tag;
|
||||
this.editedTag = Helper.deepCopy(tag);
|
||||
generateEditControls(editedTag, !edit);
|
||||
|
||||
if (edit) {
|
||||
remove(genericTagPropertiesEditorPaneScrollPanel);
|
||||
add(genericTagPropertiesEditPanelScrollPanel, BorderLayout.CENTER);
|
||||
} else {
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
remove(genericTagPropertiesEditPanelScrollPanel);
|
||||
add(genericTagPropertiesEditorPaneScrollPanel, BorderLayout.CENTER);
|
||||
setTagText(this.tag);
|
||||
}
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void setTagText(Tag tag) {
|
||||
clear();
|
||||
generateEditControls(tag, true);
|
||||
String val = "";
|
||||
for (String key : keys) {
|
||||
GenericTagEditor ed = editors.get(key);
|
||||
if (((Component) ed).isVisible()) {
|
||||
val += key + " : " + ed.getReadOnlyValue() + "<br>";
|
||||
}
|
||||
}
|
||||
//HTML for colors:
|
||||
val = "<html>" + val + "</html>";
|
||||
genericTagPropertiesEditorPane.setContentType("text/html");
|
||||
genericTagPropertiesEditorPane.setText(val);
|
||||
genericTagPropertiesEditorPane.setCaretPosition(0);
|
||||
hdr.setText(tag.toString());
|
||||
}
|
||||
|
||||
private void generateEditControls(Tag tag, boolean readonly) {
|
||||
clear();
|
||||
generateEditControlsRecursive(tag, "", new ArrayList<Field>(), new ArrayList<Integer>(), readonly);
|
||||
change(null);
|
||||
}
|
||||
|
||||
private void relayout(int propCount) {
|
||||
//Lay out the panel.
|
||||
SpringUtilities.makeCompactGrid(genericTagPropertiesEditPanel,
|
||||
propCount, 3, //rows, cols
|
||||
6, 6, //initX, initY
|
||||
6, 6); //xPad, yPad
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private int generateEditControlsRecursive(final Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
int propCount = 0;
|
||||
for (final Field field : fields) {
|
||||
try {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
String name = parent + field.getName();
|
||||
final Object value = field.get(obj);
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
if (value != null) {
|
||||
int i = 0;
|
||||
for (Object obj1 : (Iterable) value) {
|
||||
final String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, obj1.getClass(), obj1, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
i++;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else if (field.getType().isArray()) {
|
||||
if (value != null) {
|
||||
for (int i = 0; i < Array.getLength(value); i++) {
|
||||
Object item = Array.get(value, i);
|
||||
String subname = name + "[" + i + "]";
|
||||
propCount += addEditor(subname, obj, field, i, item.getClass(), item, parentFields, parentIndices, readonly);
|
||||
final int fi = i;
|
||||
JButton removeButton = new JButton(View.getIcon("close16"));
|
||||
removeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(obj, field, fi);
|
||||
}
|
||||
});
|
||||
removeButtons.put(subname, removeButton);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields, parentIndices, readonly);
|
||||
}
|
||||
if (ReflectionTools.needsIndex(field) && !readonly && !field.getName().equals("clipActionRecords")) { //No clip actions, sorry
|
||||
JButton addButton = new JButton(View.getIcon("add16"));
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(obj, field);
|
||||
}
|
||||
});
|
||||
name += "[]";
|
||||
|
||||
List<Field> parList = new ArrayList<>(parentFields);
|
||||
parList.add(field);
|
||||
fieldPaths.put(name, parList);
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(0);
|
||||
fieldIndices.put(name, parIndices);
|
||||
|
||||
addRow(name, addButton, field);
|
||||
addKeys.add(name);
|
||||
addButtons.put(name, addButton);
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
return propCount;
|
||||
}
|
||||
|
||||
private void removeItem(Object obj, Field field, int index) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().isEmpty()) { //Fields with same countField must be removed from too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.removeFromField(obj, fields[f], index);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, decrement, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
if (countField != null) {
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt--;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.removeFromField(obj, field, index);
|
||||
}
|
||||
|
||||
generateEditControls(editedTag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void addItem(Object obj, Field field) {
|
||||
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
|
||||
final int val = sb.getValue(); //save scroll top
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
if (swfType != null && !swfType.countField().isEmpty()) { //Fields with same countField must be enlarged too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
|
||||
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
|
||||
ReflectionTools.addToField(obj, fields[f], ReflectionTools.getFieldSubSize(obj, fields[f]), true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, increment, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfType.countField());
|
||||
if (countField != null) {
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt++;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.addToField(obj, field, ReflectionTools.getFieldSubSize(obj, field), true);
|
||||
}
|
||||
generateEditControls(editedTag, false);
|
||||
|
||||
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}.start();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList, List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
|
||||
Calculated calculated = field.getAnnotation(Calculated.class);
|
||||
if (calculated != null) {
|
||||
return 0;
|
||||
}
|
||||
List<Field> parList = new ArrayList<>(parentList);
|
||||
parList.add(field);
|
||||
|
||||
List<Integer> parIndices = new ArrayList<>(parentIndices);
|
||||
parIndices.add(index);
|
||||
Internal inter = field.getAnnotation(Internal.class);
|
||||
if (inter != null) {
|
||||
return 0;
|
||||
}
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
Multiline multiline = field.getAnnotation(Multiline.class);
|
||||
Component editor;
|
||||
if (type.equals(int.class) || type.equals(Integer.class)
|
||||
|| type.equals(short.class) || type.equals(Short.class)
|
||||
|| type.equals(long.class) || type.equals(Long.class)
|
||||
|| type.equals(double.class) || type.equals(Double.class)
|
||||
|| type.equals(float.class) || type.equals(Float.class)) {
|
||||
editor = new NumberEditor(name, obj, field, index, type, swfType);
|
||||
} else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
|
||||
editor = new BooleanEditor(name, obj, field, index, type);
|
||||
} else if (type.equals(String.class)) {
|
||||
editor = new StringEditor(name, obj, field, index, type, multiline != null);
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
|
||||
editor = new ColorEditor(name, obj, field, index, type);
|
||||
} else {
|
||||
if (value == null) {
|
||||
if (readonly) {
|
||||
return 0;
|
||||
}
|
||||
Optional opt = field.getAnnotation(Optional.class);
|
||||
if (opt == null) {
|
||||
try {
|
||||
value = ReflectionTools.newInstanceOf(field.getType());
|
||||
field.set(obj, value);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return generateEditControlsRecursive(value, name + ".", parList, parIndices, readonly);
|
||||
}
|
||||
if (editor instanceof GenericTagEditor) {
|
||||
GenericTagEditor ce = (GenericTagEditor) editor;
|
||||
ce.addChangeListener(this);
|
||||
editors.put(name, ce);
|
||||
fieldPaths.put(name, parList);
|
||||
fieldIndices.put(name, parIndices);
|
||||
addRow(name, editor, field);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void addRow(String name, Component editor, Field field) {
|
||||
JLabel label = new JLabel(name + ":", JLabel.TRAILING);
|
||||
label.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(label);
|
||||
label.setLabelFor(editor);
|
||||
labels.put(name, label);
|
||||
genericTagPropertiesEditPanel.add(editor);
|
||||
JLabel typeLabel = new JLabel(swfTypeToString(field.getAnnotation(SWFType.class)), JLabel.TRAILING);
|
||||
typeLabel.setVerticalAlignment(JLabel.TOP);
|
||||
genericTagPropertiesEditPanel.add(typeLabel);
|
||||
types.put(name, typeLabel);
|
||||
keys.add(name);
|
||||
}
|
||||
|
||||
public String swfTypeToString(SWFType swfType) {
|
||||
if (swfType == null) {
|
||||
return null;
|
||||
}
|
||||
String result = swfType.value().toString();
|
||||
if (swfType.count() > 0) {
|
||||
result += "[" + swfType.count();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
} else if (!swfType.countField().isEmpty()) {
|
||||
result += "[" + swfType.countField();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void assignTag(Tag t, Tag assigned) {
|
||||
if (t.getClass() != assigned.getClass()) {
|
||||
return;
|
||||
}
|
||||
for (Field f : t.getClass().getDeclaredFields()) {
|
||||
if ((f.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
|
||||
continue;
|
||||
}
|
||||
if ((f.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
f.set(t, f.get(assigned));
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
for (Object component : genericTagPropertiesEditPanel.getComponents()) {
|
||||
if (component instanceof GenericTagEditor) {
|
||||
((GenericTagEditor) component).save();
|
||||
}
|
||||
}
|
||||
SWF swf = tag.getSwf();
|
||||
assignTag(tag, editedTag);
|
||||
tag.setModified(true);
|
||||
tag.setSwf(swf);
|
||||
setTagText(tag);
|
||||
}
|
||||
|
||||
public Tag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void change(GenericTagEditor ed) {
|
||||
for (String key : editors.keySet()) {
|
||||
GenericTagEditor dependentEditor = editors.get(key);
|
||||
Component dependentLabel = labels.get(key);
|
||||
Component dependentTypeLabel = types.get(key);
|
||||
List<Field> path = fieldPaths.get(key);
|
||||
List<Integer> indices = fieldIndices.get(key);
|
||||
String p = "";
|
||||
boolean conditionMet = true;
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
Field f = path.get(i);
|
||||
int index = indices.get(i);
|
||||
String par = p;
|
||||
if (!p.isEmpty()) {
|
||||
p += ".";
|
||||
}
|
||||
p += f.getName();
|
||||
if (ReflectionTools.needsIndex(f)) {
|
||||
p += "[" + index + "]";
|
||||
}
|
||||
Conditional cond = f.getAnnotation(Conditional.class);
|
||||
if (cond != null) {
|
||||
ConditionEvaluator ev = new ConditionEvaluator(cond);
|
||||
|
||||
try {
|
||||
Set<String> fieldNames = ev.getFields();
|
||||
Map<String, Boolean> fields = new HashMap<>();
|
||||
for (String fld : fieldNames) {
|
||||
String ckey = "";
|
||||
if (!par.isEmpty()) {
|
||||
ckey = par + ".";
|
||||
}
|
||||
ckey += fld;
|
||||
if (editors.containsKey(ckey)) {
|
||||
GenericTagEditor editor = editors.get(ckey);
|
||||
Object val = editor.getChangedValue();
|
||||
fields.put(fld, true);
|
||||
if (val instanceof Boolean) {
|
||||
fields.put(fld, (Boolean) val);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean ok = ev.eval(fields);
|
||||
if (conditionMet) {
|
||||
conditionMet = ok;
|
||||
}
|
||||
((Component) dependentEditor).setVisible(conditionMet);
|
||||
dependentLabel.setVisible(conditionMet);
|
||||
dependentTypeLabel.setVisible(conditionMet);
|
||||
} catch (ParseException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, "Invalid condition", ex);
|
||||
}
|
||||
}
|
||||
if (!conditionMet) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
genericTagPropertiesEditPanel.removeAll();
|
||||
genericTagPropertiesEditPanel.setSize(0, 0);
|
||||
int propCount = 0;
|
||||
for (String key : keys) {
|
||||
|
||||
Component dependentEditor = null;
|
||||
if (addKeys.contains(key)) {
|
||||
dependentEditor = addButtons.get(key);
|
||||
} else if (removeButtons.containsKey(key)) { //It's array/list, add remove button
|
||||
JPanel editRemPanel = new JPanel(new BorderLayout());
|
||||
editRemPanel.add((Component) editors.get(key), BorderLayout.CENTER);
|
||||
editRemPanel.add(removeButtons.get(key), BorderLayout.EAST);
|
||||
dependentEditor = editRemPanel;
|
||||
} else {
|
||||
dependentEditor = (Component) editors.get(key);
|
||||
}
|
||||
Component dependentLabel = labels.get(key);
|
||||
Component dependentTypeLabel = types.get(key);
|
||||
if (dependentEditor.isVisible()) {
|
||||
genericTagPropertiesEditPanel.add(dependentLabel);
|
||||
genericTagPropertiesEditPanel.add(((Component) dependentEditor));
|
||||
genericTagPropertiesEditPanel.add(dependentTypeLabel);
|
||||
propCount++;
|
||||
}
|
||||
}
|
||||
/*genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());
|
||||
genericTagPropertiesEditPanel.add(new JPanel());*/
|
||||
relayout(propCount /*+ 1*/);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,896 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.GenericTagEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.ReflectionTools;
|
||||
import com.jpexs.decompiler.flash.gui.generictageditors.StringEditor;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.types.ARGB;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Multiline;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator;
|
||||
import com.jpexs.decompiler.flash.types.annotations.parser.ParseException;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventObject;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.AbstractCellEditor;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeCellEditor;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GenericTagTreePanel extends GenericTagPanel {
|
||||
|
||||
private JTree tree;
|
||||
private Tag editedTag;
|
||||
|
||||
private class MyTree extends JTree {
|
||||
|
||||
public MyTree() {
|
||||
setBackground(Color.white);
|
||||
setUI(new BasicTreeUI() {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
setHashColor(Color.gray);
|
||||
super.paint(g, c);
|
||||
}
|
||||
|
||||
});
|
||||
setCellRenderer(new MyTreeCellRenderer());
|
||||
setCellEditor(new MyTreeCellEditor(this));
|
||||
setInvokesStopCellEditing(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor {
|
||||
|
||||
private GenericTagEditor editor = null;
|
||||
private final JTree tree;
|
||||
private FieldNode fnode;
|
||||
|
||||
public MyTreeCellEditor(JTree tree) {
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
|
||||
if (value instanceof FieldNode) {
|
||||
fnode = (FieldNode) value;
|
||||
Field field = fnode.field;
|
||||
int index = fnode.index;
|
||||
Object obj = fnode.obj;
|
||||
Class<?> type;
|
||||
try {
|
||||
type = ReflectionTools.getValue(obj, field, index).getClass();
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
Multiline multiline = field.getAnnotation(Multiline.class);
|
||||
if (type.equals(int.class) || type.equals(Integer.class)
|
||||
|| type.equals(short.class) || type.equals(Short.class)
|
||||
|| type.equals(long.class) || type.equals(Long.class)
|
||||
|| type.equals(double.class) || type.equals(Double.class)
|
||||
|| type.equals(float.class) || type.equals(Float.class)) {
|
||||
editor = new NumberEditor(field.getName(), obj, field, index, type, swfType);
|
||||
} else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
|
||||
editor = new BooleanEditor(field.getName(), obj, field, index, type);
|
||||
} else if (type.equals(String.class)) {
|
||||
editor = new StringEditor(field.getName(), obj, field, index, type, multiline != null);
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
|
||||
editor = new ColorEditor(field.getName(), obj, field, index, type);
|
||||
}
|
||||
JPanel pan = new JPanel();
|
||||
FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 0, 0);
|
||||
fl.setAlignOnBaseline(true);
|
||||
pan.setLayout(fl);
|
||||
JLabel nameLabel = new JLabel(fnode.getNameType() + " = ") {
|
||||
|
||||
@Override
|
||||
public BaselineResizeBehavior getBaselineResizeBehavior() {
|
||||
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseline(int width, int height) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
pan.setBackground(Color.white);
|
||||
nameLabel.setSize(nameLabel.getWidth(), ((Component) editor).getHeight());
|
||||
nameLabel.setAlignmentY(TOP_ALIGNMENT);
|
||||
((JComponent) editor).setAlignmentY(TOP_ALIGNMENT);
|
||||
pan.add(nameLabel);
|
||||
pan.add((Component) editor);
|
||||
pan.setPreferredSize(new Dimension((int) nameLabel.getPreferredSize().getWidth() + 5 + (int) ((Component) editor).getPreferredSize().getWidth(), (int) ((Component) editor).getPreferredSize().getHeight()));
|
||||
return pan;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCellEditorValue() {
|
||||
return editor.getChangedValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(EventObject e) {
|
||||
if (!(e instanceof MouseEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MouseEvent me = (MouseEvent) e;
|
||||
TreePath path = tree.getPathForLocation(me.getX(), me.getY());
|
||||
|
||||
if (path == null) {
|
||||
return false;
|
||||
}
|
||||
Object obj = path.getLastPathComponent();
|
||||
|
||||
boolean ret = super.isCellEditable(e)
|
||||
&& path != null && (tree.getModel().isLeaf(obj));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopCellEditing() {
|
||||
super.stopCellEditing();
|
||||
|
||||
/*List<FieldNode> depends = ((MyTreeModel) tree.getModel()).getDependentFields(fnode);
|
||||
boolean dep = false;
|
||||
if (!depends.isEmpty()) {
|
||||
dep = true;
|
||||
} */
|
||||
editor.save();
|
||||
((MyTreeModel) tree.getModel()).vchanged(tree.getSelectionPath());
|
||||
refreshTree();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public GenericTagTreePanel() {
|
||||
setLayout(new BorderLayout());
|
||||
tree = new MyTree();
|
||||
|
||||
add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
tree.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (!tree.isEditable()) {
|
||||
return;
|
||||
}
|
||||
int selRow = tree.getRowForLocation(e.getX(), e.getY());
|
||||
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
|
||||
if (selRow != -1 && selPath != null) {
|
||||
if (e.getClickCount() == 1) {
|
||||
if (e.getButton() == MouseEvent.BUTTON3) { //right click
|
||||
Object selObject = selPath.getLastPathComponent();
|
||||
if (selObject instanceof FieldNode) {
|
||||
final FieldNode fnode = (FieldNode) selObject;
|
||||
SWFArray swfArray = fnode.field.getAnnotation(SWFArray.class);
|
||||
String itemStr = "";
|
||||
if (swfArray != null) {
|
||||
itemStr = swfArray.value();
|
||||
}
|
||||
if (itemStr.isEmpty()) {
|
||||
itemStr = AppStrings.translate("generictag.array.item");
|
||||
}
|
||||
if (ReflectionTools.needsIndex(fnode.field)) {
|
||||
|
||||
boolean canAdd = true;
|
||||
if (!ReflectionTools.canAddToField(fnode.obj, fnode.field)) {
|
||||
canAdd = false;
|
||||
}
|
||||
JPopupMenu p = new JPopupMenu();
|
||||
JMenuItem mi;
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.insertbeginning").replace("%item%", itemStr));
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(fnode.obj, fnode.field, 0);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
|
||||
if (fnode.index > -1) {
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.insertbefore").replace("%item%", itemStr));
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(fnode.obj, fnode.field, fnode.index);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.remove").replace("%item%", itemStr));
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeItem(fnode.obj, fnode.field, fnode.index);
|
||||
}
|
||||
});
|
||||
p.add(mi);
|
||||
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.insertafter").replace("%item%", itemStr));
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(fnode.obj, fnode.field, fnode.index + 1);
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
}
|
||||
|
||||
mi = new JMenuItem(AppStrings.translate("generictag.array.insertend").replace("%item%", itemStr));
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addItem(fnode.obj, fnode.field, ReflectionTools.getFieldSubSize(fnode.obj, fnode.field));
|
||||
}
|
||||
});
|
||||
if (!canAdd) {
|
||||
mi.setEnabled(false);
|
||||
}
|
||||
p.add(mi);
|
||||
//}
|
||||
p.show(tree, e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (e.getClickCount() == 2) {
|
||||
//myDoubleClick(selRow, selPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Tag tag;
|
||||
|
||||
public class MyTreeCellRenderer extends 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);
|
||||
|
||||
setUI(new BasicLabelUI());
|
||||
setOpaque(false);
|
||||
setBackgroundNonSelectionColor(Color.white);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
private static class FieldNode extends DefaultMutableTreeNode {
|
||||
|
||||
private Object obj;
|
||||
private Field field;
|
||||
private int index;
|
||||
|
||||
public FieldNode(Object obj, Field field, int index) {
|
||||
this.obj = obj;
|
||||
this.field = field;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserObject(Object userObject) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
String valStr = "";
|
||||
if (ReflectionTools.needsIndex(field) && (index == -1)) {
|
||||
valStr += "";
|
||||
} else if (hasEditor(obj, field, index)) {
|
||||
Object val = getValue();
|
||||
Color color = null;
|
||||
String colorAdd = "";
|
||||
if (val instanceof RGB) { //Note: Can be RGBA too
|
||||
color = ((RGB) val).toColor();
|
||||
}
|
||||
if (val instanceof ARGB) {
|
||||
color = ((ARGB) val).toColor();
|
||||
}
|
||||
|
||||
if (color != null) {
|
||||
colorAdd = "<cite style=\"color:rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");\">●</cite> ";
|
||||
}
|
||||
|
||||
valStr += " = " + colorAdd + val.toString();
|
||||
}
|
||||
return "<html>" + getNameType() + valStr + "</html>";
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
String typeStr = null;
|
||||
if ((swfType != null || swfArray != null) && !(ReflectionTools.needsIndex(field) && (index > -1))) {
|
||||
Class<?> type = field.getType();
|
||||
if (ReflectionTools.needsIndex(field)) {
|
||||
type = ReflectionTools.getFieldSubType(obj, field);
|
||||
}
|
||||
typeStr = swfTypeToString(type, swfType, swfArray);
|
||||
}
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
public String getNameType() {
|
||||
String typeStr = getType();
|
||||
return getName() + (typeStr != null ? " : " + typeStr : "");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
String name = "";
|
||||
if (swfArray != null) {
|
||||
name = swfArray.value();
|
||||
}
|
||||
return (index > -1 ? name + "[" + index + "]" : field.getName());
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
try {
|
||||
if (ReflectionTools.needsIndex(field) && (index == -1)) {
|
||||
return obj;
|
||||
}
|
||||
Object val = ReflectionTools.getValue(obj, field, index);
|
||||
if (val == null) {
|
||||
try {
|
||||
val = ReflectionTools.newInstanceOf(field.getType());
|
||||
ReflectionTools.setValue(obj, field, index, val);
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 11 * hash + Objects.hashCode(this.obj);
|
||||
hash = 11 * hash + Objects.hashCode(this.field);
|
||||
hash = 11 * hash + this.index;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FieldNode other = (FieldNode) obj;
|
||||
if (!Objects.equals(this.obj, other.obj)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.field, other.field)) {
|
||||
return false;
|
||||
}
|
||||
if (this.index != other.index) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyTreeModel extends DefaultTreeModel {
|
||||
|
||||
private final Object mtroot;
|
||||
private final List<TreeModelListener> listeners = new ArrayList<>();
|
||||
private final Map<String, Object> nodeCache = new HashMap<>();
|
||||
// it is much faster to store the reverse mappings, too
|
||||
private final Map<Object, String> nodeCacheReverse = new HashMap<>();
|
||||
|
||||
private Object getNodeByPath(String path) {
|
||||
|
||||
if (nodeCache.containsKey(path)) {
|
||||
return nodeCache.get(path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getNodePathName(Object find) {
|
||||
|
||||
if (nodeCacheReverse.containsKey(find)) {
|
||||
return nodeCacheReverse.get(find);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<FieldNode> getDependentFields(FieldNode fnode) {
|
||||
List<FieldNode> ret = new ArrayList<>();
|
||||
getDependentFields(getNodePathName(fnode), mtroot.getClass().getSimpleName(), mtroot, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void getDependentFields(String dependence, String currentPath, Object node, List<FieldNode> ret) {
|
||||
if (node instanceof FieldNode) {
|
||||
FieldNode fnode = (FieldNode) node;
|
||||
Conditional cond = fnode.field.getAnnotation(Conditional.class);
|
||||
if (cond != null) {
|
||||
ConditionEvaluator ev = new ConditionEvaluator(cond);
|
||||
String parentPath = currentPath.indexOf('.') == -1 ? "" : currentPath.substring(0, currentPath.lastIndexOf('.'));
|
||||
try {
|
||||
for (String cname : ev.getFields()) {
|
||||
String fullParh = parentPath + "." + cname;
|
||||
if (fullParh.equals(dependence)) {
|
||||
ret.add(fnode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (ParseException ex) {
|
||||
Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
int count = getChildCount(node);
|
||||
for (int i = 0; i < count; i++) {
|
||||
FieldNode f = (FieldNode) getChild(node, i);
|
||||
getDependentFields(dependence, currentPath + "." + f.getName(), f, ret);
|
||||
}
|
||||
}
|
||||
|
||||
public MyTreeModel(Tag root) {
|
||||
super(new DefaultMutableTreeNode(root));
|
||||
this.mtroot = root;
|
||||
buildCache(root, "");
|
||||
}
|
||||
|
||||
private void buildCache(Object obj, String parentPath) {
|
||||
if (!"".equals(parentPath)) {
|
||||
parentPath += ".";
|
||||
}
|
||||
if (obj instanceof FieldNode) {
|
||||
FieldNode fn = (FieldNode) obj;
|
||||
parentPath += fn.getName();
|
||||
} else {
|
||||
parentPath += obj.getClass().getSimpleName();
|
||||
}
|
||||
nodeCache.put(parentPath, obj);
|
||||
nodeCacheReverse.put(obj, parentPath);
|
||||
int count = getChildCount(obj, false);
|
||||
for (int i = 0; i < count; i++) {
|
||||
buildCache(getChild(obj, i, false), parentPath);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return mtroot;
|
||||
}
|
||||
|
||||
private Object getChild(Object parent, int index, boolean limited) {
|
||||
if (parent == mtroot) {
|
||||
return new FieldNode(mtroot, filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).get(index), -1);
|
||||
}
|
||||
FieldNode fnode = (FieldNode) parent;
|
||||
Field field = fnode.field;
|
||||
if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays ot Lists
|
||||
return new FieldNode(fnode.obj, field, index);
|
||||
}
|
||||
parent = fnode.getValue();
|
||||
return new FieldNode(parent, filterFields(this, getNodePathName(fnode), parent.getClass(), limited).get(index), -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
return getChild(parent, index, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
return getChildCount(parent, true);
|
||||
}
|
||||
|
||||
private int getChildCount(Object parent, boolean limited) {
|
||||
if (parent == mtroot) {
|
||||
return filterFields(this, mtroot.getClass().getSimpleName(), mtroot.getClass(), limited).size();
|
||||
}
|
||||
FieldNode fnode = (FieldNode) parent;
|
||||
if (isLeaf(fnode)) {
|
||||
return 0;
|
||||
}
|
||||
Field field = fnode.field;
|
||||
if (ReflectionTools.needsIndex(field) && (fnode.index == -1)) { //Arrays or Lists
|
||||
try {
|
||||
if (field.get(fnode.obj) == null) {
|
||||
// todo: instanciate the (Array)List or Array to allow adding items to it
|
||||
return 0;
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ReflectionTools.getFieldSubSize(fnode.obj, field);
|
||||
}
|
||||
parent = fnode.getValue();
|
||||
|
||||
return filterFields(this, getNodePathName(fnode), parent.getClass(), limited).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
if (node == mtroot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldNode fnode = (FieldNode) node;
|
||||
Field field = fnode.field;
|
||||
if (ReflectionTools.needsIndex(field) && fnode.index == -1) {
|
||||
return false;
|
||||
}
|
||||
boolean r = hasEditor(fnode.obj, field, fnode.index);
|
||||
return r;
|
||||
}
|
||||
|
||||
public void vchanged(TreePath path) {
|
||||
fireTreeNodesChanged(this, path.getPath(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
int cnt = getChildCount(parent);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (getChild(parent, i).equals(child)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private TreeModel getModel() {
|
||||
return new MyTreeModel(editedTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditMode(boolean edit, Tag tag) {
|
||||
if (tag == null) {
|
||||
tag = this.tag;
|
||||
}
|
||||
this.tag = tag;
|
||||
SWF swf = tag.getSwf();
|
||||
try {
|
||||
this.editedTag = SWFInputStream.resolveTag(swf, tag, 0, false, true, swf.gfx);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
tree.setEditable(edit);
|
||||
if (!edit) {
|
||||
tree.stopEditing();
|
||||
}
|
||||
refreshTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
tree.stopEditing();
|
||||
SWF swf = tag.getSwf();
|
||||
assignTag(tag, editedTag);
|
||||
tag.setModified(true);
|
||||
tag.setSwf(swf);
|
||||
}
|
||||
|
||||
private void assignTag(Tag t, Tag assigned) {
|
||||
if (t.getClass() != assigned.getClass()) {
|
||||
return;
|
||||
}
|
||||
for (Field f : getAvailableFields(t.getClass())) {
|
||||
try {
|
||||
f.set(t, f.get(assigned));
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static String swfArrayToString(SWFArray swfArray) {
|
||||
String result = "";
|
||||
if (swfArray == null) {
|
||||
return result;
|
||||
}
|
||||
if (swfArray.count() > 0) {
|
||||
result += "[" + swfArray.count() + "]";
|
||||
} else if (!swfArray.countField().isEmpty()) {
|
||||
result += "[" + swfArray.countField() + "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String swfTypeToString(Class<?> type, SWFType swfType, SWFArray swfArray) {
|
||||
String stype = type.getSimpleName();
|
||||
if (swfType == null) {
|
||||
return stype + swfArrayToString(swfArray);
|
||||
}
|
||||
String result = swfType.value().toString();
|
||||
if (swfType.value() == BasicType.OTHER) {
|
||||
result = stype;
|
||||
}
|
||||
if (swfType.count() > 0) {
|
||||
result += "[" + swfType.count();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
} else if (!swfType.countField().isEmpty()) {
|
||||
result += "[" + swfType.countField();
|
||||
if (swfType.countAdd() > 0) {
|
||||
result += " + " + swfType.countAdd();
|
||||
}
|
||||
result += "]";
|
||||
}
|
||||
return result + swfArrayToString(swfArray);
|
||||
}
|
||||
|
||||
private static boolean hasEditor(Object obj, Field field, int index) {
|
||||
if (ReflectionTools.needsIndex(field) && index == -1) {
|
||||
return false;
|
||||
}
|
||||
Class<?> type;
|
||||
try {
|
||||
Object val = ReflectionTools.getValue(obj, field, index);
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
type = val.getClass();
|
||||
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
||||
return false;
|
||||
}
|
||||
SWFType swfType = field.getAnnotation(SWFType.class);
|
||||
Multiline multiline = field.getAnnotation(Multiline.class);
|
||||
|
||||
if (type.equals(int.class) || type.equals(Integer.class)
|
||||
|| type.equals(short.class) || type.equals(Short.class)
|
||||
|| type.equals(long.class) || type.equals(Long.class)
|
||||
|| type.equals(double.class) || type.equals(Double.class)
|
||||
|| type.equals(float.class) || type.equals(Float.class)) {
|
||||
return true;
|
||||
} else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
|
||||
return true;
|
||||
} else if (type.equals(String.class)) {
|
||||
return true;
|
||||
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Field> filterFields(MyTreeModel mod, String parentPath, Class<?> cls, boolean limited) {
|
||||
List<Field> ret = new ArrayList<>();
|
||||
List<Field> fields = getAvailableFields(cls);
|
||||
for (Field f : fields) {
|
||||
if (limited) {
|
||||
Conditional cond = f.getAnnotation(Conditional.class);
|
||||
if (cond != null) {
|
||||
ConditionEvaluator ev = new ConditionEvaluator(cond);
|
||||
try {
|
||||
Map<String, Boolean> fieldMap = new HashMap<>();
|
||||
for (String sf : ev.getFields()) {
|
||||
String fulldf = parentPath + "." + sf;
|
||||
FieldNode condnode = (FieldNode) (mod).getNodeByPath(fulldf);
|
||||
|
||||
if (condnode != null) {
|
||||
fieldMap.put(sf, (Boolean) ReflectionTools.getValue(condnode.obj, condnode.field, condnode.index));
|
||||
} else {
|
||||
fieldMap.put(sf, true);
|
||||
}
|
||||
}
|
||||
if (!ev.eval(fieldMap)) {
|
||||
continue;
|
||||
}
|
||||
} catch (ParseException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(GenericTagTreePanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static List<Field> getAvailableFields(Class<?> cls) {
|
||||
List<Field> ret = new ArrayList<>();
|
||||
Field fields[] = cls.getFields();
|
||||
for (Field f : fields) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
f.setAccessible(true);
|
||||
Internal inter = f.getAnnotation(Internal.class);
|
||||
if (inter != null) {
|
||||
continue;
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void addItem(Object obj, Field field, int index) {
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be enlarged too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
List<Integer> sameFlds = new ArrayList<>();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class);
|
||||
if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) {
|
||||
sameFlds.add(f);
|
||||
if (!ReflectionTools.canAddToField(obj, fields[f])) {
|
||||
JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!!
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (int f : sameFlds) {
|
||||
ReflectionTools.addToField(obj, fields[f], index, true);
|
||||
}
|
||||
try {
|
||||
//If countField exists, increment, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfArray.countField());
|
||||
if (countField != null) {
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt++;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
if (!ReflectionTools.canAddToField(obj, field)) {
|
||||
JOptionPane.showMessageDialog(this, "This field is abstract, cannot be instantiated, sorry."); //TODO!!!
|
||||
return;
|
||||
}
|
||||
ReflectionTools.addToField(obj, field, index, true);
|
||||
}
|
||||
refreshTree();
|
||||
}
|
||||
|
||||
public void refreshTree() {
|
||||
View.refreshTree(tree, getModel());
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void removeItem(Object obj, Field field, int index) {
|
||||
SWFArray swfArray = field.getAnnotation(SWFArray.class);
|
||||
if (swfArray != null && !swfArray.countField().isEmpty()) { //Fields with same countField must be removed from too
|
||||
Field fields[] = obj.getClass().getDeclaredFields();
|
||||
for (int f = 0; f < fields.length; f++) {
|
||||
SWFArray fieldSwfArray = fields[f].getAnnotation(SWFArray.class);
|
||||
if (fieldSwfArray != null && fieldSwfArray.countField().equals(swfArray.countField())) {
|
||||
ReflectionTools.removeFromField(obj, fields[f], index);
|
||||
}
|
||||
}
|
||||
try {
|
||||
//If countField exists, decrement, otherwise do nothing
|
||||
Field countField = obj.getClass().getDeclaredField(swfArray.countField());
|
||||
if (countField != null) {
|
||||
int cnt = countField.getInt(obj);
|
||||
cnt--;
|
||||
countField.setInt(obj, cnt);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
//ignored
|
||||
}
|
||||
} else {
|
||||
ReflectionTools.removeFromField(obj, field, index);
|
||||
}
|
||||
|
||||
refreshTree();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GraphFrame extends AppFrame {
|
||||
|
||||
private class GraphPanel extends JPanel {
|
||||
|
||||
private static final int SPACE_VERTICAL = 16;
|
||||
private static final int SPACE_HORIZONTAL = 10;
|
||||
private static final int SPACE_BACKLINKS = 5;
|
||||
private static final int BLOCK_WIDTH = 200;
|
||||
private static final int BLOCK_HEIGHT = 20;
|
||||
private final HashMap<GraphPart, Point> partPos = new HashMap<>();
|
||||
private final Point size;
|
||||
private int backLinksLeft = 0;
|
||||
private int backLinksRight = 0;
|
||||
private final GraphPart head;
|
||||
|
||||
public GraphPanel(Graph graph) throws InterruptedException {
|
||||
graph.init(null);
|
||||
size = getPartPositions(head = graph.heads.get(0), SPACE_VERTICAL + SPACE_VERTICAL + BLOCK_HEIGHT / 2, getPartWidth(graph.heads.get(0), new HashSet<GraphPart>()) * (BLOCK_WIDTH + SPACE_HORIZONTAL) / 2 - SPACE_HORIZONTAL, partPos, true);
|
||||
backLinksLeft = 1;
|
||||
backLinksRight = 1;
|
||||
for (GraphPart part : partPos.keySet()) {
|
||||
Point p = partPos.get(part);
|
||||
for (GraphPart n : part.nextParts) {
|
||||
Point npos = partPos.get(n);
|
||||
if (npos.y < p.y) {
|
||||
if (p.x > size.x / 2) {
|
||||
backLinksRight++;
|
||||
} else {
|
||||
backLinksLeft++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
size.x += 2 * SPACE_BACKLINKS + backLinksLeft * SPACE_BACKLINKS + backLinksRight * SPACE_BACKLINKS;
|
||||
setPreferredSize(new Dimension(size.x, size.y));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
/*g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);*/
|
||||
g2.setColor(Color.black);
|
||||
int startX = SPACE_BACKLINKS + backLinksLeft * SPACE_BACKLINKS;
|
||||
int blLeft = 0;
|
||||
int blRight = 0;
|
||||
for (GraphPart part : partPos.keySet()) {
|
||||
Point p = partPos.get(part);
|
||||
g2.setColor(Color.white);
|
||||
g2.fillRect(startX + p.x - BLOCK_WIDTH / 2, p.y - BLOCK_HEIGHT / 2, BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||
g2.setColor(Color.black);
|
||||
g2.drawRect(startX + p.x - BLOCK_WIDTH / 2, p.y - BLOCK_HEIGHT / 2, BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||
g2.drawString(part.toString(), startX + p.x - g2.getFontMetrics().stringWidth(part.toString()) / 2, p.y + g2.getFontMetrics().getHeight() / 2);
|
||||
}
|
||||
|
||||
Point hp = partPos.get(head);
|
||||
drawArrow(g2, startX + hp.x, hp.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL, startX + hp.x, hp.y - BLOCK_HEIGHT / 2);
|
||||
|
||||
for (GraphPart part : partPos.keySet()) {
|
||||
Point p = partPos.get(part);
|
||||
|
||||
for (int n = 0; n < part.nextParts.size(); n++) {
|
||||
boolean isIf = part.nextParts.size() == 2;
|
||||
if (isIf) {
|
||||
if (n == 0) {
|
||||
g2.setColor(new Color(0, 0x80, 0));
|
||||
} else {
|
||||
g2.setColor(Color.red);
|
||||
}
|
||||
} else {
|
||||
g2.setColor(Color.black);
|
||||
}
|
||||
Point npos = partPos.get(part.nextParts.get(n));
|
||||
if (npos.y < p.y) {
|
||||
int sidex = startX;
|
||||
if (p.x > size.x / 2) {
|
||||
blRight++;
|
||||
sidex = size.x - backLinksRight * SPACE_BACKLINKS;
|
||||
sidex += SPACE_BACKLINKS + SPACE_BACKLINKS * blRight;
|
||||
} else {
|
||||
blLeft++;
|
||||
sidex -= SPACE_BACKLINKS + SPACE_BACKLINKS * blLeft;
|
||||
}
|
||||
g2.drawLine(startX + p.x, p.y + BLOCK_HEIGHT / 2, startX + p.x, p.y + BLOCK_HEIGHT / 2 + SPACE_VERTICAL / 2);
|
||||
g2.drawLine(startX + p.x, p.y + BLOCK_HEIGHT / 2 + SPACE_VERTICAL / 2, sidex, p.y + BLOCK_HEIGHT / 2 + SPACE_VERTICAL / 2);
|
||||
g2.drawLine(sidex, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2, sidex, p.y + BLOCK_HEIGHT / 2 + SPACE_VERTICAL / 2);
|
||||
drawArrow(g2, sidex, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2, startX + npos.x, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2);
|
||||
g2.drawLine(startX + npos.x, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2, startX + npos.x, npos.y - BLOCK_HEIGHT / 2);
|
||||
} else {
|
||||
drawArrow(g2, startX + p.x, p.y + BLOCK_HEIGHT / 2, startX + npos.x, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2);
|
||||
g2.drawLine(startX + npos.x, npos.y - BLOCK_HEIGHT / 2 - SPACE_VERTICAL / 2, startX + npos.x, npos.y - BLOCK_HEIGHT / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Point getPartSubPositions(Point ret, int totalWidth, GraphPart part, int y, int x, HashMap<GraphPart, Point> used) {
|
||||
if (used.containsKey(part)) {
|
||||
Point p = used.get(part);
|
||||
return new Point(x, y);
|
||||
}
|
||||
used.put(part, new Point(x, y));
|
||||
if (part.nextParts.size() > 0) {
|
||||
int cx = x - totalWidth / 2;
|
||||
for (int p = 0; p < part.nextParts.size(); p++) {
|
||||
HashSet<GraphPart> k = new HashSet<>();
|
||||
k.addAll(used.keySet());
|
||||
int partWidth = getPartWidth(part.nextParts.get(p), k);
|
||||
int cellWidth = partWidth * (BLOCK_WIDTH + SPACE_HORIZONTAL);
|
||||
Point pt = getPartPositions(part.nextParts.get(p), y + BLOCK_HEIGHT + SPACE_VERTICAL, cx + cellWidth / 2, used, false);
|
||||
if (pt.x > ret.x) {
|
||||
ret.x = pt.x;
|
||||
}
|
||||
if (pt.y > ret.y) {
|
||||
ret.y = pt.y;
|
||||
}
|
||||
cx += cellWidth;
|
||||
|
||||
}
|
||||
cx = x - totalWidth / 2;
|
||||
for (int p = 0; p < part.nextParts.size(); p++) {
|
||||
HashSet<GraphPart> k = new HashSet<>();
|
||||
k.addAll(used.keySet());
|
||||
int cellWidth = getPartWidth(part.nextParts.get(p), k) * (BLOCK_WIDTH + SPACE_HORIZONTAL);
|
||||
|
||||
HashSet<GraphPart> hs = new HashSet<>();
|
||||
hs.addAll(used.keySet());
|
||||
int totalWidthParts2 = getPartWidth(part.nextParts.get(p), hs);
|
||||
int totalWidth2 = totalWidthParts2 * (BLOCK_WIDTH + SPACE_HORIZONTAL);
|
||||
|
||||
Point pt = getPartSubPositions(ret, totalWidth2, part.nextParts.get(p), y + BLOCK_HEIGHT + SPACE_VERTICAL, cx + cellWidth / 2, used);
|
||||
if (pt.x > ret.x) {
|
||||
ret.x = pt.x;
|
||||
}
|
||||
if (pt.y > ret.y) {
|
||||
ret.y = pt.y;
|
||||
}
|
||||
cx += cellWidth;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Point getPartPositions(GraphPart part, int y, int x, HashMap<GraphPart, Point> used, boolean goSub) {
|
||||
HashMap<GraphPart, Point> l = new HashMap<>();
|
||||
l.putAll(used);
|
||||
HashSet<GraphPart> hs = new HashSet<>();
|
||||
hs.addAll(l.keySet());
|
||||
int totalWidthParts = getPartWidth(part, hs);
|
||||
int totalWidth = totalWidthParts * (BLOCK_WIDTH + SPACE_HORIZONTAL);
|
||||
|
||||
if (used.containsKey(part)) {
|
||||
Point p = used.get(part);
|
||||
return new Point(x, y);
|
||||
}
|
||||
Point ret = new Point(x - BLOCK_WIDTH / 2 - SPACE_HORIZONTAL / 2 + BLOCK_WIDTH, y + BLOCK_HEIGHT);
|
||||
if (goSub) {
|
||||
Point p2 = getPartSubPositions(ret, totalWidth, part, y, x, used);
|
||||
if (p2.x > ret.x) {
|
||||
ret.x = p2.x;
|
||||
}
|
||||
if (p2.y > ret.y) {
|
||||
ret.y = p2.y;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int getPartHeight(GraphPart part, List<GraphPart> used) {
|
||||
if (used.contains(part)) {
|
||||
return 1;
|
||||
}
|
||||
used.add(part);
|
||||
int maxH = 0;
|
||||
for (int p = 0; p < part.nextParts.size(); p++) {
|
||||
int h = getPartHeight(part.nextParts.get(p), used);
|
||||
if (h > maxH) {
|
||||
maxH = h;
|
||||
}
|
||||
}
|
||||
return 1 + maxH;
|
||||
}
|
||||
|
||||
private int getPartWidth(GraphPart part, HashSet<GraphPart> used) {
|
||||
|
||||
if (used.contains(part)) {
|
||||
return 1;
|
||||
}
|
||||
used.add(part);
|
||||
if (part.nextParts.isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
int w = 0;
|
||||
for (GraphPart subpart : part.nextParts) {
|
||||
w += getPartWidth(subpart, used);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
}
|
||||
GraphPanel gp;
|
||||
int scrollBarWidth;
|
||||
int scrollBarHeight;
|
||||
int frameWidthDiff;
|
||||
int frameHeightDiff;
|
||||
|
||||
public GraphFrame(Graph graph, String name) throws InterruptedException {
|
||||
setSize(500, 500);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
gp = new GraphPanel(graph);
|
||||
setTitle(translate("graph") + " " + name);
|
||||
JScrollPane scrollPane = new JScrollPane(gp);
|
||||
scrollBarWidth = scrollPane.getVerticalScrollBar().getPreferredSize().width;
|
||||
scrollBarHeight = scrollPane.getHorizontalScrollBar().getPreferredSize().height;
|
||||
cnt.add(scrollPane, BorderLayout.CENTER);
|
||||
pack();
|
||||
|
||||
Dimension size = getSize();
|
||||
Dimension innerSize = getContentPane().getSize();
|
||||
|
||||
frameWidthDiff = size.width - innerSize.width;
|
||||
frameHeightDiff = size.height - innerSize.height;
|
||||
|
||||
View.setWindowIcon(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
|
||||
super.setVisible(b);
|
||||
Dimension screen = getToolkit().getScreenSize();
|
||||
Dimension dim = new Dimension(0, 0);
|
||||
Dimension panDim = gp.getPreferredSize();
|
||||
// add some magic constants
|
||||
panDim = new Dimension(panDim.width + 3, panDim.height + 2);
|
||||
|
||||
boolean tooHigh = false;
|
||||
boolean tooWide = false;
|
||||
|
||||
if (panDim.width + frameWidthDiff < screen.width) {
|
||||
dim.width = panDim.width;
|
||||
} else {
|
||||
dim.width = screen.width;
|
||||
tooWide = true;
|
||||
}
|
||||
if (panDim.height + frameHeightDiff < screen.height) {
|
||||
dim.height = panDim.height;
|
||||
} else {
|
||||
dim.height = screen.height;
|
||||
tooHigh = true;
|
||||
}
|
||||
|
||||
if (tooWide) {
|
||||
dim.height += scrollBarHeight;
|
||||
dim.height = Math.min(dim.height, screen.height);
|
||||
}
|
||||
if (tooHigh) {
|
||||
dim.width += scrollBarWidth;
|
||||
dim.width = Math.min(dim.width, screen.width);
|
||||
}
|
||||
|
||||
setVisibleSize(dim);
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
private void setVisibleSize(Dimension dim) {
|
||||
setSize(new Dimension(dim.width + frameWidthDiff, dim.height + frameHeightDiff));
|
||||
}
|
||||
|
||||
private void drawArrow(Graphics g, int x1, int y1, int x2, int y2) {
|
||||
Polygon arrowHead = new Polygon();
|
||||
arrowHead.addPoint(0, 0);
|
||||
arrowHead.addPoint(-3, -8);
|
||||
arrowHead.addPoint(3, -8);
|
||||
Line2D.Double line = new Line2D.Double(x1, y1, x2, y2);
|
||||
AffineTransform tx = new AffineTransform();
|
||||
tx.setToIdentity();
|
||||
double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
|
||||
tx.translate(line.x2, line.y2);
|
||||
tx.rotate((angle - Math.PI / 2d));
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
AffineTransform oldTransform = g2d.getTransform();
|
||||
g2d.draw(line);
|
||||
tx.preConcatenate(oldTransform);
|
||||
g2d.setTransform(tx);
|
||||
g2d.fill(arrowHead);
|
||||
g2d.setTransform(oldTransform);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc.avm2.graph.AVM2Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GraphTreeFrame extends AppFrame {
|
||||
|
||||
public JTree graphTree;
|
||||
|
||||
public GraphTreeFrame(final AVM2Graph graph) {
|
||||
setSize(400, 400);
|
||||
graphTree = new JTree(new TreeModel() {
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return graph.heads.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
return ((GraphPart) parent).nextParts.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
return ((GraphPart) parent).nextParts.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
return getChildCount(node) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
return ((GraphPart) parent).nextParts.indexOf(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
}
|
||||
});
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(graphTree, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GuiAbortRetryIgnoreHandler implements AbortRetryIgnoreHandler {
|
||||
|
||||
@Override
|
||||
public int handle(Throwable thrown) {
|
||||
synchronized (GuiAbortRetryIgnoreHandler.class) {
|
||||
String[] options = new String[]{AppStrings.translate("button.abort"), AppStrings.translate("button.retry"), AppStrings.translate("button.ignore")};
|
||||
return View.showOptionDialog(null, AppStrings.translate("error.occured").replace("%error%", thrown.getLocalizedMessage()), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, "");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbortRetryIgnoreHandler getNewInstance() {
|
||||
// there are no non-static field in this class, so return the original instance
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import javax.swing.JLabel;
|
||||
import org.pushingpixels.substance.api.DecorationAreaType;
|
||||
import org.pushingpixels.substance.api.SubstanceConstants;
|
||||
import org.pushingpixels.substance.api.painter.border.StandardBorderPainter;
|
||||
import org.pushingpixels.substance.api.skin.OfficeBlue2007Skin;
|
||||
import org.pushingpixels.substance.internal.utils.SubstanceOutlineUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class HeaderLabel extends JLabel {
|
||||
|
||||
public HeaderLabel(String text) {
|
||||
super(text);
|
||||
//setBorder(BorderFactory.createRaisedBevelBorder());
|
||||
|
||||
|
||||
/*setBorder(new Border() {
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
g.setColor(Color.gray);
|
||||
g.drawLine(0, 0,width-1, 0);
|
||||
g.drawLine(0, 0, 0, height-1);
|
||||
g.setColor(Color.darkGray);
|
||||
g.drawLine(width-1, 0, width-1, height-1);
|
||||
g.drawLine(0, height-1, width-1, height-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(2, 2, 2, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return false;
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(new Color(217, 232, 251));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
StandardBorderPainter borderPainter = new StandardBorderPainter();
|
||||
|
||||
Set<SubstanceConstants.Side> straightSides = EnumSet.of(SubstanceConstants.Side.BOTTOM);
|
||||
int dy = 0;
|
||||
float cornerRadius = 5f;
|
||||
int borderThickness = 1;
|
||||
int borderInsets = 0;
|
||||
GeneralPath contourInner = borderPainter.isPaintingInnerContour() ? SubstanceOutlineUtilities.getBaseOutline(getWidth(), getHeight() + dy,
|
||||
cornerRadius - borderThickness, straightSides, borderThickness + borderInsets)
|
||||
: null;
|
||||
|
||||
GeneralPath contour = SubstanceOutlineUtilities.getBaseOutline(getWidth(),
|
||||
getHeight() + dy, cornerRadius, straightSides, borderInsets);
|
||||
borderPainter.paintBorder(g, this, getWidth(), getHeight() + dy,
|
||||
contour, contourInner, new OfficeBlue2007Skin().getActiveColorScheme(DecorationAreaType.HEADER));
|
||||
g.setColor(Color.black);
|
||||
JLabel lab = new JLabel(getText(), JLabel.CENTER);
|
||||
lab.setSize(getSize());
|
||||
lab.paint(g);
|
||||
//g.drawString(getText(), getWidth()/2-getFontMetrics(getFont()).stringWidth(getText())/2, getFont().getSize());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,679 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
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.imageio.ImageIO;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public final class ImagePanel extends JPanel implements ActionListener, MediaDisplay {
|
||||
|
||||
static final String ACTION_SELECT_BKCOLOR = "SELECTCOLOR";
|
||||
|
||||
//private JLabel label = new JLabel();
|
||||
private Timelined timelined;
|
||||
private boolean stillFrame = false;
|
||||
private Timer timer;
|
||||
private int frame = -1;
|
||||
private SWF swf;
|
||||
private boolean loaded;
|
||||
private int mouseButton;
|
||||
private JLabel debugLabel = new JLabel("-");
|
||||
private DepthState stateUnderCursor = null;
|
||||
private MouseEvent lastMouseEvent = null;
|
||||
private final List<SoundTagPlayer> soundPlayers = new ArrayList<>();
|
||||
private final IconPanel iconPanel;
|
||||
private int time = 0;
|
||||
|
||||
private class IconPanel extends JPanel {
|
||||
|
||||
private SerializableImage img;
|
||||
|
||||
private Rectangle rect = null;
|
||||
private List<DepthState> dss;
|
||||
private List<Shape> outlines;
|
||||
|
||||
public synchronized void setOutlines(List<DepthState> dss, List<Shape> outlines) {
|
||||
this.outlines = outlines;
|
||||
this.dss = dss;
|
||||
}
|
||||
|
||||
public void setImg(SerializableImage img) {
|
||||
this.img = img;
|
||||
calcRect();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public synchronized List<DepthState> getObjectsUnderPoint(Point p) {
|
||||
List<DepthState> ret = new ArrayList<>();
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
if (outlines.get(i).contains(p)) {
|
||||
ret.add(dss.get(i));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Rectangle getRect() {
|
||||
return rect;
|
||||
}
|
||||
|
||||
public Point toImagePoint(Point p) {
|
||||
if (img == null) {
|
||||
return null;
|
||||
}
|
||||
return new Point((p.x - rect.x) * img.getWidth() / rect.width, (p.y - rect.y) * img.getHeight() / rect.height);
|
||||
}
|
||||
|
||||
private void calcRect() {
|
||||
if (img != null) {
|
||||
int w1 = img.getWidth();
|
||||
int h1 = img.getHeight();
|
||||
|
||||
int w2 = getWidth();
|
||||
int h2 = getHeight();
|
||||
|
||||
int w;
|
||||
int h;
|
||||
if (w1 <= w2 && h1 <= h2) {
|
||||
w = w1;
|
||||
h = h1;
|
||||
} else {
|
||||
|
||||
h = h1 * w2 / w1;
|
||||
if (h > h2) {
|
||||
w = w1 * h2 / h1;
|
||||
h = h2;
|
||||
} else {
|
||||
w = w2;
|
||||
}
|
||||
}
|
||||
|
||||
rect = new Rectangle(getWidth() / 2 - w / 2, getHeight() / 2 - h / 2, w, h);
|
||||
} else {
|
||||
rect = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setPaint(View.transparentPaint);
|
||||
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
|
||||
g2d.setComposite(AlphaComposite.SrcOver);
|
||||
g2d.setPaint(View.swfBackgroundColor);
|
||||
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
|
||||
if (img != null) {
|
||||
calcRect();
|
||||
g2d.setComposite(AlphaComposite.SrcOver);
|
||||
g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0, 0, img.getWidth(), img.getHeight(), null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color bg) {
|
||||
if (iconPanel != null) {
|
||||
iconPanel.setBackground(bg);
|
||||
}
|
||||
super.setBackground(bg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addMouseListener(MouseListener l) {
|
||||
iconPanel.addMouseListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeMouseListener(MouseListener l) {
|
||||
iconPanel.removeMouseListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addMouseMotionListener(MouseMotionListener l) {
|
||||
iconPanel.addMouseMotionListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeMouseMotionListener(MouseMotionListener l) {
|
||||
iconPanel.removeMouseMotionListener(l);
|
||||
}
|
||||
|
||||
private void updatePos(MouseEvent e, boolean draw) {
|
||||
if (e == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (iconPanel) {
|
||||
lastMouseEvent = e;
|
||||
boolean handCursor = false;
|
||||
DepthState newStateUnderCursor = null;
|
||||
if (timelined != null) {
|
||||
|
||||
Timeline tim = ((Timelined) timelined).getTimeline();
|
||||
BoundedTag bounded = (BoundedTag) timelined;
|
||||
RECT rect = bounded.getRect();
|
||||
int width = rect.getWidth();
|
||||
double scale = 1.0;
|
||||
/*if (width > swf.displayRect.getWidth()) {
|
||||
scale = (double) swf.displayRect.getWidth() / (double) width;
|
||||
}*/
|
||||
Matrix m = new Matrix();
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
m.scale(scale);
|
||||
Point p = e.getPoint();
|
||||
p = iconPanel.toImagePoint(p);
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
String ret = "";
|
||||
if (p != null) {
|
||||
int x = p.x;
|
||||
int y = p.y;
|
||||
objs = iconPanel.getObjectsUnderPoint(p);
|
||||
|
||||
ret += " [" + x + "," + y + "] : ";
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
for (int i = 0; i < objs.size(); i++) {
|
||||
DepthState ds = objs.get(i);
|
||||
if (!first) {
|
||||
ret += ", ";
|
||||
}
|
||||
first = false;
|
||||
CharacterTag c = tim.swf.characters.get(ds.characterId);
|
||||
if (c instanceof ButtonTag) {
|
||||
newStateUnderCursor = ds;
|
||||
handCursor = true;
|
||||
}
|
||||
ret += c.toString();
|
||||
if (timelined instanceof ButtonTag) {
|
||||
handCursor = true;
|
||||
}
|
||||
}
|
||||
if (first) {
|
||||
ret += " - ";
|
||||
}
|
||||
debugLabel.setText(ret);
|
||||
|
||||
if (handCursor) {
|
||||
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
} else {
|
||||
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
if (newStateUnderCursor != stateUnderCursor) {
|
||||
stateUnderCursor = newStateUnderCursor;
|
||||
if (draw) {
|
||||
drawFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ImagePanel() {
|
||||
super(new BorderLayout());
|
||||
//iconPanel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setOpaque(true);
|
||||
setBackground(View.DEFAULT_BACKGROUND_COLOR);
|
||||
|
||||
iconPanel = new IconPanel();
|
||||
//labelPan.add(label, new GridBagConstraints());
|
||||
add(iconPanel, BorderLayout.CENTER);
|
||||
|
||||
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_BKCOLOR);
|
||||
selectColorButton.setToolTipText(AppStrings.translate("button.selectbkcolor.hint"));
|
||||
buttonsPanel.add(selectColorButton);
|
||||
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
add(debugLabel, BorderLayout.NORTH);
|
||||
iconPanel.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
drawFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
stateUnderCursor = null;
|
||||
drawFrame();
|
||||
debugLabel.setText(" - ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
mouseButton = e.getButton();
|
||||
updatePos(e, true);
|
||||
drawFrame();
|
||||
if (stateUnderCursor != null) {
|
||||
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
|
||||
DefineButtonSoundTag sounds = b.getSounds();
|
||||
if (sounds != null && sounds.buttonSoundChar2 != 0) { //OverUpToOverDown
|
||||
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
mouseButton = 0;
|
||||
updatePos(e, true);
|
||||
drawFrame();
|
||||
if (stateUnderCursor != null) {
|
||||
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
|
||||
DefineButtonSoundTag sounds = b.getSounds();
|
||||
if (sounds != null && sounds.buttonSoundChar3 != 0) { //OverDownToOverUp
|
||||
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
iconPanel.addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
DepthState lastUnderCur = stateUnderCursor;
|
||||
updatePos(e, true);
|
||||
if (stateUnderCursor != null) {
|
||||
if (lastUnderCur == null || lastUnderCur.instanceId != stateUnderCursor.instanceId) {
|
||||
//New mouse entered
|
||||
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
|
||||
DefineButtonSoundTag sounds = b.getSounds();
|
||||
if (sounds != null && sounds.buttonSoundChar1 != 0) { //IddleToOverUp
|
||||
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar1));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastUnderCur != null) {
|
||||
if (stateUnderCursor == null || stateUnderCursor.instanceId != lastUnderCur.instanceId) {
|
||||
//Old mouse leave
|
||||
ButtonTag b = (ButtonTag) swf.characters.get(lastUnderCur.characterId);
|
||||
DefineButtonSoundTag sounds = b.getSounds();
|
||||
if (sounds != null && sounds.buttonSoundChar0 != 0) { //OverUpToIddle
|
||||
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
updatePos(e, true);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand().equals(ACTION_SELECT_BKCOLOR)) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectbkcolor.title"), View.swfBackgroundColor);
|
||||
if (newColor != null) {
|
||||
View.swfBackgroundColor = newColor;
|
||||
setBackground(newColor);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setImage(byte[] data) {
|
||||
setBackground(View.swfBackgroundColor);
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
}
|
||||
timelined = null;
|
||||
loaded = true;
|
||||
try {
|
||||
iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))));
|
||||
iconPanel.setOutlines(new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setTimelined(final Timelined drawable, final SWF swf, int frame) {
|
||||
pause();
|
||||
if (drawable instanceof ButtonTag) {
|
||||
frame = ButtonTag.FRAME_UP;
|
||||
}
|
||||
this.timelined = drawable;
|
||||
this.swf = swf;
|
||||
if (frame > -1) {
|
||||
this.frame = frame;
|
||||
this.stillFrame = true;
|
||||
} else {
|
||||
this.frame = 0;
|
||||
this.stillFrame = false;
|
||||
}
|
||||
loaded = true;
|
||||
|
||||
if (drawable.getTimeline().frames.isEmpty()) {
|
||||
iconPanel.setImg(null);
|
||||
iconPanel.setOutlines(new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
return;
|
||||
}
|
||||
time = 0;
|
||||
play();
|
||||
}
|
||||
|
||||
public void setImage(SerializableImage image) {
|
||||
setBackground(View.swfBackgroundColor);
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
}
|
||||
timelined = null;
|
||||
loaded = true;
|
||||
stillFrame = true;
|
||||
iconPanel.setImg(image);
|
||||
iconPanel.setOutlines(new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentFrame() {
|
||||
return frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalFrames() {
|
||||
if (timelined == null) {
|
||||
return 0;
|
||||
}
|
||||
if (stillFrame) {
|
||||
return 0;
|
||||
}
|
||||
return timelined.getTimeline().frames.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
stopAllSounds();
|
||||
}
|
||||
|
||||
private void stopAllSounds() {
|
||||
for (int i = soundPlayers.size() - 1; i >= 0; i--) {
|
||||
SoundTagPlayer pl = soundPlayers.get(i);
|
||||
pl.pause();
|
||||
}
|
||||
soundPlayers.clear();
|
||||
}
|
||||
|
||||
private void nextFrame() {
|
||||
drawFrame();
|
||||
int newframe = (frame + 1) % timelined.getTimeline().frames.size();
|
||||
if (stillFrame) {
|
||||
newframe = frame;
|
||||
}
|
||||
if (newframe != frame) {
|
||||
if (newframe == 0) {
|
||||
stopAllSounds();
|
||||
}
|
||||
frame = newframe;
|
||||
time = 0;
|
||||
} else {
|
||||
time++;
|
||||
}
|
||||
}
|
||||
|
||||
private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton) {
|
||||
String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
|
||||
SerializableImage img = SWF.getFromCache(key);
|
||||
if (img == null) {
|
||||
if (drawable instanceof BoundedTag) {
|
||||
BoundedTag bounded = (BoundedTag) drawable;
|
||||
RECT rect = bounded.getRect();
|
||||
if (rect == null) { //??? Why?
|
||||
rect = new RECT(0, 0, 1, 1);
|
||||
}
|
||||
int width = rect.getWidth();
|
||||
int height = rect.getHeight();
|
||||
SerializableImage image = new SerializableImage((int) (width / SWF.unitDivisor) + 1,
|
||||
(int) (height / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
|
||||
image.fillTransparent();
|
||||
Matrix m = new Matrix();
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
drawable.getTimeline().toImage(frame, time, frame, stateUnderCursor, mouseButton, image, m, new ColorTransform());
|
||||
|
||||
Graphics2D gg = (Graphics2D) image.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.green);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
List<DepthState> dss = new ArrayList<>();
|
||||
List<Shape> os = new ArrayList<>();
|
||||
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
|
||||
|
||||
//gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
for(Shape s:os){
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(s));
|
||||
}*/
|
||||
|
||||
img = image;
|
||||
}
|
||||
if (drawable.getTimeline().isSingleFrame()) {
|
||||
SWF.putToCache(key, img);
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
private synchronized void drawFrame() {
|
||||
if (timelined == null) {
|
||||
return;
|
||||
}
|
||||
Timeline timeline = timelined.getTimeline();
|
||||
if (frame>=timeline.frames.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getOutlines();
|
||||
Matrix mat = new Matrix();
|
||||
mat.translateX = swf.displayRect.Xmin;
|
||||
mat.translateY = swf.displayRect.Ymin;
|
||||
updatePos(lastMouseEvent, false);
|
||||
SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton);
|
||||
List<Integer> sounds = new ArrayList<>();
|
||||
List<String> soundClasses = new ArrayList<>();
|
||||
timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses);
|
||||
for (int cid : swf.characters.keySet()) {
|
||||
CharacterTag c = swf.characters.get(cid);
|
||||
for (String cls : soundClasses) {
|
||||
if (cls.equals(c.getClassName())) {
|
||||
sounds.add(cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int sndId : sounds) {
|
||||
CharacterTag c = swf.characters.get(sndId);
|
||||
if (c instanceof SoundTag) {
|
||||
SoundTag st = (SoundTag) c;
|
||||
playSound(st);
|
||||
}
|
||||
}
|
||||
|
||||
iconPanel.setImg(img);
|
||||
}
|
||||
|
||||
private void playSound(SoundTag st) {
|
||||
final SoundTagPlayer sp;
|
||||
try {
|
||||
sp = new SoundTagPlayer(st, 1);
|
||||
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.add(sp);
|
||||
}
|
||||
sp.addListener(new PlayerListener() {
|
||||
|
||||
@Override
|
||||
public void playingFinished() {
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.remove(sp);
|
||||
}
|
||||
}
|
||||
});
|
||||
sp.play();
|
||||
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, "Error during playing sound", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void getOutlines() {
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
List<Shape> outlines = new ArrayList<>();
|
||||
Matrix m = new Matrix();
|
||||
RECT rect = timelined.getTimeline().displayRect;
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
m.scale(1);
|
||||
|
||||
timelined.getTimeline().getObjectsOutlines(frame, time, frame, stateUnderCursor, mouseButton, m, objs, outlines);
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i)));
|
||||
}
|
||||
iconPanel.setOutlines(objs, outlines);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
pause();
|
||||
if (timelined != null) {
|
||||
timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
boolean first = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Timeline timeline = timelined.getTimeline();
|
||||
if (timeline.frames.size() <= 1 && timeline.isSingleFrame()) {
|
||||
if (first) {
|
||||
drawFrame();
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
nextFrame();
|
||||
}
|
||||
}
|
||||
}, 0, 1000 / timelined.getTimeline().frameRate);
|
||||
} else {
|
||||
drawFrame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rewind() {
|
||||
frame = 0;
|
||||
drawFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
if (timelined == null) {
|
||||
return false;
|
||||
}
|
||||
if (stillFrame) {
|
||||
return false;
|
||||
}
|
||||
return (timelined.getTimeline().frames.size() <= 1) || (timer != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gotoFrame(int frame) {
|
||||
this.frame = frame;
|
||||
drawFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFrameRate() {
|
||||
if (timelined == null) {
|
||||
return 1;
|
||||
}
|
||||
if (stillFrame) {
|
||||
return 1;
|
||||
}
|
||||
return timelined.getTimeline().frameRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Language {
|
||||
|
||||
public String code;
|
||||
public String name;
|
||||
|
||||
public Language(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.helpers.utf8.Utf8PrintWriter;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LicenseUpdater {
|
||||
|
||||
public static void updateLicense() {
|
||||
updateLicenseInDir(new File(".\\src\\"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Script for updating license header in java files :-)
|
||||
*
|
||||
* @param dir Star directory (e.g. "src/")
|
||||
*/
|
||||
public static void updateLicenseInDir(File dir) {
|
||||
int defaultStartYear = 2010;
|
||||
int defaultFinalYear = 2013;
|
||||
String defaultAuthor = "JPEXS";
|
||||
String defaultYearStr = "" + defaultStartYear;
|
||||
if (defaultFinalYear != defaultStartYear) {
|
||||
defaultYearStr += "-" + defaultFinalYear;
|
||||
}
|
||||
String license = "/*\r\n * Copyright (C) {year} {author}\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU General Public License\r\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\r\n */";
|
||||
|
||||
File[] files = dir.listFiles();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
updateLicenseInDir(f);
|
||||
} else {
|
||||
if (f.getName().endsWith(".java")) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintWriter pw = new Utf8PrintWriter(baos);
|
||||
try {
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
|
||||
String s;
|
||||
boolean packageFound = false;
|
||||
String author = defaultAuthor;
|
||||
String yearStr = defaultYearStr;
|
||||
while ((s = br.readLine()) != null) {
|
||||
if (!packageFound) {
|
||||
if (s.trim().startsWith("package")) {
|
||||
packageFound = true;
|
||||
pw.println(license.replace("{year}", yearStr).replace("{author}", author));
|
||||
} else {
|
||||
Matcher mAuthor = Pattern.compile("^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*)$").matcher(s);
|
||||
if (mAuthor.matches()) {
|
||||
author = mAuthor.group(3).trim();
|
||||
int startYear = Integer.parseInt(mAuthor.group(1).trim());
|
||||
if (startYear == defaultFinalYear) {
|
||||
yearStr = "" + startYear;
|
||||
} else {
|
||||
yearStr = "" + startYear + "-" + defaultFinalYear;
|
||||
}
|
||||
if (!author.equals(defaultAuthor)) {
|
||||
System.out.println("Detected nodefault author:" + author + " in " + f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packageFound) {
|
||||
pw.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
pw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream(f);
|
||||
fos.write(baos.toByteArray());
|
||||
fos.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Cursor;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* An extension of JLabel which looks like a link and responds appropriately
|
||||
* when clicked. Note that this class will only work with Swing 1.1.1 and later.
|
||||
* Note that because of the way this class is implemented, getText() will not
|
||||
* return correct values, user <code>getNormalText</code> instead.
|
||||
*/
|
||||
public class LinkLabel extends JLabel {
|
||||
|
||||
/**
|
||||
* The normal text set by the user.
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Creates a new LinkLabel with the given text.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public LinkLabel(String text) {
|
||||
super(text);
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
enableEvents(MouseEvent.MOUSE_EVENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of the label.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@Override
|
||||
public void setText(String text) {
|
||||
super.setText("<html><font color=\"#0000CF\"><u>" + text + "</u></font></html>");
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text set by the user.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getNormalText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes mouse events and responds to clicks.
|
||||
*
|
||||
* @param evt
|
||||
*/
|
||||
@Override
|
||||
protected void processMouseEvent(MouseEvent evt) {
|
||||
super.processMouseEvent(evt);
|
||||
if (evt.getID() == MouseEvent.MOUSE_CLICKED) {
|
||||
clicked();
|
||||
}
|
||||
}
|
||||
|
||||
protected void clicked() {
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
|
||||
try {
|
||||
java.net.URI uri = new java.net.URI(getNormalText());
|
||||
desktop.browse(uri);
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ListLayout implements LayoutManager {
|
||||
|
||||
private int border;
|
||||
|
||||
public ListLayout() {
|
||||
this(5);
|
||||
}
|
||||
|
||||
public ListLayout(int border) {
|
||||
this.border = border;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLayoutComponent(String name, Component comp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLayoutComponent(Component comp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent) {
|
||||
int h = 0;
|
||||
int maxw = 0;
|
||||
Insets ins = parent.getInsets();
|
||||
boolean first = true;
|
||||
for (Component c : parent.getComponents()) {
|
||||
if (!c.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
if (true) { //!first) {
|
||||
h += border;
|
||||
}
|
||||
Dimension pref = c.getPreferredSize();
|
||||
if (pref.width > maxw) {
|
||||
maxw = pref.width;
|
||||
}
|
||||
h += pref.height;
|
||||
first = false;
|
||||
}
|
||||
h += border;
|
||||
|
||||
maxw = (parent.getSize().width == 0 ? maxw : parent.getSize().width) - ins.left - ins.right;
|
||||
return new Dimension(maxw, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container parent) {
|
||||
return preferredLayoutSize(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent) {
|
||||
Dimension dim = preferredLayoutSize(parent);
|
||||
int top = 0;
|
||||
Insets ins = parent.getInsets();
|
||||
top = ins.top;
|
||||
boolean first = true;
|
||||
for (Component c : parent.getComponents()) {
|
||||
if (!c.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
if (!first) {
|
||||
top += border;
|
||||
}
|
||||
Dimension pref = c.getPreferredSize();
|
||||
c.setPreferredSize(new Dimension(dim.width, pref.height));
|
||||
c.setMinimumSize(new Dimension(dim.width, pref.height));
|
||||
c.setBounds(0, top, dim.width, pref.height);
|
||||
top += pref.height;
|
||||
first = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.browsers.cache.CacheEntry;
|
||||
import com.jpexs.browsers.cache.CacheImplementation;
|
||||
import com.jpexs.browsers.cache.CacheReader;
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LoadFromCacheFrame extends AppFrame implements ActionListener {
|
||||
|
||||
static final String ACTION_OPEN = "OPEN";
|
||||
static final String ACTION_SAVE = "SAVE";
|
||||
static final String ACTION_REFRESH = "REFRESH";
|
||||
|
||||
private final JList<CacheEntry> list;
|
||||
private final JTextField searchField;
|
||||
private List<CacheImplementation> caches;
|
||||
private List<CacheEntry> entries;
|
||||
private final JProgressBar progressBar;
|
||||
JButton saveButton;
|
||||
JButton refreshButton;
|
||||
JButton openButton;
|
||||
|
||||
public LoadFromCacheFrame() {
|
||||
setSize(900, 600);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
setTitle(translate("dialog.title"));
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
Container cnt = getContentPane();
|
||||
list = new JList<>();
|
||||
list.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() > 1) {
|
||||
openSWF();
|
||||
}
|
||||
}
|
||||
});
|
||||
searchField = new JTextField();
|
||||
searchField.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
filter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
});
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(searchField, BorderLayout.NORTH);
|
||||
cnt.add(new JScrollPane(list), BorderLayout.CENTER);
|
||||
|
||||
JPanel bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
|
||||
openButton = new JButton(translate("button.open"));
|
||||
openButton.setActionCommand(ACTION_OPEN);
|
||||
openButton.addActionListener(this);
|
||||
buttonsPanel.add(openButton);
|
||||
|
||||
saveButton = new JButton(translate("button.save"));
|
||||
saveButton.setActionCommand(ACTION_SAVE);
|
||||
saveButton.addActionListener(this);
|
||||
buttonsPanel.add(saveButton);
|
||||
|
||||
refreshButton = new JButton(translate("button.refresh"));
|
||||
refreshButton.setActionCommand(ACTION_REFRESH);
|
||||
refreshButton.addActionListener(this);
|
||||
buttonsPanel.add(refreshButton);
|
||||
|
||||
JPanel browsersPanel = new JPanel(new FlowLayout());
|
||||
browsersPanel.add(new JLabel(translate("supported.browsers")));
|
||||
JLabel chromeLabel = new JLabel("Google Chrome", View.getIcon("chrome16"), JLabel.CENTER);
|
||||
JLabel firefoxLabel = new JLabel("Mozilla Firefox*", View.getIcon("firefox16"), JLabel.CENTER);
|
||||
browsersPanel.add(chromeLabel);
|
||||
browsersPanel.add(firefoxLabel);
|
||||
buttonsPanel.setAlignmentX(0.5f);
|
||||
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setAlignmentX(0.5f);
|
||||
progressBar.setIndeterminate(true);
|
||||
bottomPanel.add(progressBar);
|
||||
bottomPanel.add(buttonsPanel);
|
||||
browsersPanel.setAlignmentX(0.5f);
|
||||
bottomPanel.add(browsersPanel);
|
||||
JLabel infoLabel = new JLabel(translate("info.closed"));
|
||||
infoLabel.setAlignmentX(0.5f);
|
||||
bottomPanel.add(infoLabel);
|
||||
cnt.add(bottomPanel, BorderLayout.SOUTH);
|
||||
progressBar.setVisible(false);
|
||||
openButton.setEnabled(false);
|
||||
saveButton.setEnabled(false);
|
||||
|
||||
java.util.List<Image> images = new ArrayList<>();
|
||||
images.add(View.loadImage("loadcache16"));
|
||||
images.add(View.loadImage("loadcache32"));
|
||||
setIconImages(images);
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
progressBar.setVisible(true);
|
||||
openButton.setEnabled(false);
|
||||
saveButton.setEnabled(false);
|
||||
refreshButton.setEnabled(false);
|
||||
new SwingWorker<Object, Object>() {
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
if (caches == null) {
|
||||
caches = new ArrayList<>();
|
||||
for (String b : CacheReader.availableBrowsers()) {
|
||||
caches.add(CacheReader.getBrowserCache(b));
|
||||
}
|
||||
} else {
|
||||
for (CacheImplementation c : caches) {
|
||||
c.refresh();
|
||||
}
|
||||
}
|
||||
entries = new ArrayList<>();
|
||||
for (CacheImplementation c : caches) {
|
||||
List<CacheEntry> list = c.getEntries();
|
||||
if (list != null) {
|
||||
for (CacheEntry en : c.getEntries()) {
|
||||
String contentType = en.getHeader("Content-Type");
|
||||
if ("application/x-shockwave-flash".equals(contentType)) {
|
||||
entries.add(en);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
filter();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
openButton.setEnabled(true);
|
||||
saveButton.setEnabled(true);
|
||||
refreshButton.setEnabled(true);
|
||||
progressBar.setVisible(false);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
private void filter() {
|
||||
String search = searchField.getText();
|
||||
List<CacheEntry> filtered = new ArrayList<>();
|
||||
for (CacheEntry en : entries) {
|
||||
if (search.isEmpty() || en.getRequestURL().contains(search)) {
|
||||
filtered.add(en);
|
||||
}
|
||||
}
|
||||
list.setListData(new Vector<>(filtered));
|
||||
}
|
||||
|
||||
private static String entryToFileName(CacheEntry en) {
|
||||
String ret = en.getRequestURL();
|
||||
//Strip parameters
|
||||
if (ret.contains("?")) {
|
||||
ret = ret.substring(0, ret.indexOf('?'));
|
||||
}
|
||||
//Strip path
|
||||
if (ret.contains("/")) {
|
||||
ret = ret.substring(ret.lastIndexOf('/') + 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void openSWF() {
|
||||
CacheEntry en = list.getSelectedValue();
|
||||
if (en != null) {
|
||||
ReReadableInputStream str = new ReReadableInputStream(en.getResponseDataStream());
|
||||
SWFSourceInfo sourceInfo = new SWFSourceInfo(str, null, entryToFileName(en));
|
||||
Main.openFile(sourceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_REFRESH:
|
||||
refresh();
|
||||
break;
|
||||
case ACTION_OPEN:
|
||||
openSWF();
|
||||
break;
|
||||
case ACTION_SAVE:
|
||||
List<CacheEntry> selected = list.getSelectedValuesList();
|
||||
if (!selected.isEmpty()) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
|
||||
if (selected.size() > 1) {
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
} else {
|
||||
fc.setSelectedFile(new File(Configuration.lastSaveDir.get(), entryToFileName(selected.get(0))));
|
||||
fc.setFileFilter(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return (f.getName().endsWith(".swf")) || (f.isDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return AppStrings.translate("filter.swf");
|
||||
}
|
||||
});
|
||||
}
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
JFrame f = new JFrame();
|
||||
View.setWindowIcon(f);
|
||||
int returnVal = fc.showSaveDialog(f);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
File file = Helper.fixDialogFile(fc.getSelectedFile());
|
||||
try {
|
||||
if (selected.size() == 1) {
|
||||
Helper.saveStream(selected.get(0).getResponseDataStream(), file);
|
||||
} else {
|
||||
for (CacheEntry sel : selected) {
|
||||
Helper.saveStream(sel.getResponseDataStream(), new File(file, entryToFileName(sel)));
|
||||
}
|
||||
}
|
||||
Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
|
||||
} catch (IOException ex) {
|
||||
View.showMessageDialog(null, translate("error.file.write"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.LimitedInputStream;
|
||||
import com.jpexs.helpers.PosMarkedInputStream;
|
||||
import com.jpexs.helpers.ProgressListener;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.process.ProcessTools;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Image;
|
||||
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.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.SwingWorker.StateValue;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableRowSorter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author petrik
|
||||
*/
|
||||
public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
|
||||
|
||||
static final String ACTION_SELECT_PROCESS = "SELECTPROCESS";
|
||||
static final String ACTION_REFRESH_PROCESS_LIST = "REFRESHPROCESSLIST";
|
||||
static final String ACTION_OPEN_SWF = "OPENSWF";
|
||||
static final String ACTION_SAVE = "SAVE";
|
||||
|
||||
private MainFrame mainFrame;
|
||||
private List<com.jpexs.process.Process> processlist;
|
||||
private List<SwfInMemory> foundIs;
|
||||
private List<com.jpexs.process.Process> selProcesses;
|
||||
private JList<com.jpexs.process.Process> list;
|
||||
private DefaultListModel<com.jpexs.process.Process> model;
|
||||
private DefaultTableModel resTableModel;
|
||||
private final JTable tableRes;
|
||||
private final JLabel stateLabel;
|
||||
private boolean processing = false;
|
||||
private final JProgressBar progress;
|
||||
|
||||
private class SelectProcessWorker extends SwingWorker<List<SwfInMemory>, Object> {
|
||||
|
||||
private final List<com.jpexs.process.Process> procs;
|
||||
|
||||
public SelectProcessWorker(List<com.jpexs.process.Process> procs) {
|
||||
this.procs = procs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<Object> chunks) {
|
||||
for (Object s : chunks) {
|
||||
if (s instanceof com.jpexs.process.Process) {
|
||||
stateLabel.setText(s.toString());
|
||||
}
|
||||
if (s instanceof SwfInMemory) {
|
||||
SwfInMemory swf = (SwfInMemory) s;
|
||||
addResultRow(swf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SwfInMemory> doInBackground() throws Exception {
|
||||
Map<Long, InputStream> ret = new HashMap<>();
|
||||
List<SwfInMemory> swfStreams = new ArrayList<>();
|
||||
for (com.jpexs.process.Process proc : procs) {
|
||||
publish(proc);
|
||||
ret = proc.search(new ProgressListener() {
|
||||
@Override
|
||||
public void progress(int p) {
|
||||
setProgress(p);
|
||||
}
|
||||
}, "CWS".getBytes(), "FWS".getBytes(), "ZWS".getBytes());
|
||||
int pos = 0;
|
||||
for (Long addr : ret.keySet()) {
|
||||
setProgress(pos * 100 / ret.size());
|
||||
pos++;
|
||||
try {
|
||||
PosMarkedInputStream pmi = new PosMarkedInputStream(ret.get(addr));
|
||||
ReReadableInputStream is = new ReReadableInputStream(pmi);
|
||||
SWF swf = new SWF(is, null, false, true);
|
||||
long limit = pmi.getPos();
|
||||
is.seek(0);
|
||||
is = new ReReadableInputStream(new LimitedInputStream(is, limit));
|
||||
if (swf.fileSize > 0 && swf.version > 0 && !swf.tags.isEmpty() && swf.version < 25/*Needs to be fixed when SWF versions reaches this value*/) {
|
||||
SwfInMemory s = new SwfInMemory(is, swf.version, swf.fileSize, proc);
|
||||
String p = translate("swfitem").replace("%version%", "" + swf.version).replace("%size%", "" + swf.fileSize);
|
||||
publish(s);
|
||||
swfStreams.add(s);
|
||||
}
|
||||
|
||||
} catch (OutOfMemoryError ome) {
|
||||
System.gc();
|
||||
} catch (Exception | Error ex) {
|
||||
}
|
||||
|
||||
}
|
||||
setProgress(100);
|
||||
}
|
||||
if (swfStreams.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return swfStreams;
|
||||
}
|
||||
}
|
||||
|
||||
private void addResultRow(SwfInMemory swf) {
|
||||
if (swf != null) {
|
||||
com.jpexs.process.Process process = swf.process;
|
||||
resTableModel.addRow(new Object[]{swf.version, swf.fileSize, process.getPid(), process.getFileName()});
|
||||
} else {
|
||||
String notFound = translate("notfound");
|
||||
resTableModel.addRow(new Object[]{notFound, 0, "", ""});
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshList() {
|
||||
model.clear();
|
||||
processlist = ProcessTools.listProcesses();
|
||||
Collections.sort(processlist);
|
||||
for (com.jpexs.process.Process p : processlist) {
|
||||
model.addElement(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void openSWF() {
|
||||
if (foundIs == null) {
|
||||
return;
|
||||
}
|
||||
int index = tableRes.getRowSorter().convertRowIndexToModel(tableRes.getSelectedRow());
|
||||
if (index > -1) {
|
||||
SwfInMemory swf = foundIs.get(index);
|
||||
ReReadableInputStream str = swf.is;
|
||||
try {
|
||||
str.seek(0);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(LoadFromMemoryFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return;
|
||||
}
|
||||
str.mark(Integer.MAX_VALUE);
|
||||
SWFSourceInfo sourceInfo = new SWFSourceInfo(str, null, swf.process + " [" + (index + 1) + "]");
|
||||
Main.openFile(sourceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void selectProcess() {
|
||||
if (processing) {
|
||||
return;
|
||||
}
|
||||
selProcesses = list.getSelectedValuesList();
|
||||
if (!selProcesses.isEmpty()) {
|
||||
processing = true;
|
||||
tableRes.setEnabled(false);
|
||||
resTableModel.getDataVector().removeAllElements();
|
||||
resTableModel.fireTableDataChanged();
|
||||
foundIs = null;
|
||||
progress.setIndeterminate(true);
|
||||
progress.setString(translate("searching"));
|
||||
progress.setStringPainted(true);
|
||||
progress.setVisible(true);
|
||||
final SelectProcessWorker wrk = new SelectProcessWorker(selProcesses);
|
||||
wrk.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
switch (evt.getPropertyName()) {
|
||||
case "progress":
|
||||
progress.setIndeterminate(false);
|
||||
progress.setStringPainted(false);
|
||||
progress.setValue((Integer) evt.getNewValue());
|
||||
break;
|
||||
case "state":
|
||||
if (((StateValue) evt.getNewValue()) == StateValue.DONE) {
|
||||
try {
|
||||
foundIs = wrk.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
Logger.getLogger(LoadFromMemoryFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (foundIs == null) {
|
||||
addResultRow(null);
|
||||
}
|
||||
tableRes.setEnabled(foundIs != null);
|
||||
progress.setVisible(false);
|
||||
processing = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
wrk.execute();
|
||||
}
|
||||
}
|
||||
|
||||
public LoadFromMemoryFrame(final MainFrame mainFrame) {
|
||||
setSize(800, 600);
|
||||
//setAlwaysOnTop(true);
|
||||
setTitle(translate("dialog.title"));
|
||||
|
||||
this.mainFrame = mainFrame;
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (!mainFrame.isVisible()) {
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
model = new DefaultListModel<>();
|
||||
|
||||
resTableModel = new DefaultTableModel() {
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return Integer.class;
|
||||
case 1:
|
||||
return Integer.class;
|
||||
case 2:
|
||||
return String.class;
|
||||
case 3:
|
||||
return String.class;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
resTableModel.addColumn(translate("column.version"));
|
||||
resTableModel.addColumn(translate("column.fileSize"));
|
||||
resTableModel.addColumn(translate("column.pid"));
|
||||
resTableModel.addColumn(translate("column.processName"));
|
||||
tableRes = new JTable(resTableModel);
|
||||
TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<>(resTableModel);
|
||||
tableRes.setRowSorter(sorter);
|
||||
list = new JList<>(model);
|
||||
list.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == 10) { //Enter pressed
|
||||
selectProcess();
|
||||
}
|
||||
}
|
||||
});
|
||||
list.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() > 1) {
|
||||
selectProcess();
|
||||
}
|
||||
}
|
||||
});
|
||||
tableRes.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() > 1) {
|
||||
openSWF();
|
||||
}
|
||||
}
|
||||
});
|
||||
tableRes.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == 10) { //Enter pressed
|
||||
openSWF();
|
||||
}
|
||||
}
|
||||
});
|
||||
list.setCellRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list,
|
||||
value, index, isSelected, cellHasFocus);
|
||||
|
||||
if (value instanceof com.jpexs.process.Process) {
|
||||
if (((com.jpexs.process.Process) value).getIcon() != null) {
|
||||
label.setIcon(new ImageIcon(((com.jpexs.process.Process) value).getIcon()));
|
||||
}
|
||||
}
|
||||
if (!isSelected) {
|
||||
label.setBackground(Color.white);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
});
|
||||
refreshList();
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
|
||||
JPanel leftPanel = new JPanel(new BorderLayout());
|
||||
leftPanel.add(new JScrollPane(list), BorderLayout.CENTER);
|
||||
JPanel leftButtonsPanel = new JPanel(new FlowLayout());
|
||||
JButton selectButton = new JButton(translate("button.select"));
|
||||
selectButton.setActionCommand(ACTION_SELECT_PROCESS);
|
||||
selectButton.addActionListener(this);
|
||||
JButton refreshButton = new JButton(translate("button.refresh"));
|
||||
refreshButton.setActionCommand(ACTION_REFRESH_PROCESS_LIST);
|
||||
refreshButton.addActionListener(this);
|
||||
leftButtonsPanel.add(selectButton);
|
||||
leftButtonsPanel.add(refreshButton);
|
||||
leftPanel.add(leftButtonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel rightPanel = new JPanel(new BorderLayout());
|
||||
rightPanel.add(new JScrollPane(tableRes), BorderLayout.CENTER);
|
||||
JPanel rightButtonsPanel = new JPanel(new FlowLayout());
|
||||
JButton openButton = new JButton(translate("button.open"));
|
||||
openButton.setActionCommand(ACTION_OPEN_SWF);
|
||||
openButton.addActionListener(this);
|
||||
|
||||
JButton saveButton = new JButton(translate("button.save"));
|
||||
saveButton.setActionCommand(ACTION_SAVE);
|
||||
saveButton.addActionListener(this);
|
||||
|
||||
rightButtonsPanel.add(openButton);
|
||||
rightButtonsPanel.add(saveButton);
|
||||
rightPanel.add(rightButtonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel statePanel = new JPanel();
|
||||
statePanel.setLayout(new BoxLayout(statePanel, BoxLayout.Y_AXIS));
|
||||
|
||||
stateLabel = new JLabel(translate("noprocess"));
|
||||
statePanel.add(stateLabel);
|
||||
progress = new JProgressBar(0, 100);
|
||||
statePanel.add(progress);
|
||||
progress.setVisible(false);
|
||||
rightPanel.add(statePanel, BorderLayout.NORTH);
|
||||
|
||||
cnt.add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel), BorderLayout.CENTER);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
java.util.List<Image> images = new ArrayList<>();
|
||||
images.add(View.loadImage("loadmemory16"));
|
||||
images.add(View.loadImage("loadmemory32"));
|
||||
setIconImages(images);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_SELECT_PROCESS:
|
||||
selectProcess();
|
||||
break;
|
||||
case ACTION_OPEN_SWF:
|
||||
openSWF();
|
||||
break;
|
||||
case ACTION_REFRESH_PROCESS_LIST:
|
||||
refreshList();
|
||||
break;
|
||||
case ACTION_SAVE:
|
||||
if (foundIs == null) {
|
||||
return;
|
||||
}
|
||||
int[] selected = tableRes.getSelectedRows();
|
||||
if (selected.length > 0) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
|
||||
if (selected.length > 1) {
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
} else {
|
||||
fc.setSelectedFile(new File(Configuration.lastSaveDir.get(), "movie.swf"));
|
||||
fc.setFileFilter(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return (f.getName().endsWith(".swf")) || (f.isDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return AppStrings.translate("filter.swf");
|
||||
}
|
||||
});
|
||||
}
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
JFrame f = new JFrame();
|
||||
View.setWindowIcon(f);
|
||||
int returnVal = fc.showSaveDialog(f);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
File file = Helper.fixDialogFile(fc.getSelectedFile());
|
||||
try {
|
||||
if (selected.length == 1) {
|
||||
SwfInMemory swf = foundIs.get(tableRes.getRowSorter().convertRowIndexToModel(selected[0]));
|
||||
ReReadableInputStream bis = swf.is;
|
||||
bis.seek(0);
|
||||
Helper.saveStream(bis, file);
|
||||
} else {
|
||||
for (int sel : selected) {
|
||||
SwfInMemory swf = foundIs.get(tableRes.getRowSorter().convertRowIndexToModel(sel));
|
||||
ReReadableInputStream bis = swf.is;
|
||||
bis.seek(0);
|
||||
Helper.saveStream(bis, new File(file, "movie" + sel + ".swf"));
|
||||
}
|
||||
}
|
||||
Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
|
||||
} catch (IOException ex) {
|
||||
View.showMessageDialog(null, translate("error.file.write"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.ApplicationInfo;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.ImageObserver;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
/**
|
||||
* Dialog showing loading of SWF file
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LoadingDialog extends AppDialog implements ImageObserver {
|
||||
|
||||
private final JLabel detailLabel;
|
||||
private LoadingPanel loadingPanel;
|
||||
JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
|
||||
public void setDetail(String d) {
|
||||
detailLabel.setText(d);
|
||||
detailLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
}
|
||||
|
||||
public void setPercent(final int percent) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setValue(percent);
|
||||
progressBar.setStringPainted(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hidePercent() {
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setStringPainted(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public LoadingDialog() {
|
||||
setResizable(false);
|
||||
setTitle(ApplicationInfo.shortApplicationVerName);
|
||||
Container cntp = getContentPane();
|
||||
JPanel cnt = new JPanel();
|
||||
cntp.setLayout(new BorderLayout());
|
||||
cntp.add(cnt);
|
||||
cnt.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
cnt.setLayout(new BorderLayout());
|
||||
|
||||
//loadingPanel = new LoadingPanel(50, 50);
|
||||
//loadingPanel.setPreferredSize(new Dimension(100, 100));
|
||||
//add(loadingPanel, BorderLayout.WEST);
|
||||
JPanel pan = new JPanel();
|
||||
pan.setLayout(new ListLayout(5));
|
||||
//pan.setPreferredSize(new Dimension(120, 150));
|
||||
JLabel loadingLabel = new JLabel(translate("loadingpleasewait"));
|
||||
//loadingLabel.setBounds(0, 30, 150, 20);
|
||||
loadingLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
detailLabel = new JLabel("", JLabel.CENTER);
|
||||
detailLabel.setPreferredSize(new Dimension(loadingLabel.getPreferredSize()));
|
||||
detailLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//detailLabel.setBounds(0, 45, 150, 20);
|
||||
//progressBar.setBounds(0, 70, 125, 25);
|
||||
pan.add(loadingLabel);
|
||||
pan.add(detailLabel);
|
||||
pan.add(progressBar);
|
||||
cnt.add(pan, BorderLayout.CENTER);
|
||||
//progressBar.setVisible(false);
|
||||
progressBar.setStringPainted(true);
|
||||
//progressBar.setVisible(false);
|
||||
View.setWindowIcon(this);
|
||||
detailLabel.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
pack();
|
||||
Dimension siz = getSize();
|
||||
setSize(Math.max(300, 150 + getFontMetrics(new JLabel().getFont()).stringWidth(translate("loadingpleasewait"))), siz.height);
|
||||
View.centerScreen(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.util.Timer;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* Panel with loading animation
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LoadingPanel extends JPanel {
|
||||
|
||||
private int pos = 0;
|
||||
private final Image animationImage;
|
||||
private final int iconWidth;
|
||||
private final int iconHeight;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param iconWidth Width of displayed icon
|
||||
* @param iconHeight Height of displayed icon
|
||||
*/
|
||||
public LoadingPanel(int iconWidth, int iconHeight) {
|
||||
this.iconWidth = iconWidth;
|
||||
this.iconHeight = iconHeight;
|
||||
ImageIcon icon = View.getIcon("loading");
|
||||
animationImage = icon.getImage();
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new java.util.TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
pos = (pos + 1) % 12;
|
||||
repaint();
|
||||
}
|
||||
}, 100, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints component
|
||||
*
|
||||
* @param g Graphics to paint on
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.drawImage(animationImage, getWidth() / 2 - iconWidth / 2, getHeight() / 2 - iconHeight / 2, getWidth() / 2 + iconWidth / 2, getHeight() / 2 + iconHeight / 2, pos * 100, 0, (pos + 1) * 100, 100, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LogFormatter extends Formatter {
|
||||
|
||||
static final String lineSep = System.getProperty("line.separator");
|
||||
private DateFormat dateFormat;
|
||||
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
StringBuilder buf = new StringBuilder(180);
|
||||
|
||||
if (dateFormat == null) {
|
||||
dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
|
||||
}
|
||||
|
||||
buf.append(dateFormat.format(new Date(record.getMillis())));
|
||||
buf.append(" > ");
|
||||
|
||||
if (record.getLevel().intValue() >= Level.WARNING.intValue()) {
|
||||
buf.append(record.getLevel());
|
||||
buf.append(": ");
|
||||
}
|
||||
buf.append(formatMessage(record));
|
||||
|
||||
buf.append(lineSep);
|
||||
|
||||
Throwable throwable = record.getThrown();
|
||||
if (throwable != null) {
|
||||
StringWriter sink = new StringWriter();
|
||||
throwable.printStackTrace(new PrintWriter(sink, true));
|
||||
buf.append(record.getSourceClassName());
|
||||
buf.append(' ');
|
||||
buf.append(record.getSourceMethodName());
|
||||
buf.append(lineSep);
|
||||
buf.append(sink.toString());
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface MainFrame {
|
||||
|
||||
public void setTitle(String string);
|
||||
|
||||
public String translate(String key);
|
||||
|
||||
public MainPanel getPanel();
|
||||
|
||||
public boolean isVisible();
|
||||
|
||||
public void setVisible(boolean b);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.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 MainPanel 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 MainPanel(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) {
|
||||
Main.exit();
|
||||
}
|
||||
});
|
||||
|
||||
java.awt.Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(panel);
|
||||
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
super.setVisible(b);
|
||||
panel.setVisible(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MainPanel getPanel() {
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,579 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.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.gui.treenodes.SWFNode;
|
||||
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.ByteArrayOutputStream;
|
||||
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 final 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);
|
||||
|
||||
JMenuItem advancedSettingsCommandButton = new JMenuItem(translate("menu.advancedsettings.advancedsettings"));
|
||||
advancedSettingsCommandButton.setActionCommand(ACTION_ADVANCED_SETTINGS);
|
||||
advancedSettingsCommandButton.setIcon(View.getIcon("settings16"));
|
||||
advancedSettingsCommandButton.addActionListener(this);
|
||||
menuSettings.add(advancedSettingsCommandButton);
|
||||
|
||||
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 updateComponents(SWF swf, List<ABCContainerTag> 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);*/
|
||||
}
|
||||
|
||||
private void saveAs(SWF swf, SaveFileMode mode) {
|
||||
if (Main.saveFileDialog(swf, mode)) {
|
||||
swf.fileTitle = null;
|
||||
mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : ""));
|
||||
saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null);
|
||||
}
|
||||
}
|
||||
|
||||
@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.reloadApp();
|
||||
}
|
||||
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(), false);
|
||||
|
||||
//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: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
SWFNode snode = ((TagTreeModel)mainFrame.panel.tagTree.getModel()).getSwfNode(swf);
|
||||
if(snode.binaryData!=null){
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
swf.saveTo(baos);
|
||||
snode.binaryData.binaryData = baos.toByteArray();
|
||||
snode.binaryData.setModified(true);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MainFrameRibbonMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
|
||||
}
|
||||
}
|
||||
else if(swf.file == null) {
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
} else {
|
||||
try {
|
||||
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();
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS_EXE: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
saveAs(swf, SaveFileMode.EXE);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface MainFrameMenu {
|
||||
|
||||
public boolean isInternalFlashViewerSelected();
|
||||
|
||||
public void updateComponents(SWF swf, List<ABCContainerTag> abcList);
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
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 java.util.List;
|
||||
import javax.swing.JFrame;
|
||||
import org.pushingpixels.flamingo.api.ribbon.JRibbon;
|
||||
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public final class MainFrameRibbon extends AppRibbonFrame implements MainFrame {
|
||||
|
||||
public MainPanel panel;
|
||||
private MainFrameMenu mainMenu;
|
||||
|
||||
public MainFrameRibbon() {
|
||||
super();
|
||||
|
||||
FlashPlayerPanel flashPanel = null;
|
||||
try {
|
||||
flashPanel = new FlashPlayerPanel(this);
|
||||
} catch (FlashUnsupportedException fue) {
|
||||
}
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
JRibbon ribbon = getRibbon();
|
||||
cnt.add(ribbon, BorderLayout.NORTH);
|
||||
|
||||
boolean externalFlashPlayerUnavailable = flashPanel == null;
|
||||
mainMenu = new MainFrameRibbonMenu(this, ribbon, externalFlashPlayerUnavailable);
|
||||
|
||||
panel = new MainPanel(this, mainMenu, flashPanel);
|
||||
panel.setBackground(Color.yellow);
|
||||
cnt.add(panel, BorderLayout.CENTER);
|
||||
|
||||
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) {
|
||||
Main.exit();
|
||||
}
|
||||
});
|
||||
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
private static void getApplicationMenuButtons(Component comp, List<JRibbonApplicationMenuButton> 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);
|
||||
|
||||
/* final MainFrameRibbon t = this;
|
||||
|
||||
//TODO: Handle this better. This is awful :-(
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<JRibbonApplicationMenuButton> mbuttons = new ArrayList<>();
|
||||
getApplicationMenuButtons(t, mbuttons);
|
||||
if (mbuttons.size() < 2) {
|
||||
//return, task will run again
|
||||
return;
|
||||
}
|
||||
|
||||
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"));
|
||||
mbutton.repaint();
|
||||
}
|
||||
cancel(); //cancel task so it does not run again
|
||||
}
|
||||
}, 1, 50);*/
|
||||
panel.setVisible(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MainPanel getPanel() {
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,804 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.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.gui.helpers.CheckResources;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFNode;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import com.jpexs.process.ProcessTools;
|
||||
import com.sun.jna.Platform;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
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.JDialog;
|
||||
import javax.swing.JEditorPane;
|
||||
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 = "SEARCH";
|
||||
static final String ACTION_TIMELINE = "TIMELINE";
|
||||
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_CLOSE = "CLOSE";
|
||||
static final String ACTION_CLOSE_ALL = "CLOSEALL";
|
||||
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_IMPORT_TEXT = "IMPORTTEXT";
|
||||
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";
|
||||
static final String ACTION_CLEAR_RECENT_FILES = "CLEARRECENTFILES";
|
||||
static final String ACTION_CHECK_RESOURCES = "CHECKRESOURCES";
|
||||
|
||||
private final 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 importTextCommandButton;
|
||||
|
||||
private JCommandButton reloadCommandButton;
|
||||
private JCommandButton renameinvalidCommandButton;
|
||||
private JCommandButton globalrenameCommandButton;
|
||||
private JCommandButton deobfuscationCommandButton;
|
||||
private JCommandButton searchCommandButton;
|
||||
private JCommandButton timeLineCommandButton;
|
||||
private JCommandButton gotoDocumentClassCommandButton;
|
||||
private JCommandButton clearRecentFilesCommandButton;
|
||||
|
||||
RibbonApplicationMenuEntryPrimary exportFlaMenu;
|
||||
RibbonApplicationMenuEntryPrimary exportAllMenu;
|
||||
RibbonApplicationMenuEntryPrimary exportSelMenu;
|
||||
RibbonApplicationMenuEntryPrimary closeFileMenu;
|
||||
RibbonApplicationMenuEntryPrimary closeAllFilesMenu;
|
||||
|
||||
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);
|
||||
closeFileMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("close32"), translate("menu.file.close"), new ActionRedirector(this, ACTION_CLOSE), JCommandButton.CommandButtonKind.ACTION_ONLY);
|
||||
closeAllFilesMenu = new RibbonApplicationMenuEntryPrimary(View.getResizableIcon("close32"), translate("menu.file.closeAll"), new ActionRedirector(this, ACTION_CLOSE_ALL), JCommandButton.CommandButtonKind.ACTION_ONLY);
|
||||
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<String> 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.addMenuEntry(closeFileMenu);
|
||||
mainMenu.addMenuEntry(closeAllFilesMenu);
|
||||
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<RibbonBandResizePolicy> getResizePolicies(JRibbonBand ribbonBand) {
|
||||
List<RibbonBandResizePolicy> resizePolicies = new ArrayList<>();
|
||||
resizePolicies.add(new CoreRibbonResizePolicies.Mirror(ribbonBand.getControlPanel()));
|
||||
resizePolicies.add(new IconRibbonBandResizePolicy(ribbonBand.getControlPanel()));
|
||||
return resizePolicies;
|
||||
}
|
||||
|
||||
private List<RibbonBandResizePolicy> getIconBandResizePolicies(JRibbonBand ribbonBand) {
|
||||
List<RibbonBandResizePolicy> resizePolicies = new ArrayList<>();
|
||||
resizePolicies.add(new BaseRibbonBandResizePolicy<AbstractBandControlPanel>(ribbonBand.getControlPanel()) {
|
||||
@Override
|
||||
public int getPreferredWidth(int i, int i1) {
|
||||
return 105;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(int i, int i1) {
|
||||
}
|
||||
});
|
||||
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);
|
||||
|
||||
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(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);
|
||||
saveasexeCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.saveasexe")), View.getResizableIcon("saveasexe16"));
|
||||
assignListener(saveasexeCommandButton, ACTION_SAVE_AS_EXE);
|
||||
|
||||
exportBand.addCommandButton(exportFlaCommandButton, RibbonElementPriority.TOP);
|
||||
exportBand.addCommandButton(exportAllCommandButton, RibbonElementPriority.MEDIUM);
|
||||
exportBand.addCommandButton(exportSelectionCommandButton, RibbonElementPriority.MEDIUM);
|
||||
exportBand.addCommandButton(saveasexeCommandButton, RibbonElementPriority.MEDIUM);
|
||||
|
||||
JRibbonBand importBand = new JRibbonBand(translate("menu.import"), null);
|
||||
importBand.setResizePolicies(getResizePolicies(importBand));
|
||||
importTextCommandButton = new JCommandButton(fixCommandTitle(translate("menu.file.import.text")), View.getResizableIcon("import32"));
|
||||
assignListener(importTextCommandButton, ACTION_IMPORT_TEXT);
|
||||
|
||||
importBand.addCommandButton(importTextCommandButton, RibbonElementPriority.TOP);
|
||||
|
||||
return new RibbonTask(translate("menu.file"), editBand, exportBand, importBand);
|
||||
}
|
||||
|
||||
private RibbonTask createToolsRibbonTask() {
|
||||
//----------------------------------------- TOOLS -----------------------------------
|
||||
|
||||
JRibbonBand toolsBand = new JRibbonBand(translate("menu.tools"), null);
|
||||
toolsBand.setResizePolicies(getResizePolicies(toolsBand));
|
||||
|
||||
searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.search")), View.getResizableIcon("search32"));
|
||||
assignListener(searchCommandButton, ACTION_SEARCH);
|
||||
|
||||
timeLineCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
|
||||
assignListener(timeLineCommandButton, ACTION_TIMELINE);
|
||||
|
||||
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(timeLineCommandButton, 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);
|
||||
|
||||
//JRibbonBand otherToolsBand = new JRibbonBand(translate("menu.tools.otherTools"), null);
|
||||
//otherToolsBand.setResizePolicies(getResizePolicies(otherToolsBand));
|
||||
return new RibbonTask(translate("menu.tools"), toolsBand, deobfuscationBand/*, otherToolsBand*/);
|
||||
}
|
||||
|
||||
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<RibbonBandResizePolicy> languageBandResizePolicies = getIconBandResizePolicies(languageBand);
|
||||
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("settings32"));
|
||||
assignListener(advancedSettingsCommandButton, ACTION_ADVANCED_SETTINGS);
|
||||
advancedSettingsBand.addCommandButton(advancedSettingsCommandButton, RibbonElementPriority.TOP);
|
||||
|
||||
clearRecentFilesCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.otherTools.clearRecentFiles")), View.getResizableIcon("clearrecent16"));
|
||||
assignListener(clearRecentFilesCommandButton, ACTION_CLEAR_RECENT_FILES);
|
||||
advancedSettingsBand.addCommandButton(clearRecentFilesCommandButton, 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);
|
||||
|
||||
JCommandButton checkResourcesCommandButton = new JCommandButton(fixCommandTitle("Check resources"), View.getResizableIcon("update16"));
|
||||
assignListener(checkResourcesCommandButton, ACTION_CHECK_RESOURCES);
|
||||
|
||||
debugBand.addCommandButton(removeNonScriptsCommandButton, RibbonElementPriority.MEDIUM);
|
||||
debugBand.addCommandButton(refreshDecompiledCommandButton, RibbonElementPriority.MEDIUM);
|
||||
debugBand.addCommandButton(checkResourcesCommandButton, RibbonElementPriority.MEDIUM);
|
||||
return new RibbonTask("Debug", debugBand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateComponents(SWF swf, List<ABCContainerTag> abcList) {
|
||||
boolean swfLoaded = swf != null;
|
||||
boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty();
|
||||
|
||||
exportAllMenu.setEnabled(swfLoaded);
|
||||
exportFlaMenu.setEnabled(swfLoaded);
|
||||
exportSelMenu.setEnabled(swfLoaded);
|
||||
closeFileMenu.setEnabled(swfLoaded);
|
||||
closeAllFilesMenu.setEnabled(swfLoaded);
|
||||
|
||||
boolean isBundle = swfLoaded && (swf.swfList != null) && swf.swfList.isBundle;
|
||||
saveCommandButton.setEnabled(swfLoaded && !isBundle);
|
||||
saveasCommandButton.setEnabled(swfLoaded);
|
||||
saveasexeCommandButton.setEnabled(swfLoaded);
|
||||
exportAllCommandButton.setEnabled(swfLoaded);
|
||||
exportFlaCommandButton.setEnabled(swfLoaded);
|
||||
exportSelectionCommandButton.setEnabled(swfLoaded);
|
||||
importTextCommandButton.setEnabled(swfLoaded);
|
||||
reloadCommandButton.setEnabled(swfLoaded);
|
||||
|
||||
renameinvalidCommandButton.setEnabled(swfLoaded);
|
||||
globalrenameCommandButton.setEnabled(swfLoaded);
|
||||
deobfuscationCommandButton.setEnabled(swfLoaded);
|
||||
searchCommandButton.setEnabled(swfLoaded);
|
||||
timeLineCommandButton.setEnabled(swfLoaded);
|
||||
|
||||
gotoDocumentClassCommandButton.setEnabled(hasAbc);
|
||||
deobfuscationCommandButton.setEnabled(hasAbc);
|
||||
}
|
||||
|
||||
private void saveAs(SWF swf, SaveFileMode mode) {
|
||||
if (Main.saveFileDialog(swf, mode)) {
|
||||
swf.fileTitle = null;
|
||||
mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : ""));
|
||||
saveCommandButton.setEnabled(mainFrame.panel.getCurrentSwf() != null);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearModified(SWF swf) {
|
||||
for (Tag tag : swf.tags) {
|
||||
if (tag.isModified()) {
|
||||
tag.createOriginalData();
|
||||
tag.setModified(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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.reloadApp();
|
||||
}
|
||||
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(), false);
|
||||
|
||||
//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:
|
||||
mainFrame.panel.searchAs();
|
||||
break;
|
||||
case ACTION_TIMELINE:
|
||||
mainFrame.panel.timeline();
|
||||
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_CLEAR_RECENT_FILES:
|
||||
Configuration.recentFiles.set(null);
|
||||
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: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
SWFNode snode = ((TagTreeModel)mainFrame.panel.tagTree.getModel()).getSwfNode(swf);
|
||||
if(snode.binaryData!=null){
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
swf.saveTo(baos);
|
||||
snode.binaryData.binaryData = baos.toByteArray();
|
||||
snode.binaryData.setModified(true);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MainFrameRibbonMenu.class.getName()).log(Level.SEVERE, "Cannot save SWF", ex);
|
||||
}
|
||||
}
|
||||
else if (swf.file == null) {
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
} else {
|
||||
try {
|
||||
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);
|
||||
}
|
||||
}
|
||||
clearModified(swf);
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
clearModified(swf);
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS_EXE: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
saveAs(swf, SaveFileMode.EXE);
|
||||
}
|
||||
break;
|
||||
case ACTION_OPEN:
|
||||
Main.openFileDialog();
|
||||
break;
|
||||
case ACTION_CLOSE:
|
||||
Main.closeFile(mainFrame.panel.getCurrentSwfList());
|
||||
break;
|
||||
case ACTION_CLOSE_ALL:
|
||||
Main.closeAll();
|
||||
break;
|
||||
case ACTION_EXPORT_FLA:
|
||||
mainFrame.panel.exportFla(mainFrame.panel.getCurrentSwf());
|
||||
break;
|
||||
case ACTION_IMPORT_TEXT:
|
||||
mainFrame.panel.importText(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;
|
||||
case ACTION_CHECK_RESOURCES:
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
PrintStream stream = new PrintStream(os);
|
||||
CheckResources.checkResources(stream);
|
||||
final String str = new String(os.toByteArray(), Utf8Helper.charset);
|
||||
JDialog dialog = new JDialog() {
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean bln) {
|
||||
setSize(new Dimension(800, 600));
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
ScrollPane scrollPane = new ScrollPane();
|
||||
JEditorPane editor = new JEditorPane();
|
||||
editor.setEditable(false);
|
||||
editor.setText(str);
|
||||
scrollPane.add(editor);
|
||||
this.add(scrollPane, BorderLayout.CENTER);
|
||||
this.setModal(true);
|
||||
View.centerScreen(this);
|
||||
super.setVisible(bln);
|
||||
}
|
||||
};
|
||||
dialog.setVisible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.helpers.CancellableWorker;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MainFrameStatusPanel extends JPanel implements ActionListener {
|
||||
|
||||
static final String ACTION_SHOW_ERROR_LOG = "SHOWERRORLOG";
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
private final LoadingPanel loadingPanel = new LoadingPanel(20, 20);
|
||||
private final JLabel statusLabel = new JLabel("");
|
||||
private final JButton cancelButton = new JButton();
|
||||
private JButton errorNotificationButton;
|
||||
|
||||
private Icon currentIcon;
|
||||
private Timer blinkTimer;
|
||||
private int blinkPos;
|
||||
|
||||
private CancellableWorker currentWorker;
|
||||
|
||||
public MainFrameStatusPanel(MainPanel mainPanel) {
|
||||
this.mainPanel = mainPanel;
|
||||
createStatusPanel();
|
||||
}
|
||||
|
||||
private void createStatusPanel() {
|
||||
JPanel statusLeftPanel = new JPanel();
|
||||
statusLeftPanel.setLayout(new BoxLayout(statusLeftPanel, BoxLayout.X_AXIS));
|
||||
loadingPanel.setPreferredSize(new Dimension(30, 30));
|
||||
// todo: this button is a little bit ugly in the UI. Maybe it can be changed to an icon (as in NetBeans)
|
||||
cancelButton.setText(translate("button.cancel"));
|
||||
cancelButton.setPreferredSize(new Dimension(100, 30));
|
||||
cancelButton.setBorderPainted(false);
|
||||
cancelButton.setOpaque(false);
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (currentWorker != null) {
|
||||
currentWorker.cancel(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
statusLeftPanel.add(loadingPanel);
|
||||
statusLeftPanel.add(statusLabel);
|
||||
statusLeftPanel.add(cancelButton);
|
||||
setPreferredSize(new Dimension(1, 30));
|
||||
setBorder(new BevelBorder(BevelBorder.LOWERED));
|
||||
setLayout(new BorderLayout());
|
||||
add(statusLeftPanel, BorderLayout.WEST);
|
||||
|
||||
errorNotificationButton = new JButton("");
|
||||
errorNotificationButton.setIcon(View.getIcon("okay16"));
|
||||
errorNotificationButton.setBorderPainted(false);
|
||||
errorNotificationButton.setFocusPainted(false);
|
||||
errorNotificationButton.setContentAreaFilled(false);
|
||||
errorNotificationButton.setMargin(new Insets(2, 2, 2, 2));
|
||||
errorNotificationButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
errorNotificationButton.setActionCommand(ACTION_SHOW_ERROR_LOG);
|
||||
errorNotificationButton.addActionListener(this);
|
||||
errorNotificationButton.setToolTipText(translate("errors.none"));
|
||||
add(errorNotificationButton, BorderLayout.EAST);
|
||||
|
||||
loadingPanel.setVisible(false);
|
||||
cancelButton.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_SHOW_ERROR_LOG:
|
||||
Main.displayErrorFrame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String translate(String key) {
|
||||
return mainPanel.translate(key);
|
||||
}
|
||||
|
||||
public void setStatus(String s) {
|
||||
statusLabel.setText(s);
|
||||
}
|
||||
|
||||
public void setWorkStatus(String s, CancellableWorker worker) {
|
||||
if (s.isEmpty()) {
|
||||
loadingPanel.setVisible(false);
|
||||
} else {
|
||||
loadingPanel.setVisible(true);
|
||||
}
|
||||
statusLabel.setText(s);
|
||||
currentWorker = worker;
|
||||
cancelButton.setVisible(worker != null);
|
||||
}
|
||||
|
||||
public void setErrorState(ErrorState errorState) {
|
||||
if (errorNotificationButton == null) {
|
||||
// todo: honfika
|
||||
// why null?
|
||||
return;
|
||||
}
|
||||
switch (errorState) {
|
||||
case NO_ERROR:
|
||||
currentIcon = View.getIcon("okay16");
|
||||
errorNotificationButton.setToolTipText(translate("errors.none"));
|
||||
blinkPos = 0;
|
||||
break;
|
||||
case INFO:
|
||||
currentIcon = View.getIcon("information16");
|
||||
errorNotificationButton.setToolTipText(translate("errors.info"));
|
||||
break;
|
||||
case WARNING:
|
||||
currentIcon = View.getIcon("warning16");
|
||||
errorNotificationButton.setToolTipText(translate("errors.warning"));
|
||||
break;
|
||||
case ERROR:
|
||||
currentIcon = View.getIcon("error16");
|
||||
errorNotificationButton.setToolTipText(translate("errors.present"));
|
||||
break;
|
||||
}
|
||||
|
||||
errorNotificationButton.setIcon(currentIcon);
|
||||
|
||||
if (errorState != ErrorState.NO_ERROR) {
|
||||
if (blinkTimer != null) {
|
||||
blinkTimer.cancel();
|
||||
}
|
||||
blinkTimer = new Timer();
|
||||
blinkTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
blinkPos++;
|
||||
if ((blinkPos % 2) == 0 || (blinkPos >= 4)) {
|
||||
errorNotificationButton.setIcon(currentIcon);
|
||||
} else {
|
||||
errorNotificationButton.setIcon(null);
|
||||
errorNotificationButton.setSize(16, 16);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (blinkPos >= 4) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}, 500, 500);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.ApplicationInfo;
|
||||
import java.awt.Container;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* Frame with selection on application startServer
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ModeFrame extends AppFrame implements ActionListener {
|
||||
|
||||
static final String ACTION_OPEN = "OPEN";
|
||||
static final String ACTION_PROXY = "PROXY";
|
||||
static final String ACTION_EXIT = "EXIT";
|
||||
|
||||
private final JButton openButton = new JButton(translate("button.open"));
|
||||
private final JButton proxyButton = new JButton(translate("button.proxy"));
|
||||
private final JButton exitButton = new JButton(translate("button.exit"));
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ModeFrame() {
|
||||
setSize(350, 200);
|
||||
openButton.addActionListener(this);
|
||||
openButton.setActionCommand(ACTION_OPEN);
|
||||
openButton.setIcon(View.getIcon("open32"));
|
||||
proxyButton.addActionListener(this);
|
||||
proxyButton.setActionCommand(ACTION_PROXY);
|
||||
proxyButton.setIcon(View.getIcon("proxy32"));
|
||||
exitButton.addActionListener(this);
|
||||
exitButton.setActionCommand(ACTION_EXIT);
|
||||
exitButton.setIcon(View.getIcon("exit32"));
|
||||
setResizable(false);
|
||||
Container cont = getContentPane();
|
||||
cont.setLayout(new GridLayout(4, 1));
|
||||
JLabel logoLabel = new JLabel();
|
||||
logoLabel.setIcon(View.getIcon("logo"));
|
||||
cont.add(logoLabel);
|
||||
cont.add(openButton);
|
||||
cont.add(proxyButton);
|
||||
cont.add(exitButton);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
setTitle(ApplicationInfo.shortApplicationVerName);
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
Main.exit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method handling actions from buttons
|
||||
*
|
||||
* @param e event
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OPEN:
|
||||
setVisible(false);
|
||||
if (!Main.openFileDialog()) {
|
||||
setVisible(true);
|
||||
}
|
||||
break;
|
||||
case ACTION_PROXY:
|
||||
setVisible(false);
|
||||
Main.showProxy();
|
||||
break;
|
||||
case ACTION_EXIT:
|
||||
setVisible(false);
|
||||
Main.exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import org.pushingpixels.flamingo.api.common.JCommandButton;
|
||||
import org.pushingpixels.flamingo.api.common.popup.JCommandPopupMenu;
|
||||
import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
|
||||
import org.pushingpixels.flamingo.api.common.popup.PopupPanelManager;
|
||||
import org.pushingpixels.substance.flamingo.common.ui.SubstanceCommandButtonUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* Own CommandButtonUI because original Flamingo UI throws Exception in some cases
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyCommandButtonUI extends SubstanceCommandButtonUI{
|
||||
public static ComponentUI createUI(JComponent comp) {
|
||||
return new MyCommandButtonUI((JCommandButton)comp);
|
||||
}
|
||||
|
||||
public MyCommandButtonUI(JCommandButton jcb) {
|
||||
super(jcb);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
this.commandButton.removeActionListener(this.disposePopupsActionListener);
|
||||
this.disposePopupsActionListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(commandButton == null){ //Added by JPEXS
|
||||
return;
|
||||
}
|
||||
boolean toDismiss = !Boolean.TRUE.equals(commandButton
|
||||
.getClientProperty(DONT_DISPOSE_POPUPS));
|
||||
if (toDismiss) {
|
||||
JCommandPopupMenu menu = (JCommandPopupMenu) SwingUtilities
|
||||
.getAncestorOfClass(JCommandPopupMenu.class,
|
||||
commandButton);
|
||||
if (menu != null) {
|
||||
toDismiss = menu.isToDismissOnChildClick();
|
||||
}
|
||||
}
|
||||
if (toDismiss) {
|
||||
if (SwingUtilities.getAncestorOfClass(JPopupPanel.class,
|
||||
commandButton) != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// command button may be cleared if the
|
||||
// button click resulted in LAF switch
|
||||
if (commandButton != null) {
|
||||
// clear the active states
|
||||
commandButton.getActionModel().setPressed(
|
||||
false);
|
||||
commandButton.getActionModel().setRollover(
|
||||
false);
|
||||
commandButton.getActionModel().setArmed(
|
||||
false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
PopupPanelManager.defaultManager().hidePopups(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
this.commandButton.addActionListener(disposePopupsActionListener);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.text.Format;
|
||||
import javax.swing.JFormattedTextField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyFormattedTextField extends JFormattedTextField {
|
||||
|
||||
public MyFormattedTextField(Format format) {
|
||||
super(format);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 javax.swing.CellRendererPane;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import org.pushingpixels.substance.internal.ui.SubstanceProgressBarUI;
|
||||
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyProgressBarUI extends SubstanceProgressBarUI {
|
||||
|
||||
private final class MySubstanceChangeListener implements ChangeListener {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
SubstanceCoreUtilities.testComponentStateChangeThreadingViolation(progressBar);
|
||||
|
||||
if (displayTimeline != null) { //Main Change - this should be first
|
||||
//displayTimeline.abort();
|
||||
}
|
||||
int currValue = progressBar.getValue();
|
||||
int span = progressBar.getMaximum() - progressBar.getMinimum();
|
||||
|
||||
int barRectWidth = progressBar.getWidth() - 2 * margin;
|
||||
int barRectHeight = progressBar.getHeight() - 2 * margin;
|
||||
int totalPixels = (progressBar.getOrientation() == JProgressBar.HORIZONTAL) ? barRectWidth
|
||||
: barRectHeight;
|
||||
|
||||
int pixelDelta = (span <= 0) ? 0 : (currValue - displayedValue)
|
||||
* totalPixels / span;
|
||||
|
||||
|
||||
/*displayTimeline = new Timeline(progressBar);
|
||||
displayTimeline.addPropertyToInterpolate(Timeline
|
||||
.<Integer>property("displayedValue").from(displayedValue)
|
||||
.to(currValue).setWith(new TimelinePropertyBuilder.PropertySetter<Integer>() {
|
||||
@Override
|
||||
public void set(Object obj, String fieldName,
|
||||
Integer value) {
|
||||
displayedValue = value;
|
||||
progressBar.repaint();
|
||||
}
|
||||
}));
|
||||
displayTimeline.setEase(new Spline(0.4f));
|
||||
AnimationConfigurationManager.getInstance().configureTimeline(
|
||||
displayTimeline);*/
|
||||
boolean isInCellRenderer = (SwingUtilities.getAncestorOfClass(
|
||||
CellRendererPane.class, progressBar) != null);
|
||||
if (false) {//currValue > 0 && !isInCellRenderer && Math.abs(pixelDelta) > 5) {
|
||||
displayTimeline.play();
|
||||
} else {
|
||||
displayedValue = currValue;
|
||||
progressBar.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ComponentUI createUI(JComponent comp) {
|
||||
SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
|
||||
return new MyProgressBarUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
this.progressBar.removeChangeListener(substanceValueChangeListener);
|
||||
this.substanceValueChangeListener = new MySubstanceChangeListener();
|
||||
this.progressBar.addChangeListener(this.substanceValueChangeListener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.Icon;
|
||||
import org.pushingpixels.flamingo.internal.utils.FlamingoUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyResizableIcon implements Icon {
|
||||
|
||||
protected BufferedImage originalImage;
|
||||
protected Map<String, BufferedImage> cachedImages = new HashMap<>();
|
||||
|
||||
public MyResizableIcon(BufferedImage originalImage) {
|
||||
this.originalImage = originalImage;
|
||||
width = originalImage.getWidth();
|
||||
height = originalImage.getHeight();
|
||||
}
|
||||
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected BufferedImage image;
|
||||
|
||||
public void setDimension(Dimension dim) {
|
||||
setIconSize(dim.width, dim.height);
|
||||
}
|
||||
|
||||
public void setIconSize(int renderWidth, int renderHeight) {
|
||||
width = renderWidth;
|
||||
height = renderHeight;
|
||||
String key = renderWidth + ":" + renderHeight;
|
||||
if (this.cachedImages.containsKey(key)) {
|
||||
image = this.cachedImages.get(key);
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedImage result = originalImage;
|
||||
float scaleX = (float) originalImage.getWidth()
|
||||
/ (float) renderWidth;
|
||||
float scaleY = (float) originalImage.getHeight()
|
||||
/ (float) renderHeight;
|
||||
|
||||
float scale = Math.max(scaleX, scaleY);
|
||||
if (scale > 1.0f) {
|
||||
int finalWidth = (int) (originalImage.getWidth() / scale);
|
||||
result = FlamingoUtilities.createThumbnail(originalImage,
|
||||
finalWidth);
|
||||
}
|
||||
cachedImages.put(renderWidth + ":" + renderHeight, result);
|
||||
image = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if (image != null) {
|
||||
int dx = (this.width - image.getWidth()) / 2;
|
||||
int dy = (this.height - image.getHeight()) / 2;
|
||||
g.drawImage(image, x + dx, y + dy, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import org.pushingpixels.flamingo.api.common.model.PopupButtonModel;
|
||||
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.BasicRibbonApplicationMenuButtonUI;
|
||||
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton;
|
||||
import org.pushingpixels.lafwidget.animation.effects.GhostingListener;
|
||||
import org.pushingpixels.substance.flamingo.common.ui.ActionPopupTransitionAwareUI;
|
||||
import org.pushingpixels.substance.flamingo.utils.CommandButtonVisualStateTracker;
|
||||
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
|
||||
|
||||
/**
|
||||
* UI for {@link JRibbonApplicationMenuButton} components in <b>Substance</b>
|
||||
* look and feel.
|
||||
*
|
||||
* @author Kirill Grouchnikov
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyRibbonApplicationMenuButtonUI extends BasicRibbonApplicationMenuButtonUI implements
|
||||
ActionPopupTransitionAwareUI {
|
||||
|
||||
private MyResizableIcon hoverIcon = null;
|
||||
private MyResizableIcon clickIcon = null;
|
||||
private MyResizableIcon normalIcon = null;
|
||||
private final boolean buttonResized = false;
|
||||
|
||||
public MyResizableIcon getClickIcon() {
|
||||
return clickIcon;
|
||||
}
|
||||
|
||||
public MyRibbonApplicationMenuButtonUI() {
|
||||
super();
|
||||
hoverIcon = View.getMyResizableIcon("buttonicon_hover_256");
|
||||
normalIcon = View.getMyResizableIcon("buttonicon_256");
|
||||
clickIcon = View.getMyResizableIcon("buttonicon_down_256");
|
||||
}
|
||||
|
||||
/**
|
||||
* Model change listener for ghost image effects.
|
||||
*/
|
||||
private GhostingListener substanceModelChangeListener;
|
||||
/**
|
||||
* Tracker for visual state transitions.
|
||||
*/
|
||||
protected CommandButtonVisualStateTracker substanceVisualStateTracker;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new MyRibbonApplicationMenuButtonUI();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jvnet.flamingo.common.ui.BasicCommandButtonUI#installListeners()
|
||||
*/
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
this.substanceVisualStateTracker = new CommandButtonVisualStateTracker();
|
||||
this.substanceVisualStateTracker.installListeners(this.commandButton);
|
||||
|
||||
this.substanceModelChangeListener = new GhostingListener(
|
||||
this.commandButton, this.commandButton.getActionModel());
|
||||
this.substanceModelChangeListener.registerListeners();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jvnet.flamingo.common.ui.BasicCommandButtonUI#uninstallListeners()
|
||||
*/
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
this.substanceVisualStateTracker.uninstallListeners(this.commandButton);
|
||||
this.substanceVisualStateTracker = null;
|
||||
|
||||
this.substanceModelChangeListener.unregisterListeners();
|
||||
this.substanceModelChangeListener = null;
|
||||
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
private void updateIcons(JComponent c) {
|
||||
|
||||
Dimension dim = c.getPreferredSize();
|
||||
hoverIcon.setDimension(dim);
|
||||
clickIcon.setDimension(dim);
|
||||
normalIcon.setDimension(dim);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicButtonUI#paint(java.awt.Graphics,
|
||||
* javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
JRibbonApplicationMenuButton b = (JRibbonApplicationMenuButton) c;
|
||||
|
||||
updateIcons(c);
|
||||
|
||||
this.layoutInfo = this.layoutManager.getLayoutInfo(this.commandButton, g);
|
||||
commandButton.putClientProperty("icon.bounds", layoutInfo.iconRect);
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
|
||||
// Paint the icon
|
||||
Icon icon = getCurrentIcon(b);
|
||||
|
||||
if (icon != null) {
|
||||
paintButtonIcon(g2d);
|
||||
}
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
private Icon getCurrentIcon(JRibbonApplicationMenuButton button) {
|
||||
PopupButtonModel mod = button.getPopupModel();
|
||||
if (mod.isPopupShowing()) {
|
||||
if (clickIcon != null) {
|
||||
return clickIcon;
|
||||
}
|
||||
}
|
||||
if (mod.isRollover()) {
|
||||
if (hoverIcon != null) {
|
||||
return hoverIcon;
|
||||
}
|
||||
}
|
||||
if (normalIcon != null) {
|
||||
return normalIcon;
|
||||
}
|
||||
return button.getIcon();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jvnet.flamingo.common.ui.BasicCommandButtonUI#paintButtonIcon(java
|
||||
* .awt.Graphics, java.awt.Rectangle)
|
||||
*/
|
||||
protected void paintButtonIcon(Graphics g) {
|
||||
Icon regular = getCurrentIcon(this.applicationMenuButton);
|
||||
if (regular == null) {
|
||||
return;
|
||||
}
|
||||
if (regular != null) {
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
regular.paintIcon(this.applicationMenuButton, g2d, 0, 0);
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jvnet.flamingo.ribbon.ui.appmenu.BasicRibbonApplicationMenuButtonUI
|
||||
* #update(java.awt.Graphics, javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
this.paint(g, c);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jvnet.substance.SubstanceButtonUI#contains(javax.swing.JComponent,
|
||||
* int, int)
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(JComponent c, int x, int y) {
|
||||
// allow clicking anywhere in the area (around the button
|
||||
// round outline as well) to activate the button.
|
||||
return (x >= 0) && (x < c.getWidth()) && (y >= 0)
|
||||
&& (y < c.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateTransitionTracker getActionTransitionTracker() {
|
||||
return this.substanceVisualStateTracker
|
||||
.getActionStateTransitionTracker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateTransitionTracker getPopupTransitionTracker() {
|
||||
return this.substanceVisualStateTracker
|
||||
.getPopupStateTransitionTracker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateTransitionTracker getTransitionTracker() {
|
||||
return this.substanceVisualStateTracker
|
||||
.getPopupStateTransitionTracker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInside(MouseEvent me) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.BasicRibbonApplicationMenuPopupPanelUI;
|
||||
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton;
|
||||
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
|
||||
import org.pushingpixels.substance.api.ComponentState;
|
||||
import org.pushingpixels.substance.api.SubstanceColorScheme;
|
||||
import org.pushingpixels.substance.internal.painter.HighlightPainterUtils;
|
||||
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
|
||||
import org.pushingpixels.substance.internal.utils.SubstanceSizeUtils;
|
||||
import org.pushingpixels.substance.internal.utils.border.SubstanceBorder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyRibbonApplicationMenuPopupPanelUI extends BasicRibbonApplicationMenuPopupPanelUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new MyRibbonApplicationMenuPopupPanelUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
super.installComponents();
|
||||
Border newBorder = new CompoundBorder(new SubstanceBorder(new Insets(2,
|
||||
2, 2, 2)), new Border() {
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(18, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
SubstanceColorScheme bgFillScheme = SubstanceColorSchemeUtilities
|
||||
.getColorScheme(c,
|
||||
ColorSchemeAssociationKind.HIGHLIGHT,
|
||||
ComponentState.ENABLED);
|
||||
SubstanceColorScheme bgBorderScheme = SubstanceColorSchemeUtilities
|
||||
.getColorScheme(c,
|
||||
ColorSchemeAssociationKind.HIGHLIGHT_BORDER,
|
||||
ComponentState.ENABLED);
|
||||
HighlightPainterUtils.paintHighlight(g, null, c, new Rectangle(
|
||||
x, y, width, height), 0.0f, null, bgFillScheme,
|
||||
bgBorderScheme);
|
||||
|
||||
// draw the application menu button
|
||||
JRibbonApplicationMenuButton rendererButton = new JRibbonApplicationMenuButton(
|
||||
applicationMenuPopupPanel.getAppMenuButton()
|
||||
.getRibbon());
|
||||
|
||||
JRibbonApplicationMenuButton appMenuButton = applicationMenuPopupPanel
|
||||
.getAppMenuButton();
|
||||
rendererButton.applyComponentOrientation(appMenuButton
|
||||
.getComponentOrientation());
|
||||
|
||||
rendererButton.setPopupKeyTip(appMenuButton.getPopupKeyTip());
|
||||
rendererButton.getPopupModel().setPopupShowing(true);
|
||||
rendererButton.setDisplayState(appMenuButton.getDisplayState());
|
||||
|
||||
rendererButton.getPopupModel().setRollover(false);
|
||||
rendererButton.getPopupModel().setPressed(true);
|
||||
rendererButton.getPopupModel().setArmed(true);
|
||||
|
||||
CellRendererPane buttonRendererPane = new CellRendererPane();
|
||||
Point buttonLoc = appMenuButton.getLocationOnScreen();
|
||||
Point panelLoc = c.getLocationOnScreen();
|
||||
|
||||
buttonRendererPane.setBounds(panelLoc.x - buttonLoc.x,
|
||||
panelLoc.y - buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight());
|
||||
|
||||
buttonRendererPane.paintComponent(g, rendererButton,
|
||||
(Container) c, -panelLoc.x + buttonLoc.x, -panelLoc.y
|
||||
+ buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight(), true);
|
||||
/*g.setColor(Color.red);
|
||||
g.fillRect(0, 0, width,height);*/
|
||||
}
|
||||
});
|
||||
this.applicationMenuPopupPanel.setBorder(newBorder);
|
||||
|
||||
this.panelLevel2.setBorder(new Border() {
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
boolean ltr = c.getComponentOrientation().isLeftToRight();
|
||||
return new Insets(0, ltr ? 1 : 0, 0, ltr ? 0 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
int componentFontSize = SubstanceSizeUtils
|
||||
.getComponentFontSize(null);
|
||||
int borderDelta = (int) Math.floor(SubstanceSizeUtils
|
||||
.getBorderStrokeWidth(componentFontSize) / 2.0);
|
||||
float borderThickness = SubstanceSizeUtils
|
||||
.getBorderStrokeWidth(componentFontSize);
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
SubstanceColorScheme scheme = SubstanceColorSchemeUtilities
|
||||
.getColorScheme(applicationMenuPopupPanel,
|
||||
ColorSchemeAssociationKind.BORDER,
|
||||
ComponentState.ENABLED);
|
||||
g2d.setColor(scheme.getMidColor());
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||
RenderingHints.VALUE_STROKE_NORMALIZE);
|
||||
int joinKind = BasicStroke.JOIN_ROUND;
|
||||
int capKind = BasicStroke.CAP_BUTT;
|
||||
g2d.setStroke(new BasicStroke(borderThickness, capKind,
|
||||
joinKind));
|
||||
|
||||
boolean ltr = applicationMenuPopupPanel
|
||||
.getComponentOrientation().isLeftToRight();
|
||||
int lineX = ltr ? borderDelta : c.getWidth() - borderDelta - 1;
|
||||
g2d.drawLine(lineX, borderDelta, lineX, height - 1 - 2
|
||||
* borderDelta);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
});
|
||||
this.mainPanel.setBorder(new SubstanceBorder());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyTextField extends JTextField {
|
||||
|
||||
public MyTextField() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public MyTextField(String text) {
|
||||
super(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Color;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.tree.TreeModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyTree extends JTree {
|
||||
|
||||
public MyTree() {
|
||||
setUI(new MyTreeUI());
|
||||
setBackground(Color.white);
|
||||
}
|
||||
|
||||
public MyTree(TreeModel newModel) {
|
||||
super(newModel);
|
||||
setUI(new MyTreeUI());
|
||||
setBackground(Color.white);
|
||||
}
|
||||
private boolean overrideIsEnabled = false;
|
||||
|
||||
public void setOverrideIsEnable(boolean b) {
|
||||
overrideIsEnabled = true;
|
||||
}
|
||||
|
||||
public boolean isOverrideIsEnable(boolean b) {
|
||||
return overrideIsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
if (overrideIsEnabled) {
|
||||
return false;
|
||||
}
|
||||
return super.isEnabled();
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
super.paint(g);
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.lang.reflect.Field;
|
||||
import javax.swing.tree.TreePath;
|
||||
import org.pushingpixels.substance.internal.ui.SubstanceTreeUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class MyTreeUI extends SubstanceTreeUI {
|
||||
|
||||
@Override
|
||||
protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
|
||||
Insets insets, Rectangle bounds, TreePath path, int row,
|
||||
boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) {
|
||||
System.out.println("");
|
||||
if (this.tree instanceof MyTree) {
|
||||
Field f = null;
|
||||
Boolean v = false;
|
||||
try {
|
||||
f = SubstanceTreeUI.class.getDeclaredField("inside");
|
||||
f.setAccessible(true);
|
||||
v = (Boolean) f.get(this);
|
||||
f.set(this, Boolean.TRUE);
|
||||
((MyTree) this.tree).setOverrideIsEnable(true);
|
||||
} catch (Throwable t) {
|
||||
//want to default back to substanceUI if this fails.
|
||||
}
|
||||
|
||||
super.paintHorizontalPartOfLeg(g, bounds, insets, bounds, path, row, isLeaf, isLeaf, isLeaf);
|
||||
try {
|
||||
f.set(this, v);
|
||||
((MyTree) this.tree).setOverrideIsEnable(true);
|
||||
} catch (Throwable t) {
|
||||
//see above
|
||||
}
|
||||
}
|
||||
}
|
||||
//repeat for Vertical
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.ApplicationInfo;
|
||||
import com.jpexs.decompiler.flash.Version;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class NewVersionDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
Version latestVersion;
|
||||
|
||||
public NewVersionDialog(List<Version> versions) {
|
||||
setSize(new Dimension(500, 300));
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.PAGE_AXIS));
|
||||
JEditorPane changesText = new JEditorPane();
|
||||
changesText.setEditable(false);
|
||||
changesText.setFont(UIManager.getFont("TextField.font"));
|
||||
String changesStr = "";
|
||||
SimpleDateFormat serverFormatter = new SimpleDateFormat("MM/dd/yyyy");
|
||||
DateFormat formatter;
|
||||
String customFormat = translate("customDateFormat");
|
||||
if (customFormat.equals("default")) {
|
||||
formatter = DateFormat.getDateInstance();
|
||||
} else {
|
||||
formatter = new SimpleDateFormat(customFormat);
|
||||
}
|
||||
boolean first = true;
|
||||
for (Version v : versions) {
|
||||
if (!first) {
|
||||
changesStr += "<hr />";
|
||||
}
|
||||
first = false;
|
||||
changesStr += "<b>" + translate("version") + " " + v.versionName + (v.nightly ? " nightly " + v.revision : "") + "</b><br />";
|
||||
String releaseDate = v.releaseDate;
|
||||
try {
|
||||
Date date = serverFormatter.parse(releaseDate);
|
||||
releaseDate = formatter.format(date);
|
||||
} catch (ParseException ex) {
|
||||
Logger.getLogger(NewVersionDialog.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
changesStr += translate("releasedate") + " " + releaseDate;
|
||||
if (!v.changes.isEmpty()) {
|
||||
changesStr += "<br />";
|
||||
changesStr += "<pre>";
|
||||
for (String type : v.changes.keySet()) {
|
||||
changesStr += type + ":" + "<br />";
|
||||
for (String ch : v.changes.get(type)) {
|
||||
changesStr += " - " + ch + "<br />";
|
||||
}
|
||||
}
|
||||
changesStr += "</pre>";
|
||||
}
|
||||
}
|
||||
latestVersion = null;
|
||||
if (!versions.isEmpty()) {
|
||||
latestVersion = versions.get(0);
|
||||
}
|
||||
changesText.setContentType("text/html");
|
||||
changesText.setText("<html>" + changesStr + "</html>");
|
||||
JLabel newAvailableLabel = new JLabel("<html><b><center>" + translate("newversionavailable") + " " + latestVersion.appName + " " + translate("version") + " " + latestVersion.versionName + (latestVersion.nightly ? " " + latestVersion.revision : "") + "</center></b></html>", SwingConstants.CENTER);
|
||||
newAvailableLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
|
||||
cnt.add(newAvailableLabel);
|
||||
|
||||
JLabel changeslogLabel = new JLabel("<html>" + translate("changeslog") + "</html>");
|
||||
changeslogLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
|
||||
cnt.add(changeslogLabel);
|
||||
|
||||
JScrollPane span = new JScrollPane(changesText);
|
||||
span.setAlignmentX(JLabel.CENTER_ALIGNMENT);
|
||||
cnt.add(span);
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton buttonOk = new JButton(translate("button.ok"));
|
||||
buttonOk.setActionCommand(ACTION_OK);
|
||||
buttonOk.addActionListener(this);
|
||||
|
||||
JButton buttonCancel = new JButton(translate("button.cancel"));
|
||||
buttonCancel.setActionCommand(ACTION_CANCEL);
|
||||
buttonCancel.addActionListener(this);
|
||||
|
||||
buttonsPanel.add(buttonOk);
|
||||
buttonsPanel.add(buttonCancel);
|
||||
buttonsPanel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
|
||||
|
||||
JLabel downloadNowLabel = new JLabel("<html><b><center>" + translate("downloadnow") + "</center></b></html>", SwingConstants.CENTER);
|
||||
downloadNowLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
|
||||
cnt.add(downloadNowLabel);
|
||||
cnt.add(buttonsPanel);
|
||||
|
||||
setResizable(false);
|
||||
setTitle(translate("dialog.title"));
|
||||
this.getRootPane().setDefaultButton(buttonOk);
|
||||
View.centerScreen(this);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
changesText.setCaretPosition(0);
|
||||
View.setWindowIcon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand() == ACTION_OK) {
|
||||
java.awt.Desktop desktop = null;
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
desktop = java.awt.Desktop.getDesktop();
|
||||
if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
try {
|
||||
if (latestVersion.updateLink != null) {
|
||||
java.net.URI uri = new java.net.URI(latestVersion.updateLink);
|
||||
desktop.browse(uri);
|
||||
} else {
|
||||
java.net.URI uri = new java.net.URI(ApplicationInfo.updatePage);
|
||||
desktop.browse(uri);
|
||||
}
|
||||
Main.exit();
|
||||
} catch (URISyntaxException | IOException ex) {
|
||||
}
|
||||
} else {
|
||||
desktop = null;
|
||||
}
|
||||
}
|
||||
if (desktop == null) {
|
||||
View.showMessageDialog(null, translate("newvermessage").replace("%oldAppName%", ApplicationInfo.SHORT_APPLICATION_NAME).replace("%newAppName%", latestVersion.appName).replace("%projectPage%", ApplicationInfo.PROJECT_PAGE), translate("newversion"), JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum OpenFileResult {
|
||||
|
||||
OK,
|
||||
NOT_FOUND,
|
||||
ERROR
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface PlayerListener {
|
||||
|
||||
public void playingFinished();
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PreviewImage extends JPanel {
|
||||
|
||||
private static final ExecutorService executor;
|
||||
private static final int PREVIEW_SIZE = 150;
|
||||
private static final int BORDER_SIZE = 5;
|
||||
private Image image;
|
||||
private boolean rendering;
|
||||
private final MainPanel mainPanel;
|
||||
private final TreeItem treeItem;
|
||||
|
||||
static {
|
||||
executor = Executors.newFixedThreadPool(Configuration.parallelSpeedUp.get() ? Configuration.parallelThreadCount.get() : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mainPanel
|
||||
* @param treeItem
|
||||
*/
|
||||
public PreviewImage(final MainPanel mainPanel, final TreeItem treeItem) {
|
||||
this.mainPanel = mainPanel;
|
||||
this.treeItem = treeItem;
|
||||
Dimension dim = new Dimension(PREVIEW_SIZE + 2 * BORDER_SIZE, PREVIEW_SIZE + 2 * BORDER_SIZE);
|
||||
setMinimumSize(dim);
|
||||
setMaximumSize(dim);
|
||||
setPreferredSize(dim);
|
||||
setSize(dim);
|
||||
setLayout(null);
|
||||
setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
|
||||
if (treeItem instanceof Tag) {
|
||||
JPopupMenu contextMenu = new JPopupMenu();
|
||||
final JMenuItem removeMenuItem = new JMenuItem(mainPanel.translate("contextmenu.remove"));
|
||||
removeMenuItem.addActionListener(new AbstractAction() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainPanel.removeTag((Tag) treeItem);
|
||||
mainPanel.refreshTree();
|
||||
}
|
||||
});
|
||||
contextMenu.add(removeMenuItem);
|
||||
this.setComponentPopupMenu(contextMenu);
|
||||
}
|
||||
|
||||
this.addMouseListener(new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() >= 2) {
|
||||
mainPanel.setTreeItem(treeItem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized void renderImageTask(final TreeItem treeItem) {
|
||||
if (rendering) {
|
||||
return;
|
||||
}
|
||||
rendering = true;
|
||||
executor.submit(new Callable<Void>() {
|
||||
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
image = renderImage(treeItem.getSwf(), treeItem);
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private Image renderImage(SWF swf, TreeItem treeItem) {
|
||||
|
||||
double scale = 1;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
SerializableImage imgSrc = null;
|
||||
Matrix m = new Matrix();
|
||||
if (treeItem instanceof FrameNodeItem) {
|
||||
FrameNodeItem fn = (FrameNodeItem) treeItem;
|
||||
RECT rect = swf.displayRect;
|
||||
imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame() - 1, 0, null, 0, rect, Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform(), null);
|
||||
width = (imgSrc.getWidth());
|
||||
height = (imgSrc.getHeight());
|
||||
} else if (treeItem instanceof ImageTag) {
|
||||
imgSrc = ((ImageTag) treeItem).getImage();
|
||||
width = (imgSrc.getWidth());
|
||||
height = (imgSrc.getHeight());
|
||||
} else if (treeItem instanceof BoundedTag) {
|
||||
BoundedTag boundedTag = (BoundedTag) treeItem;
|
||||
RECT rect = boundedTag.getRect();
|
||||
width = (int) (rect.getWidth() / SWF.unitDivisor);
|
||||
height = (int) (rect.getHeight() / SWF.unitDivisor);
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
}
|
||||
|
||||
int w1 = width;
|
||||
int h1 = height;
|
||||
int w2 = PREVIEW_SIZE;
|
||||
int h2 = PREVIEW_SIZE;
|
||||
|
||||
int w;
|
||||
int h = h1 * w2 / w1;
|
||||
if (h > h2) {
|
||||
w = w1 * h2 / h1;
|
||||
h = h2;
|
||||
} else {
|
||||
w = w2;
|
||||
}
|
||||
|
||||
scale = (double) w / (double) w1;
|
||||
if (w1 <= w2 && h1 <= h2) {
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
m = m.preConcatenate(Matrix.getScaleInstance(scale));
|
||||
width = (int) (scale * width);
|
||||
height = (int) (scale * height);
|
||||
if (width == 0 || height == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage image = new SerializableImage(width, height, SerializableImage.TYPE_INT_ARGB);
|
||||
image.fillTransparent();
|
||||
if (imgSrc == null) {
|
||||
DrawableTag drawable = (DrawableTag) treeItem;
|
||||
drawable.toImage(0, 0, 0, null, 0, image, m, new ColorTransform());
|
||||
} else {
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
g.setTransform(m.toTransform());
|
||||
g.drawImage(imgSrc.getBufferedImage(), 0, 0, null);
|
||||
}
|
||||
return image.getBufferedImage();
|
||||
}
|
||||
|
||||
public static Component createFolderPreviewImage(MainPanel mainPanel, TreeItem treeItem) {
|
||||
JPanel pan = new JPanel(new BorderLayout());
|
||||
PreviewImage imagePanel = new PreviewImage(mainPanel, treeItem);
|
||||
pan.add(imagePanel, BorderLayout.CENTER);
|
||||
String s;
|
||||
if (treeItem instanceof Tag) {
|
||||
s = ((Tag) treeItem).getTagName();
|
||||
if (treeItem instanceof CharacterTag) {
|
||||
s = s + " (" + ((CharacterTag) treeItem).getCharacterId() + ")";
|
||||
}
|
||||
} else {
|
||||
s = treeItem.toString();
|
||||
}
|
||||
JLabel lab = new JLabel(s);
|
||||
lab.setFont(lab.getFont().deriveFont(AffineTransform.getScaleInstance(0.8, 0.8)));
|
||||
pan.add(lab, BorderLayout.SOUTH);
|
||||
return pan;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setPaint(View.transparentPaint);
|
||||
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
|
||||
g2d.setComposite(AlphaComposite.SrcOver);
|
||||
g2d.setPaint(View.swfBackgroundColor);
|
||||
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
|
||||
if (image != null) {
|
||||
int x = (getWidth() / 2) - (image.getWidth(this) / 2);
|
||||
int y = (getHeight() / 2) - (image.getHeight(this) / 2);
|
||||
g.drawImage(image, x, y, null);
|
||||
} else {
|
||||
renderImageTask(treeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,920 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
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.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.gui.player.PlayerControls;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
|
||||
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.DoInitActionTag;
|
||||
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.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
|
||||
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.FontTag;
|
||||
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.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
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.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
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.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PreviewPanel extends JSplitPane implements ActionListener {
|
||||
|
||||
private static final String FLASH_VIEWER_CARD = "FLASHVIEWER";
|
||||
private static final String DRAW_PREVIEW_CARD = "DRAWPREVIEW";
|
||||
private static final String GENERIC_TAG_CARD = "GENERICTAG";
|
||||
private static final String BINARY_TAG_CARD = "BINARYTAG";
|
||||
|
||||
private static final String CARDTEXTPANEL = "Text card";
|
||||
private static final String CARDFONTPANEL = "Font card";
|
||||
|
||||
private static final String ACTION_EDIT_GENERIC_TAG = "EDITGENERICTAG";
|
||||
private static final String ACTION_SAVE_GENERIC_TAG = "SAVEGENERICTAG";
|
||||
private static final String ACTION_CANCEL_GENERIC_TAG = "CANCELGENERICTAG";
|
||||
|
||||
private static final String ACTION_PREV_FONTS = "PREVFONTS";
|
||||
private static final String ACTION_NEXT_FONTS = "NEXTFONTS";
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
private final JPanel viewerCards;
|
||||
|
||||
private PlayerControls flashControls;
|
||||
private final FlashPlayerPanel flashPanel;
|
||||
private File tempFile;
|
||||
|
||||
private ImagePanel imagePanel;
|
||||
private PlayerControls imagePlayControls;
|
||||
|
||||
private BinaryPanel binaryPanel;
|
||||
private GenericTagPanel genericTagPanel;
|
||||
|
||||
private JPanel displayWithPreview;
|
||||
|
||||
// Image tag buttons
|
||||
private JButton replaceImageButton;
|
||||
private JButton prevFontsButton;
|
||||
private JButton nextFontsButton;
|
||||
|
||||
// Binary tag buttons
|
||||
private JButton replaceBinaryButton;
|
||||
|
||||
// Generic tag buttons
|
||||
private JButton editButton;
|
||||
private JButton saveButton;
|
||||
private JButton cancelButton;
|
||||
|
||||
private JPanel parametersPanel;
|
||||
private FontPanel fontPanel;
|
||||
private int fontPageNum;
|
||||
private TextPanel textPanel;
|
||||
|
||||
private boolean splitsInited;
|
||||
|
||||
public PreviewPanel(MainPanel mainPanel, FlashPlayerPanel flashPanel) {
|
||||
super(JSplitPane.HORIZONTAL_SPLIT);
|
||||
this.mainPanel = mainPanel;
|
||||
this.flashPanel = flashPanel;
|
||||
|
||||
addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
if (splitsInited && getRightComponent().isVisible()) {
|
||||
Configuration.guiPreviewSplitPaneDividerLocation.set((int) pce.getNewValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewerCards = new JPanel();
|
||||
viewerCards.setLayout(new CardLayout());
|
||||
|
||||
viewerCards.add(createFlashPlayerPanel(flashPanel), FLASH_VIEWER_CARD);
|
||||
viewerCards.add(createImagesCard(), DRAW_PREVIEW_CARD);
|
||||
viewerCards.add(createBinaryCard(), BINARY_TAG_CARD);
|
||||
viewerCards.add(createGenericTagCard(), GENERIC_TAG_CARD);
|
||||
setLeftComponent(viewerCards);
|
||||
|
||||
createParametersPanel();
|
||||
|
||||
showCardLeft(FLASH_VIEWER_CARD);
|
||||
}
|
||||
|
||||
private void createParametersPanel() {
|
||||
displayWithPreview = new JPanel(new CardLayout());
|
||||
|
||||
textPanel = new TextPanel(mainPanel);
|
||||
displayWithPreview.add(textPanel, CARDTEXTPANEL);
|
||||
|
||||
fontPanel = new FontPanel(mainPanel);
|
||||
displayWithPreview.add(fontPanel, CARDFONTPANEL);
|
||||
|
||||
JLabel paramsLabel = new HeaderLabel(mainPanel.translate("parameters"));
|
||||
paramsLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//paramsLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
|
||||
parametersPanel = new JPanel(new BorderLayout());
|
||||
parametersPanel.add(paramsLabel, BorderLayout.NORTH);
|
||||
parametersPanel.add(displayWithPreview, BorderLayout.CENTER);
|
||||
setRightComponent(parametersPanel);
|
||||
}
|
||||
|
||||
private JPanel createImageButtonsPanel() {
|
||||
replaceImageButton = new JButton(mainPanel.translate("button.replace"), View.getIcon("edit16"));
|
||||
replaceImageButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
replaceImageButton.setActionCommand(MainPanel.ACTION_REPLACE);
|
||||
replaceImageButton.addActionListener(mainPanel);
|
||||
replaceImageButton.setVisible(false);
|
||||
|
||||
prevFontsButton = new JButton(mainPanel.translate("button.prev"), View.getIcon("prev16"));
|
||||
prevFontsButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
prevFontsButton.setActionCommand(ACTION_PREV_FONTS);
|
||||
prevFontsButton.addActionListener(this);
|
||||
prevFontsButton.setVisible(false);
|
||||
|
||||
nextFontsButton = new JButton(mainPanel.translate("button.next"), View.getIcon("next16"));
|
||||
nextFontsButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
nextFontsButton.setActionCommand(ACTION_NEXT_FONTS);
|
||||
nextFontsButton.addActionListener(this);
|
||||
nextFontsButton.setVisible(false);
|
||||
|
||||
ButtonsPanel imageButtonsPanel = new ButtonsPanel();
|
||||
imageButtonsPanel.add(replaceImageButton);
|
||||
imageButtonsPanel.add(prevFontsButton);
|
||||
imageButtonsPanel.add(nextFontsButton);
|
||||
return imageButtonsPanel;
|
||||
}
|
||||
|
||||
private JPanel createBinaryButtonsPanel() {
|
||||
replaceBinaryButton = new JButton(mainPanel.translate("button.replace"), View.getIcon("edit16"));
|
||||
replaceBinaryButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
replaceBinaryButton.setActionCommand(MainPanel.ACTION_REPLACE);
|
||||
replaceBinaryButton.addActionListener(mainPanel);
|
||||
|
||||
ButtonsPanel binaryButtonsPanel = new ButtonsPanel();
|
||||
binaryButtonsPanel.add(replaceBinaryButton);
|
||||
return binaryButtonsPanel;
|
||||
}
|
||||
|
||||
private JPanel createGenericTagButtonsPanel() {
|
||||
editButton = new JButton(mainPanel.translate("button.edit"), View.getIcon("edit16"));
|
||||
editButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
editButton.setActionCommand(ACTION_EDIT_GENERIC_TAG);
|
||||
editButton.addActionListener(this);
|
||||
saveButton = new JButton(mainPanel.translate("button.save"), View.getIcon("save16"));
|
||||
saveButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
saveButton.setActionCommand(ACTION_SAVE_GENERIC_TAG);
|
||||
saveButton.addActionListener(this);
|
||||
saveButton.setVisible(false);
|
||||
cancelButton = new JButton(mainPanel.translate("button.cancel"), View.getIcon("cancel16"));
|
||||
cancelButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
cancelButton.setActionCommand(ACTION_CANCEL_GENERIC_TAG);
|
||||
cancelButton.addActionListener(this);
|
||||
cancelButton.setVisible(false);
|
||||
|
||||
ButtonsPanel genericTagButtonsPanel = new ButtonsPanel();
|
||||
genericTagButtonsPanel.add(editButton);
|
||||
genericTagButtonsPanel.add(saveButton);
|
||||
genericTagButtonsPanel.add(cancelButton);
|
||||
return genericTagButtonsPanel;
|
||||
}
|
||||
|
||||
private JPanel createFlashPlayerPanel(FlashPlayerPanel flashPanel) {
|
||||
JPanel pan = new JPanel(new BorderLayout());
|
||||
JLabel prevLabel = new HeaderLabel(mainPanel.translate("swfpreview"));
|
||||
prevLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//prevLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
|
||||
pan.add(prevLabel, BorderLayout.NORTH);
|
||||
|
||||
Component leftComponent;
|
||||
if (flashPanel != null) {
|
||||
JPanel flashPlayPanel = new JPanel(new BorderLayout());
|
||||
flashPlayPanel.add(flashPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton selectColorButton = new JButton(View.getIcon("color16"));
|
||||
selectColorButton.addActionListener(mainPanel);
|
||||
selectColorButton.setActionCommand(MainPanel.ACTION_SELECT_BKCOLOR);
|
||||
selectColorButton.setToolTipText(AppStrings.translate("button.selectbkcolor.hint"));
|
||||
buttonsPanel.add(selectColorButton);
|
||||
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||
|
||||
flashPlayPanel.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel flashPlayPanel2 = new JPanel(new BorderLayout());
|
||||
flashPlayPanel2.add(flashPlayPanel, BorderLayout.CENTER);
|
||||
flashPlayPanel2.add(flashControls = new PlayerControls(flashPanel), BorderLayout.SOUTH);
|
||||
leftComponent = flashPlayPanel2;
|
||||
} else {
|
||||
JPanel swtPanel = new JPanel(new BorderLayout());
|
||||
swtPanel.add(new JLabel("<html><center>" + mainPanel.translate("notavailonthisplatform") + "</center></html>", JLabel.CENTER), BorderLayout.CENTER);
|
||||
swtPanel.setBackground(View.DEFAULT_BACKGROUND_COLOR);
|
||||
leftComponent = swtPanel;
|
||||
}
|
||||
|
||||
pan.add(leftComponent, BorderLayout.CENTER);
|
||||
return pan;
|
||||
}
|
||||
|
||||
private JPanel createImagesCard() {
|
||||
JPanel shapesCard = new JPanel(new BorderLayout());
|
||||
JPanel previewPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel previewCnt = new JPanel(new BorderLayout());
|
||||
imagePanel = new ImagePanel();
|
||||
previewCnt.add(imagePanel, BorderLayout.CENTER);
|
||||
previewCnt.add(imagePlayControls = new PlayerControls(imagePanel), BorderLayout.SOUTH);
|
||||
imagePlayControls.setMedia(imagePanel);
|
||||
previewPanel.add(previewCnt, BorderLayout.CENTER);
|
||||
JLabel prevIntLabel = new HeaderLabel(mainPanel.translate("swfpreview.internal"));
|
||||
prevIntLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//prevIntLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
previewPanel.add(prevIntLabel, BorderLayout.NORTH);
|
||||
|
||||
shapesCard.add(previewPanel, BorderLayout.CENTER);
|
||||
|
||||
shapesCard.add(createImageButtonsPanel(), BorderLayout.SOUTH);
|
||||
return shapesCard;
|
||||
}
|
||||
|
||||
private JPanel createBinaryCard() {
|
||||
JPanel binaryCard = new JPanel(new BorderLayout());
|
||||
binaryPanel = new BinaryPanel();
|
||||
binaryCard.add(binaryPanel, BorderLayout.CENTER);
|
||||
binaryCard.add(createBinaryButtonsPanel(), BorderLayout.SOUTH);
|
||||
return binaryCard;
|
||||
}
|
||||
|
||||
private JPanel createGenericTagCard() {
|
||||
JPanel genericTagCard = new JPanel(new BorderLayout());
|
||||
genericTagPanel = new GenericTagTreePanel();
|
||||
genericTagCard.add(genericTagPanel, BorderLayout.CENTER);
|
||||
genericTagCard.add(createGenericTagButtonsPanel(), BorderLayout.SOUTH);
|
||||
return genericTagCard;
|
||||
}
|
||||
|
||||
private void showCardLeft(String card) {
|
||||
CardLayout cl = (CardLayout) (viewerCards.getLayout());
|
||||
cl.show(viewerCards, card);
|
||||
}
|
||||
|
||||
private void showCardRight(String card) {
|
||||
CardLayout cl = (CardLayout) (displayWithPreview.getLayout());
|
||||
cl.show(displayWithPreview, card);
|
||||
}
|
||||
|
||||
public void setSplitsInited() {
|
||||
splitsInited = true;
|
||||
}
|
||||
|
||||
public TextPanel getTextPanel() {
|
||||
return textPanel;
|
||||
}
|
||||
|
||||
public void setParametersPanelVisible(boolean show) {
|
||||
parametersPanel.setVisible(show);
|
||||
}
|
||||
|
||||
public void showFlashViewerPanel() {
|
||||
parametersPanel.setVisible(false);
|
||||
showCardLeft(FLASH_VIEWER_CARD);
|
||||
}
|
||||
|
||||
public void showImagePanel(Timelined timelined, SWF swf, int frame) {
|
||||
showCardLeft(DRAW_PREVIEW_CARD);
|
||||
parametersPanel.setVisible(false);
|
||||
imagePlayControls.setMedia(imagePanel);
|
||||
imagePanel.setTimelined(timelined, swf, frame);
|
||||
}
|
||||
|
||||
public void showImagePanel(SerializableImage image) {
|
||||
showCardLeft(DRAW_PREVIEW_CARD);
|
||||
parametersPanel.setVisible(false);
|
||||
imagePlayControls.setMedia(imagePanel);
|
||||
imagePanel.setImage(image);
|
||||
}
|
||||
|
||||
public void setMedia(MediaDisplay media) {
|
||||
imagePlayControls.setMedia(media);
|
||||
}
|
||||
|
||||
public void showFontPanel(FontTag fontTag) {
|
||||
fontPageNum = 0;
|
||||
showFontPage(fontTag);
|
||||
|
||||
showCardRight(CARDFONTPANEL);
|
||||
parametersPanel.setVisible(true);
|
||||
setDividerLocation(Configuration.guiPreviewSplitPaneDividerLocation.get(getWidth() / 2));
|
||||
fontPanel.showFontTag(fontTag);
|
||||
|
||||
int pageCount = getFontPageCount(fontTag);
|
||||
if (pageCount > 1) {
|
||||
prevFontsButton.setVisible(true);
|
||||
nextFontsButton.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void showFontPage(FontTag fontTag) {
|
||||
if (mainPanel.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) {
|
||||
showImagePanel(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getFontPageCount(FontTag fontTag) {
|
||||
int pageCount = (fontTag.getGlyphShapeTable().size() - 1) / SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW + 1;
|
||||
if (pageCount < 1) {
|
||||
pageCount = 1;
|
||||
}
|
||||
return pageCount;
|
||||
}
|
||||
|
||||
public void showTextPanel(TextTag textTag) {
|
||||
if (mainPanel.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) {
|
||||
showImagePanel(MainPanel.makeTimelined(textTag), textTag.getSwf(), 0);
|
||||
}
|
||||
|
||||
showCardRight(CARDTEXTPANEL);
|
||||
parametersPanel.setVisible(true);
|
||||
setDividerLocation(Configuration.guiPreviewSplitPaneDividerLocation.get(getWidth() / 2));
|
||||
textPanel.setText(textTag.getFormattedText());
|
||||
}
|
||||
|
||||
public void setEditText(boolean edit) {
|
||||
textPanel.setEditText(edit);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
imagePanel.stop();
|
||||
binaryPanel.setBinaryData(null);
|
||||
genericTagPanel.clear();
|
||||
fontPanel.clear();
|
||||
}
|
||||
|
||||
public void showBinaryPanel(byte[] data) {
|
||||
showCardLeft(BINARY_TAG_CARD);
|
||||
binaryPanel.setBinaryData(data);
|
||||
parametersPanel.setVisible(false);
|
||||
}
|
||||
|
||||
public void showGenericTagPanel(Tag tag) {
|
||||
showCardLeft(GENERIC_TAG_CARD);
|
||||
editButton.setVisible(true);
|
||||
saveButton.setVisible(false);
|
||||
cancelButton.setVisible(false);
|
||||
genericTagPanel.setEditMode(false, tag);
|
||||
parametersPanel.setVisible(false);
|
||||
}
|
||||
|
||||
public void setImageReplaceButtonVisible(boolean show) {
|
||||
replaceImageButton.setVisible(show);
|
||||
prevFontsButton.setVisible(false);
|
||||
nextFontsButton.setVisible(false);
|
||||
}
|
||||
|
||||
private static Tag classicTag(Tag t) {
|
||||
if (t instanceof DefineCompactedFont) {
|
||||
return ((DefineCompactedFont) t).toClassicFont();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void createAndShowTempSwf(TreeItem 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 FrameNodeItem) {
|
||||
FrameNodeItem fn = (FrameNodeItem) 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<Integer, VideoFrameTag> videoFrames = new HashMap<>();
|
||||
if (tagObj instanceof DefineVideoStreamTag) {
|
||||
DefineVideoStreamTag vs = (DefineVideoStreamTag) tagObj;
|
||||
SWF.populateVideoFrames(vs.getCharacterId(), swf.tags, videoFrames);
|
||||
frameCount = videoFrames.size();
|
||||
}
|
||||
|
||||
List<SoundStreamBlockTag> soundFrames = new ArrayList<>();
|
||||
if (tagObj instanceof SoundStreamHeadTypeTag) {
|
||||
soundFrames = ((SoundStreamHeadTypeTag) tagObj).getBlocks();
|
||||
frameCount = soundFrames.size();
|
||||
}
|
||||
|
||||
if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
|
||||
frameRate = MainPanel.MORPH_SHAPE_ANIMATION_FRAME_RATE;
|
||||
frameCount = MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate;
|
||||
}
|
||||
|
||||
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);
|
||||
*/
|
||||
new SetBackgroundColorTag(swf, new RGB(backgroundColor)).writeTag(sos2);
|
||||
|
||||
if (tagObj instanceof FrameNodeItem) {
|
||||
FrameNodeItem fn = (FrameNodeItem) tagObj;
|
||||
Tag parent = fn.getParent();
|
||||
List<ContainerItem> subs = new ArrayList<>();
|
||||
if (parent == null) {
|
||||
subs.addAll(swf.tags);
|
||||
} else {
|
||||
if (parent instanceof Container) {
|
||||
subs = ((Container) parent).getSubItems();
|
||||
}
|
||||
}
|
||||
List<Integer> doneCharacters = new ArrayList<>();
|
||||
int frameCnt = 1;
|
||||
for (ContainerItem item : subs) {
|
||||
if (item instanceof ShowFrameTag) {
|
||||
frameCnt++;
|
||||
continue;
|
||||
}
|
||||
if (frameCnt > fn.getFrame()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (item instanceof DoActionTag || item instanceof DoInitActionTag) {
|
||||
// todo: Maybe DoABC tags should be removed, too
|
||||
continue;
|
||||
}
|
||||
|
||||
Tag t = (Tag) item;
|
||||
Set<Integer> needed = t.getDeepNeededCharacters(swf.characters);
|
||||
for (int n : needed) {
|
||||
if (!doneCharacters.contains(n)) {
|
||||
classicTag(swf.characters.get(n)).writeTag(sos2);
|
||||
doneCharacters.add(n);
|
||||
}
|
||||
}
|
||||
if (t instanceof CharacterTag) {
|
||||
int characterId = ((CharacterTag) t).getCharacterId();
|
||||
if (!doneCharacters.contains(characterId)) {
|
||||
doneCharacters.add(((CharacterTag) t).getCharacterId());
|
||||
}
|
||||
}
|
||||
classicTag(t).writeTag(sos2);
|
||||
|
||||
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 = Helper.deepCopy(mat);
|
||||
if (parent instanceof BoundedTag) {
|
||||
RECT r = ((BoundedTag) parent).getRect();
|
||||
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;
|
||||
}
|
||||
new PlaceObject2Tag(swf, false, false, false, false, false, true, false, true, depth, chid, mat, null, 0, null, 0, null).writeTag(sos2);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
} else {
|
||||
|
||||
if (tagObj instanceof DefineBitsTag) {
|
||||
JPEGTablesTag jtt = swf.jtt;
|
||||
if (jtt != null) {
|
||||
jtt.writeTag(sos2);
|
||||
}
|
||||
} else if (tagObj instanceof AloneTag) {
|
||||
} else {
|
||||
Set<Integer> needed = ((Tag) tagObj).getDeepNeededCharacters(swf.characters);
|
||||
for (int n : needed) {
|
||||
classicTag(swf.characters.get(n)).writeTag(sos2);
|
||||
}
|
||||
}
|
||||
|
||||
classicTag((Tag) tagObj).writeTag(sos2);
|
||||
|
||||
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();
|
||||
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 countGlyphsTotal = ((FontTag) tagObj).getGlyphShapeTable().size();
|
||||
int countGlyphs = Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW, countGlyphsTotal);
|
||||
int fontId = ((FontTag) tagObj).getFontId();
|
||||
int cols = (int) Math.ceil(Math.sqrt(countGlyphs));
|
||||
int rows = (int) Math.ceil(((float) countGlyphs) / ((float) cols));
|
||||
int x = 0;
|
||||
int y = 1;
|
||||
int firstGlyphIndex = fontPageNum * SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW;
|
||||
countGlyphs = Math.min(SHAPERECORD.MAX_CHARACTERS_IN_FONT_PREVIEW, countGlyphsTotal - firstGlyphIndex);
|
||||
for (int f = firstGlyphIndex; f < firstGlyphIndex + countGlyphs; f++) {
|
||||
if (x >= cols) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
List<TEXTRECORD> rec = new ArrayList<>();
|
||||
TEXTRECORD tr = new TEXTRECORD();
|
||||
int textHeight = height / rows;
|
||||
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 / cols;
|
||||
mat.translateY = y * height / rows;
|
||||
new DefineTextTag(swf, 999 + f, new RECT(0, width, 0, height), new MATRIX(), rec).writeTag(sos2);
|
||||
new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1 + f, 999 + f, mat, null, 0, null, 0, null).writeTag(sos2);
|
||||
x++;
|
||||
}
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
} else if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
|
||||
new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
for (int ratio = 0; ratio < 65536; ratio += 65536 / frameCount) {
|
||||
new PlaceObject2Tag(swf, false, false, false, true, false, true, false, true, 1, chtId, mat, null, ratio, null, 0, null).writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
}
|
||||
} else if (tagObj instanceof SoundStreamHeadTypeTag) {
|
||||
for (SoundStreamBlockTag blk : soundFrames) {
|
||||
blk.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
}
|
||||
} else if (tagObj instanceof DefineSoundTag) {
|
||||
ExportAssetsTag ea = new ExportAssetsTag(swf);
|
||||
DefineSoundTag ds = (DefineSoundTag) tagObj;
|
||||
ea.tags.add(ds.soundId);
|
||||
ea.names.add("my_define_sound");
|
||||
ea.writeTag(sos2);
|
||||
List<Action> actions;
|
||||
DoActionTag doa;
|
||||
|
||||
doa = new DoActionTag(swf, new byte[0], new byte[0], 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.version, false);
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
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.version, false);
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
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.version, false);
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, 0, false,
|
||||
"StopSounds\n"
|
||||
+ "Stop", swf.version, false);
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
if (flashPanel != null) {
|
||||
flashPanel.specialPlayback = true;
|
||||
}
|
||||
} else if (tagObj instanceof DefineVideoStreamTag) {
|
||||
|
||||
new PlaceObject2Tag(swf, false, false, false, false, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2);
|
||||
List<VideoFrameTag> frs = new ArrayList<>(videoFrames.values());
|
||||
Collections.sort(frs, new Comparator<VideoFrameTag>() {
|
||||
@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++;
|
||||
new PlaceObject2Tag(swf, false, false, false, true, false, false, false, true, 1, 0, null, null, ratio, null, 0, null).writeTag(sos2);
|
||||
}
|
||||
f.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
new PlaceObject2Tag(swf, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null).writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
}
|
||||
|
||||
}//not showframe
|
||||
|
||||
new EndTag(swf).writeTag(sos2);
|
||||
data = baos.toByteArray();
|
||||
}
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
|
||||
SWFOutputStream sos = new SWFOutputStream(fos, Math.max(10, swf.version));
|
||||
sos.write("FWS".getBytes());
|
||||
sos.write(swf.version);
|
||||
sos.writeUI32(sos.getPos() + data.length + 4);
|
||||
sos.write(data);
|
||||
fos.flush();
|
||||
}
|
||||
|
||||
if (flashPanel != null) {
|
||||
flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, frameRate);
|
||||
}
|
||||
showFlashViewerPanel();
|
||||
} catch (IOException | com.jpexs.decompiler.flash.action.parser.ParseException ex) {
|
||||
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void showSwf(SWF swf) {
|
||||
Color backgroundColor = View.DEFAULT_BACKGROUND_COLOR;
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
backgroundColor = ((SetBackgroundColorTag) t).backgroundColor.toColor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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(PreviewPanel.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_EDIT_GENERIC_TAG: {
|
||||
TreeItem item = mainPanel.tagTree.getCurrentTreeItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof Tag) {
|
||||
editButton.setVisible(false);
|
||||
saveButton.setVisible(true);
|
||||
cancelButton.setVisible(true);
|
||||
//genericTagPanel.generateEditControls((Tag) item, false);
|
||||
genericTagPanel.setEditMode(true, (Tag) item);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_GENERIC_TAG: {
|
||||
genericTagPanel.save();
|
||||
mainPanel.refreshTree();
|
||||
mainPanel.setTreeItem(genericTagPanel.getTag());
|
||||
editButton.setVisible(true);
|
||||
saveButton.setVisible(false);
|
||||
cancelButton.setVisible(false);
|
||||
genericTagPanel.setEditMode(false, null);
|
||||
}
|
||||
break;
|
||||
case ACTION_CANCEL_GENERIC_TAG: {
|
||||
editButton.setVisible(true);
|
||||
saveButton.setVisible(false);
|
||||
cancelButton.setVisible(false);
|
||||
genericTagPanel.setEditMode(false, null);
|
||||
}
|
||||
break;
|
||||
case ACTION_PREV_FONTS: {
|
||||
FontTag fontTag = fontPanel.getFontTag();
|
||||
int pageCount = getFontPageCount(fontTag);
|
||||
fontPageNum = (fontPageNum + pageCount - 1) % pageCount;
|
||||
if (mainPanel.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) {
|
||||
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_NEXT_FONTS: {
|
||||
FontTag fontTag = fontPanel.getFontTag();
|
||||
int pageCount = getFontPageCount(fontTag);
|
||||
fontPageNum = (fontPageNum + 1) % pageCount;
|
||||
if (mainPanel.isInternalFlashViewerSelected() /*|| ft instanceof GFxDefineCompactedFont*/) {
|
||||
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 org.pushingpixels.flamingo.api.common.JCommandButton;
|
||||
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RecentFilesButton extends JCommandButton {
|
||||
|
||||
public String fileName;
|
||||
|
||||
public RecentFilesButton(String title, ResizableIcon icon) {
|
||||
super(title, icon);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RenameDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
private final JRadioButton typeNumberRadioButton = new JRadioButton(translate("rename.type.typenumber"));
|
||||
private final JRadioButton randomWordRadioButton = new JRadioButton(translate("rename.type.randomword"));
|
||||
private final JButton okButton = new JButton(translate("button.ok"));
|
||||
private final JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
private boolean confirmed = false;
|
||||
|
||||
public RenameType getRenameType() {
|
||||
if (!isConfirmed()) {
|
||||
return null;
|
||||
}
|
||||
if (typeNumberRadioButton.isSelected()) {
|
||||
return RenameType.TYPENUMBER;
|
||||
}
|
||||
return RenameType.RANDOMWORD;
|
||||
}
|
||||
|
||||
public RenameDialog() {
|
||||
setSize(300, 150);
|
||||
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
|
||||
int renameType = Configuration.lastRenameType.get();
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
group.add(typeNumberRadioButton);
|
||||
group.add(randomWordRadioButton);
|
||||
JPanel pan = new JPanel();
|
||||
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
|
||||
pan.add(typeNumberRadioButton);
|
||||
pan.add(randomWordRadioButton);
|
||||
typeNumberRadioButton.setSelected(renameType == 1);
|
||||
randomWordRadioButton.setSelected(renameType == 2);
|
||||
setLayout(new BorderLayout());
|
||||
add(new JLabel(translate("rename.type")), BorderLayout.NORTH);
|
||||
add(pan, BorderLayout.CENTER);
|
||||
JPanel panButtons = new JPanel(new FlowLayout());
|
||||
panButtons.add(okButton);
|
||||
okButton.setActionCommand(ACTION_OK);
|
||||
okButton.addActionListener(this);
|
||||
panButtons.add(cancelButton);
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
add(panButtons, BorderLayout.SOUTH);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
View.setWindowIcon(this);
|
||||
setTitle(translate("dialog.title"));
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
pack();
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
confirmed = false;
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OK:
|
||||
confirmed = true;
|
||||
Configuration.lastRenameType.set((Integer) (getRenameType() == RenameType.TYPENUMBER ? 1 : 2));
|
||||
setVisible(false);
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
confirmed = false;
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConfirmed() {
|
||||
return confirmed;
|
||||
}
|
||||
|
||||
public RenameType display() {
|
||||
setVisible(true);
|
||||
return getRenameType();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum SaveFileMode {
|
||||
|
||||
SAVE, SAVEAS, EXE
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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 java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SearchDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
public JTextField searchField = new MyTextField();
|
||||
public JCheckBox ignoreCaseCheckBox = new JCheckBox(translate("checkbox.ignorecase"));
|
||||
public JCheckBox regexpCheckBox = new JCheckBox(translate("checkbox.regexp"));
|
||||
public JRadioButton searchInASRadioButton = new JRadioButton(translate("checkbox.searchAS"));
|
||||
public JRadioButton searchInTextsRadioButton = new JRadioButton(translate("checkbox.searchText"));
|
||||
public boolean result = false;
|
||||
|
||||
public SearchDialog() {
|
||||
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
|
||||
Container cnt = getContentPane();
|
||||
setSize(400, 150);
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.PAGE_AXIS));
|
||||
JPanel panButtons = new JPanel(new FlowLayout());
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.setActionCommand(ACTION_OK);
|
||||
okButton.addActionListener(this);
|
||||
JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
panButtons.add(okButton);
|
||||
panButtons.add(cancelButton);
|
||||
JPanel panField = new JPanel(new FlowLayout());
|
||||
searchField.setPreferredSize(new Dimension(250, searchField.getPreferredSize().height));
|
||||
panField.add(new JLabel(translate("label.searchtext")));
|
||||
panField.add(searchField);
|
||||
cnt.add(panField);
|
||||
|
||||
JPanel checkPanel = new JPanel(new FlowLayout());
|
||||
checkPanel.add(ignoreCaseCheckBox);
|
||||
checkPanel.add(regexpCheckBox);
|
||||
cnt.add(checkPanel);
|
||||
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
group.add(searchInASRadioButton);
|
||||
group.add(searchInTextsRadioButton);
|
||||
|
||||
JPanel rbPanel = new JPanel(new FlowLayout());
|
||||
searchInASRadioButton.setSelected(true);
|
||||
searchInTextsRadioButton.setSelected(false);
|
||||
rbPanel.add(searchInASRadioButton);
|
||||
rbPanel.add(searchInTextsRadioButton);
|
||||
cnt.add(rbPanel);
|
||||
|
||||
cnt.add(panButtons);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
View.centerScreen(this);
|
||||
//View.setWindowIcon(this);
|
||||
setIconImage(View.loadImage("search16"));
|
||||
setTitle(translate("dialog.title"));
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
pack();
|
||||
java.util.List<Image> images = new ArrayList<>();
|
||||
images.add(View.loadImage("search16"));
|
||||
images.add(View.loadImage("search32"));
|
||||
setIconImages(images);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
result = false;
|
||||
searchField.requestFocusInWindow();
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand() == ACTION_OK) {
|
||||
if (regexpCheckBox.isSelected()) {
|
||||
try {
|
||||
Pattern pat = Pattern.compile(searchField.getText());
|
||||
} catch (PatternSyntaxException ex) {
|
||||
View.showMessageDialog(null, translate("error.invalidregexp"), translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
* @param <E>
|
||||
*/
|
||||
public interface SearchListener<E> {
|
||||
|
||||
public void updateSearchPos(E item);
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import jsyntaxpane.actions.DocumentSearchData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
* @param <E>
|
||||
*/
|
||||
public class SearchPanel<E> extends JPanel implements ActionListener {
|
||||
|
||||
static final String ACTION_SEARCH_PREV = "SEARCHPREV";
|
||||
static final String ACTION_SEARCH_NEXT = "SEARCHNEXT";
|
||||
static final String ACTION_SEARCH_CANCEL = "SEARCHCANCEL";
|
||||
|
||||
private final SearchListener<E> listener;
|
||||
|
||||
private final JLabel searchPos;
|
||||
private int foundPos = 0;
|
||||
private final JLabel searchForLabel;
|
||||
private String searchFor;
|
||||
private boolean searchIgnoreCase;
|
||||
private boolean searchRegexp;
|
||||
private List<E> found = new ArrayList<>();
|
||||
|
||||
public SearchPanel(LayoutManager lm, SearchListener<E> listener) {
|
||||
super(lm);
|
||||
|
||||
this.listener = listener;
|
||||
|
||||
JButton prevSearchButton = new JButton(View.getIcon("prev16"));
|
||||
prevSearchButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
prevSearchButton.addActionListener(this);
|
||||
prevSearchButton.setActionCommand(ACTION_SEARCH_PREV);
|
||||
JButton nextSearchButton = new JButton(View.getIcon("next16"));
|
||||
nextSearchButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
nextSearchButton.addActionListener(this);
|
||||
nextSearchButton.setActionCommand(ACTION_SEARCH_NEXT);
|
||||
JButton cancelSearchButton = new JButton(View.getIcon("cancel16"));
|
||||
cancelSearchButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
cancelSearchButton.addActionListener(this);
|
||||
cancelSearchButton.setActionCommand(ACTION_SEARCH_CANCEL);
|
||||
searchPos = new JLabel("0/0");
|
||||
searchForLabel = new JLabel(AppStrings.translate("search.info").replace("%text%", ""));
|
||||
add(searchForLabel);
|
||||
add(prevSearchButton);
|
||||
add(new JLabel(AppStrings.translate("search.script") + " "));
|
||||
add(searchPos);
|
||||
add(nextSearchButton);
|
||||
add(cancelSearchButton);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public void showQuickFindDialog(JTextComponent editor) {
|
||||
DocumentSearchData dsd = DocumentSearchData.getFromEditor(editor);
|
||||
dsd.setPattern(searchFor, searchRegexp, searchIgnoreCase);
|
||||
dsd.showQuickFindDialogEx(editor, searchIgnoreCase, searchRegexp);
|
||||
}
|
||||
|
||||
public void setSearchText(String txt) {
|
||||
searchFor = txt;
|
||||
searchForLabel.setText(AppStrings.translate("search.info").replace("%text%", txt) + " ");
|
||||
}
|
||||
|
||||
public boolean setResults(List<E> results) {
|
||||
found = results;
|
||||
if (found.isEmpty()) {
|
||||
setVisible(false);
|
||||
return false;
|
||||
} else {
|
||||
setPos(0);
|
||||
setVisible(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOptions(boolean ignoreCase, boolean regExp) {
|
||||
searchIgnoreCase = ignoreCase;
|
||||
searchRegexp = regExp;
|
||||
}
|
||||
|
||||
public void setPos(int pos) {
|
||||
foundPos = pos;
|
||||
doUpdate();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
foundPos = 0;
|
||||
found.clear();
|
||||
}
|
||||
|
||||
private void doUpdate() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searchPos.setText((foundPos + 1) + "/" + found.size());
|
||||
listener.updateSearchPos(found.get(foundPos));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_SEARCH_CANCEL:
|
||||
foundPos = 0;
|
||||
setVisible(false);
|
||||
found = new ArrayList<>();
|
||||
searchFor = null;
|
||||
break;
|
||||
case ACTION_SEARCH_PREV:
|
||||
foundPos--;
|
||||
if (foundPos < 0) {
|
||||
foundPos += found.size();
|
||||
}
|
||||
doUpdate();
|
||||
break;
|
||||
case ACTION_SEARCH_NEXT:
|
||||
foundPos = (foundPos + 1) % found.size();
|
||||
doUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import jsyntaxpane.DefaultSyntaxKit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SelectLanguageDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
JComboBox<Language> languageCombobox = new JComboBox<>();
|
||||
public String languageCode = null;
|
||||
private static final String[] languages = new String[]{"en", "cs", "zh", "de", "es", "fr", "hu", "nl", "pt", "pt-BR", "ru", "sv", "uk"};
|
||||
|
||||
public SelectLanguageDialog() {
|
||||
setSize(350, 130);
|
||||
Container cnt1 = getContentPane();
|
||||
JPanel cnt = new JPanel();
|
||||
cnt1.setLayout(new BorderLayout());
|
||||
cnt1.add(cnt, BorderLayout.CENTER);
|
||||
|
||||
String currentLanguage = Configuration.locale.get(Locale.getDefault().getLanguage());
|
||||
boolean found = false;
|
||||
int enIndex = 0;
|
||||
for (String code : languages) {
|
||||
String name = ResourceBundle.getBundle(AppStrings.getResourcePath(getClass()), Locale.forLanguageTag(code.equals("en") ? "" : code)).getString("language");
|
||||
if (name.length() > 1) {
|
||||
name = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
}
|
||||
if (code.equals("en")) {
|
||||
enIndex = languageCombobox.getItemCount();
|
||||
}
|
||||
languageCombobox.addItem(new Language(code, name));
|
||||
if (code.equals(currentLanguage)) {
|
||||
languageCombobox.setSelectedIndex(languageCombobox.getItemCount() - 1);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
languageCombobox.setSelectedIndex(enIndex);
|
||||
}
|
||||
cnt.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
|
||||
JLabel langLabel = new JLabel(translate("language.label"));
|
||||
langLabel.setAlignmentX(0.5f);
|
||||
cnt.add(langLabel);
|
||||
languageCombobox.setAlignmentX(0.5f);
|
||||
cnt.add(languageCombobox);
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
buttonsPanel.setAlignmentX(0.5f);
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.setActionCommand(ACTION_OK);
|
||||
okButton.addActionListener(this);
|
||||
JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
cnt.add(buttonsPanel);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
setTitle(translate("dialog.title"));
|
||||
pack();
|
||||
if (getWidth() < 350) {
|
||||
setSize(350, getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OK:
|
||||
if (languageCombobox.getSelectedIndex() == -1) {
|
||||
} else {
|
||||
languageCode = ((Language) languageCombobox.getSelectedItem()).code;
|
||||
String newLanguage = languageCode;
|
||||
if (newLanguage.equals("en")) {
|
||||
newLanguage = "";
|
||||
}
|
||||
Configuration.locale.set(newLanguage);
|
||||
setVisible(false);
|
||||
reloadUi();
|
||||
}
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void reloadUi() {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get()));
|
||||
DefaultSyntaxKit.reloadConfigs();
|
||||
Main.initLang();
|
||||
Main.reloadApp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String[] getAvailableLanguages() {
|
||||
return languages;
|
||||
}
|
||||
|
||||
public String display() {
|
||||
setVisible(true);
|
||||
return languageCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.helpers.SoundPlayer;
|
||||
import java.awt.Color;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundTagPlayer implements MediaDisplay {
|
||||
|
||||
private final SoundPlayer player;
|
||||
|
||||
private Thread thr;
|
||||
private int actualPos = 0;
|
||||
private final SoundTag tag;
|
||||
private final List<PlayerListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addListener(PlayerListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeListener(PlayerListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public void fireFinished() {
|
||||
for (PlayerListener l : listeners) {
|
||||
l.playingFinished();
|
||||
}
|
||||
}
|
||||
|
||||
private static final int FRAME_DIVISOR = 8000;
|
||||
|
||||
private int loops;
|
||||
private boolean paused = true;
|
||||
private final Object playLock = new Object();
|
||||
|
||||
public SoundTagPlayer(SoundTag tag, int loops) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
|
||||
this.tag = tag;
|
||||
this.loops = loops;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(tag.getRawSoundData());
|
||||
tag.getSoundFormat().createWav(bais, baos);
|
||||
player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getCurrentFrame() {
|
||||
|
||||
synchronized (playLock) {
|
||||
if (isPlaying()) {
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
}
|
||||
return actualPos;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getTotalFrames() {
|
||||
|
||||
int ret = (int) (player.samplesCount() / FRAME_DIVISOR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void pause() {
|
||||
if (!isPlaying()) {
|
||||
paused = true;
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (playLock) {
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
}
|
||||
|
||||
waitStop();
|
||||
}
|
||||
|
||||
private void waitStop() {
|
||||
synchronized (playLock) {
|
||||
if (!paused) {
|
||||
paused = true;
|
||||
player.stop();
|
||||
try {
|
||||
playLock.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void play(boolean async) {
|
||||
|
||||
waitStop();
|
||||
Runnable r = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
boolean playAgain = true;
|
||||
while (playAgain) {
|
||||
int startPos = 0;
|
||||
synchronized (playLock) {
|
||||
startPos = actualPos * FRAME_DIVISOR;
|
||||
}
|
||||
player.setPosition(startPos);
|
||||
player.play();
|
||||
|
||||
synchronized (playLock) {
|
||||
playAgain = !paused && loops > 0;
|
||||
if (!paused) {
|
||||
if (loops == 0) {
|
||||
paused = true;
|
||||
} else if (loops != Integer.MAX_VALUE) {
|
||||
loops--;
|
||||
}
|
||||
}
|
||||
if (playAgain) {
|
||||
actualPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fireFinished();
|
||||
synchronized (playLock) {
|
||||
playLock.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
synchronized (playLock) {
|
||||
paused = false;
|
||||
}
|
||||
if (async) {
|
||||
thr = new Thread(r);
|
||||
thr.start();
|
||||
} else {
|
||||
r.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void play() {
|
||||
play(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rewind() {
|
||||
gotoFrame(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return player.isPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void gotoFrame(int frame) {
|
||||
pause();
|
||||
synchronized (playLock) {
|
||||
actualPos = frame;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFrameRate() {
|
||||
if (player == null) {
|
||||
return 1;
|
||||
}
|
||||
return (int) (player.getFrameRate() / FRAME_DIVISOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwfInMemory {
|
||||
|
||||
public ReReadableInputStream is;
|
||||
public int version;
|
||||
public long fileSize;
|
||||
public com.jpexs.process.Process process;
|
||||
|
||||
public SwfInMemory(ReReadableInputStream is, int version, long fileSize, com.jpexs.process.Process process) {
|
||||
this.is = is;
|
||||
this.version = version;
|
||||
this.fileSize = fileSize;
|
||||
this.process = process;
|
||||
}
|
||||
|
||||
private static final ResourceBundle resourceBundle = ResourceBundle.getBundle(AppStrings.getResourcePath(LoadFromMemoryFrame.class));
|
||||
|
||||
public String translate(String key) {
|
||||
return resourceBundle.getString(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String p = translate("swfitem").replace("%version%", "" + version).replace("%size%", "" + fileSize);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.TagTreeRoot;
|
||||
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.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
|
||||
import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.decompiler.flash.treeitems.StringItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeElementItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TagTree extends JTree {
|
||||
|
||||
public class TagTreeCellRenderer extends 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);
|
||||
TreeNode treeNode = (TreeNode) value;
|
||||
TreeItem val = treeNode.getItem();
|
||||
TreeNodeType type = getTreeNodeType(val);
|
||||
if (type != null) {
|
||||
if (type == TreeNodeType.FOLDER && expanded) {
|
||||
type = TreeNodeType.FOLDER_OPEN;
|
||||
}
|
||||
String itemName = type.toString();
|
||||
if (type == TreeNodeType.FOLDER || type == TreeNodeType.FOLDER_OPEN) {
|
||||
if (val instanceof StringItem) {
|
||||
StringItem si = (StringItem) val;
|
||||
if (!TagTreeRoot.FOLDER_ROOT.equals(si.getName())) {
|
||||
itemName = "folder" + si.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
String tagTypeStr = itemName.toLowerCase().replace("_", "");
|
||||
setIcon(View.getIcon(tagTypeStr + "16"));
|
||||
}
|
||||
|
||||
Font font = getFont();
|
||||
boolean isModified = false;
|
||||
if (treeNode instanceof TreeNode) {
|
||||
if (treeNode.getItem() instanceof Tag) {
|
||||
Tag tag = (Tag) treeNode.getItem();
|
||||
if (tag.isModified()) {
|
||||
isModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isModified) {
|
||||
font = font.deriveFont(Font.BOLD);
|
||||
} else {
|
||||
font = font.deriveFont(Font.PLAIN);
|
||||
}
|
||||
setFont(font);
|
||||
|
||||
setUI(new BasicLabelUI());
|
||||
setOpaque(false);
|
||||
//setBackground(Color.green);
|
||||
setBackgroundNonSelectionColor(Color.white);
|
||||
//setBackgroundSelectionColor(Color.ORANGE);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
TagTree(TagTreeModel treeModel) {
|
||||
super(treeModel);
|
||||
setCellRenderer(new TagTreeCellRenderer());
|
||||
setRootVisible(false);
|
||||
setBackground(Color.white);
|
||||
setUI(new BasicTreeUI() {
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
setHashColor(Color.gray);
|
||||
super.paint(g, c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static TreeNodeType getTreeNodeType(TreeItem t) {
|
||||
if ((t instanceof DefineFontTag)
|
||||
|| (t instanceof DefineFont2Tag)
|
||||
|| (t instanceof DefineFont3Tag)
|
||||
|| (t instanceof DefineFont4Tag)
|
||||
|| (t instanceof DefineCompactedFont)) {
|
||||
return TreeNodeType.FONT;
|
||||
}
|
||||
if ((t instanceof DefineTextTag)
|
||||
|| (t instanceof DefineText2Tag)
|
||||
|| (t instanceof DefineEditTextTag)) {
|
||||
return TreeNodeType.TEXT;
|
||||
}
|
||||
|
||||
if ((t instanceof DefineBitsTag)
|
||||
|| (t instanceof DefineBitsJPEG2Tag)
|
||||
|| (t instanceof DefineBitsJPEG3Tag)
|
||||
|| (t instanceof DefineBitsJPEG4Tag)
|
||||
|| (t instanceof DefineBitsLosslessTag)
|
||||
|| (t instanceof DefineBitsLossless2Tag)) {
|
||||
return TreeNodeType.IMAGE;
|
||||
}
|
||||
if ((t instanceof DefineShapeTag)
|
||||
|| (t instanceof DefineShape2Tag)
|
||||
|| (t instanceof DefineShape3Tag)
|
||||
|| (t instanceof DefineShape4Tag)) {
|
||||
return TreeNodeType.SHAPE;
|
||||
}
|
||||
|
||||
if ((t instanceof DefineMorphShapeTag) || (t instanceof DefineMorphShape2Tag)) {
|
||||
return TreeNodeType.MORPH_SHAPE;
|
||||
}
|
||||
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
return TreeNodeType.SPRITE;
|
||||
}
|
||||
if ((t instanceof DefineButtonTag) || (t instanceof DefineButton2Tag)) {
|
||||
return TreeNodeType.BUTTON;
|
||||
}
|
||||
if (t instanceof ASMSource) {
|
||||
return TreeNodeType.AS;
|
||||
}
|
||||
if (t instanceof ScriptPack) {
|
||||
return TreeNodeType.AS;
|
||||
}
|
||||
if (t instanceof AS2PackageNodeItem) {
|
||||
return TreeNodeType.PACKAGE;
|
||||
}
|
||||
if (t instanceof AS3PackageNodeItem) {
|
||||
return TreeNodeType.PACKAGE;
|
||||
}
|
||||
if (t instanceof FrameNodeItem) {
|
||||
return TreeNodeType.FRAME;
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
return TreeNodeType.SHOW_FRAME;
|
||||
}
|
||||
|
||||
if (t instanceof DefineVideoStreamTag) {
|
||||
return TreeNodeType.MOVIE;
|
||||
}
|
||||
|
||||
if ((t instanceof DefineSoundTag) || (t instanceof SoundStreamHeadTag) || (t instanceof SoundStreamHead2Tag)) {
|
||||
return TreeNodeType.SOUND;
|
||||
}
|
||||
|
||||
if (t instanceof DefineBinaryDataTag) {
|
||||
return TreeNodeType.BINARY_DATA;
|
||||
}
|
||||
|
||||
if (t instanceof SWF) {
|
||||
return TreeNodeType.FLASH;
|
||||
}
|
||||
|
||||
if (t instanceof SWFList) {
|
||||
SWFList slist = (SWFList) t;
|
||||
if (slist.name != null) {
|
||||
if (slist.name.toLowerCase().endsWith(".zip")) {
|
||||
return TreeNodeType.BUNDLE_ZIP;
|
||||
}
|
||||
if (slist.name.toLowerCase().endsWith(".swc")) {
|
||||
return TreeNodeType.BUNDLE_SWC;
|
||||
} else {
|
||||
return TreeNodeType.BUNDLE_BINARY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t instanceof Tag) {
|
||||
return TreeNodeType.OTHER_TAG;
|
||||
}
|
||||
|
||||
/*if(t instanceof StringNode){
|
||||
StringNode sn=(StringNode)t;
|
||||
String name = sn.getItem().getName();
|
||||
if(name!=null){
|
||||
switch(name){
|
||||
case TagTreeModel.FOLDER_BINARY_DATA:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_BUTTONS:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_FONTS:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_FRAMES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_IMAGES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_MORPHSHAPES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_MOVIES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_OTHERS:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_SCRIPTS:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_SHAPES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_SOUNDS:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_SPRITES:
|
||||
break;
|
||||
case TagTreeModel.FOLDER_TEXTS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return TreeNodeType.FOLDER;
|
||||
}
|
||||
|
||||
public List<TreeElementItem> getTagsWithType(List<TreeElementItem> list, TreeNodeType type) {
|
||||
List<TreeElementItem> ret = new ArrayList<>();
|
||||
for (TreeElementItem item : list) {
|
||||
TreeNodeType ttype = getTreeNodeType(item);
|
||||
if (type == ttype) {
|
||||
ret.add(item);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public TreeItem getCurrentTreeItem() {
|
||||
TreeNode treeNode = (TreeNode) getLastSelectedPathComponent();
|
||||
if (treeNode == null) {
|
||||
return null;
|
||||
}
|
||||
return treeNode.getItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.ClassesListNode;
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFContainerNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.StringNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.TagTreeRoot;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.decompiler.flash.treeitems.StringItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeElementItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.treenodes.FrameNode;
|
||||
import com.jpexs.decompiler.flash.treenodes.TagNode;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
public class TagTreeModel implements TreeModel {
|
||||
|
||||
public static final String FOLDER_TEXTS = "texts";
|
||||
public static final String FOLDER_IMAGES = "images";
|
||||
public static final String FOLDER_MOVIES = "movies";
|
||||
public static final String FOLDER_SOUNDS = "sounds";
|
||||
public static final String FOLDER_BINARY_DATA = "binaryData";
|
||||
public static final String FOLDER_FONTS = "fonts";
|
||||
public static final String FOLDER_SPRITES = "sprites";
|
||||
public static final String FOLDER_SHAPES = "shapes";
|
||||
public static final String FOLDER_MORPHSHAPES = "morphshapes";
|
||||
public static final String FOLDER_BUTTONS = "buttons";
|
||||
public static final String FOLDER_FRAMES = "frames";
|
||||
public static final String FOLDER_OTHERS = "others";
|
||||
public static final String FOLDER_SCRIPTS = "scripts";
|
||||
private final TagTreeRoot root = new TagTreeRoot();
|
||||
private final List<SWFContainerNode> swfs;
|
||||
private final Map<SWF, SWFNode> swfToSwfNode;
|
||||
private final MainFrame mainFrame;
|
||||
|
||||
public TagTreeModel(MainFrame mainFrame, List<SWFList> swfs) {
|
||||
this.mainFrame = mainFrame;
|
||||
this.swfs = new ArrayList<>();
|
||||
swfToSwfNode = new HashMap<>();
|
||||
for (SWFList swfList : swfs) {
|
||||
if (swfList.isBundle) {
|
||||
SWFBundleNode bundleNode = new SWFBundleNode(swfList, swfList.name);
|
||||
for (SWF swf : swfList) {
|
||||
bundleNode.swfs.add(createSwfNode(swf));
|
||||
}
|
||||
this.swfs.add(bundleNode);
|
||||
} else {
|
||||
SWF swf = swfList.get(0);
|
||||
this.swfs.add(createSwfNode(swf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SWFNode createSwfNode(SWF swf) {
|
||||
ClassesListTreeModel classTreeModel = new ClassesListTreeModel(swf);
|
||||
SWFNode swfNode = new SWFNode(swf, swf.getShortFileName());
|
||||
swfNode.list = createTagList(swf.tags, null, swf, swfNode, classTreeModel);
|
||||
swfToSwfNode.put(swf, swfNode);
|
||||
return swfNode;
|
||||
}
|
||||
|
||||
private String translate(String key) {
|
||||
return mainFrame.translate(key);
|
||||
}
|
||||
|
||||
private List<TreeNode> createTagList(List<Tag> list, Tag parent, SWF swf, SWFNode swfNode, ClassesListTreeModel classTreeModel) {
|
||||
boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty();
|
||||
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
List<TreeNode> frames = new ArrayList<>();
|
||||
List<TreeNode> shapes = new ArrayList<>();
|
||||
List<TreeNode> morphShapes = new ArrayList<>();
|
||||
List<TreeNode> sprites = new ArrayList<>();
|
||||
List<TreeNode> buttons = new ArrayList<>();
|
||||
List<TreeNode> images = new ArrayList<>();
|
||||
List<TreeNode> fonts = new ArrayList<>();
|
||||
List<TreeNode> texts = new ArrayList<>();
|
||||
List<TreeNode> movies = new ArrayList<>();
|
||||
List<TreeNode> sounds = new ArrayList<>();
|
||||
List<TreeNode> binaryData = new ArrayList<>();
|
||||
List<TreeNode> others = new ArrayList<>();
|
||||
|
||||
List<TreeNode> actionScript = SWF.createASTagList(list, null);
|
||||
List<Tag> actionScriptTags = new ArrayList<>();
|
||||
SWF.getTagsFromTreeNodes(actionScript, actionScriptTags);
|
||||
|
||||
int frameCnt = 0;
|
||||
for (Tag t : list) {
|
||||
TreeNodeType ttype = TagTree.getTreeNodeType(t);
|
||||
switch (ttype) {
|
||||
case SHOW_FRAME:
|
||||
ShowFrameTag showFrameTag = (ShowFrameTag) t;
|
||||
frames.add(new FrameNode(new FrameNodeItem(t.getSwf(), ++frameCnt, parent, showFrameTag, true), showFrameTag.innerTags, false));
|
||||
break;
|
||||
case SHAPE:
|
||||
shapes.add(new TagNode(t));
|
||||
break;
|
||||
case MORPH_SHAPE:
|
||||
morphShapes.add(new TagNode(t));
|
||||
break;
|
||||
case SPRITE:
|
||||
sprites.add(new TagNode(t));
|
||||
break;
|
||||
case BUTTON:
|
||||
buttons.add(new TagNode(t));
|
||||
break;
|
||||
case IMAGE:
|
||||
images.add(new TagNode(t));
|
||||
break;
|
||||
case FONT:
|
||||
fonts.add(new TagNode(t));
|
||||
break;
|
||||
case TEXT:
|
||||
texts.add(new TagNode(t));
|
||||
break;
|
||||
case MOVIE:
|
||||
movies.add(new TagNode(t));
|
||||
break;
|
||||
case SOUND:
|
||||
sounds.add(new TagNode(t));
|
||||
break;
|
||||
case BINARY_DATA:
|
||||
TagNode bt;
|
||||
binaryData.add(bt = new TagNode(t));
|
||||
|
||||
DefineBinaryDataTag b=(DefineBinaryDataTag)t;
|
||||
|
||||
try {
|
||||
SWF bswf=new SWF(new ByteArrayInputStream(b.binaryData),Configuration.parallelSpeedUp.get());
|
||||
bswf.fileTitle = "(SWF Data)";
|
||||
SWFNode snode=createSwfNode(bswf);
|
||||
snode.binaryData = b;
|
||||
bt.subNodes.add(snode);
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!actionScriptTags.contains(t) && !ShowFrameTag.isNestedTagType(t.getId())) {
|
||||
others.add(new TagNode(t));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < sounds.size(); i++) {
|
||||
if (sounds.get(i).getItem() instanceof SoundStreamHeadTypeTag) {
|
||||
List<SoundStreamBlockTag> blocks = ((SoundStreamHeadTypeTag) sounds.get(i).getItem()).getBlocks();
|
||||
if (blocks.isEmpty()) {
|
||||
sounds.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TreeNode n : sprites) {
|
||||
Tag tag = n.getItem() instanceof Tag ? (Tag) n.getItem() : null;
|
||||
n.subNodes = createSubTagList(((DefineSpriteTag) n.getItem()).subTags, tag, swf, actionScriptTags);
|
||||
}
|
||||
|
||||
StringNode textsNode = new StringNode(new StringItem(translate("node.texts"), FOLDER_TEXTS, swf));
|
||||
textsNode.subNodes.addAll(texts);
|
||||
|
||||
StringNode imagesNode = new StringNode(new StringItem(translate("node.images"), FOLDER_IMAGES, swf));
|
||||
imagesNode.subNodes.addAll(images);
|
||||
|
||||
StringNode moviesNode = new StringNode(new StringItem(translate("node.movies"), FOLDER_MOVIES, swf));
|
||||
moviesNode.subNodes.addAll(movies);
|
||||
|
||||
StringNode soundsNode = new StringNode(new StringItem(translate("node.sounds"), FOLDER_SOUNDS, swf));
|
||||
soundsNode.subNodes.addAll(sounds);
|
||||
|
||||
StringNode binaryDataNode = new StringNode(new StringItem(translate("node.binaryData"), FOLDER_BINARY_DATA, swf));
|
||||
binaryDataNode.subNodes.addAll(binaryData);
|
||||
|
||||
StringNode fontsNode = new StringNode(new StringItem(translate("node.fonts"), FOLDER_FONTS, swf));
|
||||
fontsNode.subNodes.addAll(fonts);
|
||||
|
||||
StringNode spritesNode = new StringNode(new StringItem(translate("node.sprites"), FOLDER_SPRITES, swf));
|
||||
spritesNode.subNodes.addAll(sprites);
|
||||
|
||||
StringNode shapesNode = new StringNode(new StringItem(translate("node.shapes"), FOLDER_SHAPES, swf));
|
||||
shapesNode.subNodes.addAll(shapes);
|
||||
|
||||
StringNode morphShapesNode = new StringNode(new StringItem(translate("node.morphshapes"), FOLDER_MORPHSHAPES, swf));
|
||||
morphShapesNode.subNodes.addAll(morphShapes);
|
||||
|
||||
StringNode buttonsNode = new StringNode(new StringItem(translate("node.buttons"), FOLDER_BUTTONS, swf));
|
||||
buttonsNode.subNodes.addAll(buttons);
|
||||
|
||||
StringNode framesNode = new StringNode(new StringItem(translate("node.frames"), FOLDER_FRAMES, swf));
|
||||
framesNode.subNodes.addAll(frames);
|
||||
|
||||
StringNode otherNode = new StringNode(new StringItem(translate("node.others"), FOLDER_OTHERS, swf));
|
||||
otherNode.subNodes.addAll(others);
|
||||
|
||||
TreeNode actionScriptNode;
|
||||
if (hasAbc) {
|
||||
actionScriptNode = new ClassesListNode(classTreeModel);
|
||||
} else {
|
||||
actionScriptNode = new StringNode(new StringItem(translate("node.scripts"), FOLDER_SCRIPTS, swf));
|
||||
actionScriptNode.subNodes.addAll(actionScript);
|
||||
}
|
||||
swfNode.scriptsNode = actionScriptNode;
|
||||
|
||||
if (!shapesNode.subNodes.isEmpty()) {
|
||||
ret.add(shapesNode);
|
||||
}
|
||||
if (!morphShapesNode.subNodes.isEmpty()) {
|
||||
ret.add(morphShapesNode);
|
||||
}
|
||||
if (!spritesNode.subNodes.isEmpty()) {
|
||||
ret.add(spritesNode);
|
||||
}
|
||||
if (!textsNode.subNodes.isEmpty()) {
|
||||
ret.add(textsNode);
|
||||
}
|
||||
if (!imagesNode.subNodes.isEmpty()) {
|
||||
ret.add(imagesNode);
|
||||
}
|
||||
if (!moviesNode.subNodes.isEmpty()) {
|
||||
ret.add(moviesNode);
|
||||
}
|
||||
if (!soundsNode.subNodes.isEmpty()) {
|
||||
ret.add(soundsNode);
|
||||
}
|
||||
if (!buttonsNode.subNodes.isEmpty()) {
|
||||
ret.add(buttonsNode);
|
||||
}
|
||||
if (!fontsNode.subNodes.isEmpty()) {
|
||||
ret.add(fontsNode);
|
||||
}
|
||||
if (!binaryDataNode.subNodes.isEmpty()) {
|
||||
ret.add(binaryDataNode);
|
||||
}
|
||||
if (!framesNode.subNodes.isEmpty()) {
|
||||
ret.add(framesNode);
|
||||
}
|
||||
if (!otherNode.subNodes.isEmpty()) {
|
||||
ret.add(otherNode);
|
||||
}
|
||||
|
||||
if ((!actionScriptNode.subNodes.isEmpty()) || hasAbc) {
|
||||
ret.add(actionScriptNode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<TreeNode> createSubTagList(List<Tag> list, Tag parent, SWF swf, List<Tag> actionScriptTags) {
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
List<TreeNode> frames = new ArrayList<>();
|
||||
List<TreeNode> others = new ArrayList<>();
|
||||
|
||||
int frameCnt = 0;
|
||||
for (Tag t : list) {
|
||||
TreeNodeType ttype = TagTree.getTreeNodeType(t);
|
||||
switch (ttype) {
|
||||
case SHOW_FRAME:
|
||||
ShowFrameTag showFrameTag = (ShowFrameTag) t;
|
||||
frames.add(new FrameNode(new FrameNodeItem(t.getSwf(), ++frameCnt, parent, showFrameTag, true), showFrameTag.innerTags, false));
|
||||
break;
|
||||
default:
|
||||
if (!actionScriptTags.contains(t) && !ShowFrameTag.isNestedTagType(t.getId())) {
|
||||
if (!(t instanceof SoundStreamHeadTypeTag)) {
|
||||
others.add(new TagNode(t));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret.addAll(frames);
|
||||
|
||||
if (!others.isEmpty()) {
|
||||
StringNode otherNode = new StringNode(new StringItem(translate("node.others"), FOLDER_OTHERS, swf));
|
||||
otherNode.subNodes.addAll(others);
|
||||
ret.add(otherNode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<TreeNode> searchTag(TreeItem obj, TreeNode parent, List<TreeNode> path) {
|
||||
List<TreeNode> ret = null;
|
||||
int cnt = getChildCount(parent);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
TreeNode n = getChild(parent, i);
|
||||
List<TreeNode> newPath = new ArrayList<>();
|
||||
newPath.addAll(path);
|
||||
newPath.add(n);
|
||||
|
||||
if (n instanceof TreeElement) {
|
||||
TreeElement te = (TreeElement) n;
|
||||
TreeElementItem it = te.getItem();
|
||||
if (obj == it) {
|
||||
return newPath;
|
||||
}
|
||||
}
|
||||
if (n instanceof TreeNode) {
|
||||
TreeNode nd = (TreeNode) n;
|
||||
if (obj instanceof StringItem && nd.getItem() instanceof StringItem) {
|
||||
// StringItems are always recreated, so compare them by name
|
||||
StringItem nds = (StringItem) nd.getItem();
|
||||
StringItem objs = (StringItem) obj;
|
||||
if (objs.getName().equals(nds.getName())) {
|
||||
return newPath;
|
||||
}
|
||||
} else {
|
||||
if (nd.getItem() == obj) {
|
||||
return newPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = searchTag(obj, n, newPath);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SWFNode getSwfNode(SWF swf) {
|
||||
return swfToSwfNode.get(swf);
|
||||
}
|
||||
|
||||
public TreePath getTagPath(TreeItem obj) {
|
||||
List<TreeNode> path = new ArrayList<>();
|
||||
path.add(getRoot());
|
||||
path = searchTag(obj, getRoot(), path);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
TreePath tp = new TreePath(path.toArray(new Object[path.size()]));
|
||||
return tp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode getChild(Object parent, int index) {
|
||||
TreeNode parentNode = (TreeNode) parent;
|
||||
if (parent instanceof TreeElement) {
|
||||
return ((TreeElement) parent).getChild(index);
|
||||
} else {
|
||||
if (parentNode.getItem() instanceof ClassesListTreeModel) {
|
||||
ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem();
|
||||
return clt.getChild(clt.getRoot(), index);
|
||||
}
|
||||
}
|
||||
if (parent == root) {
|
||||
return swfs.get(index);
|
||||
} else if (parent instanceof SWFBundleNode) {
|
||||
return ((SWFBundleNode) parent).swfs.get(index);
|
||||
} else if (parent instanceof SWFNode) {
|
||||
return ((SWFNode) parent).list.get(index);
|
||||
}
|
||||
return parentNode.subNodes.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
TreeNode parentNode = (TreeNode) parent;
|
||||
if (parent == root) {
|
||||
return swfs.size();
|
||||
} else if (parent instanceof TreeElement) {
|
||||
return ((TreeElement) parent).getChildCount();
|
||||
} else if (parent instanceof SWFBundleNode) {
|
||||
return ((SWFBundleNode) parent).swfs.size();
|
||||
} else if (parent instanceof SWFNode) {
|
||||
return ((SWFNode) parent).list.size();
|
||||
} else {
|
||||
if (parentNode.getItem() instanceof ClassesListTreeModel) {
|
||||
ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem();
|
||||
return clt.getChildCount(clt.getRoot());
|
||||
}
|
||||
return parentNode.subNodes.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
return (getChildCount(node) == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
TreeNode parentNode = (TreeNode) parent;
|
||||
if (parent == root) {
|
||||
return swfs.indexOf(child);
|
||||
} else if (parent instanceof TreeElement) {
|
||||
return ((TreeElement) parent).getIndexOfChild((TreeElement) child);
|
||||
} else if (parent instanceof SWFBundleNode) {
|
||||
return ((SWFBundleNode) parent).swfs.indexOf(child);
|
||||
} else if (parent instanceof SWFNode) {
|
||||
return ((SWFNode) parent).list.indexOf(child);
|
||||
} else {
|
||||
if (parentNode.getItem() instanceof ClassesListTreeModel) {
|
||||
ClassesListTreeModel clt = (ClassesListTreeModel) parentNode.getItem();
|
||||
return clt.getIndexOfChild(clt.getRoot(), child);
|
||||
}
|
||||
return parentNode.subNodes.indexOf(child);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.SWF;
|
||||
import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TextPanel extends JPanel implements ActionListener {
|
||||
|
||||
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 final MainPanel mainPanel;
|
||||
private final SearchPanel<TextTag> textSearchPanel;
|
||||
private final LineMarkedEditorPane textValue;
|
||||
private final JButton textSaveButton;
|
||||
private final JButton textEditButton;
|
||||
private final JButton textCancelButton;
|
||||
|
||||
public TextPanel(MainPanel mainPanel) {
|
||||
super(new BorderLayout());
|
||||
|
||||
this.mainPanel = mainPanel;
|
||||
textSearchPanel = new SearchPanel<>(new FlowLayout(), mainPanel);
|
||||
add(textSearchPanel, BorderLayout.NORTH);
|
||||
textValue = new LineMarkedEditorPane();
|
||||
add(new JScrollPane(textValue), BorderLayout.CENTER);
|
||||
textValue.setEditable(false);
|
||||
|
||||
JPanel textButtonsPanel = new JPanel();
|
||||
textButtonsPanel.setLayout(new FlowLayout());
|
||||
|
||||
textSaveButton = new JButton(mainPanel.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(mainPanel.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(mainPanel.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);
|
||||
|
||||
add(textButtonsPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
public SearchPanel<TextTag> getSearchPanel() {
|
||||
return textSearchPanel;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
textValue.setContentType("text/swf_text");
|
||||
// textValue.setFont(new Font("Monospaced", Font.PLAIN, 13));
|
||||
textValue.setText(text);
|
||||
textValue.setCaretPosition(0);
|
||||
}
|
||||
|
||||
public void setEditText(boolean edit) {
|
||||
textValue.setEditable(edit);
|
||||
textSaveButton.setVisible(edit);
|
||||
textEditButton.setVisible(!edit);
|
||||
textCancelButton.setVisible(edit);
|
||||
}
|
||||
|
||||
public void updateSearchPos() {
|
||||
textValue.setCaretPosition(0);
|
||||
textSearchPanel.showQuickFindDialog(textValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_EDIT_TEXT:
|
||||
setEditText(true);
|
||||
break;
|
||||
case ACTION_CANCEL_TEXT:
|
||||
setEditText(false);
|
||||
mainPanel.reload(true);
|
||||
break;
|
||||
case ACTION_SAVE_TEXT:
|
||||
TreeItem item = mainPanel.tagTree.getCurrentTreeItem();
|
||||
if (item instanceof TextTag) {
|
||||
TextTag textTag = (TextTag) item;
|
||||
if (mainPanel.saveText(textTag, textValue.getText(), null)) {
|
||||
setEditText(false);
|
||||
mainPanel.reload(true);
|
||||
}
|
||||
SWF.clearImageCache();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum TreeNodeType {
|
||||
|
||||
FLASH,
|
||||
FONT,
|
||||
TEXT,
|
||||
IMAGE,
|
||||
SHAPE,
|
||||
MORPH_SHAPE,
|
||||
SPRITE,
|
||||
BUTTON,
|
||||
AS,
|
||||
PACKAGE,
|
||||
FRAME,
|
||||
SHOW_FRAME,
|
||||
MOVIE,
|
||||
SOUND,
|
||||
BINARY_DATA,
|
||||
OTHER_TAG,
|
||||
FOLDER,
|
||||
FOLDER_OPEN,
|
||||
BUNDLE_ZIP,
|
||||
BUNDLE_SWC,
|
||||
BUNDLE_BINARY
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.AppStrings;
|
||||
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.TexturePaint;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.basic.BasicColorChooserUI;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon;
|
||||
import org.pushingpixels.substance.api.ComponentState;
|
||||
import org.pushingpixels.substance.api.SubstanceColorScheme;
|
||||
import org.pushingpixels.substance.api.SubstanceConstants;
|
||||
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
|
||||
import org.pushingpixels.substance.api.fonts.FontPolicy;
|
||||
import org.pushingpixels.substance.api.fonts.FontSet;
|
||||
import org.pushingpixels.substance.api.skin.SubstanceOfficeBlue2007LookAndFeel;
|
||||
import org.pushingpixels.substance.internal.utils.SubstanceColorSchemeUtilities;
|
||||
|
||||
/**
|
||||
* Contains methods for GUI
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class View {
|
||||
|
||||
public static final Color DEFAULT_BACKGROUND_COLOR = new Color(217, 231, 250);
|
||||
public static Color swfBackgroundColor = DEFAULT_BACKGROUND_COLOR;
|
||||
|
||||
private static final BufferedImage transparentTexture;
|
||||
public static final TexturePaint transparentPaint;
|
||||
|
||||
private static final Color transparentColor1 = new Color(0x99, 0x99, 0x99);
|
||||
private static final Color transparentColor2 = new Color(0x66, 0x66, 0x66);
|
||||
|
||||
static {
|
||||
transparentTexture = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics g = transparentTexture.getGraphics();
|
||||
g.setColor(transparentColor1);
|
||||
g.fillRect(0, 0, 16, 16);
|
||||
g.setColor(transparentColor2);
|
||||
g.fillRect(0, 0, 8, 8);
|
||||
g.fillRect(8, 8, 8, 8);
|
||||
transparentPaint = new TexturePaint(View.transparentTexture, new Rectangle(0, 0, transparentTexture.getWidth(), transparentTexture.getHeight()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets windows Look and Feel
|
||||
*/
|
||||
public static void setLookAndFeel() {
|
||||
|
||||
//Save default font for Chinese characters
|
||||
final Font defaultFont = (new JLabel()).getFont();
|
||||
try {
|
||||
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
|
||||
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) {
|
||||
}
|
||||
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel());
|
||||
UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, 0.999);//This works for not changing labels color and not changing Dialogs title
|
||||
UIManager.put("Tree.expandedIcon", getIcon("expand16"));
|
||||
UIManager.put("Tree.collapsedIcon", getIcon("collapse16"));
|
||||
UIManager.put("ColorChooserUI", BasicColorChooserUI.class.getName());
|
||||
UIManager.put("ColorChooser.swatchesRecentSwatchSize", new Dimension(20, 20));
|
||||
UIManager.put("ColorChooser.swatchesSwatchSize", new Dimension(20, 20));
|
||||
UIManager.put("RibbonApplicationMenuPopupPanelUI", MyRibbonApplicationMenuPopupPanelUI.class.getName());
|
||||
UIManager.put("RibbonApplicationMenuButtonUI", MyRibbonApplicationMenuButtonUI.class.getName());
|
||||
UIManager.put("ProgressBarUI", MyProgressBarUI.class.getName());
|
||||
UIManager.put("TextField.background", Color.WHITE);
|
||||
UIManager.put("FormattedTextField.background", Color.WHITE);
|
||||
UIManager.put("CommandButtonUI", MyCommandButtonUI.class.getName());
|
||||
|
||||
|
||||
FontPolicy pol = SubstanceLookAndFeel.getFontPolicy();
|
||||
final FontSet fs = pol.getFontSet("Substance", null);
|
||||
|
||||
//Restore default font for chinese characters
|
||||
SubstanceLookAndFeel.setFontPolicy(new FontPolicy() {
|
||||
|
||||
private final FontSet fontSet = new FontSet() {
|
||||
|
||||
private FontUIResource controlFont;
|
||||
private FontUIResource menuFont;
|
||||
private FontUIResource titleFont;
|
||||
private FontUIResource windowTitleFont;
|
||||
private FontUIResource smallFont;
|
||||
private FontUIResource messageFont;
|
||||
|
||||
@Override
|
||||
public FontUIResource getControlFont() {
|
||||
if (controlFont == null) {
|
||||
FontUIResource f = fs.getControlFont();
|
||||
controlFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return controlFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontUIResource getMenuFont() {
|
||||
if (menuFont == null) {
|
||||
FontUIResource f = fs.getMenuFont();
|
||||
menuFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return menuFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontUIResource getTitleFont() {
|
||||
if (titleFont == null) {
|
||||
FontUIResource f = fs.getTitleFont();
|
||||
titleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return titleFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontUIResource getWindowTitleFont() {
|
||||
if (windowTitleFont == null) {
|
||||
FontUIResource f = fs.getWindowTitleFont();
|
||||
windowTitleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return windowTitleFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontUIResource getSmallFont() {
|
||||
if (smallFont == null) {
|
||||
FontUIResource f = fs.getSmallFont();
|
||||
smallFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return smallFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontUIResource getMessageFont() {
|
||||
if (messageFont == null) {
|
||||
FontUIResource f = fs.getMessageFont();
|
||||
messageFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize());
|
||||
}
|
||||
return messageFont;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public FontSet getFontSet(String string, UIDefaults uid) {
|
||||
return fontSet;
|
||||
}
|
||||
});
|
||||
} catch (UnsupportedLookAndFeelException ex) {
|
||||
Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
UIManager.put(SubstanceLookAndFeel.TABBED_PANE_CONTENT_BORDER_KIND, SubstanceConstants.TabContentPaneBorderKind.SINGLE_FULL);
|
||||
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
JDialog.setDefaultLookAndFeelDecorated(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads image from resources
|
||||
*
|
||||
* @param name Name of the image
|
||||
* @return loaded Image
|
||||
*/
|
||||
public static BufferedImage loadImage(String name) {
|
||||
java.net.URL imageURL = View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + name + ".png");
|
||||
try {
|
||||
return ImageIO.read(imageURL);
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets icon of specified frame to ASDec icon
|
||||
*
|
||||
* @param f Frame to set icon in
|
||||
*/
|
||||
public static void setWindowIcon(Window f) {
|
||||
java.util.List<Image> images = new ArrayList<>();
|
||||
images.add(loadImage("icon16"));
|
||||
images.add(loadImage("icon32"));
|
||||
images.add(loadImage("icon48"));
|
||||
images.add(loadImage("icon256"));
|
||||
f.setIconImages(images);
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers specified frame on the screen
|
||||
*
|
||||
* @param f Frame to center on the screen
|
||||
*/
|
||||
public static void centerScreen(Window f) {
|
||||
centerScreen(f, 0); // todo, set screen to the currently active screen instead of the first screen in a multi screen setup, (maybe by using the screen where the main window is now classic or ribbon?)
|
||||
}
|
||||
|
||||
public static void centerScreen(Window f, int screen) {
|
||||
|
||||
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice[] allDevices = env.getScreenDevices();
|
||||
int topLeftX, topLeftY, screenX, screenY, windowPosX, windowPosY;
|
||||
|
||||
if (screen < allDevices.length && screen > -1) {
|
||||
topLeftX = allDevices[screen].getDefaultConfiguration().getBounds().x;
|
||||
topLeftY = allDevices[screen].getDefaultConfiguration().getBounds().y;
|
||||
|
||||
screenX = allDevices[screen].getDefaultConfiguration().getBounds().width;
|
||||
screenY = allDevices[screen].getDefaultConfiguration().getBounds().height;
|
||||
} else {
|
||||
topLeftX = allDevices[0].getDefaultConfiguration().getBounds().x;
|
||||
topLeftY = allDevices[0].getDefaultConfiguration().getBounds().y;
|
||||
|
||||
screenX = allDevices[0].getDefaultConfiguration().getBounds().width;
|
||||
screenY = allDevices[0].getDefaultConfiguration().getBounds().height;
|
||||
}
|
||||
|
||||
windowPosX = ((screenX - f.getWidth()) / 2) + topLeftX;
|
||||
windowPosY = ((screenY - f.getHeight()) / 2) + topLeftY;
|
||||
|
||||
f.setLocation(windowPosX, windowPosY);
|
||||
}
|
||||
|
||||
public static ImageIcon getIcon(String name) {
|
||||
return new ImageIcon(View.class.getClassLoader().getResource("com/jpexs/decompiler/flash/gui/graphics/" + name + ".png"));
|
||||
}
|
||||
private static final KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
||||
private static final String dispatchWindowClosingActionMapKey = "com.jpexs.dispatch:WINDOW_CLOSING";
|
||||
|
||||
public static void installEscapeCloseOperation(final JDialog dialog) {
|
||||
Action dispatchClosing = new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
dialog.dispatchEvent(new WindowEvent(
|
||||
dialog, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
};
|
||||
JRootPane root = dialog.getRootPane();
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
|
||||
escapeStroke, dispatchWindowClosingActionMapKey);
|
||||
root.getActionMap().put(dispatchWindowClosingActionMapKey, dispatchClosing);
|
||||
}
|
||||
|
||||
public static ImageWrapperResizableIcon getResizableIcon(String resource) {
|
||||
return ImageWrapperResizableIcon.getIcon(View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + resource + ".png"), new Dimension(256, 256));
|
||||
}
|
||||
|
||||
public static MyResizableIcon getMyResizableIcon(String resource) {
|
||||
try {
|
||||
return new MyResizableIcon(ImageIO.read(View.class.getResourceAsStream("/com/jpexs/decompiler/flash/gui/graphics/" + resource + ".png")));
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void execInEventDispatch(Runnable r) {
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
r.run();
|
||||
} else {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(r);
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (InvocationTargetException ex) {
|
||||
Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void execInEventDispatchLater(Runnable r) {
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
r.run();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(r);
|
||||
}
|
||||
}
|
||||
|
||||
public static int showOptionDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageType, final Icon icon, final Object[] options, final Object initialValue) {
|
||||
final int[] ret = new int[1];
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ret[0] = JOptionPane.showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, initialValue);
|
||||
}
|
||||
});
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType) {
|
||||
return showConfirmDialog(parentComponent, message, title, optionType, JOptionPane.PLAIN_MESSAGE);
|
||||
}
|
||||
|
||||
public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageTyp) {
|
||||
final int ret[] = new int[1];
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ret[0] = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageTyp);
|
||||
}
|
||||
});
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static int showConfirmDialog(final Component parentComponent, String message, final String title, final int optionType, final int messageTyp, ConfigurationItem<Boolean> showAgainConfig, int defaultOption) {
|
||||
|
||||
JLabel warLabel = new JLabel(message);
|
||||
final JPanel warPanel = new JPanel(new BorderLayout());
|
||||
warPanel.add(warLabel, BorderLayout.CENTER);
|
||||
JCheckBox donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain"));
|
||||
donotShowAgainCheckBox.setSelected(!showAgainConfig.get());
|
||||
warPanel.add(donotShowAgainCheckBox, BorderLayout.SOUTH);
|
||||
|
||||
if (donotShowAgainCheckBox.isSelected()) {
|
||||
return defaultOption;
|
||||
}
|
||||
|
||||
final int ret[] = new int[1];
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ret[0] = JOptionPane.showConfirmDialog(parentComponent, warPanel, title, optionType, messageTyp);
|
||||
}
|
||||
});
|
||||
showAgainConfig.set(!donotShowAgainCheckBox.isSelected());
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static void showMessageDialog(final Component parentComponent, final Object message, final String title, final int messageType) {
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(parentComponent, message, title, messageType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void showMessageDialog(final Component parentComponent, final Object message) {
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(parentComponent, message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String showInputDialog(final Object message, final Object initialSelection) {
|
||||
final String[] ret = new String[1];
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ret[0] = JOptionPane.showInputDialog(message, initialSelection);
|
||||
}
|
||||
});
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static SubstanceColorScheme getColorScheme() {
|
||||
return SubstanceColorSchemeUtilities.getActiveColorScheme(new JButton(), ComponentState.ENABLED);
|
||||
}
|
||||
|
||||
public static void refreshTree(JTree tree, TreeModel model) {
|
||||
List<List<String>> expandedNodes = getExpandedNodes(tree);
|
||||
tree.setModel(model);
|
||||
expandTreeNodes(tree, expandedNodes);
|
||||
}
|
||||
|
||||
private static List<List<String>> getExpandedNodes(JTree tree) {
|
||||
List<List<String>> expandedNodes = new ArrayList<>();
|
||||
int rowCount = tree.getRowCount();
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
TreePath path = tree.getPathForRow(i);
|
||||
if (tree.isExpanded(path)) {
|
||||
List<String> pathAsStringList = new ArrayList<>();
|
||||
for (Object pathCompnent : path.getPath()) {
|
||||
pathAsStringList.add(pathCompnent.toString());
|
||||
}
|
||||
expandedNodes.add(pathAsStringList);
|
||||
}
|
||||
}
|
||||
return expandedNodes;
|
||||
}
|
||||
|
||||
private static void expandTreeNodes(JTree tree, List<List<String>> pathsToExpand) {
|
||||
for (List<String> pathAsStringList : pathsToExpand) {
|
||||
expandTreeNode(tree, pathAsStringList);
|
||||
}
|
||||
}
|
||||
|
||||
private static void expandTreeNode(JTree tree, List<String> pathAsStringList) {
|
||||
TreeModel model = tree.getModel();
|
||||
Object node = model.getRoot();
|
||||
|
||||
if (pathAsStringList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!pathAsStringList.get(0).equals(node.toString())) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Object> 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 static void expandTreeNodesRecursive(JTree tree, TreePath parent, boolean expand) {
|
||||
TreeModel model = tree.getModel();
|
||||
|
||||
Object node = parent.getLastPathComponent();
|
||||
int childCount = model.getChildCount(node);
|
||||
for (int j = 0; j < childCount; j++) {
|
||||
Object child = model.getChild(node, j);
|
||||
TreePath path = parent.pathByAddingChild(child);
|
||||
expandTreeNodesRecursive(tree, path, expand);
|
||||
}
|
||||
|
||||
if (expand) {
|
||||
tree.expandPath(parent);
|
||||
} else {
|
||||
tree.collapsePath(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* FlowLayout subclass that fully supports wrapping of components.
|
||||
*
|
||||
* Taken from: http://tips4java.wordpress.com/2008/11/06/wrap-layout/
|
||||
*/
|
||||
public class WrapLayout extends FlowLayout {
|
||||
|
||||
private Dimension preferredLayoutSize;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>WrapLayout</code> with a left alignment and a
|
||||
* default 5-unit horizontal and vertical gap.
|
||||
*/
|
||||
public WrapLayout() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>FlowLayout</code> with the specified alignment and
|
||||
* a default 5-unit horizontal and vertical gap. The value of the alignment
|
||||
* argument must be one of <code>WrapLayout</code>, <code>WrapLayout</code>,
|
||||
* or <code>WrapLayout</code>.
|
||||
*
|
||||
* @param align the alignment value
|
||||
*/
|
||||
public WrapLayout(int align) {
|
||||
super(align);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new flow layout manager with the indicated alignment and the
|
||||
* indicated horizontal and vertical gaps.
|
||||
* <p>
|
||||
* The value of the alignment argument must be one of
|
||||
* <code>WrapLayout</code>, <code>WrapLayout</code>, or
|
||||
* <code>WrapLayout</code>.
|
||||
*
|
||||
* @param align the alignment value
|
||||
* @param hgap the horizontal gap between components
|
||||
* @param vgap the vertical gap between components
|
||||
*/
|
||||
public WrapLayout(int align, int hgap, int vgap) {
|
||||
super(align, hgap, vgap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred dimensions for this layout given the
|
||||
* <i>visible</i> components in the specified target container.
|
||||
*
|
||||
* @param target the component which needs to be laid out
|
||||
* @return the preferred dimensions to lay out the subcomponents of the
|
||||
* specified container
|
||||
*/
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container target) {
|
||||
return layoutSize(target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum dimensions needed to layout the <i>visible</i>
|
||||
* components contained in the specified target container.
|
||||
*
|
||||
* @param target the component which needs to be laid out
|
||||
* @return the minimum dimensions to lay out the subcomponents of the
|
||||
* specified container
|
||||
*/
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container target) {
|
||||
Dimension minimum = layoutSize(target, false);
|
||||
minimum.width -= (getHgap() + 1);
|
||||
return minimum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum or preferred dimension needed to layout the target
|
||||
* container.
|
||||
*
|
||||
* @param target target to get layout size for
|
||||
* @param preferred should preferred size be calculated
|
||||
* @return the dimension to layout the target container
|
||||
*/
|
||||
private Dimension layoutSize(Container target, boolean preferred) {
|
||||
synchronized (target.getTreeLock()) {
|
||||
// Each row must fit with the width allocated to the containter.
|
||||
// When the container width = 0, the preferred width of the container
|
||||
// has not yet been calculated so lets ask for the maximum.
|
||||
|
||||
int targetWidth = target.getSize().width;
|
||||
|
||||
if (targetWidth == 0) {
|
||||
targetWidth = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
int hgap = getHgap();
|
||||
int vgap = getVgap();
|
||||
Insets insets = target.getInsets();
|
||||
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
|
||||
int maxWidth = targetWidth - horizontalInsetsAndGap;
|
||||
|
||||
// Fit components into the allowed width
|
||||
Dimension dim = new Dimension(0, 0);
|
||||
int rowWidth = 0;
|
||||
int rowHeight = 0;
|
||||
|
||||
int nmembers = target.getComponentCount();
|
||||
|
||||
for (int i = 0; i < nmembers; i++) {
|
||||
Component m = target.getComponent(i);
|
||||
|
||||
if (m.isVisible()) {
|
||||
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
|
||||
|
||||
// Can't add the component to current row. Start a new row.
|
||||
if (rowWidth + d.width > maxWidth) {
|
||||
addRow(dim, rowWidth, rowHeight);
|
||||
rowWidth = 0;
|
||||
rowHeight = 0;
|
||||
}
|
||||
|
||||
// Add a horizontal gap for all components after the first
|
||||
if (rowWidth != 0) {
|
||||
rowWidth += hgap;
|
||||
}
|
||||
|
||||
rowWidth += d.width;
|
||||
rowHeight = Math.max(rowHeight, d.height);
|
||||
}
|
||||
}
|
||||
|
||||
addRow(dim, rowWidth, rowHeight);
|
||||
|
||||
dim.width += horizontalInsetsAndGap;
|
||||
dim.height += insets.top + insets.bottom + vgap * 2;
|
||||
|
||||
// When using a scroll pane or the DecoratedLookAndFeel we need to
|
||||
// make sure the preferred size is less than the size of the
|
||||
// target containter so shrinking the container size works
|
||||
// correctly. Removing the horizontal gap is an easy way to do this.
|
||||
Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
|
||||
|
||||
if (scrollPane != null && target.isValid()) {
|
||||
dim.width -= (hgap + 1);
|
||||
}
|
||||
|
||||
return dim;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A new row has been completed. Use the dimensions of this row
|
||||
* to update the preferred size for the container.
|
||||
*
|
||||
* @param dim update the width and height when appropriate
|
||||
* @param rowWidth the width of the row to add
|
||||
* @param rowHeight the height of the row to add
|
||||
*/
|
||||
private void addRow(Dimension dim, int rowWidth, int rowHeight) {
|
||||
dim.width = Math.max(dim.width, rowWidth);
|
||||
|
||||
if (dim.height > 0) {
|
||||
dim.height += getVgap();
|
||||
}
|
||||
|
||||
dim.height += rowHeight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
|
||||
public class ABCComboBoxModel implements ComboBoxModel<ABCContainerTag> {
|
||||
|
||||
public List<ABCContainerTag> list;
|
||||
public int itemIndex = 0;
|
||||
public static final ABCContainerTag ROOT = new RootABCContainerTag();
|
||||
|
||||
public ABCComboBoxModel(List<ABCContainerTag> list) {
|
||||
this.list = list;
|
||||
Collections.sort(this.list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 1 + list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ABCContainerTag getElementAt(int index) {
|
||||
if (index == 0) {
|
||||
return ROOT;
|
||||
}
|
||||
return list.get(index - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object anItem) {
|
||||
if (anItem == ROOT) {
|
||||
itemIndex = 0;
|
||||
} else {
|
||||
itemIndex = 1 + list.indexOf(anItem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ABCContainerTag getSelectedItem() {
|
||||
return getElementAt(itemIndex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,818 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.HeaderLabel;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.MainPanel;
|
||||
import com.jpexs.decompiler.flash.gui.SearchListener;
|
||||
import com.jpexs.decompiler.flash.gui.SearchPanel;
|
||||
import com.jpexs.decompiler.flash.gui.TagTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.DecimalTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.DoubleTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.IntTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.MultinameTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceSetTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.StringTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.tablemodels.UIntTableModel;
|
||||
import com.jpexs.decompiler.flash.helpers.Freed;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableColumnModel;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import jsyntaxpane.DefaultSyntaxKit;
|
||||
|
||||
public class ABCPanel extends JPanel implements ItemListener, ActionListener, SearchListener<ABCPanelSearchResult>, Freed {
|
||||
|
||||
private MainPanel mainPanel;
|
||||
public TraitsList navigator;
|
||||
public ABC abc;
|
||||
public SWF swf;
|
||||
public JComboBox<ABCContainerTag> abcComboBox;
|
||||
public int listIndex = -1;
|
||||
public DecompiledEditorPane decompiledTextArea;
|
||||
public JScrollPane decompiledScrollPane;
|
||||
public JSplitPane splitPane;
|
||||
//public JSplitPane splitPaneTreeVSNavigator;
|
||||
//public JSplitPane splitPaneTreeNavVSDecompiledDetail;
|
||||
private JTable constantTable;
|
||||
public JComboBox<String> constantTypeList;
|
||||
public JLabel asmLabel = new HeaderLabel(AppStrings.translate("panel.disassembled"));
|
||||
public JLabel decLabel = new HeaderLabel(AppStrings.translate("panel.decompiled"));
|
||||
public DetailPanel detailPanel;
|
||||
public JPanel navPanel;
|
||||
public JTabbedPane tabbedPane;
|
||||
public SearchPanel<ABCPanelSearchResult> searchPanel;
|
||||
private NewTraitDialog newTraitDialog;
|
||||
public JLabel scriptNameLabel;
|
||||
|
||||
static final String ACTION_SAVE_DECOMPILED = "SAVEDECOMPILED";
|
||||
static final String ACTION_EDIT_DECOMPILED = "EDITDECOMPILED";
|
||||
static final String ACTION_CANCEL_DECOMPILED = "CANCELDECOMPILED";
|
||||
|
||||
public JLabel experimentalLabel = new JLabel(AppStrings.translate("action.edit.experimental"));
|
||||
public JButton editDecompiledButton = new JButton(AppStrings.translate("button.edit"), View.getIcon("edit16"));
|
||||
public JButton saveDecompiledButton = new JButton(AppStrings.translate("button.save"), View.getIcon("save16"));
|
||||
public JButton cancelDecompiledButton = new JButton(AppStrings.translate("button.cancel"), View.getIcon("cancel16"));
|
||||
|
||||
static final String ACTION_ADD_TRAIT = "ADDTRAIT";
|
||||
|
||||
public boolean search(String txt, boolean ignoreCase, boolean regexp) {
|
||||
if ((txt != null) && (!txt.isEmpty())) {
|
||||
searchPanel.setOptions(ignoreCase, regexp);
|
||||
TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel();
|
||||
TreeNode scriptsNode = ttm.getSwfNode(mainPanel.getCurrentSwf()).scriptsNode;
|
||||
final List<ABCPanelSearchResult> found = new ArrayList<>();
|
||||
if (scriptsNode.getItem() instanceof ClassesListTreeModel) {
|
||||
ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode.getItem();
|
||||
List<MyEntry<ClassPath, ScriptPack>> allpacks = clModel.getList();
|
||||
final Pattern pat = regexp
|
||||
? Pattern.compile(txt, ignoreCase ? Pattern.CASE_INSENSITIVE : 0)
|
||||
: Pattern.compile(Pattern.quote(txt), ignoreCase ? Pattern.CASE_INSENSITIVE : 0);
|
||||
int pos = 0;
|
||||
for (final MyEntry<ClassPath, ScriptPack> item : allpacks) {
|
||||
pos++;
|
||||
String workText = AppStrings.translate("work.searching");
|
||||
String decAdd = "";
|
||||
if (!decompiledTextArea.isCached(item.value)) {
|
||||
decAdd = ", " + AppStrings.translate("work.decompiling");
|
||||
}
|
||||
|
||||
try {
|
||||
CancellableWorker worker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
decompiledTextArea.cacheScriptPack(item.value, swf.abcList);
|
||||
if (pat.matcher(decompiledTextArea.getCachedText(item.value)).find()) {
|
||||
ABCPanelSearchResult searchResult = new ABCPanelSearchResult();
|
||||
searchResult.scriptPack = item.value;
|
||||
searchResult.classPath = item.key;
|
||||
found.add(searchResult);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
worker.execute();
|
||||
Main.startWork(workText + " \"" + txt + "\"" + decAdd + " - (" + pos + "/" + allpacks.size() + ") " + item.key.toString() + "... ", worker);
|
||||
worker.get();
|
||||
} catch (InterruptedException ex) {
|
||||
break;
|
||||
} catch (ExecutionException ex) {
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.gc();
|
||||
Main.stopWork();
|
||||
searchPanel.setSearchText(txt);
|
||||
return searchPanel.setResults(found);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private JTable autoResizeColWidth(final JTable table, final TableModel model) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
table.setModel(model);
|
||||
|
||||
int margin = 5;
|
||||
|
||||
for (int i = 0; i < table.getColumnCount(); i++) {
|
||||
int vColIndex = i;
|
||||
DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
|
||||
TableColumn col = colModel.getColumn(vColIndex);
|
||||
int width;
|
||||
|
||||
// Get width of column header
|
||||
TableCellRenderer renderer = col.getHeaderRenderer();
|
||||
|
||||
if (renderer == null) {
|
||||
renderer = table.getTableHeader().getDefaultRenderer();
|
||||
}
|
||||
|
||||
Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0);
|
||||
|
||||
width = comp.getPreferredSize().width;
|
||||
|
||||
// Get maximum width of column data
|
||||
for (int r = 0; r < table.getRowCount(); r++) {
|
||||
renderer = table.getCellRenderer(r, vColIndex);
|
||||
comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false,
|
||||
r, vColIndex);
|
||||
width = Math.max(width, comp.getPreferredSize().width);
|
||||
}
|
||||
|
||||
// Add margin
|
||||
width += 2 * margin;
|
||||
|
||||
// Set the width
|
||||
col.setPreferredWidth(width);
|
||||
}
|
||||
|
||||
((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment(
|
||||
SwingConstants.LEFT);
|
||||
|
||||
// table.setAutoCreateRowSorter(true);
|
||||
table.getTableHeader().setReorderingAllowed(false);
|
||||
}
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
public void setAbc(ABC abc) {
|
||||
this.abc = abc;
|
||||
updateConstList();
|
||||
}
|
||||
|
||||
public void updateConstList() {
|
||||
switch (constantTypeList.getSelectedIndex()) {
|
||||
case 0:
|
||||
autoResizeColWidth(constantTable, new UIntTableModel(abc));
|
||||
break;
|
||||
case 1:
|
||||
autoResizeColWidth(constantTable, new IntTableModel(abc));
|
||||
break;
|
||||
case 2:
|
||||
autoResizeColWidth(constantTable, new DoubleTableModel(abc));
|
||||
break;
|
||||
case 3:
|
||||
autoResizeColWidth(constantTable, new DecimalTableModel(abc));
|
||||
break;
|
||||
case 4:
|
||||
autoResizeColWidth(constantTable, new StringTableModel(abc));
|
||||
break;
|
||||
case 5:
|
||||
autoResizeColWidth(constantTable, new NamespaceTableModel(abc));
|
||||
break;
|
||||
case 6:
|
||||
autoResizeColWidth(constantTable, new NamespaceSetTableModel(abc));
|
||||
break;
|
||||
case 7:
|
||||
autoResizeColWidth(constantTable, new MultinameTableModel(abc));
|
||||
break;
|
||||
}
|
||||
//DefaultTableColumnModel colModel = (DefaultTableColumnModel) constantTable.getColumnModel();
|
||||
//colModel.getColumn(0).setMaxWidth(50);
|
||||
}
|
||||
|
||||
public void clearSwf() {
|
||||
this.swf = null;
|
||||
this.abc = null;
|
||||
constantTable.setModel(new DefaultTableModel());
|
||||
abcComboBox.setModel(new ABCComboBoxModel(new ArrayList<ABCContainerTag>()));
|
||||
navigator.clearABC();
|
||||
}
|
||||
|
||||
public void setSwf(SWF swf) {
|
||||
if (this.swf != swf) {
|
||||
this.swf = swf;
|
||||
listIndex = -1;
|
||||
switchAbc(0); // todo honika: do we need this?
|
||||
abcComboBox.setModel(new ABCComboBoxModel(swf.abcList));
|
||||
if (swf.abcList.size() > 0) {
|
||||
this.abc = swf.abcList.get(0).getABC();
|
||||
}
|
||||
|
||||
navigator.setABC(swf.abcList, abc);
|
||||
}
|
||||
}
|
||||
|
||||
public void switchAbc(int index) {
|
||||
listIndex = index;
|
||||
|
||||
if (index != -1) {
|
||||
this.abc = swf.abcList.get(index).getABC();
|
||||
}
|
||||
updateConstList();
|
||||
}
|
||||
|
||||
public void initSplits() {
|
||||
//splitPaneTreeVSNavigator.setDividerLocation(splitPaneTreeVSNavigator.getHeight() / 2);
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
//splitPaneTreeNavVSDecompiledDetail.setDividerLocation(splitPaneTreeNavVSDecompiledDetail.getWidth() * 1 / 3);
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
splitPane.setDividerLocation(Configuration.guiAvm2SplitPaneDividerLocation.get(splitPane.getWidth() * 1 / 2));
|
||||
|
||||
}
|
||||
|
||||
private boolean isFreeing;
|
||||
|
||||
@Override
|
||||
public boolean isFreeing() {
|
||||
return isFreeing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
isFreeing = true;
|
||||
Helper.emptyObject(this);
|
||||
}
|
||||
|
||||
public ABCPanel(MainPanel mainPanel) {
|
||||
DefaultSyntaxKit.initKit();
|
||||
|
||||
this.mainPanel = mainPanel;
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
decompiledTextArea = new DecompiledEditorPane(this);
|
||||
|
||||
searchPanel = new SearchPanel<>(new FlowLayout(), this);
|
||||
|
||||
decompiledScrollPane = new JScrollPane(decompiledTextArea);
|
||||
|
||||
JPanel iconDecPanel = new JPanel();
|
||||
iconDecPanel.setLayout(new BoxLayout(iconDecPanel, BoxLayout.Y_AXIS));
|
||||
JPanel iconsPanel = new JPanel();
|
||||
iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.X_AXIS));
|
||||
|
||||
JButton newTraitButton = new JButton(View.getIcon("traitadd16"));
|
||||
newTraitButton.setMargin(new Insets(5, 5, 5, 5));
|
||||
newTraitButton.addActionListener(this);
|
||||
newTraitButton.setActionCommand(ACTION_ADD_TRAIT);
|
||||
newTraitButton.setToolTipText(AppStrings.translate("button.addtrait"));
|
||||
iconsPanel.add(newTraitButton);
|
||||
|
||||
scriptNameLabel = new JLabel("-");
|
||||
scriptNameLabel.setAlignmentX(0);
|
||||
iconsPanel.setAlignmentX(0);
|
||||
decompiledScrollPane.setAlignmentX(0);
|
||||
iconDecPanel.add(scriptNameLabel);
|
||||
iconDecPanel.add(iconsPanel);
|
||||
iconDecPanel.add(decompiledScrollPane);
|
||||
|
||||
JPanel decButtonsPan = new JPanel(new FlowLayout());
|
||||
decButtonsPan.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
decButtonsPan.add(editDecompiledButton);
|
||||
decButtonsPan.add(experimentalLabel);
|
||||
decButtonsPan.add(saveDecompiledButton);
|
||||
decButtonsPan.add(cancelDecompiledButton);
|
||||
|
||||
editDecompiledButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
saveDecompiledButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
cancelDecompiledButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
|
||||
saveDecompiledButton.addActionListener(this);
|
||||
saveDecompiledButton.setActionCommand(ACTION_SAVE_DECOMPILED);
|
||||
editDecompiledButton.addActionListener(this);
|
||||
editDecompiledButton.setActionCommand(ACTION_EDIT_DECOMPILED);
|
||||
|
||||
cancelDecompiledButton.addActionListener(this);
|
||||
cancelDecompiledButton.setActionCommand(ACTION_CANCEL_DECOMPILED);
|
||||
saveDecompiledButton.setVisible(false);
|
||||
cancelDecompiledButton.setVisible(false);
|
||||
decButtonsPan.setAlignmentX(0);
|
||||
|
||||
JPanel decPanel = new JPanel(new BorderLayout());
|
||||
decPanel.add(searchPanel, BorderLayout.NORTH);
|
||||
decPanel.add(iconDecPanel, BorderLayout.CENTER);
|
||||
decPanel.add(decButtonsPan, BorderLayout.SOUTH);
|
||||
detailPanel = new DetailPanel(this);
|
||||
JPanel panB = new JPanel();
|
||||
panB.setLayout(new BorderLayout());
|
||||
panB.add(decPanel, BorderLayout.CENTER);
|
||||
panB.add(decLabel, BorderLayout.NORTH);
|
||||
decLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//decLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
||||
panB, detailPanel);
|
||||
splitPane.setResizeWeight(0.5);
|
||||
splitPane.setContinuousLayout(true);
|
||||
|
||||
splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
if (!directEditing) {
|
||||
Configuration.guiAvm2SplitPaneDividerLocation.set((int) pce.getNewValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
decompiledTextArea.setContentType("text/actionscript");
|
||||
decompiledTextArea.setFont(new Font("Monospaced", Font.PLAIN, decompiledTextArea.getFont().getSize()));
|
||||
|
||||
JPanel pan2 = new JPanel();
|
||||
pan2.setLayout(new BorderLayout());
|
||||
pan2.add((abcComboBox = new JComboBox<>(new ABCComboBoxModel(new ArrayList<ABCContainerTag>()))), BorderLayout.NORTH);
|
||||
|
||||
navigator = new TraitsList(this);
|
||||
|
||||
navPanel = new JPanel(new BorderLayout());
|
||||
JPanel navIconsPanel = new JPanel();
|
||||
navIconsPanel.setLayout(new BoxLayout(navIconsPanel, BoxLayout.X_AXIS));
|
||||
final JToggleButton sortButton = new JToggleButton(View.getIcon("sort16"));
|
||||
sortButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
navIconsPanel.add(sortButton);
|
||||
navPanel.add(navIconsPanel, BorderLayout.SOUTH);
|
||||
navPanel.add(new JScrollPane(navigator), BorderLayout.CENTER);
|
||||
sortButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
navigator.setSorted(sortButton.isSelected());
|
||||
navigator.updateUI();
|
||||
}
|
||||
});
|
||||
|
||||
Main.startWork(AppStrings.translate("work.buildingscripttree") + "...");
|
||||
|
||||
/* splitPaneTreeVSNavigator = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
|
||||
treePanel,
|
||||
navPanel);
|
||||
splitPaneTreeVSNavigator.setResizeWeight(0.5);
|
||||
splitPaneTreeVSNavigator.setContinuousLayout(true);*/
|
||||
tabbedPane = new JTabbedPane();
|
||||
tabbedPane.addTab(AppStrings.translate("traits"), navPanel);
|
||||
//tabbedPane.setTabPlacement(JTabbedPane.BOTTOM);
|
||||
|
||||
//pan2.add(tabbedPane, BorderLayout.CENTER);
|
||||
abcComboBox.addItemListener(this);
|
||||
/*
|
||||
|
||||
splitPaneTreeNavVSDecompiledDetail = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
||||
pan2,
|
||||
splitPaneDecompiledVSDetail);
|
||||
splitPaneTreeNavVSDecompiledDetail.setResizeWeight(0);
|
||||
splitPaneTreeNavVSDecompiledDetail.setContinuousLayout(true);
|
||||
//pan2.setPreferredSize(new Dimension(300, 200));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
add(splitPaneTreeNavVSDecompiledDetail, BorderLayout.CENTER);*/
|
||||
add(splitPane, BorderLayout.CENTER);
|
||||
|
||||
JPanel panConstants = new JPanel();
|
||||
panConstants.setLayout(new BorderLayout());
|
||||
|
||||
constantTypeList = new JComboBox<>(new String[]{"UINT", "INT", "DOUBLE", "DECIMAL", "STRING", "NAMESPACE", "NAMESPACESET", "MULTINAME"});
|
||||
constantTable = new JTable();
|
||||
if (abc != null) {
|
||||
autoResizeColWidth(constantTable, new UIntTableModel(abc));
|
||||
}
|
||||
constantTable.setAutoCreateRowSorter(true);
|
||||
|
||||
final ABCPanel t = this;
|
||||
constantTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
if (constantTypeList.getSelectedIndex() == 7) { //MULTINAME
|
||||
int rowIndex = constantTable.getSelectedRow();
|
||||
if (rowIndex == -1) {
|
||||
return;
|
||||
}
|
||||
int multinameIndex = constantTable.convertRowIndexToModel(rowIndex);
|
||||
if (multinameIndex > 0) {
|
||||
UsageFrame usageFrame = new UsageFrame(t.swf.abcList, abc, multinameIndex, t);
|
||||
usageFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
constantTypeList.addItemListener(this);
|
||||
panConstants.add(constantTypeList, BorderLayout.NORTH);
|
||||
panConstants.add(new JScrollPane(constantTable), BorderLayout.CENTER);
|
||||
tabbedPane.addTab(AppStrings.translate("constants"), panConstants);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
switchAbc(listIndex);
|
||||
decompiledTextArea.clearScriptCache();
|
||||
decompiledTextArea.reloadClass();
|
||||
detailPanel.methodTraitPanel.methodCodePanel.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getSource() == abcComboBox) {
|
||||
int index = ((JComboBox) e.getSource()).getSelectedIndex();
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
switchAbc(index - 1);
|
||||
}
|
||||
if (e.getSource() == constantTypeList) {
|
||||
int index = ((JComboBox) e.getSource()).getSelectedIndex();
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
updateConstList();
|
||||
}
|
||||
}
|
||||
|
||||
public void display() {
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void hilightScript(SWF swf, String name) {
|
||||
TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel();
|
||||
TreeNode scriptsNode = ttm.getSwfNode(swf).scriptsNode;
|
||||
if (scriptsNode.getItem() instanceof ClassesListTreeModel) {
|
||||
ClassesListTreeModel clModel = (ClassesListTreeModel) scriptsNode.getItem();
|
||||
ScriptPack pack = null;
|
||||
for (MyEntry<ClassPath, ScriptPack> item : clModel.getList()) {
|
||||
if (item.key.toString().equals(name)) {
|
||||
pack = item.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pack != null) {
|
||||
hilightScript(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hilightScript(ScriptPack pack) {
|
||||
TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel();
|
||||
final TreePath tp = ttm.getTagPath(pack);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mainPanel.tagTree.setSelectionPath(tp);
|
||||
mainPanel.tagTree.scrollPathToVisible(tp);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSearchPos(ABCPanelSearchResult item) {
|
||||
ScriptPack pack = item.scriptPack;
|
||||
setAbc(pack.abc);
|
||||
decompiledTextArea.setScript(pack, swf.abcList);
|
||||
hilightScript(pack);
|
||||
decompiledTextArea.setCaretPosition(0);
|
||||
|
||||
searchPanel.showQuickFindDialog(decompiledTextArea);
|
||||
}
|
||||
|
||||
public String lastDecompiled = null;
|
||||
public boolean directEditing = false;
|
||||
private int detWidth = 0;
|
||||
private int detsp = 0;
|
||||
|
||||
public void setDecompiledEditMode(boolean val) {
|
||||
if (val) {
|
||||
lastDecompiled = decompiledTextArea.getText();
|
||||
decompiledTextArea.setEditable(true);
|
||||
saveDecompiledButton.setVisible(true);
|
||||
editDecompiledButton.setVisible(false);
|
||||
experimentalLabel.setVisible(false);
|
||||
cancelDecompiledButton.setVisible(true);
|
||||
decompiledTextArea.getCaret().setVisible(true);
|
||||
decLabel.setIcon(View.getIcon("editing16"));
|
||||
directEditing = true;
|
||||
detWidth = detailPanel.getWidth();
|
||||
detsp = splitPane.getDividerLocation();
|
||||
detailPanel.setVisible(false);
|
||||
} else {
|
||||
decompiledTextArea.setText(lastDecompiled);
|
||||
decompiledTextArea.setEditable(false);
|
||||
saveDecompiledButton.setVisible(false);
|
||||
editDecompiledButton.setVisible(true);
|
||||
experimentalLabel.setVisible(true);
|
||||
cancelDecompiledButton.setVisible(false);
|
||||
decompiledTextArea.getCaret().setVisible(true);
|
||||
decLabel.setIcon(null);
|
||||
directEditing = false;
|
||||
detailPanel.setVisible(true);
|
||||
detailPanel.setSize(detailPanel.getHeight(), detWidth);
|
||||
splitPane.setDividerLocation(detsp);
|
||||
}
|
||||
decompiledTextArea.ignoreCarret = directEditing;
|
||||
|
||||
decompiledTextArea.requestFocusInWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_EDIT_DECOMPILED:
|
||||
File swc = Configuration.getPlayerSWC();
|
||||
final String adobePage = "http://www.adobe.com/support/flashplayer/downloads.html";
|
||||
if (swc == null) {
|
||||
if (View.showConfirmDialog(this, AppStrings.translate("message.action.playerglobal.needed").replace("%adobehomepage%", adobePage), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION) {
|
||||
|
||||
java.awt.Desktop desktop = null;
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
desktop = java.awt.Desktop.getDesktop();
|
||||
if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
try {
|
||||
java.net.URI uri = new java.net.URI(adobePage);
|
||||
desktop.browse(uri);
|
||||
} catch (URISyntaxException | IOException ex) {
|
||||
}
|
||||
} else {
|
||||
desktop = null;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
do {
|
||||
ret = View.showConfirmDialog(this, AppStrings.translate("message.action.playerglobal.place").replace("%libpath%", Configuration.getFlashLibPath().getAbsolutePath()), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
|
||||
swc = Configuration.getPlayerSWC();
|
||||
} while (ret == JOptionPane.OK_OPTION && swc == null);
|
||||
}
|
||||
}
|
||||
if (swc != null) {
|
||||
if (View.showConfirmDialog(null, AppStrings.translate("message.confirm.experimental.function"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, Configuration.warningExperimentalAS3Edit, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) {
|
||||
setDecompiledEditMode(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_CANCEL_DECOMPILED:
|
||||
setDecompiledEditMode(false);
|
||||
break;
|
||||
case ACTION_SAVE_DECOMPILED:
|
||||
ScriptPack pack = decompiledTextArea.getScriptLeaf();
|
||||
String scriptName = pack.getPathScriptName() + ".as";
|
||||
int oldIndex = pack.scriptIndex;
|
||||
int newIndex = abc.script_info.size();
|
||||
String documentClass = "";
|
||||
loopt:
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof SymbolClassTag) {
|
||||
SymbolClassTag sc = (SymbolClassTag) t;
|
||||
for (int i = 0; i < sc.tags.length; i++) {
|
||||
if (sc.tags[i] == 0) {
|
||||
documentClass = sc.names[i];
|
||||
break loopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean isDocumentClass = documentClass.equals(pack.getPath().toString());
|
||||
|
||||
try {
|
||||
ActionScriptParser.compile(decompiledTextArea.getText(), abc,new ArrayList<ABC>(), isDocumentClass, scriptName);
|
||||
//Move newly added script to its position
|
||||
abc.script_info.set(oldIndex, abc.script_info.get(newIndex));
|
||||
abc.script_info.remove(newIndex);
|
||||
((Tag) abc.parentTag).setModified(true);
|
||||
lastDecompiled = decompiledTextArea.getText();
|
||||
mainPanel.updateClassesList();
|
||||
List<MyEntry<ClassPath,ScriptPack>> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex);
|
||||
if(!packs.isEmpty()){
|
||||
hilightScript(swf,packs.get(0).key.toString());
|
||||
}
|
||||
//decompiledTextArea.setClassIndex(-1);
|
||||
//navigator.setClassIndex(-1, oldIndex);
|
||||
setDecompiledEditMode(false);
|
||||
View.showMessageDialog(this, AppStrings.translate("message.action.saved"));
|
||||
//reload();
|
||||
} catch (ParseException ex) {
|
||||
ex.printStackTrace();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
} catch (CompilationException ex) {
|
||||
ex.printStackTrace();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
break;
|
||||
case ACTION_ADD_TRAIT:
|
||||
int class_index = decompiledTextArea.getClassIndex();
|
||||
if (class_index < 0) {
|
||||
return;
|
||||
}
|
||||
if (newTraitDialog == null) {
|
||||
newTraitDialog = new NewTraitDialog();
|
||||
}
|
||||
int void_type = abc.constants.getPublicQnameId("void", true);//abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, abc.constants.forceGetStringId("void"), abc.constants.forceGetNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, -1, new ArrayList<Integer>()));
|
||||
int int_type = abc.constants.getPublicQnameId("int", true); //abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, abc.constants.forceGetStringId("int"), abc.constants.forceGetNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, -1, new ArrayList<Integer>()));
|
||||
|
||||
Trait t = null;
|
||||
int kind;
|
||||
int nskind;
|
||||
String name = null;
|
||||
boolean isStatic;
|
||||
Multiname m;
|
||||
|
||||
boolean again = false;
|
||||
loopm:
|
||||
do {
|
||||
if (again) {
|
||||
View.showMessageDialog(null, AppStrings.translate("error.trait.exists").replace("%name%", name), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
again = false;
|
||||
if (!newTraitDialog.display()) {
|
||||
return;
|
||||
}
|
||||
kind = newTraitDialog.getTraitType();
|
||||
nskind = newTraitDialog.getNamespaceKind();
|
||||
name = newTraitDialog.getTraitName();
|
||||
isStatic = newTraitDialog.getStatic();
|
||||
m = new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(nskind, abc.constants.getStringId("", true)), 0, true), -1, -1, new ArrayList<Integer>());
|
||||
int mid = abc.constants.getMultinameId(m);
|
||||
if (mid == 0) {
|
||||
break;
|
||||
}
|
||||
for (Trait tr : abc.class_info.get(class_index).static_traits.traits) {
|
||||
if (tr.name_index == mid) {
|
||||
again = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (Trait tr : abc.instance_info.get(class_index).instance_traits.traits) {
|
||||
if (tr.name_index == mid) {
|
||||
again = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (again);
|
||||
switch (kind) {
|
||||
case Trait.TRAIT_GETTER:
|
||||
case Trait.TRAIT_SETTER:
|
||||
case Trait.TRAIT_METHOD:
|
||||
TraitMethodGetterSetter tm = new TraitMethodGetterSetter();
|
||||
MethodInfo mi = new MethodInfo(new int[0], void_type, abc.constants.getStringId(name, true), 0, new ValueKind[0], new int[0]);
|
||||
int method_info = abc.addMethodInfo(mi);
|
||||
tm.method_info = method_info;
|
||||
MethodBody body = new MethodBody();
|
||||
body.method_info = method_info;
|
||||
body.init_scope_depth = 1;
|
||||
body.max_regs = 1;
|
||||
body.max_scope_depth = 1;
|
||||
body.max_stack = 1;
|
||||
body.exceptions = new ABCException[0];
|
||||
AVM2Code code = new AVM2Code();
|
||||
code.code.add(new AVM2Instruction(0, new GetLocal0Ins(), new int[0], new byte[0]));
|
||||
code.code.add(new AVM2Instruction(0, new PushScopeIns(), new int[0], new byte[0]));
|
||||
code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[0], new byte[0]));
|
||||
body.code = code;
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new ArrayList<>();
|
||||
body.traits = traits;
|
||||
abc.addMethodBody(body);
|
||||
mi.setBody(body);
|
||||
t = tm;
|
||||
break;
|
||||
case Trait.TRAIT_SLOT:
|
||||
case Trait.TRAIT_CONST:
|
||||
TraitSlotConst ts = new TraitSlotConst();
|
||||
ts.type_index = int_type;
|
||||
ts.value_kind = ValueKind.CONSTANT_Int;
|
||||
ts.value_index = abc.constants.getIntId(0, true);
|
||||
t = ts;
|
||||
break;
|
||||
}
|
||||
if (t != null) {
|
||||
t.kindType = kind;
|
||||
t.name_index = abc.constants.getMultinameId(m, true);
|
||||
int traitId;
|
||||
if (isStatic) {
|
||||
traitId = abc.class_info.get(class_index).static_traits.addTrait(t);
|
||||
} else {
|
||||
traitId = abc.class_info.get(class_index).static_traits.traits.size() + abc.instance_info.get(class_index).instance_traits.addTrait(t);
|
||||
}
|
||||
reload();
|
||||
decompiledTextArea.gotoTrait(traitId);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ABCPanelSearchResult {
|
||||
|
||||
public ScriptPack scriptPack;
|
||||
public ClassPath classPath;
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.MissingSymbolHandler;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.GraphFrame;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
|
||||
public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretListener {
|
||||
|
||||
public ABC abc;
|
||||
public int bodyIndex = -1;
|
||||
private List<Highlighting> disassembledHilights = new ArrayList<>();
|
||||
private List<Highlighting> specialHilights = new ArrayList<>();
|
||||
private final DecompiledEditorPane decompiledEditor;
|
||||
private boolean ignoreCarret = false;
|
||||
private String name;
|
||||
private HilightedText textWithHex;
|
||||
private HilightedText textNoHex;
|
||||
private HilightedText textHexOnly;
|
||||
private ScriptExportMode exportMode = ScriptExportMode.PCODE;
|
||||
private Trait trait;
|
||||
|
||||
public ScriptExportMode getExportMode() {
|
||||
return exportMode;
|
||||
}
|
||||
|
||||
private HilightedText getHilightedText(ScriptExportMode exportMode) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true);
|
||||
abc.bodies.get(bodyIndex).code.toASMSource(abc.constants, trait, abc.method_info.get(abc.bodies.get(bodyIndex).method_info), abc.bodies.get(bodyIndex), exportMode, writer);
|
||||
return new HilightedText(writer);
|
||||
}
|
||||
|
||||
public void setHex(ScriptExportMode exportMode, boolean force) {
|
||||
if (this.exportMode == exportMode & !force) {
|
||||
return;
|
||||
}
|
||||
this.exportMode = exportMode;
|
||||
long oldOffset = getSelectedOffset();
|
||||
if (exportMode == ScriptExportMode.PCODE) {
|
||||
setContentType("text/flasm");
|
||||
if (textNoHex == null) {
|
||||
textNoHex = getHilightedText(exportMode);
|
||||
}
|
||||
setText(textNoHex);
|
||||
} else if (exportMode == ScriptExportMode.PCODE_HEX) {
|
||||
setContentType("text/flasm");
|
||||
if (textWithHex == null) {
|
||||
textWithHex = getHilightedText(exportMode);
|
||||
}
|
||||
setText(textWithHex);
|
||||
} else {
|
||||
setContentType("text/plain");
|
||||
if (textHexOnly == null) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true);
|
||||
Helper.byteArrayToHexWithHeader(writer, abc.bodies.get(bodyIndex).code.getBytes());
|
||||
textHexOnly = new HilightedText(writer);
|
||||
}
|
||||
setText(textHexOnly);
|
||||
}
|
||||
hilighOffset(oldOffset);
|
||||
}
|
||||
|
||||
public void setIgnoreCarret(boolean ignoreCarret) {
|
||||
this.ignoreCarret = ignoreCarret;
|
||||
}
|
||||
|
||||
public ASMSourceEditorPane(DecompiledEditorPane decompiledEditor) {
|
||||
this.decompiledEditor = decompiledEditor;
|
||||
addCaretListener(this);
|
||||
}
|
||||
|
||||
public void hilighSpecial(String type, int index) {
|
||||
Highlighting h2 = null;
|
||||
for (Highlighting sh : specialHilights) {
|
||||
if (type.equals(sh.getPropertyString("subtype"))) {
|
||||
if (sh.getPropertyString("index").equals("" + index)) {
|
||||
h2 = sh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (h2 != null) {
|
||||
ignoreCarret = true;
|
||||
if (h2.startPos <= getDocument().getLength()) {
|
||||
setCaretPosition(h2.startPos);
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
ignoreCarret = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void hilighOffset(long offset) {
|
||||
if (isEditable()) {
|
||||
return;
|
||||
}
|
||||
Highlighting h2 = Highlighting.search(disassembledHilights, "offset", "" + offset);
|
||||
if (h2 != null) {
|
||||
ignoreCarret = true;
|
||||
if (h2.startPos <= getDocument().getLength()) {
|
||||
setCaretPosition(h2.startPos);
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
ignoreCarret = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
public void setBodyIndex(int bodyIndex, ABC abc, String name, Trait trait) {
|
||||
this.bodyIndex = bodyIndex;
|
||||
this.abc = abc;
|
||||
this.name = name;
|
||||
this.trait = trait;
|
||||
if (bodyIndex == -1) {
|
||||
return;
|
||||
}
|
||||
textWithHex = null;
|
||||
textNoHex = null;
|
||||
setHex(exportMode, true);
|
||||
}
|
||||
|
||||
public void graph() {
|
||||
try {
|
||||
AVM2Graph gr = new AVM2Graph(abc.bodies.get(bodyIndex).code, abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap<Integer, GraphTargetItem>(), new Stack<GraphTargetItem>(), new HashMap<Integer, String>(), new ArrayList<String>(), new HashMap<Integer, Integer>(), abc.bodies.get(bodyIndex).code.visitCode(abc.bodies.get(bodyIndex)));
|
||||
(new GraphFrame(gr, name)).setVisible(true);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(ASMSourceEditorPane.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void exec() {
|
||||
HashMap<Integer, Object> args = new HashMap<>();
|
||||
args.put(0, new Object()); //object "this"
|
||||
args.put(1, new Long(466561)); //param1
|
||||
Object o = abc.bodies.get(bodyIndex).code.execute(args, abc.constants);
|
||||
View.showMessageDialog(this, "Returned object:" + o.toString());
|
||||
}
|
||||
|
||||
public boolean save(ConstantPool constants) {
|
||||
try {
|
||||
String text = getText();
|
||||
if (text.trim().startsWith("#hexdata")) {
|
||||
byte[] data = Helper.getBytesFromHexaText(text);
|
||||
MethodBody mb = abc.bodies.get(bodyIndex);
|
||||
mb.codeBytes = data;
|
||||
try {
|
||||
mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes));
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re);
|
||||
}
|
||||
mb.code.compact();
|
||||
} else {
|
||||
AVM2Code acode = ASM3Parser.parse(new StringReader(text), constants, trait, new MissingSymbolHandler() {
|
||||
//no longer ask for adding new constants
|
||||
@Override
|
||||
public boolean missingString(String value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingInt(long value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingUInt(long value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingDouble(double value) {
|
||||
return true;
|
||||
}
|
||||
}, abc.bodies.get(bodyIndex), abc.method_info.get(abc.bodies.get(bodyIndex).method_info));
|
||||
acode.getBytes(abc.bodies.get(bodyIndex).codeBytes);
|
||||
abc.bodies.get(bodyIndex).code = acode;
|
||||
}
|
||||
((Tag) abc.parentTag).setModified(true);
|
||||
} catch (IOException ex) {
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (ParseException ex) {
|
||||
View.showMessageDialog(this, (ex.text + " on line " + ex.line));
|
||||
selectLine((int) ex.line);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
disassembledHilights = new ArrayList<>();
|
||||
specialHilights = new ArrayList<>();
|
||||
super.setText(t);
|
||||
setCaretPosition(0);
|
||||
}
|
||||
|
||||
public void setText(HilightedText hilightedText) {
|
||||
disassembledHilights = hilightedText.instructionHilights;
|
||||
specialHilights = hilightedText.specialHilights;
|
||||
super.setText(hilightedText.text);
|
||||
setCaretPosition(0);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
setText("");
|
||||
bodyIndex = -1;
|
||||
setCaretPosition(0);
|
||||
}
|
||||
|
||||
public void selectInstruction(int pos) {
|
||||
String text = getText();
|
||||
int lineCnt = 1;
|
||||
int lineStart = 0;
|
||||
int lineEnd;
|
||||
int instrCount = 0;
|
||||
int dot = -2;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
|
||||
lineCnt++;
|
||||
lineEnd = i;
|
||||
String ins = text.substring(lineStart, lineEnd).trim();
|
||||
if (!((i > 0) && (text.charAt(i - 1) == ':'))) {
|
||||
if (!ins.startsWith("exception ")) {
|
||||
instrCount++;
|
||||
}
|
||||
}
|
||||
if (instrCount == pos + 1) {
|
||||
break;
|
||||
}
|
||||
lineStart = i + 1;
|
||||
}
|
||||
}
|
||||
if (lineCnt == -1) {
|
||||
//lineEnd = text.length() - 1;
|
||||
}
|
||||
//select(lineStart, lineEnd);
|
||||
setCaretPosition(lineStart);
|
||||
//requestFocus();
|
||||
}
|
||||
|
||||
public void selectLine(int line) {
|
||||
String text = getText();
|
||||
int lineCnt = 1;
|
||||
int lineStart = 0;
|
||||
int lineEnd = -1;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
lineCnt++;
|
||||
if (lineCnt == line) {
|
||||
lineStart = i;
|
||||
}
|
||||
if (lineCnt == line + 1) {
|
||||
lineEnd = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lineCnt == -1) {
|
||||
lineEnd = text.length() - 1;
|
||||
}
|
||||
select(lineStart, lineEnd);
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
public Highlighting getSelectedSpecial() {
|
||||
return Highlighting.search(specialHilights, getCaretPosition());
|
||||
}
|
||||
|
||||
public long getSelectedOffset() {
|
||||
int pos = getCaretPosition();
|
||||
Highlighting lastH = null;
|
||||
for (Highlighting h : disassembledHilights) {
|
||||
if (pos < h.startPos) {
|
||||
break;
|
||||
}
|
||||
lastH = h;
|
||||
}
|
||||
return lastH == null ? 0 : lastH.getPropertyLong("offset");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
if (isEditable()) {
|
||||
return;
|
||||
}
|
||||
if (ignoreCarret) {
|
||||
return;
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
|
||||
decompiledEditor.hilightOffset(getSelectedOffset());
|
||||
Highlighting spec = getSelectedSpecial();
|
||||
if (spec != null) {
|
||||
decompiledEditor.hilightSpecial(spec.getPropertyString("subtype"), (int) (long) spec.getPropertyLong("index"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CachedDecompilation implements Serializable {
|
||||
|
||||
public String text;
|
||||
public List<Highlighting> traitHilights;
|
||||
public List<Highlighting> classHilights;
|
||||
public List<Highlighting> methodHilights;
|
||||
public List<Highlighting> instructionHilights;
|
||||
public List<Highlighting> specialHilights;
|
||||
|
||||
public List<Highlighting> getInstructionHighlights() {
|
||||
return instructionHilights;
|
||||
}
|
||||
|
||||
public List<Highlighting> getTraitHighlights() {
|
||||
return traitHilights;
|
||||
}
|
||||
|
||||
public List<Highlighting> getMethodHighlights() {
|
||||
return methodHilights;
|
||||
}
|
||||
|
||||
public List<Highlighting> getClassHighlights() {
|
||||
return classHilights;
|
||||
}
|
||||
|
||||
public List<Highlighting> getSpecialHighligths() {
|
||||
return specialHilights;
|
||||
}
|
||||
|
||||
public CachedDecompilation(HilightedText hilightedText) {
|
||||
this.text = hilightedText.text;
|
||||
this.traitHilights = hilightedText.traitHilights;
|
||||
this.classHilights = hilightedText.classHilights;
|
||||
this.methodHilights = hilightedText.methodHilights;
|
||||
this.instructionHilights = hilightedText.instructionHilights;
|
||||
this.specialHilights = hilightedText.specialHilights;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS, Paolo Cancedda
|
||||
*
|
||||
* 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
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.gui.abc.treenodes.TreeElement;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeElementItem;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
class ClassIndexVisitor implements TreeVisitor {
|
||||
|
||||
private TreeElement found = null;
|
||||
private int classIndex = 0;
|
||||
|
||||
public ClassIndexVisitor(int classIndex) {
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBranch(TreeElement branch) {
|
||||
Object o = branch.getItem();
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
ScriptPack sc = (ScriptPack) o;
|
||||
for (Trait t : sc.abc.script_info.get(sc.scriptIndex).traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
if (((TraitClass) t).class_info == classIndex) {
|
||||
found = branch;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeaf(TreeElement leaf) {
|
||||
Object o = leaf.getItem();
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
ScriptPack sc = (ScriptPack) o;
|
||||
for (Trait t : sc.abc.script_info.get(sc.scriptIndex).traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
if (((TraitClass) t).class_info == classIndex) {
|
||||
found = leaf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TreeElement getFound() {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassesListTreeModel implements TreeModel, TreeElementItem {
|
||||
|
||||
private SWF swf;
|
||||
private Tree classTree;
|
||||
private List<MyEntry<ClassPath, ScriptPack>> list;
|
||||
private final List<TreeModelListener> listeners = new ArrayList<>();
|
||||
|
||||
public List<MyEntry<ClassPath, ScriptPack>> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public ClassesListTreeModel(SWF swf) {
|
||||
this(swf, null);
|
||||
}
|
||||
|
||||
public ClassesListTreeModel(SWF swf, String filter) {
|
||||
this.swf = swf;
|
||||
this.list = swf.getAS3Packs();
|
||||
setFilter(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
public final void update() {
|
||||
this.list = swf.getAS3Packs();
|
||||
TreeModelEvent event = new TreeModelEvent(this, new TreePath(classTree.getRoot()));
|
||||
for (TreeModelListener listener : listeners) {
|
||||
listener.treeStructureChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
public final void setFilter(String filter) {
|
||||
classTree = new Tree();
|
||||
filter = (filter == null || filter.isEmpty()) ? null : filter.toLowerCase();
|
||||
for (MyEntry<ClassPath, ScriptPack> item : list) {
|
||||
if (filter != null) {
|
||||
if (!item.key.toString().toLowerCase().contains(filter)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//String nsName = path.contains(".") ? path.substring(path.lastIndexOf(".") + 1) : path;
|
||||
//String packageName = path.contains(".") ? path.substring(0, path.lastIndexOf(".")) : "";
|
||||
classTree.add(item.key.className, item.key.packageStr, item.value);
|
||||
}
|
||||
}
|
||||
|
||||
public TreeElement getElementByClassIndex(int classIndex) {
|
||||
ClassIndexVisitor civ = new ClassIndexVisitor(classIndex);
|
||||
classTree.visit(civ);
|
||||
return civ.getFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeElement getRoot() {
|
||||
return classTree.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode getChild(Object parent, int index) {
|
||||
TreeElement pte = (TreeElement) parent;
|
||||
TreeElement te = pte.getChild(index);
|
||||
return te;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
TreeElement te = (TreeElement) parent;
|
||||
return te.getChildCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
TreeElement te = (TreeElement) node;
|
||||
return te.isLeaf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
TreeElement te1 = (TreeElement) parent;
|
||||
TreeElement te2 = (TreeElement) child;
|
||||
return te1.getIndexOfChild(te2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return AppStrings.translate("node.scripts");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
|
||||
public class ConstantsListModel implements ListModel {
|
||||
|
||||
private final ConstantPool constants;
|
||||
public static final int TYPE_UINT = 0;
|
||||
public static final int TYPE_INT = 1;
|
||||
public static final int TYPE_DOUBLE = 2;
|
||||
public static final int TYPE_DECIMAL = 3;
|
||||
public static final int TYPE_STRING = 4;
|
||||
public static final int TYPE_NAMESPACE = 5;
|
||||
public static final int TYPE_NAMESPACESET = 6;
|
||||
public static final int TYPE_MULTINAME = 7;
|
||||
private int type = TYPE_INT;
|
||||
|
||||
public ConstantsListModel(ConstantPool constants, int type) {
|
||||
this.type = type;
|
||||
this.constants = constants;
|
||||
}
|
||||
|
||||
private int makeUp(int i) {
|
||||
if (i < 0) {
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
switch (type) {
|
||||
case TYPE_UINT:
|
||||
return makeUp(constants.getUIntCount() - 1);
|
||||
case TYPE_INT:
|
||||
return makeUp(constants.getIntCount() - 1);
|
||||
case TYPE_DOUBLE:
|
||||
return makeUp(constants.getDoubleCount() - 1);
|
||||
case TYPE_DECIMAL:
|
||||
return makeUp(constants.getDecimalCount() - 1);
|
||||
case TYPE_STRING:
|
||||
return makeUp(constants.getStringCount() - 1);
|
||||
case TYPE_NAMESPACE:
|
||||
return makeUp(constants.getNamespaceCount() - 1);
|
||||
case TYPE_NAMESPACESET:
|
||||
return makeUp(constants.getNamespaceSetCount() - 1);
|
||||
case TYPE_MULTINAME:
|
||||
return makeUp(constants.getMultinameCount() - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
switch (type) {
|
||||
case TYPE_UINT:
|
||||
return "" + (index + 1) + ":" + constants.getUInt(index + 1);
|
||||
case TYPE_INT:
|
||||
return "" + (index + 1) + ":" + constants.getInt(index + 1);
|
||||
case TYPE_DOUBLE:
|
||||
return "" + (index + 1) + ":" + constants.getDouble(index + 1);
|
||||
case TYPE_DECIMAL:
|
||||
return "" + (index + 1) + ":" + constants.getDecimal(index + 1);
|
||||
case TYPE_STRING:
|
||||
return "" + (index + 1) + ":" + Helper.escapeString(constants.getString(index + 1));
|
||||
case TYPE_NAMESPACE:
|
||||
return "" + (index + 1) + ":" + constants.getNamespace(index + 1).getNameWithKind(constants);
|
||||
case TYPE_NAMESPACESET:
|
||||
return "" + (index + 1) + ":" + constants.getNamespaceSet(index + 1).toString(constants);
|
||||
case TYPE_MULTINAME:
|
||||
return "" + (index + 1) + ":" + constants.getMultiname(index + 1).toString(constants, new ArrayList<String>());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
|
||||
public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretListener {
|
||||
|
||||
private List<Highlighting> highlights = new ArrayList<>();
|
||||
private List<Highlighting> specialHighlights = new ArrayList<>();
|
||||
private List<Highlighting> traitHighlights = new ArrayList<>();
|
||||
private List<Highlighting> methodHighlights = new ArrayList<>();
|
||||
private List<Highlighting> classHighlights = new ArrayList<>();
|
||||
private Highlighting currentMethodHighlight;
|
||||
private Highlighting currentTraitHighlight;
|
||||
private ABC abc;
|
||||
private ScriptPack script;
|
||||
public int lastTraitIndex = 0;
|
||||
public boolean ignoreCarret = false;
|
||||
private boolean reset = false;
|
||||
private final ABCPanel abcPanel;
|
||||
private int classIndex = -1;
|
||||
private boolean isStatic = false;
|
||||
private final Cache<CachedDecompilation> cache = Cache.getInstance(true);
|
||||
private Trait currentTrait = null;
|
||||
|
||||
public Trait getCurrentTrait() {
|
||||
return currentTrait;
|
||||
}
|
||||
|
||||
public ScriptPack getScriptLeaf() {
|
||||
return script;
|
||||
}
|
||||
|
||||
public boolean getIsStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public void setNoTrait() {
|
||||
abcPanel.detailPanel.showCard(DetailPanel.UNSUPPORTED_TRAIT_CARD, null);
|
||||
}
|
||||
|
||||
public void hilightSpecial(String type, int index) {
|
||||
int startPos;
|
||||
int endPos;
|
||||
if (currentMethodHighlight == null) {
|
||||
if (currentTraitHighlight == null) {
|
||||
return;
|
||||
}
|
||||
startPos = currentTraitHighlight.startPos;
|
||||
endPos = currentTraitHighlight.startPos + currentTraitHighlight.len;
|
||||
} else {
|
||||
startPos = currentMethodHighlight.startPos;
|
||||
endPos = currentMethodHighlight.startPos + currentMethodHighlight.len;
|
||||
}
|
||||
|
||||
List<Highlighting> allh = new ArrayList<>();
|
||||
for (Highlighting h : traitHighlights) {
|
||||
if (h.getPropertyString("index").equals("" + lastTraitIndex)) {
|
||||
for (Highlighting sh : specialHighlights) {
|
||||
if (sh.startPos >= h.startPos && (sh.startPos + sh.len < h.startPos + h.len)) {
|
||||
allh.add(sh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentMethodHighlight != null) {
|
||||
for (Highlighting h : specialHighlights) {
|
||||
if (h.startPos >= startPos && (h.startPos + h.len < endPos)) {
|
||||
allh.add(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Highlighting h : allh) {
|
||||
if (h.getPropertyString("subtype").equals(type) && ((long) h.getPropertyLong("index") == index)) {
|
||||
ignoreCarret = true;
|
||||
if (h.startPos <= getDocument().getLength()) {
|
||||
setCaretPosition(h.startPos);
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
ignoreCarret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hilightOffset(long offset) {
|
||||
if (currentMethodHighlight == null) {
|
||||
return;
|
||||
}
|
||||
List<Highlighting> allh = new ArrayList<>();
|
||||
for (Highlighting h : traitHighlights) {
|
||||
if (h.getPropertyString("index").equals("" + lastTraitIndex)) {
|
||||
Highlighting h2 = Highlighting.search(highlights, "offset", "" + offset, h.startPos, h.startPos + h.len);
|
||||
if (h2 != null) {
|
||||
ignoreCarret = true;
|
||||
if (h2.startPos <= getDocument().getLength()) {
|
||||
setCaretPosition(h2.startPos);
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
ignoreCarret = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setClassIndex(int classIndex) {
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
private boolean displayMethod(int pos, int methodIndex, String name, Trait trait, boolean isStatic) {
|
||||
if (abc == null) {
|
||||
return false;
|
||||
}
|
||||
int bi = abc.findBodyIndex(methodIndex);
|
||||
if (bi == -1) {
|
||||
return false;
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
});
|
||||
//fix for inner functions:
|
||||
if (trait instanceof TraitMethodGetterSetter) {
|
||||
TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait;
|
||||
if (tm.method_info != methodIndex) {
|
||||
trait = null;
|
||||
}
|
||||
}
|
||||
if (trait instanceof TraitFunction) {
|
||||
TraitFunction tf = (TraitFunction) trait;
|
||||
if (tf.method_info != methodIndex) {
|
||||
trait = null;
|
||||
}
|
||||
}
|
||||
abcPanel.detailPanel.showCard(DetailPanel.METHOD_TRAIT_CARD, trait);
|
||||
if (reset || (abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex() != bi)) {
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name, trait);
|
||||
abcPanel.detailPanel.setEditMode(false);
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
boolean success = false;
|
||||
Highlighting h = Highlighting.search(highlights, pos);
|
||||
if (h != null) {
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighOffset(h.getPropertyLong("offset"));
|
||||
success = true;
|
||||
}
|
||||
Highlighting sh = Highlighting.search(specialHighlights, pos);
|
||||
if (sh != null) {
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.hilighSpecial(sh.getPropertyString("subtype"), (int) (long) sh.getPropertyLong("index"));
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public void displayClass(int classIndex, int scriptIndex) {
|
||||
if (abcPanel.navigator.getClassIndex() != classIndex) {
|
||||
abcPanel.navigator.setClassIndex(classIndex, scriptIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetEditing() {
|
||||
reset = true;
|
||||
caretUpdate(null);
|
||||
reset = false;
|
||||
}
|
||||
|
||||
public int getMultinameUnderCursor() {
|
||||
int pos = getCaretPosition();
|
||||
Highlighting h = Highlighting.search(highlights, pos);
|
||||
if (h != null) {
|
||||
List<AVM2Instruction> list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).code.code;
|
||||
AVM2Instruction lastIns = null;
|
||||
long inspos = 0;
|
||||
AVM2Instruction selIns = null;
|
||||
for (AVM2Instruction ins : list) {
|
||||
if (h.getPropertyLong("offset") == ins.getOffset()) {
|
||||
selIns = ins;
|
||||
break;
|
||||
}
|
||||
if (ins.getOffset() > h.getPropertyLong("offset")) {
|
||||
inspos = h.getPropertyLong("offset") - lastIns.offset;
|
||||
selIns = lastIns;
|
||||
break;
|
||||
}
|
||||
lastIns = ins;
|
||||
}
|
||||
if (selIns != null) {
|
||||
for (int i = 0; i < selIns.definition.operands.length; i++) {
|
||||
if (selIns.definition.operands[i] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
return selIns.operands[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int currentMethod = -1;
|
||||
if (currentTrait instanceof TraitMethodGetterSetter) {
|
||||
currentMethod = ((TraitMethodGetterSetter) currentTrait).method_info;
|
||||
}
|
||||
if (currentMethodHighlight != null) {
|
||||
currentMethod = (int) (long) currentMethodHighlight.getPropertyLong("index");
|
||||
}
|
||||
Highlighting sh = Highlighting.search(specialHighlights, pos);
|
||||
if (sh != null) {
|
||||
switch (sh.getPropertyString("subtype")) {
|
||||
case "traittypename":
|
||||
if (currentTrait instanceof TraitSlotConst) {
|
||||
TraitSlotConst ts = (TraitSlotConst) currentTrait;
|
||||
return ts.type_index;
|
||||
}
|
||||
break;
|
||||
case "traitname":
|
||||
if (currentTrait != null) {
|
||||
return currentTrait.name_index;
|
||||
}
|
||||
break;
|
||||
case "returns":
|
||||
if (currentMethod > -1) {
|
||||
return abc.method_info.get(currentMethod).ret_type;
|
||||
}
|
||||
break;
|
||||
case "param":
|
||||
if (currentMethod > -1) {
|
||||
return abc.method_info.get(currentMethod).param_types[(int) (long) sh.getPropertyLong("index")];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void caretUpdate(final CaretEvent e) {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
caretUpdate(e);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (abc == null) {
|
||||
return;
|
||||
}
|
||||
if (ignoreCarret) {
|
||||
return;
|
||||
}
|
||||
|
||||
getCaret().setVisible(true);
|
||||
int pos = getCaretPosition();
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(true);
|
||||
try {
|
||||
classIndex = -1;
|
||||
Highlighting cm = Highlighting.search(classHighlights, pos);
|
||||
if (cm != null) {
|
||||
classIndex = (int) (long) cm.getPropertyLong("index");
|
||||
displayClass(classIndex, script.scriptIndex);
|
||||
}
|
||||
Highlighting tm = Highlighting.search(methodHighlights, pos);
|
||||
if (tm != null) {
|
||||
String name = "";
|
||||
if (abc != null) {
|
||||
if (classIndex > -1) {
|
||||
name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants);
|
||||
}
|
||||
}
|
||||
currentTrait = null;
|
||||
currentTraitHighlight = Highlighting.search(traitHighlights, pos);
|
||||
if (currentTraitHighlight != null) {
|
||||
lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index");
|
||||
if ((abc != null) && (classIndex != -1)) {
|
||||
currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex);
|
||||
isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex);
|
||||
if (currentTrait != null) {
|
||||
name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList<String>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displayMethod(pos, (int) (long) tm.getPropertyLong("index"), name, currentTrait, isStatic);
|
||||
currentMethodHighlight = tm;
|
||||
return;
|
||||
}
|
||||
|
||||
if (classIndex == -1) {
|
||||
setNoTrait();
|
||||
return;
|
||||
}
|
||||
currentTrait = null;
|
||||
currentTraitHighlight = Highlighting.search(traitHighlights, pos);
|
||||
if (currentTraitHighlight != null) {
|
||||
lastTraitIndex = (int) (long) currentTraitHighlight.getPropertyLong("index");
|
||||
currentTrait = abc.findTraitByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index"));
|
||||
if (currentTrait != null) {
|
||||
if (currentTrait instanceof TraitSlotConst) {
|
||||
abcPanel.detailPanel.slotConstTraitPanel.load((TraitSlotConst) currentTrait, abc,
|
||||
abc.isStaticTraitId(classIndex, lastTraitIndex));
|
||||
abcPanel.detailPanel.showCard(DetailPanel.SLOT_CONST_TRAIT_CARD, currentTrait);
|
||||
abcPanel.detailPanel.setEditMode(false);
|
||||
currentMethodHighlight = null;
|
||||
Highlighting spec = Highlighting.search(specialHighlights, pos, null, null, currentTraitHighlight.startPos, currentTraitHighlight.startPos + currentTraitHighlight.len);
|
||||
if (spec != null) {
|
||||
abcPanel.detailPanel.slotConstTraitPanel.hilightSpecial(spec);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentMethodHighlight = null;
|
||||
String name = "";
|
||||
currentTrait = null;
|
||||
if (abc != null) {
|
||||
name = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants);
|
||||
currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex);
|
||||
isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex);
|
||||
if (currentTrait != null) {
|
||||
name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList<String>());
|
||||
}
|
||||
}
|
||||
|
||||
displayMethod(pos, abc.findMethodIdByTraitId(classIndex, (int) (long) currentTraitHighlight.getPropertyLong("index")), name, currentTrait, isStatic);
|
||||
return;
|
||||
}
|
||||
setNoTrait();
|
||||
} finally {
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setIgnoreCarret(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void uncache(ScriptPack pack) {
|
||||
cache.remove(pack);
|
||||
}
|
||||
|
||||
public boolean isCached(ScriptPack pack) {
|
||||
return cache.contains(pack);
|
||||
}
|
||||
|
||||
private CachedDecompilation getCached(ScriptPack pack) throws InterruptedException {
|
||||
if (!cache.contains(pack)) {
|
||||
cacheScriptPack(pack, abcList);
|
||||
}
|
||||
return (CachedDecompilation) cache.get(pack);
|
||||
}
|
||||
|
||||
public String getCachedText(ScriptPack pack) throws InterruptedException {
|
||||
return getCached(pack).text;
|
||||
}
|
||||
|
||||
public void gotoLastTrait() {
|
||||
gotoTrait(lastTraitIndex);
|
||||
}
|
||||
|
||||
public void gotoTrait(int traitId) {
|
||||
if (traitId == -1) {
|
||||
setCaretPosition(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Highlighting tc = Highlighting.search(classHighlights, "index", "" + classIndex);
|
||||
if (tc != null) {
|
||||
Highlighting th = Highlighting.search(traitHighlights, "index", "" + traitId, tc.startPos, tc.startPos + tc.len);
|
||||
if (th != null) {
|
||||
ignoreCarret = true;
|
||||
int startPos = th.startPos + th.len - 1;
|
||||
if (startPos <= getDocument().getLength()) {
|
||||
setCaretPosition(startPos);
|
||||
}
|
||||
ignoreCarret = false;
|
||||
final int pos = th.startPos;
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (pos <= getDocument().getLength()) {
|
||||
setCaretPosition(pos);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setCaretPosition(0);
|
||||
}
|
||||
|
||||
public DecompiledEditorPane(ABCPanel abcPanel) {
|
||||
setEditable(false);
|
||||
getCaret().setVisible(true);
|
||||
addCaretListener(this);
|
||||
this.abcPanel = abcPanel;
|
||||
}
|
||||
private List<ABCContainerTag> abcList;
|
||||
|
||||
public void clearScriptCache() {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
public void cacheScriptPack(ScriptPack scriptLeaf, List<ABCContainerTag> abcList) throws InterruptedException {
|
||||
int maxCacheSize = 50;
|
||||
int scriptIndex = scriptLeaf.scriptIndex;
|
||||
HilightedText hilightedCode = null;
|
||||
ScriptInfo script = null;
|
||||
ABC abc = scriptLeaf.abc;
|
||||
if (scriptIndex > -1) {
|
||||
script = abc.script_info.get(scriptIndex);
|
||||
}
|
||||
if (!cache.contains(scriptLeaf)) {
|
||||
boolean parallel = Configuration.parallelSpeedUp.get();
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true);
|
||||
scriptLeaf.toSource(writer, abcList, script.traits.traits, ScriptExportMode.AS, parallel);
|
||||
hilightedCode = new HilightedText(writer);
|
||||
cache.put(scriptLeaf, new CachedDecompilation(hilightedCode));
|
||||
}
|
||||
}
|
||||
|
||||
public void setScript(ScriptPack scriptLeaf, List<ABCContainerTag> abcList) {
|
||||
abcPanel.scriptNameLabel.setText(scriptLeaf.getPath().toString());
|
||||
int scriptIndex = scriptLeaf.scriptIndex;
|
||||
ScriptInfo script = null;
|
||||
ABC abc = scriptLeaf.abc;
|
||||
if (scriptIndex > -1) {
|
||||
script = abc.script_info.get(scriptIndex);
|
||||
}
|
||||
if (script == null) {
|
||||
highlights = new ArrayList<>();
|
||||
specialHighlights = new ArrayList<>();
|
||||
traitHighlights = new ArrayList<>();
|
||||
methodHighlights = new ArrayList<>();
|
||||
this.script = scriptLeaf;
|
||||
return;
|
||||
}
|
||||
setText("//" + AppStrings.translate("pleasewait") + "...");
|
||||
|
||||
this.abc = abc;
|
||||
this.abcList = abcList;
|
||||
this.script = scriptLeaf;
|
||||
CachedDecompilation cd = null;
|
||||
try {
|
||||
cacheScriptPack(scriptLeaf, abcList);
|
||||
cd = getCached(scriptLeaf);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
if (cd != null) {
|
||||
final String hilightedCode = cd.text;
|
||||
highlights = cd.getInstructionHighlights();
|
||||
specialHighlights = cd.getSpecialHighligths();
|
||||
traitHighlights = cd.getTraitHighlights();
|
||||
methodHighlights = cd.getMethodHighlights();
|
||||
classHighlights = cd.getClassHighlights();
|
||||
setContentType("text/actionscript");
|
||||
setText(hilightedCode);
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadClass() {
|
||||
int ci = classIndex;
|
||||
uncache(script);
|
||||
if ((script != null) && (abc != null)) {
|
||||
setScript(script, abcList);
|
||||
}
|
||||
setNoTrait();
|
||||
setClassIndex(ci);
|
||||
}
|
||||
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
public void setABC(ABC abc) {
|
||||
this.abc = abc;
|
||||
cache.clear();
|
||||
setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
super.setText(t);
|
||||
setCaretPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Hashtable;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DeobfuscationDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
public JCheckBox processAllCheckbox = new JCheckBox(translate("processallclasses"));
|
||||
public JSlider codeProcessingLevel;
|
||||
public boolean ok = false;
|
||||
public static final int LEVEL_REMOVE_DEAD_CODE = 1;
|
||||
public static final int LEVEL_REMOVE_TRAPS = 2;
|
||||
public static final int LEVEL_RESTORE_CONTROL_FLOW = 3;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public DeobfuscationDialog() {
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setSize(new Dimension(330, 270));
|
||||
setTitle(translate("dialog.title"));
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
|
||||
codeProcessingLevel = new JSlider(JSlider.VERTICAL, 1, 3, 3);
|
||||
codeProcessingLevel.setMajorTickSpacing(1);
|
||||
codeProcessingLevel.setPaintTicks(true);
|
||||
codeProcessingLevel.setMinorTickSpacing(1);
|
||||
codeProcessingLevel.setSnapToTicks(true);
|
||||
JLabel lab1 = new JLabel(translate("deobfuscation.level"));
|
||||
//lab1.setBounds(30, 0, getWidth() - 60, 25);
|
||||
lab1.setAlignmentX(0.5f);
|
||||
cp.add(lab1);
|
||||
Hashtable labelTable = new Hashtable();
|
||||
//labelTable.put(new Integer(LEVEL_NONE), new JLabel("None"));
|
||||
|
||||
labelTable.put(new Integer(LEVEL_REMOVE_DEAD_CODE), new JLabel(translate("deobfuscation.removedeadcode")));
|
||||
labelTable.put(new Integer(LEVEL_REMOVE_TRAPS), new JLabel(translate("deobfuscation.removetraps")));
|
||||
labelTable.put(new Integer(LEVEL_RESTORE_CONTROL_FLOW), new JLabel(translate("deobfuscation.restorecontrolflow")));
|
||||
codeProcessingLevel.setLabelTable(labelTable);
|
||||
|
||||
codeProcessingLevel.setPaintLabels(true);
|
||||
codeProcessingLevel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
//codeProcessingLevel.setSize(300, 200);
|
||||
|
||||
//codeProcessingLevel.setBounds(30, 25, getWidth() - 60, 125);
|
||||
codeProcessingLevel.setAlignmentX(0.5f);
|
||||
add(codeProcessingLevel);
|
||||
//processAllCheckbox.setBounds(50, 150, getWidth() - 100, 25);
|
||||
processAllCheckbox.setAlignmentX(0.5f);
|
||||
add(processAllCheckbox);
|
||||
|
||||
processAllCheckbox.setSelected(true);
|
||||
|
||||
JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
cancelButton.addActionListener(this);
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.addActionListener(this);
|
||||
okButton.setActionCommand(ACTION_OK);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
buttonsPanel.setAlignmentX(0.5f);
|
||||
cp.add(buttonsPanel);
|
||||
|
||||
setModal(true);
|
||||
View.centerScreen(this);
|
||||
//View.setWindowIcon(this);
|
||||
setIconImage(View.loadImage("deobfuscate16"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OK:
|
||||
ok = true;
|
||||
setVisible(false);
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
ok = false;
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
ok = false;
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.gui.HeaderLabel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DetailPanel extends JPanel implements ActionListener {
|
||||
|
||||
static final String ACTION_SAVE_DETAIL = "SAVEDETAIL";
|
||||
static final String ACTION_EDIT_DETAIL = "EDITDETAIL";
|
||||
static final String ACTION_CANCEL_DETAIL = "CANCELDETAIL";
|
||||
|
||||
public MethodTraitDetailPanel methodTraitPanel;
|
||||
public JPanel unsupportedTraitPanel;
|
||||
public SlotConstTraitDetailPanel slotConstTraitPanel;
|
||||
public static final String METHOD_TRAIT_CARD = AppStrings.translate("abc.detail.methodtrait");
|
||||
public static final String UNSUPPORTED_TRAIT_CARD = AppStrings.translate("abc.detail.unsupported");
|
||||
public static final String SLOT_CONST_TRAIT_CARD = AppStrings.translate("abc.detail.slotconsttrait");
|
||||
private final JPanel innerPanel;
|
||||
public JButton saveButton = new JButton(AppStrings.translate("button.save"), View.getIcon("save16"));
|
||||
public JButton editButton = new JButton(AppStrings.translate("button.edit"), View.getIcon("edit16"));
|
||||
public JButton cancelButton = new JButton(AppStrings.translate("button.cancel"), View.getIcon("cancel16"));
|
||||
private final HashMap<String, JComponent> cardMap = new HashMap<>();
|
||||
private String selectedCard;
|
||||
private final JLabel selectedLabel;
|
||||
private boolean editMode = false;
|
||||
private final JPanel buttonsPanel;
|
||||
private final ABCPanel abcPanel;
|
||||
private final JLabel traitNameLabel;
|
||||
|
||||
public DetailPanel(ABCPanel abcPanel) {
|
||||
this.abcPanel = abcPanel;
|
||||
innerPanel = new JPanel();
|
||||
CardLayout layout = new CardLayout();
|
||||
innerPanel.setLayout(layout);
|
||||
methodTraitPanel = new MethodTraitDetailPanel(abcPanel);
|
||||
cardMap.put(METHOD_TRAIT_CARD, methodTraitPanel);
|
||||
|
||||
unsupportedTraitPanel = new JPanel(new BorderLayout());
|
||||
JLabel unsup = new JLabel(AppStrings.translate("info.selecttrait"), SwingConstants.CENTER);
|
||||
unsupportedTraitPanel.add(unsup, BorderLayout.CENTER);
|
||||
|
||||
cardMap.put(UNSUPPORTED_TRAIT_CARD, unsupportedTraitPanel);
|
||||
|
||||
slotConstTraitPanel = new SlotConstTraitDetailPanel(abcPanel.decompiledTextArea);
|
||||
cardMap.put(SLOT_CONST_TRAIT_CARD, slotConstTraitPanel);
|
||||
|
||||
for (String key : cardMap.keySet()) {
|
||||
innerPanel.add(cardMap.get(key), key);
|
||||
}
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(innerPanel, BorderLayout.CENTER);
|
||||
|
||||
editButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
saveButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
cancelButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
|
||||
buttonsPanel = new JPanel();
|
||||
buttonsPanel.setLayout(new FlowLayout());
|
||||
saveButton.setActionCommand(ACTION_SAVE_DETAIL);
|
||||
saveButton.addActionListener(this);
|
||||
editButton.setActionCommand(ACTION_EDIT_DETAIL);
|
||||
editButton.addActionListener(this);
|
||||
cancelButton.setActionCommand(ACTION_CANCEL_DETAIL);
|
||||
cancelButton.addActionListener(this);
|
||||
buttonsPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
buttonsPanel.add(editButton);
|
||||
buttonsPanel.add(saveButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
add(buttonsPanel, BorderLayout.SOUTH);
|
||||
selectedCard = UNSUPPORTED_TRAIT_CARD;
|
||||
layout.show(innerPanel, UNSUPPORTED_TRAIT_CARD);
|
||||
buttonsPanel.setVisible(false);
|
||||
selectedLabel = new HeaderLabel("");
|
||||
selectedLabel.setText(selectedCard);
|
||||
//selectedLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
selectedLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
topPanel.add(selectedLabel, BorderLayout.NORTH);
|
||||
traitNameLabel = new JLabel("");
|
||||
JPanel traitInfoPanel = new JPanel();
|
||||
traitInfoPanel.setLayout(new BoxLayout(traitInfoPanel, BoxLayout.LINE_AXIS));
|
||||
//traitInfoPanel.add(new JLabel(" " + translate("abc.detail.traitname")));
|
||||
traitInfoPanel.add(traitNameLabel);
|
||||
topPanel.add(traitInfoPanel, BorderLayout.CENTER);
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
public void setEditMode(boolean val) {
|
||||
slotConstTraitPanel.setEditMode(val);
|
||||
methodTraitPanel.setEditMode(val);
|
||||
saveButton.setVisible(val);
|
||||
editButton.setVisible(!val);
|
||||
cancelButton.setVisible(val);
|
||||
editMode = val;
|
||||
if (val) {
|
||||
selectedLabel.setIcon(View.getIcon("editing16"));
|
||||
} else {
|
||||
selectedLabel.setIcon(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void showCard(String name, Trait trait) {
|
||||
CardLayout layout = (CardLayout) innerPanel.getLayout();
|
||||
layout.show(innerPanel, name);
|
||||
boolean b = cardMap.get(name) instanceof TraitDetail;
|
||||
buttonsPanel.setVisible(b);
|
||||
|
||||
TraitDetail newDetail = null;
|
||||
if (b) {
|
||||
newDetail = (TraitDetail) cardMap.get(name);
|
||||
}
|
||||
for (JComponent v : cardMap.values()) {
|
||||
if (v instanceof TraitDetail) {
|
||||
if (v != newDetail) {
|
||||
TraitDetail oldDetail = (TraitDetail) v;
|
||||
oldDetail.setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newDetail != null) {
|
||||
newDetail.setActive(true);
|
||||
}
|
||||
|
||||
selectedCard = name;
|
||||
selectedLabel.setText(selectedCard);
|
||||
if (trait == null) {
|
||||
traitNameLabel.setText("-");
|
||||
} else {
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_EDIT_DETAIL:
|
||||
setEditMode(true);
|
||||
methodTraitPanel.methodCodePanel.focusEditor();
|
||||
break;
|
||||
case ACTION_CANCEL_DETAIL:
|
||||
setEditMode(false);
|
||||
abcPanel.decompiledTextArea.resetEditing();
|
||||
break;
|
||||
case ACTION_SAVE_DETAIL:
|
||||
if (cardMap.get(selectedCard) instanceof TraitDetail) {
|
||||
if (((TraitDetail) cardMap.get(selectedCard)).save()) {
|
||||
CancellableWorker worker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
int lasttrait = abcPanel.decompiledTextArea.lastTraitIndex;
|
||||
abcPanel.decompiledTextArea.reloadClass();
|
||||
abcPanel.decompiledTextArea.gotoTrait(lasttrait);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
setEditMode(false);
|
||||
View.showMessageDialog(null, AppStrings.translate("message.trait.saved"));
|
||||
}
|
||||
};
|
||||
worker.execute();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.MissingSymbolHandler;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class DialogMissingSymbolHandler implements MissingSymbolHandler {
|
||||
|
||||
@Override
|
||||
public boolean missingString(String value) {
|
||||
return View.showConfirmDialog(null, AppStrings.translate("message.constant.new.string").replace("%value%", value), AppStrings.translate("message.constant.new.string.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingInt(long value) {
|
||||
return View.showConfirmDialog(null, AppStrings.translate("message.constant.new.integer").replace("%value%", "" + value), AppStrings.translate("message.constant.new.integer.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingUInt(long value) {
|
||||
return View.showConfirmDialog(null, AppStrings.translate("message.constant.new.unsignedinteger").replace("%value%", "" + value), AppStrings.translate("message.constant.new.unsignedinteger.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingDouble(double value) {
|
||||
return View.showConfirmDialog(null, AppStrings.translate("message.constant.new.double").replace("%value%", "" + value), AppStrings.translate("message.constant.new.double.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import java.awt.Component;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
|
||||
public class IconListRenderer extends DefaultListCellRenderer {
|
||||
|
||||
private final Icon constIcon;
|
||||
private final Icon functionIcon;
|
||||
private final Icon variableIcon;
|
||||
|
||||
private Icon loadIcon(String path) {
|
||||
ClassLoader cldr = this.getClass().getClassLoader();
|
||||
java.net.URL imageURL = cldr.getResource(path);
|
||||
return new ImageIcon(imageURL);
|
||||
}
|
||||
|
||||
public IconListRenderer() {
|
||||
constIcon = View.getIcon("constant");
|
||||
functionIcon = View.getIcon("function");
|
||||
variableIcon = View.getIcon("variable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
// Get the renderer component from parent class
|
||||
JLabel label
|
||||
= (JLabel) super.getListCellRendererComponent(list,
|
||||
value, index, isSelected, cellHasFocus);
|
||||
|
||||
// Get icon to use for the list item value
|
||||
TraitsListItem tli = (TraitsListItem) value;
|
||||
|
||||
if (tli.getType() == TraitsListItem.Type.CONST) {
|
||||
label.setIcon(constIcon);
|
||||
}
|
||||
if (tli.getType() == TraitsListItem.Type.VAR) {
|
||||
label.setIcon(variableIcon);
|
||||
}
|
||||
if (tli.getType() == TraitsListItem.Type.METHOD) {
|
||||
label.setIcon(functionIcon);
|
||||
}
|
||||
if (tli.getType() == TraitsListItem.Type.INITIALIZER) {
|
||||
label.setIcon(functionIcon);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.text.Element;
|
||||
import jsyntaxpane.actions.ActionUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LineMarkedEditorPane extends UndoFixedEditorPane {
|
||||
|
||||
int lastLine = -1;
|
||||
|
||||
public int getLine() {
|
||||
return lastLine;
|
||||
}
|
||||
|
||||
public void gotoLine(int line) {
|
||||
setCaretPosition(ActionUtils.getDocumentPosition(this, line, 0));
|
||||
}
|
||||
|
||||
public LineMarkedEditorPane() {
|
||||
setOpaque(false);
|
||||
addCaretListener(new CaretListener() {
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
int caretPosition = getCaretPosition();
|
||||
Element root = getDocument().getDefaultRootElement();
|
||||
int currentLine = root.getElementIndex(caretPosition);
|
||||
if (currentLine != lastLine) {
|
||||
lastLine = currentLine;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
lastLine = -1;
|
||||
if (Configuration.debugMode.get() && t.length() > 4192) {
|
||||
t = t.substring(0, 4192);
|
||||
}
|
||||
super.setText(t);
|
||||
setCaretPosition(0); //scroll to top
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t, String contentType) {
|
||||
lastLine = -1;
|
||||
super.setText(t, contentType);
|
||||
setCaretPosition(0); //scroll to top
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
int lh = fontMetrics.getHeight();
|
||||
int a = fontMetrics.getAscent();
|
||||
int d = fontMetrics.getDescent();
|
||||
int h = a + d;
|
||||
int rH = h;
|
||||
g.setColor(new Color(0xee, 0xee, 0xee));
|
||||
g.fillRect(0, d + lh * lastLine - 1, getWidth(), lh);
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JToggleButton;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MethodCodePanel extends JPanel implements ActionListener {
|
||||
|
||||
static final String ACTION_GRAPH = "GRAPH";
|
||||
static final String ACTION_HEX = "HEX";
|
||||
static final String ACTION_HEX_ONLY = "HEXONLY";
|
||||
|
||||
private final ASMSourceEditorPane sourceTextArea;
|
||||
public JPanel buttonsPanel;
|
||||
private final JToggleButton hexButton;
|
||||
private final JToggleButton hexOnlyButton;
|
||||
|
||||
public void focusEditor() {
|
||||
sourceTextArea.requestFocusInWindow();
|
||||
}
|
||||
|
||||
public String getTraitName() {
|
||||
return sourceTextArea.getName();
|
||||
}
|
||||
|
||||
public void setIgnoreCarret(boolean ignoreCarret) {
|
||||
sourceTextArea.setIgnoreCarret(ignoreCarret);
|
||||
}
|
||||
|
||||
public void hilighOffset(long offset) {
|
||||
sourceTextArea.hilighOffset(offset);
|
||||
}
|
||||
|
||||
public void hilighSpecial(String type, int index) {
|
||||
sourceTextArea.hilighSpecial(type, index);
|
||||
}
|
||||
|
||||
public void setBodyIndex(int bodyIndex, ABC abc, Trait trait) {
|
||||
sourceTextArea.setBodyIndex(bodyIndex, abc, sourceTextArea.getName(), trait);
|
||||
}
|
||||
|
||||
public void setBodyIndex(int bodyIndex, ABC abc, String name, Trait trait) {
|
||||
sourceTextArea.setBodyIndex(bodyIndex, abc, name, trait);
|
||||
}
|
||||
|
||||
public int getBodyIndex() {
|
||||
return sourceTextArea.bodyIndex;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
sourceTextArea.clear();
|
||||
}
|
||||
|
||||
public boolean save(ConstantPool constants) {
|
||||
return sourceTextArea.save(constants);
|
||||
}
|
||||
|
||||
public MethodCodePanel(DecompiledEditorPane decompiledEditor) {
|
||||
sourceTextArea = new ASMSourceEditorPane(decompiledEditor);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(new JScrollPane(sourceTextArea), BorderLayout.CENTER);
|
||||
sourceTextArea.setContentType("text/flasm3");
|
||||
sourceTextArea.setFont(new Font("Monospaced", Font.PLAIN, sourceTextArea.getFont().getSize()));
|
||||
|
||||
buttonsPanel = new JPanel();
|
||||
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
|
||||
|
||||
JButton graphButton = new JButton(View.getIcon("graph16"));
|
||||
graphButton.setActionCommand(ACTION_GRAPH);
|
||||
graphButton.addActionListener(this);
|
||||
graphButton.setToolTipText(AppStrings.translate("button.viewgraph"));
|
||||
graphButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
hexButton = new JToggleButton(View.getIcon("hexas16"));
|
||||
hexButton.setActionCommand(ACTION_HEX);
|
||||
hexButton.addActionListener(this);
|
||||
hexButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
hexOnlyButton = new JToggleButton(View.getIcon("hex16"));
|
||||
hexOnlyButton.setActionCommand(ACTION_HEX_ONLY);
|
||||
hexOnlyButton.addActionListener(this);
|
||||
hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexOnlyButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
buttonsPanel.add(graphButton);
|
||||
buttonsPanel.add(hexButton);
|
||||
buttonsPanel.add(hexOnlyButton);
|
||||
buttonsPanel.add(new JPanel());
|
||||
// buttonsPanel.add(saveButton);
|
||||
// buttonsPan.add(execButton);
|
||||
|
||||
add(buttonsPanel, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (Main.isWorking()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_GRAPH:
|
||||
sourceTextArea.graph();
|
||||
break;
|
||||
case ACTION_HEX:
|
||||
case ACTION_HEX_ONLY:
|
||||
if (e.getActionCommand() == ACTION_HEX) {
|
||||
hexOnlyButton.setSelected(false);
|
||||
} else {
|
||||
hexButton.setSelected(false);
|
||||
}
|
||||
sourceTextArea.setHex(getExportMode(), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private ScriptExportMode getExportMode() {
|
||||
ScriptExportMode exportMode = hexOnlyButton.isSelected() ? ScriptExportMode.HEX
|
||||
: (hexButton.isSelected() ? ScriptExportMode.PCODE_HEX : ScriptExportMode.PCODE);
|
||||
return exportMode;
|
||||
}
|
||||
|
||||
public void setEditMode(boolean val) {
|
||||
ScriptExportMode exportMode = getExportMode();
|
||||
if (val) {
|
||||
sourceTextArea.setHex(exportMode == ScriptExportMode.HEX ? ScriptExportMode.HEX : ScriptExportMode.PCODE, false);
|
||||
} else {
|
||||
if (exportMode != ScriptExportMode.PCODE) {
|
||||
sourceTextArea.setHex(exportMode, false);
|
||||
}
|
||||
}
|
||||
|
||||
sourceTextArea.setEditable(val);
|
||||
sourceTextArea.getCaret().setVisible(true);
|
||||
buttonsPanel.setVisible(!val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MethodTraitDetailPanel extends JPanel implements TraitDetail {
|
||||
|
||||
public MethodCodePanel methodCodePanel;
|
||||
public ABCPanel abcPanel;
|
||||
|
||||
public MethodTraitDetailPanel(ABCPanel abcPanel) {
|
||||
this.abcPanel = abcPanel;
|
||||
methodCodePanel = new MethodCodePanel(abcPanel.decompiledTextArea);
|
||||
setLayout(new BorderLayout());
|
||||
add(methodCodePanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save() {
|
||||
if (!methodCodePanel.save(abcPanel.abc.constants)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditMode(boolean val) {
|
||||
methodCodePanel.setEditMode(val);
|
||||
}
|
||||
private boolean active = false;
|
||||
|
||||
@Override
|
||||
public void setActive(boolean val) {
|
||||
this.active = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.AncestorEvent;
|
||||
import javax.swing.event.AncestorListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class NewTraitDialog extends AppDialog implements ActionListener {
|
||||
|
||||
static final String ACTION_OK = "OK";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
private static final int modifiers[] = new int[]{
|
||||
Namespace.KIND_PACKAGE,
|
||||
Namespace.KIND_PRIVATE,
|
||||
Namespace.KIND_PROTECTED,
|
||||
Namespace.KIND_NAMESPACE,
|
||||
Namespace.KIND_PACKAGE_INTERNAL,
|
||||
Namespace.KIND_EXPLICIT,
|
||||
Namespace.KIND_STATIC_PROTECTED
|
||||
};
|
||||
private static final int types[] = new int[]{
|
||||
Trait.TRAIT_METHOD,
|
||||
Trait.TRAIT_GETTER,
|
||||
Trait.TRAIT_SETTER,
|
||||
Trait.TRAIT_CONST,
|
||||
Trait.TRAIT_SLOT
|
||||
};
|
||||
private final JComboBox<String> accessComboBox;
|
||||
private final JComboBox<String> typeComboBox;
|
||||
private final JCheckBox staticCheckbox;
|
||||
private final JTextField nameField;
|
||||
|
||||
public boolean getStatic() {
|
||||
return staticCheckbox.isSelected();
|
||||
}
|
||||
|
||||
public int getNamespaceKind() {
|
||||
return modifiers[accessComboBox.getSelectedIndex()];
|
||||
}
|
||||
|
||||
public int getTraitType() {
|
||||
return types[typeComboBox.getSelectedIndex()];
|
||||
}
|
||||
|
||||
public String getTraitName() {
|
||||
return nameField.getText();
|
||||
}
|
||||
|
||||
public NewTraitDialog() {
|
||||
setSize(500, 300);
|
||||
setTitle(translate("dialog.title"));
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
JPanel optionsPanel = new JPanel(new FlowLayout());
|
||||
//optionsPanel.add(new JLabel(translate("label.type")));
|
||||
typeComboBox = new JComboBox<>(new String[]{
|
||||
translate("type.method"),
|
||||
translate("type.getter"),
|
||||
translate("type.setter"),
|
||||
translate("type.const"),
|
||||
translate("type.slot"),});
|
||||
staticCheckbox = new JCheckBox(translate("checkbox.static"));
|
||||
optionsPanel.add(staticCheckbox);
|
||||
String accessStrings[] = new String[modifiers.length];
|
||||
for (int i = 0; i < accessStrings.length; i++) {
|
||||
String pref = Namespace.kindToPrefix(modifiers[i]);
|
||||
String name = Namespace.kindToStr(modifiers[i]);
|
||||
accessStrings[i] = (pref.isEmpty() ? "" : pref + " ") + "(" + name + ")";
|
||||
}
|
||||
|
||||
//optionsPanel.add(new JLabel(translate("label.access")));
|
||||
accessComboBox = new JComboBox<>(accessStrings);
|
||||
optionsPanel.add(accessComboBox);
|
||||
|
||||
optionsPanel.add(typeComboBox);
|
||||
|
||||
//optionsPanel.add(new JLabel(translate("label.name")));
|
||||
nameField = new JTextField();
|
||||
nameField.setPreferredSize(new Dimension(300, nameField.getPreferredSize().height));
|
||||
optionsPanel.add(nameField);
|
||||
|
||||
cnt.add(optionsPanel, BorderLayout.CENTER);
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton buttonOk = new JButton(AppStrings.translate("button.ok"));
|
||||
buttonOk.setActionCommand(ACTION_OK);
|
||||
buttonOk.addActionListener(this);
|
||||
JButton buttonCancel = new JButton(AppStrings.translate("button.cancel"));
|
||||
buttonCancel.setActionCommand(ACTION_CANCEL);
|
||||
buttonCancel.addActionListener(this);
|
||||
buttonsPanel.add(buttonOk);
|
||||
buttonsPanel.add(buttonCancel);
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
pack();
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
|
||||
nameField.addAncestorListener(new AncestorListener() {
|
||||
@Override
|
||||
public void ancestorAdded(AncestorEvent event) {
|
||||
JComponent component = event.getComponent();
|
||||
component.requestFocusInWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ancestorRemoved(AncestorEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ancestorMoved(AncestorEvent event) {
|
||||
}
|
||||
});
|
||||
getRootPane().setDefaultButton(buttonOk);
|
||||
}
|
||||
|
||||
public boolean display() {
|
||||
nameField.setText("");
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
private boolean result = false;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_OK:
|
||||
if (nameField.getText().trim().isEmpty()) {
|
||||
View.showMessageDialog(null, translate("error.name"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
result = true;
|
||||
setVisible(false);
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
result = false;
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RootABCContainerTag implements ABCContainerTag {
|
||||
|
||||
@Override
|
||||
public ABC getABC() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ABCContainerTag t) {
|
||||
if (t instanceof RootABCContainerTag) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return " - all - ";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import java.awt.BorderLayout;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SlotConstTraitDetailPanel extends JPanel implements TraitDetail {
|
||||
|
||||
public JEditorPane slotConstEditor;
|
||||
private ABC abc;
|
||||
private TraitSlotConst trait;
|
||||
private boolean showWarning = false;
|
||||
private List<Highlighting> specialHilights;
|
||||
private boolean ignoreCaret = false;
|
||||
|
||||
public SlotConstTraitDetailPanel(final DecompiledEditorPane editor) {
|
||||
slotConstEditor = new LineMarkedEditorPane();
|
||||
setLayout(new BorderLayout());
|
||||
add(new JScrollPane(slotConstEditor), BorderLayout.CENTER);
|
||||
slotConstEditor.setContentType("text/flasm3");
|
||||
slotConstEditor.addCaretListener(new CaretListener() {
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
if (ignoreCaret) {
|
||||
return;
|
||||
}
|
||||
Highlighting spec = Highlighting.search(specialHilights, slotConstEditor.getCaretPosition());
|
||||
if (spec != null) {
|
||||
editor.hilightSpecial(spec.getPropertyString("subtype"), (int) (long) spec.getPropertyLong("index"));
|
||||
slotConstEditor.getCaret().setVisible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hilightSpecial(Highlighting special) {
|
||||
Highlighting sel = null;
|
||||
for (Highlighting h : specialHilights) {
|
||||
if (h.getPropertyString("subtype").equals(special.getPropertyString("subtype"))) {
|
||||
if (h.getPropertyString("index").equals(special.getPropertyString("index"))) {
|
||||
sel = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sel != null) {
|
||||
ignoreCaret = true;
|
||||
slotConstEditor.setCaretPosition(sel.startPos);
|
||||
slotConstEditor.getCaret().setVisible(true);
|
||||
ignoreCaret = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void load(TraitSlotConst trait, ABC abc, boolean isStatic) {
|
||||
this.abc = abc;
|
||||
this.trait = trait;
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true);
|
||||
writer.appendNoHilight("trait ");
|
||||
writer.hilightSpecial(abc.constants.multinameToString(trait.name_index), "traitname");
|
||||
writer.appendNoHilight(" ");
|
||||
writer.hilightSpecial(trait.isConst() ? "const" : "slot", "traittype");
|
||||
writer.appendNoHilight(" slotid ");
|
||||
writer.hilightSpecial("" + trait.slot_id, "slotid");
|
||||
writer.appendNoHilight(" type ");
|
||||
writer.hilightSpecial(abc.constants.multinameToString(trait.type_index), "traittypename");
|
||||
writer.appendNoHilight(" value ");
|
||||
writer.hilightSpecial((new ValueKind(trait.value_index, trait.value_kind).toASMString(abc.constants)), "traitvalue");
|
||||
String s = writer.toString();
|
||||
specialHilights = writer.specialHilights;
|
||||
showWarning = trait.isConst() || isStatic;
|
||||
slotConstEditor.setText(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save() {
|
||||
try {//(slotConstEditor.getText(), trait, abc)
|
||||
if (!ASM3Parser.parseSlotConst(new StringReader(slotConstEditor.getText()), abc.constants, trait)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ParseException ex) {
|
||||
View.showMessageDialog(slotConstEditor, ex.text, AppStrings.translate("error.slotconst.typevalue"), JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SlotConstTraitDetailPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditMode(boolean val) {
|
||||
if (val && active) {
|
||||
JOptionPane.showMessageDialog(null, AppStrings.translate("warning.initializers"), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
slotConstEditor.setEditable(val);
|
||||
}
|
||||
private boolean active = false;
|
||||
|
||||
@Override
|
||||
public void setActive(boolean val) {
|
||||
this.active = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface TraitDetail {
|
||||
|
||||
public void setEditMode(boolean val);
|
||||
|
||||
public boolean save();
|
||||
|
||||
public void setActive(boolean val);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.List;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
public class TraitsList extends JList<Object> implements ListSelectionListener {
|
||||
|
||||
ABC abc;
|
||||
List<ABCContainerTag> abcTags;
|
||||
int classIndex = -1;
|
||||
private final ABCPanel abcPanel;
|
||||
private boolean sorted = false;
|
||||
|
||||
public void setSorted(boolean sorted) {
|
||||
if (getModel() instanceof TraitsListModel) {
|
||||
((TraitsListModel) getModel()).setSorted(sorted);
|
||||
}
|
||||
this.sorted = sorted;
|
||||
}
|
||||
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
public TraitsList(ABCPanel abcPanel) {
|
||||
addListSelectionListener(this);
|
||||
this.abcPanel = abcPanel;
|
||||
setCellRenderer(new IconListRenderer());
|
||||
//setUI(new BasicListUI());
|
||||
setBackground(Color.white);
|
||||
}
|
||||
|
||||
public void clearABC() {
|
||||
this.abc = null;
|
||||
this.abcTags = null;
|
||||
setModel(new DefaultListModel<>());
|
||||
}
|
||||
|
||||
public void setABC(List<ABCContainerTag> abcTags, ABC abc) {
|
||||
this.abc = abc;
|
||||
this.abcTags = abcTags;
|
||||
setModel(new DefaultListModel<>());
|
||||
setClassIndex(-1, -1);
|
||||
}
|
||||
|
||||
public void setClassIndex(int classIndex, int scriptIndex) {
|
||||
if (classIndex >= abc.instance_info.size()) {
|
||||
return;
|
||||
}
|
||||
this.classIndex = classIndex;
|
||||
if (classIndex == -1) {
|
||||
setModel(new DefaultListModel<>());
|
||||
} else {
|
||||
if (abc != null) {
|
||||
setModel(new TraitsListModel(abcTags, abc, classIndex, scriptIndex, sorted));
|
||||
}
|
||||
}
|
||||
}
|
||||
private int lastSelected = -1;
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (getSelectedIndex() == lastSelected) {
|
||||
return;
|
||||
}
|
||||
lastSelected = getSelectedIndex();
|
||||
TraitsListItem sel = (TraitsListItem) getSelectedValue();
|
||||
abcPanel.decompiledTextArea.gotoTrait(sel == null ? -1 : sel.getGlobalTraitId());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setComposite(AlphaComposite.SrcOver);
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppStrings;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TraitsListItem {
|
||||
|
||||
private final Type type;
|
||||
private final boolean isStatic;
|
||||
private final List<ABCContainerTag> abcTags;
|
||||
private final ABC abc;
|
||||
private final int classIndex;
|
||||
private final int index;
|
||||
private final int scriptIndex;
|
||||
public String STR_INSTANCE_INITIALIZER = AppStrings.translate("abc.traitslist.instanceinitializer");
|
||||
public String STR_CLASS_INITIALIZER = AppStrings.translate("abc.traitslist.classinitializer");
|
||||
|
||||
public TraitsListItem(Type type, int index, boolean isStatic, List<ABCContainerTag> abcTags, ABC abc, int classIndex, int scriptIndex) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.isStatic = isStatic;
|
||||
this.abcTags = abcTags;
|
||||
this.abc = abc;
|
||||
this.classIndex = classIndex;
|
||||
this.scriptIndex = scriptIndex;
|
||||
}
|
||||
|
||||
public int getGlobalTraitId() {
|
||||
if (type == Type.INITIALIZER) {
|
||||
if (!isStatic) {
|
||||
return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size();
|
||||
} else {
|
||||
return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size() + 1;
|
||||
}
|
||||
}
|
||||
if (isStatic) {
|
||||
return index;
|
||||
} else {
|
||||
return abc.class_info.get(classIndex).static_traits.traits.size() + index;
|
||||
}
|
||||
}
|
||||
|
||||
public String toStringName() {
|
||||
if ((type != Type.INITIALIZER) && isStatic) {
|
||||
return abc.class_info.get(classIndex).static_traits.traits.get(index).getName(abc).getName(abc.constants, new ArrayList<String>());
|
||||
} else if ((type != Type.INITIALIZER) && (!isStatic)) {
|
||||
return abc.instance_info.get(classIndex).instance_traits.traits.get(index).getName(abc).getName(abc.constants, new ArrayList<String>());
|
||||
} else if (!isStatic) {
|
||||
return "__" + STR_INSTANCE_INITIALIZER;
|
||||
} else {
|
||||
return "__" + STR_CLASS_INITIALIZER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = "";
|
||||
try {
|
||||
if ((type != Type.INITIALIZER) && isStatic) {
|
||||
abc.class_info.get(classIndex).static_traits.traits.get(index).convertHeader(null, "", abcTags, abc, true, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<String>(), false);
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), false);
|
||||
abc.class_info.get(classIndex).static_traits.traits.get(index).toStringHeader(null, "", abcTags, abc, true, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<String>(), false);
|
||||
s = writer.toString();
|
||||
} else if ((type != Type.INITIALIZER) && (!isStatic)) {
|
||||
abc.instance_info.get(classIndex).instance_traits.traits.get(index).convertHeader(null, "", abcTags, abc, false, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<String>(), false);
|
||||
HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), false);
|
||||
abc.instance_info.get(classIndex).instance_traits.traits.get(index).toStringHeader(null, "", abcTags, abc, false, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<String>(), false);
|
||||
s = writer.toString();
|
||||
} else if (!isStatic) {
|
||||
s = STR_INSTANCE_INITIALIZER;
|
||||
} else {
|
||||
s = STR_CLASS_INITIALIZER;
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(TraitsListItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
s = s.replaceAll("[ \r\n]+", " ");
|
||||
return s;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
METHOD,
|
||||
VAR,
|
||||
CONST,
|
||||
INITIALIZER;
|
||||
|
||||
public static Type getTypeForTrait(Trait t) {
|
||||
if (t instanceof TraitMethodGetterSetter) {
|
||||
return METHOD;
|
||||
}
|
||||
if (t instanceof TraitSlotConst) {
|
||||
if (((TraitSlotConst) t).isConst()) {
|
||||
return CONST;
|
||||
} else {
|
||||
return VAR;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
|
||||
public final class TraitsListModel implements ListModel<Object> {
|
||||
|
||||
private List<TraitsListItem> items;
|
||||
private final List<ABCContainerTag> abcTags;
|
||||
private final ABC abc;
|
||||
private final int classIndex;
|
||||
private final int scriptIndex;
|
||||
|
||||
public void setSorted(boolean sorted) {
|
||||
if (sorted) {
|
||||
Collections.sort(items, new Comparator<TraitsListItem>() {
|
||||
@Override
|
||||
public int compare(TraitsListItem o1, TraitsListItem o2) {
|
||||
return o1.toStringName().compareTo(o2.toStringName());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
items = new ArrayList<>();
|
||||
for (int t = 0; t < abc.class_info.get(classIndex).static_traits.traits.size(); t++) {
|
||||
items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.class_info.get(classIndex).static_traits.traits.get(t)), t, true, abcTags, abc, classIndex, scriptIndex));
|
||||
}
|
||||
for (int t = 0; t < abc.instance_info.get(classIndex).instance_traits.traits.size(); t++) {
|
||||
items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.instance_info.get(classIndex).instance_traits.traits.get(t)), t, false, abcTags, abc, classIndex, scriptIndex));
|
||||
}
|
||||
items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, false, abcTags, abc, classIndex, scriptIndex));
|
||||
items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, true, abcTags, abc, classIndex, scriptIndex));
|
||||
}
|
||||
|
||||
public TraitsListModel(List<ABCContainerTag> abcTags, ABC abc, int classIndex, int scriptIndex, boolean sorted) {
|
||||
this.abcTags = abcTags;
|
||||
this.abc = abc;
|
||||
this.classIndex = classIndex;
|
||||
this.scriptIndex = scriptIndex;
|
||||
reset();
|
||||
if (sorted) {
|
||||
setSorted(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
return items.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Paolo Cancedda
|
||||
*
|
||||
* 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.AS3PackageNode;
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement;
|
||||
import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class Tree {
|
||||
|
||||
private final TreeElement ROOT = new AS3PackageNode("", "", new AS3PackageNodeItem(null, null), null);
|
||||
|
||||
public void add(String name, String path, ScriptPack item) {
|
||||
StringTokenizer st = new StringTokenizer(path, ".");
|
||||
TreeElement parent = ROOT;
|
||||
while (st.hasMoreTokens()) {
|
||||
String pathElement = st.nextToken();
|
||||
parent = parent.getBranch(pathElement, item.getSwf());
|
||||
}
|
||||
parent.addLeaf(name, item);
|
||||
}
|
||||
|
||||
public TreeElement getRoot() {
|
||||
return ROOT;
|
||||
}
|
||||
|
||||
public void visit(TreeVisitor visitor) {
|
||||
ROOT.visitLeafs(visitor);
|
||||
ROOT.visitBranches(visitor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Paolo Cancedda
|
||||
*
|
||||
* 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement;
|
||||
|
||||
public interface TreeVisitor {
|
||||
|
||||
public void onBranch(TreeElement branch);
|
||||
|
||||
public void onLeaf(TreeElement leaf);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.text.Document;
|
||||
import jsyntaxpane.SyntaxDocument;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UndoFixedEditorPane extends JEditorPane {
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
if (getText() != t) {
|
||||
super.setText(t);
|
||||
clearUndos();
|
||||
}
|
||||
}
|
||||
|
||||
public void setText(String t, String contentType) {
|
||||
if (getText() != t) {
|
||||
// OK to check reference equals, because the string object should be the same
|
||||
super.setText(null);
|
||||
if (t.length() > Configuration.syntaxHighlightLimit.get()) {
|
||||
setContentType("text/plain");
|
||||
} else {
|
||||
if (!getContentType().equals(contentType)) {
|
||||
setContentType(contentType);
|
||||
}
|
||||
}
|
||||
super.setText(t);
|
||||
clearUndos();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processKeyEvent(KeyEvent ke) {
|
||||
if (!isEditable()) {
|
||||
// disable Ctrl-E: delete line
|
||||
// and Ctrl-H: Search and replace
|
||||
if ((ke.getKeyCode() == KeyEvent.VK_E && ke.isControlDown())
|
||||
|| (ke.getKeyCode() == KeyEvent.VK_H && ke.isControlDown())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.processKeyEvent(ke);
|
||||
}
|
||||
|
||||
public void clearUndos() {
|
||||
Document doc = getDocument();
|
||||
if (doc instanceof SyntaxDocument) {
|
||||
SyntaxDocument sdoc = (SyntaxDocument) doc;
|
||||
sdoc.clearUndos();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.usages.InsideClassMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MethodMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TraitMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.gui.AppFrame;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.List;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UsageFrame extends AppFrame implements ActionListener, MouseListener {
|
||||
|
||||
static final String ACTION_GOTO = "GOTO";
|
||||
static final String ACTION_CANCEL = "CANCEL";
|
||||
|
||||
private final JButton gotoButton = new JButton(translate("button.goto"));
|
||||
private final JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
private final JList usageList;
|
||||
private final UsageListModel usageListModel;
|
||||
private final ABC abc;
|
||||
private final ABCPanel abcPanel;
|
||||
|
||||
public UsageFrame(List<ABCContainerTag> abcTags, ABC abc, int multinameIndex, ABCPanel abcPanel) {
|
||||
this.abcPanel = abcPanel;
|
||||
List<MultinameUsage> usages = abc.findMultinameUsage(multinameIndex);
|
||||
this.abc = abc;
|
||||
usageListModel = new UsageListModel(abcTags, abc);
|
||||
for (MultinameUsage u : usages) {
|
||||
usageListModel.addElement(u);
|
||||
}
|
||||
usageList = new JList<>(usageListModel);
|
||||
usageList.setBackground(Color.white);
|
||||
gotoButton.setActionCommand(ACTION_GOTO);
|
||||
gotoButton.addActionListener(this);
|
||||
cancelButton.setActionCommand(ACTION_CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
buttonsPanel.setLayout(new FlowLayout());
|
||||
buttonsPanel.add(gotoButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
|
||||
usageList.addMouseListener(this);
|
||||
Container cont = getContentPane();
|
||||
cont.setLayout(new BorderLayout());
|
||||
cont.add(new JScrollPane(usageList), BorderLayout.CENTER);
|
||||
cont.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
setSize(400, 300);
|
||||
setTitle(translate("dialog.title") + abc.constants.getMultiname(multinameIndex).getNameWithNamespace(abc.constants));
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
}
|
||||
|
||||
private void gotoUsage() {
|
||||
if (usageList.getSelectedIndex() != -1) {
|
||||
MultinameUsage usage = usageListModel.getUsage(usageList.getSelectedIndex());
|
||||
if (usage instanceof InsideClassMultinameUsage) {
|
||||
InsideClassMultinameUsage icu = (InsideClassMultinameUsage) usage;
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
if (usage instanceof TraitMultinameUsage) {
|
||||
TraitMultinameUsage tmu = (TraitMultinameUsage) usage;
|
||||
int traitIndex;
|
||||
if (tmu.parentTraitIndex > -1) {
|
||||
traitIndex = tmu.parentTraitIndex;
|
||||
} else {
|
||||
traitIndex = tmu.traitIndex;
|
||||
}
|
||||
if (!tmu.isStatic) {
|
||||
traitIndex += abc.class_info.get(tmu.classIndex).static_traits.traits.size();
|
||||
}
|
||||
if (tmu instanceof MethodMultinameUsage) {
|
||||
MethodMultinameUsage mmu = (MethodMultinameUsage) usage;
|
||||
if (mmu.isInitializer == true) {
|
||||
traitIndex = abc.class_info.get(mmu.classIndex).static_traits.traits.size() + abc.instance_info.get(mmu.classIndex).instance_traits.traits.size() + (mmu.isStatic ? 1 : 0);
|
||||
}
|
||||
}
|
||||
abcPanel.decompiledTextArea.gotoTrait(traitIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_GOTO:
|
||||
gotoUsage();
|
||||
setVisible(false);
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
gotoUsage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.DefaultListModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UsageListModel extends DefaultListModel<Object> {
|
||||
|
||||
private final ABC abc;
|
||||
private final List<ABCContainerTag> abcTags;
|
||||
|
||||
public UsageListModel(List<ABCContainerTag> abcTags, ABC abc) {
|
||||
this.abc = abc;
|
||||
this.abcTags = abcTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index) {
|
||||
try {
|
||||
return ((MultinameUsage) super.get(index)).toString(abcTags, abc);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(UsageListModel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
try {
|
||||
return ((MultinameUsage) super.getElementAt(index)).toString(abcTags, abc);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(UsageListModel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MultinameUsage getUsage(int index) {
|
||||
return ((MultinameUsage) super.getElementAt(index));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user