mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 04:50:46 +00:00
dumpview: allow opening multiple swfs, context menu: expand all and close menu items
show abc and actionbytes in dump view, hexview style fixes better scroll to view mode in hex editor
This commit is contained in:
@@ -27,7 +27,6 @@ import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -41,6 +40,8 @@ public class HexView extends JTable {
|
||||
private byte[] data;
|
||||
private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"};
|
||||
private final Color[] highlightColors;
|
||||
private Color bgColor = Color.decode("#F7F7F7");
|
||||
private Color bgColorAlternate = Color.decode("#EDEDED");
|
||||
|
||||
public class HighlightCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
@@ -48,9 +49,9 @@ public class HexView extends JTable {
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
|
||||
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
|
||||
if (highlightStarts != null) {
|
||||
int level = -1;
|
||||
if (col > 0 && highlightStarts != null) {
|
||||
int idx = row * bytesInRow + ((col > bytesInRow) ? (col - bytesInRow - 1) : (col - 1));
|
||||
int level = -1;
|
||||
for (int i = 0; i < highlightStarts.length; i++) {
|
||||
if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) {
|
||||
level++;
|
||||
@@ -58,12 +59,14 @@ public class HexView extends JTable {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (level > -1) {
|
||||
l.setBackground(highlightColors[level % highlightColors.length]);
|
||||
} else {
|
||||
l.setBackground(Color.white);
|
||||
}
|
||||
}
|
||||
|
||||
if (level > -1) {
|
||||
l.setBackground(highlightColors[level % highlightColors.length]);
|
||||
} else {
|
||||
l.setBackground(row % 2 == 0 ? bgColor : bgColorAlternate);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
||||
@@ -131,17 +134,20 @@ public class HexView extends JTable {
|
||||
|
||||
setShowHorizontalLines(false);
|
||||
setShowVerticalLines(false);
|
||||
setRowSelectionAllowed(false);
|
||||
setColumnSelectionAllowed(false);
|
||||
|
||||
HighlightCellRenderer cellRenderer = new HighlightCellRenderer();
|
||||
TableColumnModel columnModel = getColumnModel();
|
||||
columnModel.getColumn(0).setMaxWidth(80);
|
||||
TableColumn column = columnModel.getColumn(0);
|
||||
column.setMaxWidth(80);
|
||||
//column.setCellRenderer(cellRenderer);
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
TableColumn column = columnModel.getColumn(i + 1);
|
||||
column = columnModel.getColumn(i + 1);
|
||||
column.setMaxWidth(25);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
TableColumn column = columnModel.getColumn(i + bytesInRow + 1);
|
||||
column = columnModel.getColumn(i + bytesInRow + 1);
|
||||
column.setMaxWidth(10);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
@@ -163,24 +169,18 @@ public class HexView extends JTable {
|
||||
}
|
||||
|
||||
public void scrollToByte(long byteNum) {
|
||||
// HACK to scroll current selection to visible
|
||||
int row = (int) (byteNum / bytesInRow);
|
||||
|
||||
final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight());
|
||||
|
||||
int byteCount = data.length;
|
||||
int rowCount = byteCount / bytesInRow;
|
||||
if (byteCount % bytesInRow != 0) {
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
int row2 = Math.min(row + pageSize - 2, rowCount - 1);
|
||||
getSelectionModel().setSelectionInterval(row2, row2);
|
||||
scrollRectToVisible(new Rectangle(getCellRect(row2, 0, true)));
|
||||
|
||||
//final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight());
|
||||
getSelectionModel().setSelectionInterval(row, row);
|
||||
scrollRectToVisible(new Rectangle(getCellRect(row, 0, true)));
|
||||
// END HACK
|
||||
}
|
||||
|
||||
public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) {
|
||||
for (int i = 0; i < byteNumStarts.length; i++) {
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
scrollToByte(byteNumEnds[i]);
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,12 +357,14 @@ public class MainFrameClassicMenu implements MainFrameMenu, ActionListener {
|
||||
deobfuscationCommandButton.setEnabled(hasAbc);*/
|
||||
}
|
||||
|
||||
private void saveAs(SWF swf, SaveFileMode mode) {
|
||||
private boolean 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);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -481,17 +483,19 @@ public class MainFrameClassicMenu implements MainFrameMenu, ActionListener {
|
||||
case ACTION_SAVE: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
SWFNode snode = ((TagTreeModel) mainFrame.panel.tagTree.getModel()).getSwfNode(swf);
|
||||
boolean saved = false;
|
||||
if (snode.binaryData != null) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
swf.saveTo(baos);
|
||||
snode.binaryData.binaryData = baos.toByteArray();
|
||||
snode.binaryData.setModified(true);
|
||||
saved = 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);
|
||||
saved = saveAs(swf, SaveFileMode.SAVEAS);
|
||||
} else {
|
||||
try {
|
||||
Main.saveFile(swf, swf.file);
|
||||
@@ -500,13 +504,16 @@ public class MainFrameClassicMenu implements MainFrameMenu, ActionListener {
|
||||
View.showMessageDialog(null, translate("error.file.save"), translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
swf.clearModified();
|
||||
if (saved) {
|
||||
swf.clearModified();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
swf.clearModified();
|
||||
if (saveAs(swf, SaveFileMode.SAVEAS)) {
|
||||
swf.clearModified();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS_EXE: {
|
||||
|
||||
@@ -538,12 +538,14 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
deobfuscationCommandButton.setEnabled(hasAbc);
|
||||
}
|
||||
|
||||
private void saveAs(SWF swf, SaveFileMode mode) {
|
||||
private boolean 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);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -672,32 +674,38 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
case ACTION_SAVE: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
SWFNode snode = ((TagTreeModel) mainFrame.panel.tagTree.getModel()).getSwfNode(swf);
|
||||
boolean saved = false;
|
||||
if (snode.binaryData != null) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
swf.saveTo(baos);
|
||||
snode.binaryData.binaryData = baos.toByteArray();
|
||||
snode.binaryData.setModified(true);
|
||||
saved = 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);
|
||||
saved = saveAs(swf, SaveFileMode.SAVEAS);
|
||||
} else {
|
||||
try {
|
||||
Main.saveFile(swf, swf.file);
|
||||
saved = true;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
swf.clearModified();
|
||||
if (saved) {
|
||||
swf.clearModified();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS: {
|
||||
SWF swf = mainFrame.panel.getCurrentSwf();
|
||||
saveAs(swf, SaveFileMode.SAVEAS);
|
||||
swf.clearModified();
|
||||
if (saveAs(swf, SaveFileMode.SAVEAS)) {
|
||||
swf.clearModified();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SAVE_AS_EXE: {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode;
|
||||
import com.jpexs.decompiler.flash.exporters.BinaryDataExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.FontExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.ImageExporter;
|
||||
@@ -59,6 +60,9 @@ import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog;
|
||||
import com.jpexs.decompiler.flash.gui.abc.treenodes.TreeElement;
|
||||
import com.jpexs.decompiler.flash.gui.action.ActionPanel;
|
||||
import com.jpexs.decompiler.flash.gui.dumpview.DumpTree;
|
||||
import com.jpexs.decompiler.flash.gui.dumpview.DumpTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.dumpview.DumpViewPanel;
|
||||
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.timeline.TimelineFrame;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode;
|
||||
@@ -96,7 +100,6 @@ import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.Container;
|
||||
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
|
||||
@@ -182,17 +185,13 @@ import javax.swing.JColorChooser;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
@@ -204,7 +203,6 @@ import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -247,6 +245,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
private final PreviewPanel previewPanel;
|
||||
private DumpViewPanel dumpViewPanel;
|
||||
private final JPanel treePanel;
|
||||
private TreePanelMode treePanelMode;
|
||||
private AbortRetryIgnoreHandler errorHandler = new GuiAbortRetryIgnoreHandler();
|
||||
private CancellableWorker setSourceWorker;
|
||||
public TreeNode oldNode;
|
||||
@@ -255,12 +254,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
|
||||
public static final String ACTION_SELECT_BKCOLOR = "SELECTCOLOR";
|
||||
public static final String ACTION_REPLACE = "REPLACE";
|
||||
private static final String ACTION_RAW_EDIT = "RAWEDIT";
|
||||
private static final String ACTION_JUMP_TO_CHARACTER = "JUMPTOCHARACTER";
|
||||
private static final String ACTION_REMOVE_ITEM = "REMOVEITEM";
|
||||
private static final String ACTION_REMOVE_ITEM_WITH_DEPENDENCIES = "REMOVEITEMWITHDEPENDENCIES";
|
||||
private static final String ACTION_CLOSE_SWF = "CLOSESWF";
|
||||
private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE";
|
||||
|
||||
// play morph shape in 2 second(s)
|
||||
public static final int MORPH_SHAPE_ANIMATION_LENGTH = 2;
|
||||
@@ -311,146 +304,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
statusPanel.setWorkStatus(s, worker);
|
||||
}
|
||||
|
||||
private void createContextMenu() {
|
||||
final JPopupMenu contextPopupMenu = new JPopupMenu();
|
||||
|
||||
final JMenuItem expandRecursiveMenuItem = new JMenuItem(translate("contextmenu.expandAll"));
|
||||
expandRecursiveMenuItem.addActionListener(this);
|
||||
expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE);
|
||||
contextPopupMenu.add(expandRecursiveMenuItem);
|
||||
|
||||
final JMenuItem removeMenuItem = new JMenuItem(translate("contextmenu.remove"));
|
||||
removeMenuItem.addActionListener(this);
|
||||
removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM);
|
||||
contextPopupMenu.add(removeMenuItem);
|
||||
|
||||
final JMenuItem removeWithDependenciesMenuItem = new JMenuItem(translate("contextmenu.removeWithDependencies"));
|
||||
removeWithDependenciesMenuItem.addActionListener(this);
|
||||
removeWithDependenciesMenuItem.setActionCommand(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES);
|
||||
contextPopupMenu.add(removeWithDependenciesMenuItem);
|
||||
|
||||
final JMenuItem exportSelectionMenuItem = new JMenuItem(translate("menu.file.export.selection"));
|
||||
exportSelectionMenuItem.setActionCommand(MainFrameRibbonMenu.ACTION_EXPORT_SEL);
|
||||
exportSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(exportSelectionMenuItem);
|
||||
|
||||
final JMenuItem replaceSelectionMenuItem = new JMenuItem(translate("button.replace"));
|
||||
replaceSelectionMenuItem.setActionCommand(ACTION_REPLACE);
|
||||
replaceSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(replaceSelectionMenuItem);
|
||||
|
||||
final JMenuItem rawEditMenuItem = new JMenuItem(translate("contextmenu.rawEdit"));
|
||||
rawEditMenuItem.setActionCommand(ACTION_RAW_EDIT);
|
||||
rawEditMenuItem.addActionListener(this);
|
||||
rawEditMenuItem.setVisible(false);
|
||||
contextPopupMenu.add(rawEditMenuItem);
|
||||
|
||||
final JMenuItem jumpToCharacterMenuItem = new JMenuItem(translate("contextmenu.jumpToCharacter"));
|
||||
jumpToCharacterMenuItem.setActionCommand(ACTION_JUMP_TO_CHARACTER);
|
||||
jumpToCharacterMenuItem.addActionListener(this);
|
||||
jumpToCharacterMenuItem.setVisible(false);
|
||||
contextPopupMenu.add(jumpToCharacterMenuItem);
|
||||
|
||||
final JMenuItem closeSelectionMenuItem = new JMenuItem(translate("contextmenu.closeSwf"));
|
||||
closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF);
|
||||
closeSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(closeSelectionMenuItem);
|
||||
|
||||
final JMenu moveTagMenu = new JMenu(translate("contextmenu.moveTag"));
|
||||
contextPopupMenu.add(moveTagMenu);
|
||||
|
||||
tagTree.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
|
||||
int row = tagTree.getClosestRowForLocation(e.getX(), e.getY());
|
||||
int[] selectionRows = tagTree.getSelectionRows();
|
||||
if (!Helper.contains(selectionRows, row)) {
|
||||
tagTree.setSelectionRow(row);
|
||||
}
|
||||
|
||||
TreePath[] paths = tagTree.getSelectionPaths();
|
||||
if (paths == null || paths.length == 0) {
|
||||
return;
|
||||
}
|
||||
boolean allSelectedIsTagOrFrame = true;
|
||||
for (TreePath treePath : paths) {
|
||||
TreeNode treeNode = (TreeNode) treePath.getLastPathComponent();
|
||||
|
||||
TreeItem tag = treeNode.getItem();
|
||||
if (!(tag instanceof Tag) && !(tag instanceof FrameNodeItem)) {
|
||||
allSelectedIsTagOrFrame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
replaceSelectionMenuItem.setVisible(false);
|
||||
closeSelectionMenuItem.setVisible(false);
|
||||
moveTagMenu.setVisible(false);
|
||||
expandRecursiveMenuItem.setVisible(false);
|
||||
|
||||
if (paths.length == 1) {
|
||||
TreeNode treeNode = (TreeNode) paths[0].getLastPathComponent();
|
||||
|
||||
TreeItem item = ((TreeNode) treeNode).getItem();
|
||||
|
||||
if (item instanceof ImageTag && ((ImageTag) item).importSupported()) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof DefineBinaryDataTag) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof DefineSoundTag) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (treeNode instanceof SWFNode) {
|
||||
closeSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof Tag && swfs.size() > 1) {
|
||||
final Tag tag = (Tag) item;
|
||||
moveTagMenu.removeAll();
|
||||
for (SWFList targetSwfList : swfs) {
|
||||
for (final SWF targetSwf : targetSwfList) {
|
||||
if (targetSwf != tag.getSwf()) {
|
||||
JMenuItem swfItem = new JMenuItem(targetSwf.getShortFileName());
|
||||
swfItem.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
tag.getSwf().tags.remove(tag);
|
||||
tag.setSwf(targetSwf);
|
||||
targetSwf.tags.add(tag);
|
||||
refreshTree();
|
||||
}
|
||||
});
|
||||
moveTagMenu.add(swfItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
moveTagMenu.setVisible(true);
|
||||
}
|
||||
|
||||
TreeModel model = tagTree.getModel();
|
||||
expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0);
|
||||
|
||||
jumpToCharacterMenuItem.setVisible(item instanceof CharacterIdTag && !(item instanceof CharacterTag));
|
||||
|
||||
rawEditMenuItem.setVisible(item instanceof Tag);
|
||||
}
|
||||
|
||||
removeMenuItem.setVisible(allSelectedIsTagOrFrame);
|
||||
exportSelectionMenuItem.setEnabled(hasExportableNodes());
|
||||
contextPopupMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JPanel createWelcomePanel() {
|
||||
JPanel welcomePanel = new JPanel();
|
||||
welcomePanel.setLayout(new BoxLayout(welcomePanel, BoxLayout.Y_AXIS));
|
||||
@@ -530,7 +383,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
cl2.show(detailPanel, DETAILCARDEMPTYPANEL);
|
||||
|
||||
UIManager.getDefaults().put("TreeUI", BasicTreeUI.class.getName());
|
||||
tagTree = new TagTree((TagTreeModel) null);
|
||||
tagTree = new TagTree((TagTreeModel) null, this);
|
||||
tagTree.addTreeSelectionListener(this);
|
||||
|
||||
DragSource dragSource = DragSource.getDefaultDragSource();
|
||||
@@ -612,10 +465,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
});
|
||||
|
||||
createContextMenu();
|
||||
tagTree.createContextMenu(swfs);
|
||||
|
||||
dumpTree = new DumpTree((DumpTreeModel) null);
|
||||
dumpTree = new DumpTree((DumpTreeModel) null, this);
|
||||
dumpTree.addTreeSelectionListener(this);
|
||||
dumpTree.createContextMenu();
|
||||
|
||||
statusPanel = new MainFrameStatusPanel(this);
|
||||
add(statusPanel, BorderLayout.SOUTH);
|
||||
@@ -1034,19 +888,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
|
||||
public List<TagNode> getSelectedNodes() {
|
||||
List<TagNode> ret = new ArrayList<>();
|
||||
TreePath[] tps = tagTree.getSelectionPaths();
|
||||
if (tps == null) {
|
||||
return ret;
|
||||
}
|
||||
for (TreePath tp : tps) {
|
||||
TagNode te = (TagNode) tp.getLastPathComponent();
|
||||
ret.add(te);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void renameIdentifier(SWF swf, String identifier) throws InterruptedException {
|
||||
String oldName = identifier;
|
||||
String newName = View.showInputDialog(translate("rename.enternew"), oldName);
|
||||
@@ -1094,48 +935,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
|
||||
public List<TreeNode> getSelected(JTree tree) {
|
||||
TreeSelectionModel tsm = tree.getSelectionModel();
|
||||
TreePath[] tps = tsm.getSelectionPaths();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
if (tps == null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (TreePath tp : tps) {
|
||||
TreeNode treeNode = (TreeNode) tp.getLastPathComponent();
|
||||
ret.add(treeNode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TreeNode> getAllSubs(JTree tree, TreeNode o) {
|
||||
TagTreeModel tm = (TagTreeModel) tree.getModel();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
for (int i = 0; i < tm.getChildCount(o); i++) {
|
||||
TreeNode c = tm.getChild(o, i);
|
||||
ret.add(c);
|
||||
ret.addAll(getAllSubs(tree, c));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TreeNode> getAllSelected(TagTree tree) {
|
||||
TreeSelectionModel tsm = tree.getSelectionModel();
|
||||
TreePath[] tps = tsm.getSelectionPaths();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
if (tps == null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (TreePath tp : tps) {
|
||||
TreeNode treeNode = (TreeNode) tp.getLastPathComponent();
|
||||
ret.add(treeNode);
|
||||
ret.addAll(getAllSubs(tree, treeNode));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TreeNode> getASTreeNodes(TagTree tree) {
|
||||
List<TreeNode> result = new ArrayList<>();
|
||||
TagTreeModel tm = (TagTreeModel) tree.getModel();
|
||||
@@ -1165,68 +964,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
private SearchDialog searchDialog;
|
||||
|
||||
public boolean hasExportableNodes() {
|
||||
return !getSelection(getCurrentSwf()).isEmpty();
|
||||
}
|
||||
|
||||
private List<Object> getSelection(SWF swf) {
|
||||
List<Object> ret = new ArrayList<>();
|
||||
List<TreeNode> sel = getAllSelected(tagTree);
|
||||
for (TreeNode d : sel) {
|
||||
if (d.getItem().getSwf() != swf) {
|
||||
continue;
|
||||
}
|
||||
if (d instanceof ContainerNode) {
|
||||
ContainerNode n = (ContainerNode) d;
|
||||
TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem());
|
||||
if (nodeType == TreeNodeType.IMAGE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.SHAPE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.MORPH_SHAPE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.AS) {
|
||||
ret.add(n);
|
||||
}
|
||||
if (nodeType == TreeNodeType.MOVIE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.SOUND) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.BINARY_DATA) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.TEXT) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.FONT) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
}
|
||||
if (d instanceof FrameNode) {
|
||||
FrameNode fn = (FrameNode) d;
|
||||
if (!fn.scriptsNode) {
|
||||
ret.add(d.getItem());
|
||||
}
|
||||
}
|
||||
if (d instanceof TreeElement) {
|
||||
if (((TreeElement) d).isLeaf()) {
|
||||
TreeElement treeElement = (TreeElement) d;
|
||||
ret.add((ScriptPack) treeElement.getItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<File> exportSelection(AbortRetryIgnoreHandler handler, String selFile, ExportDialog export) throws IOException {
|
||||
|
||||
List<File> ret = new ArrayList<>();
|
||||
List<TreeNode> sel = getAllSelected(tagTree);
|
||||
List<TreeNode> sel = tagTree.getAllSelected(tagTree);
|
||||
|
||||
for (SWFList swfList : swfs) {
|
||||
for (SWF swf : swfList) {
|
||||
@@ -1371,16 +1112,24 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
return null;
|
||||
}
|
||||
|
||||
TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent();
|
||||
if (treeNode == null) {
|
||||
return swfs.get(0).get(0);
|
||||
}
|
||||
if (treePanelMode == TreePanelMode.TAG_TREE) {
|
||||
TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent();
|
||||
if (treeNode == null) {
|
||||
return swfs.get(0).get(0);
|
||||
}
|
||||
|
||||
if (treeNode instanceof SWFBundleNode) {
|
||||
return null;
|
||||
}
|
||||
if (treeNode instanceof SWFBundleNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return treeNode.getItem().getSwf();
|
||||
return treeNode.getItem().getSwf();
|
||||
} else if (treePanelMode == TreePanelMode.DUMP_TREE) {
|
||||
DumpInfo dumpInfo = (DumpInfo) dumpTree.getLastSelectedPathComponent();
|
||||
|
||||
return DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
@@ -1849,7 +1598,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
public void export(final boolean onlySel) {
|
||||
|
||||
final SWF swf = getCurrentSwf();
|
||||
List<Object> sel = getSelection(swf);
|
||||
List<Object> sel = tagTree.getSelection(swf);
|
||||
if (!onlySel) {
|
||||
sel = null;
|
||||
} else {
|
||||
@@ -2085,6 +1834,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
showCard(CARDEMPTYPANEL);
|
||||
TreeItem treeItem = tagTree.getCurrentTreeItem();
|
||||
View.refreshTree(tagTree, new TagTreeModel(mainFrame, swfs));
|
||||
View.refreshTree(dumpTree, new DumpTreeModel(swfs));
|
||||
if (treeItem != null) {
|
||||
setTreeItem(treeItem);
|
||||
}
|
||||
@@ -2238,7 +1988,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
try {
|
||||
SWF swf = it.getSwf();
|
||||
if (it instanceof DefineBitsTag) {
|
||||
DefineBitsJPEG2Tag jpeg2Tag = new DefineBitsJPEG2Tag(swf, it.getPos(), it.getOriginalLength(), it.getCharacterId(), data);
|
||||
DefineBitsJPEG2Tag jpeg2Tag = new DefineBitsJPEG2Tag(swf, it.getOriginalRange(), it.getCharacterId(), data);
|
||||
jpeg2Tag.setModified(true);
|
||||
swf.tags.set(swf.tags.indexOf(it), jpeg2Tag);
|
||||
swf.updateCharacters();
|
||||
@@ -2274,74 +2024,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_RAW_EDIT: {
|
||||
TreeItem item = tagTree.getCurrentTreeItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
previewPanel.showGenericTagPanel((Tag) item);
|
||||
}
|
||||
break;
|
||||
case ACTION_JUMP_TO_CHARACTER: {
|
||||
TreeItem item = tagTree.getCurrentTreeItem();
|
||||
if (item == null || !(item instanceof CharacterIdTag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterIdTag characterIdTag = (CharacterIdTag) item;
|
||||
setTreeItem(item.getSwf().characters.get(characterIdTag.getCharacterId()));
|
||||
}
|
||||
break;
|
||||
case ACTION_EXPAND_RECURSIVE: {
|
||||
TreePath path = tagTree.getSelectionPath();
|
||||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
View.expandTreeNodesRecursive(tagTree, path, true);
|
||||
}
|
||||
break;
|
||||
case ACTION_REMOVE_ITEM:
|
||||
case ACTION_REMOVE_ITEM_WITH_DEPENDENCIES:
|
||||
List<TreeNode> sel = getSelected(tagTree);
|
||||
|
||||
List<Tag> tagsToRemove = new ArrayList<>();
|
||||
for (TreeNode o : sel) {
|
||||
TreeItem tag = o.getItem();
|
||||
if (tag instanceof Tag) {
|
||||
tagsToRemove.add((Tag) tag);
|
||||
} else if (tag instanceof FrameNodeItem) {
|
||||
FrameNodeItem frameNode = (FrameNodeItem) tag;
|
||||
Frame frame = frameNode.getParent().getTimeline().frames.get(frameNode.getFrame() - 1);
|
||||
if (frame.showFrameTag != null) {
|
||||
tagsToRemove.add(frame.showFrameTag);
|
||||
} else {
|
||||
// this should be the last frame, so remove the inner tags
|
||||
tagsToRemove.addAll(frame.innerTags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean removeDependencies = e.getActionCommand().equals(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES);
|
||||
if (tagsToRemove.size() == 1) {
|
||||
Tag tag = tagsToRemove.get(0);
|
||||
if (View.showConfirmDialog(this, translate("message.confirm.remove").replace("%item%", tag.toString()), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
tag.getSwf().removeTag(tag, removeDependencies);
|
||||
refreshTree();
|
||||
}
|
||||
} else if (tagsToRemove.size() > 1) {
|
||||
if (View.showConfirmDialog(this, translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
for (Tag tag : tagsToRemove) {
|
||||
tag.getSwf().removeTag(tag, removeDependencies);
|
||||
}
|
||||
refreshTree();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_CLOSE_SWF: {
|
||||
Main.closeFile(getCurrentSwfList());
|
||||
}
|
||||
}
|
||||
if (Main.isWorking()) {
|
||||
return;
|
||||
@@ -2382,8 +2064,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
private void dumpTreeValueChanged(TreeSelectionEvent e) {
|
||||
DumpInfo dumpInfo = (DumpInfo) e.getPath().getLastPathComponent();
|
||||
|
||||
// todo honfika: support multiple swf
|
||||
dumpViewPanel.setData(swfs.get(0).swfs.get(0).uncompressedData, dumpInfo);
|
||||
|
||||
dumpViewPanel.setData(DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().uncompressedData, dumpInfo);
|
||||
dumpViewPanel.revalidate();
|
||||
showCard(CARDDUMPVIEW);
|
||||
}
|
||||
@@ -2438,8 +2120,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
treePanel.removeAll();
|
||||
if (show) {
|
||||
treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER);
|
||||
treePanelMode = TreePanelMode.DUMP_TREE;
|
||||
} else {
|
||||
treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER);
|
||||
treePanelMode = TreePanelMode.TAG_TREE;
|
||||
}
|
||||
treePanel.revalidate();
|
||||
}
|
||||
@@ -2619,13 +2303,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
previewPanel.setParametersPanelVisible(false);
|
||||
}
|
||||
} else if (tagObj instanceof Tag) {
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
previewPanel.showGenericTagPanel((Tag) tagObj);
|
||||
showGenericTag((Tag) tagObj);
|
||||
} else {
|
||||
showCard(CARDEMPTYPANEL);
|
||||
}
|
||||
}
|
||||
|
||||
public void showGenericTag(Tag tag) {
|
||||
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
previewPanel.showGenericTagPanel(tag);
|
||||
}
|
||||
|
||||
private void showFontTag(FontTag ft) {
|
||||
|
||||
previewPanel.showFontPanel(ft);
|
||||
|
||||
@@ -683,8 +683,8 @@ public class PreviewPanel extends JSplitPane implements ActionListener {
|
||||
List<Action> actions;
|
||||
DoActionTag doa;
|
||||
|
||||
doa = new DoActionTag(swf, 0, 0);
|
||||
actions = ASMParser.parse(0, 0, false,
|
||||
doa = new DoActionTag(swf, null);
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\"\n"
|
||||
+ "Push \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
@@ -703,7 +703,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener {
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, 0, false,
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n"
|
||||
+ "StopSounds\n"
|
||||
+ "Push \"_root\"\n"
|
||||
@@ -730,7 +730,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener {
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, 0, false,
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"onSoundComplete\" \"start\" \"execParam\"\n"
|
||||
+ "StopSounds\n"
|
||||
+ "Push \"_root\"\n"
|
||||
@@ -774,7 +774,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener {
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, 0, false,
|
||||
actions = ASMParser.parse(0, false,
|
||||
"StopSounds\n"
|
||||
+ "Stop", swf.version, false);
|
||||
doa.setActions(actions);
|
||||
|
||||
@@ -1,304 +1,614 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.abc.treenodes.TreeElement;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFNode;
|
||||
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.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
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.ContainerNode;
|
||||
import com.jpexs.decompiler.flash.treenodes.FrameNode;
|
||||
import com.jpexs.decompiler.flash.treenodes.TreeNode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
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.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TagTree extends JTree implements ActionListener {
|
||||
|
||||
private static final String ACTION_RAW_EDIT = "RAWEDIT";
|
||||
private static final String ACTION_JUMP_TO_CHARACTER = "JUMPTOCHARACTER";
|
||||
private static final String ACTION_REMOVE_ITEM = "REMOVEITEM";
|
||||
private static final String ACTION_REMOVE_ITEM_WITH_DEPENDENCIES = "REMOVEITEMWITHDEPENDENCIES";
|
||||
private static final String ACTION_CLOSE_SWF = "CLOSESWF";
|
||||
private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE";
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
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, MainPanel mainPanel) {
|
||||
super(treeModel);
|
||||
this.mainPanel = mainPanel;
|
||||
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;
|
||||
}
|
||||
|
||||
return TreeNodeType.FOLDER;
|
||||
}
|
||||
|
||||
public void createContextMenu(final List<SWFList> swfs) {
|
||||
final JPopupMenu contextPopupMenu = new JPopupMenu();
|
||||
|
||||
final JMenuItem expandRecursiveMenuItem = new JMenuItem(mainPanel.translate("contextmenu.expandAll"));
|
||||
expandRecursiveMenuItem.addActionListener(this);
|
||||
expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE);
|
||||
contextPopupMenu.add(expandRecursiveMenuItem);
|
||||
|
||||
final JMenuItem removeMenuItem = new JMenuItem(mainPanel.translate("contextmenu.remove"));
|
||||
removeMenuItem.addActionListener(this);
|
||||
removeMenuItem.setActionCommand(ACTION_REMOVE_ITEM);
|
||||
contextPopupMenu.add(removeMenuItem);
|
||||
|
||||
final JMenuItem removeWithDependenciesMenuItem = new JMenuItem(mainPanel.translate("contextmenu.removeWithDependencies"));
|
||||
removeWithDependenciesMenuItem.addActionListener(this);
|
||||
removeWithDependenciesMenuItem.setActionCommand(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES);
|
||||
contextPopupMenu.add(removeWithDependenciesMenuItem);
|
||||
|
||||
final JMenuItem exportSelectionMenuItem = new JMenuItem(mainPanel.translate("menu.file.export.selection"));
|
||||
exportSelectionMenuItem.setActionCommand(MainFrameRibbonMenu.ACTION_EXPORT_SEL);
|
||||
exportSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(exportSelectionMenuItem);
|
||||
|
||||
final JMenuItem replaceSelectionMenuItem = new JMenuItem(mainPanel.translate("button.replace"));
|
||||
replaceSelectionMenuItem.setActionCommand(MainPanel.ACTION_REPLACE);
|
||||
replaceSelectionMenuItem.addActionListener(mainPanel);
|
||||
contextPopupMenu.add(replaceSelectionMenuItem);
|
||||
|
||||
final JMenuItem rawEditMenuItem = new JMenuItem(mainPanel.translate("contextmenu.rawEdit"));
|
||||
rawEditMenuItem.setActionCommand(ACTION_RAW_EDIT);
|
||||
rawEditMenuItem.addActionListener(this);
|
||||
rawEditMenuItem.setVisible(false);
|
||||
contextPopupMenu.add(rawEditMenuItem);
|
||||
|
||||
final JMenuItem jumpToCharacterMenuItem = new JMenuItem(mainPanel.translate("contextmenu.jumpToCharacter"));
|
||||
jumpToCharacterMenuItem.setActionCommand(ACTION_JUMP_TO_CHARACTER);
|
||||
jumpToCharacterMenuItem.addActionListener(this);
|
||||
jumpToCharacterMenuItem.setVisible(false);
|
||||
contextPopupMenu.add(jumpToCharacterMenuItem);
|
||||
|
||||
final JMenuItem closeSelectionMenuItem = new JMenuItem(mainPanel.translate("contextmenu.closeSwf"));
|
||||
closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF);
|
||||
closeSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(closeSelectionMenuItem);
|
||||
|
||||
final JMenu moveTagMenu = new JMenu(mainPanel.translate("contextmenu.moveTag"));
|
||||
contextPopupMenu.add(moveTagMenu);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
|
||||
int row = getClosestRowForLocation(e.getX(), e.getY());
|
||||
int[] selectionRows = getSelectionRows();
|
||||
if (!Helper.contains(selectionRows, row)) {
|
||||
setSelectionRow(row);
|
||||
}
|
||||
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
if (paths == null || paths.length == 0) {
|
||||
return;
|
||||
}
|
||||
boolean allSelectedIsTagOrFrame = true;
|
||||
for (TreePath treePath : paths) {
|
||||
TreeNode treeNode = (TreeNode) treePath.getLastPathComponent();
|
||||
|
||||
TreeItem tag = treeNode.getItem();
|
||||
if (!(tag instanceof Tag) && !(tag instanceof FrameNodeItem)) {
|
||||
allSelectedIsTagOrFrame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
replaceSelectionMenuItem.setVisible(false);
|
||||
closeSelectionMenuItem.setVisible(false);
|
||||
moveTagMenu.setVisible(false);
|
||||
expandRecursiveMenuItem.setVisible(false);
|
||||
|
||||
if (paths.length == 1) {
|
||||
TreeNode treeNode = (TreeNode) paths[0].getLastPathComponent();
|
||||
|
||||
TreeItem item = ((TreeNode) treeNode).getItem();
|
||||
|
||||
if (item instanceof ImageTag && ((ImageTag) item).importSupported()) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof DefineBinaryDataTag) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof DefineSoundTag) {
|
||||
replaceSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (treeNode instanceof SWFNode) {
|
||||
closeSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (item instanceof Tag && swfs.size() > 1) {
|
||||
final Tag tag = (Tag) item;
|
||||
moveTagMenu.removeAll();
|
||||
for (SWFList targetSwfList : swfs) {
|
||||
for (final SWF targetSwf : targetSwfList) {
|
||||
if (targetSwf != tag.getSwf()) {
|
||||
JMenuItem swfItem = new JMenuItem(targetSwf.getShortFileName());
|
||||
swfItem.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
tag.getSwf().tags.remove(tag);
|
||||
tag.setSwf(targetSwf);
|
||||
targetSwf.tags.add(tag);
|
||||
mainPanel.refreshTree();
|
||||
}
|
||||
});
|
||||
moveTagMenu.add(swfItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
moveTagMenu.setVisible(true);
|
||||
}
|
||||
|
||||
TreeModel model = getModel();
|
||||
expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0);
|
||||
|
||||
jumpToCharacterMenuItem.setVisible(item instanceof CharacterIdTag && !(item instanceof CharacterTag));
|
||||
|
||||
rawEditMenuItem.setVisible(item instanceof Tag);
|
||||
}
|
||||
|
||||
removeMenuItem.setVisible(allSelectedIsTagOrFrame);
|
||||
exportSelectionMenuItem.setEnabled(hasExportableNodes());
|
||||
contextPopupMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_RAW_EDIT: {
|
||||
TreeItem item = getCurrentTreeItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mainPanel.showGenericTag((Tag) item);
|
||||
}
|
||||
break;
|
||||
case ACTION_JUMP_TO_CHARACTER: {
|
||||
TreeItem item = getCurrentTreeItem();
|
||||
if (item == null || !(item instanceof CharacterIdTag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterIdTag characterIdTag = (CharacterIdTag) item;
|
||||
mainPanel.setTreeItem(item.getSwf().characters.get(characterIdTag.getCharacterId()));
|
||||
}
|
||||
break;
|
||||
case ACTION_EXPAND_RECURSIVE: {
|
||||
TreePath path = getSelectionPath();
|
||||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
View.expandTreeNodesRecursive(this, path, true);
|
||||
}
|
||||
break;
|
||||
case ACTION_REMOVE_ITEM:
|
||||
case ACTION_REMOVE_ITEM_WITH_DEPENDENCIES:
|
||||
List<TreeNode> sel = getSelected(this);
|
||||
|
||||
List<Tag> tagsToRemove = new ArrayList<>();
|
||||
for (TreeNode o : sel) {
|
||||
TreeItem tag = o.getItem();
|
||||
if (tag instanceof Tag) {
|
||||
tagsToRemove.add((Tag) tag);
|
||||
} else if (tag instanceof FrameNodeItem) {
|
||||
FrameNodeItem frameNode = (FrameNodeItem) tag;
|
||||
Frame frame = frameNode.getParent().getTimeline().frames.get(frameNode.getFrame() - 1);
|
||||
if (frame.showFrameTag != null) {
|
||||
tagsToRemove.add(frame.showFrameTag);
|
||||
} else {
|
||||
// this should be the last frame, so remove the inner tags
|
||||
tagsToRemove.addAll(frame.innerTags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean removeDependencies = e.getActionCommand().equals(ACTION_REMOVE_ITEM_WITH_DEPENDENCIES);
|
||||
if (tagsToRemove.size() == 1) {
|
||||
Tag tag = tagsToRemove.get(0);
|
||||
if (View.showConfirmDialog(this, mainPanel.translate("message.confirm.remove").replace("%item%", tag.toString()), mainPanel.translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
tag.getSwf().removeTag(tag, removeDependencies);
|
||||
mainPanel.refreshTree();
|
||||
}
|
||||
} else if (tagsToRemove.size() > 1) {
|
||||
if (View.showConfirmDialog(this, mainPanel.translate("message.confirm.removemultiple").replace("%count%", Integer.toString(tagsToRemove.size())), mainPanel.translate("message.confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
for (Tag tag : tagsToRemove) {
|
||||
tag.getSwf().removeTag(tag, removeDependencies);
|
||||
}
|
||||
mainPanel.refreshTree();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_CLOSE_SWF: {
|
||||
Main.closeFile(mainPanel.getCurrentSwfList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasExportableNodes() {
|
||||
return !getSelection(mainPanel.getCurrentSwf()).isEmpty();
|
||||
}
|
||||
|
||||
public List<TreeNode> getAllSubs(JTree tree, TreeNode o) {
|
||||
TagTreeModel tm = (TagTreeModel) tree.getModel();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
for (int i = 0; i < tm.getChildCount(o); i++) {
|
||||
TreeNode c = tm.getChild(o, i);
|
||||
ret.add(c);
|
||||
ret.addAll(getAllSubs(tree, c));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TreeNode> getAllSelected(TagTree tree) {
|
||||
TreeSelectionModel tsm = tree.getSelectionModel();
|
||||
TreePath[] tps = tsm.getSelectionPaths();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
if (tps == null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (TreePath tp : tps) {
|
||||
TreeNode treeNode = (TreeNode) tp.getLastPathComponent();
|
||||
ret.add(treeNode);
|
||||
ret.addAll(getAllSubs(tree, treeNode));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TreeNode> getSelected(JTree tree) {
|
||||
TreeSelectionModel tsm = tree.getSelectionModel();
|
||||
TreePath[] tps = tsm.getSelectionPaths();
|
||||
List<TreeNode> ret = new ArrayList<>();
|
||||
if (tps == null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (TreePath tp : tps) {
|
||||
TreeNode treeNode = (TreeNode) tp.getLastPathComponent();
|
||||
ret.add(treeNode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Object> getSelection(SWF swf) {
|
||||
List<Object> ret = new ArrayList<>();
|
||||
List<TreeNode> sel = getAllSelected(this);
|
||||
for (TreeNode d : sel) {
|
||||
if (d.getItem().getSwf() != swf) {
|
||||
continue;
|
||||
}
|
||||
if (d instanceof ContainerNode) {
|
||||
ContainerNode n = (ContainerNode) d;
|
||||
TreeNodeType nodeType = TagTree.getTreeNodeType(n.getItem());
|
||||
if (nodeType == TreeNodeType.IMAGE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.SHAPE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.MORPH_SHAPE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.AS) {
|
||||
ret.add(n);
|
||||
}
|
||||
if (nodeType == TreeNodeType.MOVIE) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.SOUND) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.BINARY_DATA) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.TEXT) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
if (nodeType == TreeNodeType.FONT) {
|
||||
ret.add((Tag) n.getItem());
|
||||
}
|
||||
}
|
||||
if (d instanceof FrameNode) {
|
||||
FrameNode fn = (FrameNode) d;
|
||||
if (!fn.scriptsNode) {
|
||||
ret.add(d.getItem());
|
||||
}
|
||||
}
|
||||
if (d instanceof TreeElement) {
|
||||
if (((TreeElement) d).isLeaf()) {
|
||||
TreeElement treeElement = (TreeElement) d;
|
||||
ret.add((ScriptPack) treeElement.getItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,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 TreePanelMode {
|
||||
|
||||
TAG_TREE, DUMP_TREE
|
||||
}
|
||||
@@ -733,7 +733,7 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene
|
||||
if (text.trim().startsWith("#hexdata")) {
|
||||
src.setActionBytes(Helper.getBytesFromHexaText(text));
|
||||
} else {
|
||||
src.setActions(ASMParser.parse(0, src.getPos(), true, text, src.getSwf().version, false));
|
||||
src.setActions(ASMParser.parse(0, true, text, src.getSwf().version, false));
|
||||
}
|
||||
src.setModified();
|
||||
setSource(this.src, false);
|
||||
|
||||
@@ -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.dumpview;
|
||||
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.MainPanel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
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 javax.swing.JComponent;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DumpTree extends JTree implements ActionListener {
|
||||
|
||||
private static final String ACTION_CLOSE_SWF = "CLOSESWF";
|
||||
private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE";
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
public class DumpTreeCellRenderer 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);
|
||||
|
||||
//DumpInfo dumpInfo = (DumpInfo) value;
|
||||
setUI(new BasicLabelUI());
|
||||
setOpaque(false);
|
||||
setBackgroundNonSelectionColor(Color.white);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public DumpTree(DumpTreeModel treeModel, MainPanel mainPanel) {
|
||||
super(treeModel);
|
||||
this.mainPanel = mainPanel;
|
||||
setCellRenderer(new DumpTreeCellRenderer());
|
||||
setRootVisible(false);
|
||||
setBackground(Color.white);
|
||||
setUI(new BasicTreeUI() {
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
setHashColor(Color.gray);
|
||||
super.paint(g, c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void createContextMenu() {
|
||||
final JPopupMenu contextPopupMenu = new JPopupMenu();
|
||||
|
||||
final JMenuItem expandRecursiveMenuItem = new JMenuItem(mainPanel.translate("contextmenu.expandAll"));
|
||||
expandRecursiveMenuItem.addActionListener(this);
|
||||
expandRecursiveMenuItem.setActionCommand(ACTION_EXPAND_RECURSIVE);
|
||||
contextPopupMenu.add(expandRecursiveMenuItem);
|
||||
|
||||
final JMenuItem closeSelectionMenuItem = new JMenuItem(mainPanel.translate("contextmenu.closeSwf"));
|
||||
closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF);
|
||||
closeSelectionMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(closeSelectionMenuItem);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
|
||||
int row = getClosestRowForLocation(e.getX(), e.getY());
|
||||
int[] selectionRows = getSelectionRows();
|
||||
if (!Helper.contains(selectionRows, row)) {
|
||||
setSelectionRow(row);
|
||||
}
|
||||
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
if (paths == null || paths.length == 0) {
|
||||
return;
|
||||
}
|
||||
closeSelectionMenuItem.setVisible(false);
|
||||
expandRecursiveMenuItem.setVisible(false);
|
||||
|
||||
if (paths.length == 1) {
|
||||
DumpInfo treeNode = (DumpInfo) paths[0].getLastPathComponent();
|
||||
|
||||
if (treeNode instanceof DumpInfoSwfNode) {
|
||||
closeSelectionMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
TreeModel model = getModel();
|
||||
expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0);
|
||||
}
|
||||
|
||||
contextPopupMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_EXPAND_RECURSIVE: {
|
||||
TreePath path = getSelectionPath();
|
||||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
View.expandTreeNodesRecursive(this, path, true);
|
||||
}
|
||||
break;
|
||||
case ACTION_CLOSE_SWF: {
|
||||
Main.closeFile(mainPanel.getCurrentSwfList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(TreeModel tm) {
|
||||
super.setModel(tm);
|
||||
if (tm != null) {
|
||||
int rowCount = tm.getChildCount(tm.getRoot());
|
||||
for (int i = rowCount - 1; i >= 0; i--) {
|
||||
expandRow(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.dumpview;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import java.util.List;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DumpTreeModel implements TreeModel {
|
||||
|
||||
private final DumpInfo root;
|
||||
|
||||
public DumpTreeModel(List<SWFList> swfs) {
|
||||
DumpInfo root = new DumpInfo("root", "", null, 0, 0);
|
||||
for (SWFList swfList : swfs) {
|
||||
for (SWF swf : swfList) {
|
||||
swf.dumpInfo.name = swf.getFileTitle();
|
||||
root.childInfos.add(swf.dumpInfo);
|
||||
}
|
||||
}
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object o, int i) {
|
||||
return ((DumpInfo) o).childInfos.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object o) {
|
||||
return ((DumpInfo) o).childInfos.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object o) {
|
||||
return ((DumpInfo) o).childInfos.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath tp, Object o) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object o, Object o1) {
|
||||
return ((DumpInfo) o).childInfos.indexOf(o1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener tl) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener tl) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.dumpview;
|
||||
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.gui.HexView;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DumpViewPanel extends JPanel {
|
||||
|
||||
private final JLabel dumpViewLabel;
|
||||
private final HexView dumpViewHexTable;
|
||||
|
||||
public DumpViewPanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
dumpViewLabel = new JLabel();
|
||||
dumpViewLabel.setMinimumSize(new Dimension(100, 20));
|
||||
add(dumpViewLabel, BorderLayout.SOUTH);
|
||||
|
||||
dumpViewHexTable = new HexView();
|
||||
add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private int getEndIndex(DumpInfo dumpInfo) {
|
||||
int end = (int) dumpInfo.startByte;
|
||||
if (dumpInfo.lengthBytes != 0) {
|
||||
end += dumpInfo.lengthBytes;
|
||||
} else {
|
||||
int bits = dumpInfo.startBit + dumpInfo.lengthBits;
|
||||
end += bits / 8;
|
||||
if (bits % 8 != 0) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
return end - 1;
|
||||
}
|
||||
|
||||
public void setData(byte[] data, DumpInfo dumpInfo) {
|
||||
List<DumpInfo> dumpInfos = new ArrayList<>();
|
||||
DumpInfo di = dumpInfo;
|
||||
while (di.parent != null) {
|
||||
dumpInfos.add(di);
|
||||
di = di.parent;
|
||||
}
|
||||
long[] highlightStarts = new long[dumpInfos.size()];
|
||||
long[] highlightEnds = new long[dumpInfos.size()];
|
||||
for (int i = 0; i < dumpInfos.size(); i++) {
|
||||
DumpInfo di2 = dumpInfos.get(highlightStarts.length - i - 1);
|
||||
highlightStarts[i] = di2.startByte;
|
||||
highlightEnds[i] = getEndIndex(di2);
|
||||
}
|
||||
dumpViewHexTable.setData(data, highlightStarts, highlightEnds);
|
||||
|
||||
if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) {
|
||||
int selectionStart = (int) dumpInfo.startByte;
|
||||
int selectionEnd = getEndIndex(dumpInfo);
|
||||
|
||||
dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds);
|
||||
|
||||
setLabelText("startByte: " + dumpInfo.startByte
|
||||
+ " startBit: " + dumpInfo.startBit
|
||||
+ " lengthBytes: " + dumpInfo.lengthBytes
|
||||
+ " lengthBits: " + dumpInfo.lengthBits
|
||||
+ " selectionStart: " + selectionStart
|
||||
+ " selectionEnd: " + selectionEnd);
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setLabelText(String text) {
|
||||
dumpViewLabel.setText(text);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user