diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index afed5026e..192225a1c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -56,6 +56,7 @@ import com.jpexs.decompiler.flash.flv.FLVOutputStream; import com.jpexs.decompiler.flash.flv.FLVTAG; import com.jpexs.decompiler.flash.flv.VIDEODATA; import com.jpexs.decompiler.flash.gui.SWFSourceInfo; +import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; @@ -212,6 +213,7 @@ public final class SWF { public HashMap characters; public List abcList; public JPEGTablesTag jtt; + public ClassesListTreeModel classTreeModel; /** * Gets all tags with specified id diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 8fc1e678a..73a3b9bb0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -40,6 +40,7 @@ import java.awt.event.MouseEvent; import java.io.*; import java.net.Socket; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Locale; @@ -191,13 +192,35 @@ public class Main { public static SWF parseSWF(SWFSourceInfo sourceInfo) throws Exception { SWF locswf; - InputStream fis = sourceInfo.getInputStream(); - locswf = new SWF(fis, new ProgressListener() { + + InputStream inputStream = sourceInfo.getInputStream(); + if (inputStream == null) { + inputStream = new FileInputStream(sourceInfo.getFile()); + } else if (inputStream instanceof SeekableInputStream) { + try { + ((SeekableInputStream) inputStream).seek(0); + } catch (IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } else if (inputStream instanceof BufferedInputStream) { + try { + ((BufferedInputStream) inputStream).reset(); + } catch (IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } + + locswf = new SWF(inputStream, new ProgressListener() { @Override public void progress(int p) { startWork(AppStrings.translate("work.reading.swf"), p); } }, Configuration.parallelSpeedUp.get()); + + if (inputStream instanceof FileInputStream) { + inputStream.close(); + } + locswf.sourceInfo = sourceInfo; locswf.file = sourceInfo.getFile(); locswf.fileTitle = sourceInfo.getFileTitle(); @@ -242,51 +265,52 @@ public class Main { private static class OpenFileWorker extends SwingWorker { - private SWFSourceInfo sourceInfo; + private SWFSourceInfo[] sourceInfos; public OpenFileWorker(SWFSourceInfo sourceInfo) { - this.sourceInfo = sourceInfo; + this.sourceInfos = new SWFSourceInfo[] { sourceInfo }; + } + + public OpenFileWorker(SWFSourceInfo[] sourceInfos) { + this.sourceInfos = sourceInfos; } @Override protected Object doInBackground() throws Exception { - SWF swf = null; - try { - Main.startWork(AppStrings.translate("work.reading.swf") + "..."); - InputStream inputStream = sourceInfo.getInputStream(); - swf = parseSWF(sourceInfo); - if (inputStream instanceof FileInputStream) { - inputStream.close(); + for (SWFSourceInfo sourceInfo : sourceInfos) { + SWF swf = null; + try { + Main.startWork(AppStrings.translate("work.reading.swf") + "..."); + swf = parseSWF(sourceInfo); + } catch (OutOfMemoryError ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + View.showMessageDialog(null, "Cannot load SWF file. Out of memory."); + } catch (Exception ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + View.showMessageDialog(null, "Cannot load SWF file."); + } + + final SWF swf1 = swf; + try { + Main.startWork(AppStrings.translate("work.creatingwindow") + "..."); + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + if (mainFrame == null) { + mainFrame = new MainFrame(); + } + mainFrame.load(swf1); + if (errorState) { + mainFrame.setErrorState(); + } + } + }); + + } catch (Exception ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } - } catch (OutOfMemoryError ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - View.showMessageDialog(null, "Cannot load SWF file. Out of memory."); - loadingDialog.setVisible(false); - } catch (Exception ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - View.showMessageDialog(null, "Cannot load SWF file."); - loadingDialog.setVisible(false); } - final SWF swf1 = swf; - try { - Main.startWork(AppStrings.translate("work.creatingwindow") + "..."); - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - if (mainFrame == null) { - mainFrame = new MainFrame(); - } - mainFrame.load(swf1); - if (errorState) { - mainFrame.setErrorState(); - } - } - }); - - } catch (Exception ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - } loadingDialog.setVisible(false); View.execInEventDispatch(new Runnable() { @Override @@ -304,6 +328,7 @@ public class Main { public static boolean reloadSWFs() { CancellableWorker.cancelBackgroundThreads(); + mainFrame.closeAll(); if (Main.sourceInfos.isEmpty()) { Cache.clearAll(); System.gc(); @@ -312,27 +337,9 @@ public class Main { } else { SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()]; sourceInfos.toArray(sourceInfosCopy); - for (SWFSourceInfo sourceInfo : sourceInfosCopy) { - InputStream inputStream = sourceInfo.getInputStream(); - if (inputStream instanceof FileInputStream) { - openFile(sourceInfo.getFile(), null); - } else if (inputStream instanceof SeekableInputStream) { - try { - ((SeekableInputStream) inputStream).seek(0); - } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - } - return openFile(inputStream, sourceInfo.getFileTitle()) == OpenFileResult.OK; - } else if (inputStream instanceof BufferedInputStream) { - try { - ((BufferedInputStream) inputStream).reset(); - } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); - } - return openFile(inputStream, sourceInfo.getFileTitle()) == OpenFileResult.OK; - } - } - return false; + sourceInfos.clear(); + openFile(sourceInfosCopy); + return true; } } @@ -363,14 +370,15 @@ public class Main { public static OpenFileResult openFile(String swfFile, String fileTitle) { try { File file = new File(swfFile); + if (!file.exists()) { + View.showMessageDialog(null, "File not found", "Error", JOptionPane.ERROR_MESSAGE); + return OpenFileResult.NOT_FOUND; + } swfFile = file.getCanonicalPath(); Configuration.addRecentFile(swfFile); - SWFSourceInfo sourceInfo = new SWFSourceInfo(new FileInputStream(swfFile), swfFile, fileTitle); + SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle); OpenFileResult openResult = openFile(sourceInfo); return openResult; - } catch (FileNotFoundException ex) { - View.showMessageDialog(null, "File not found", "Error", JOptionPane.ERROR_MESSAGE); - return OpenFileResult.NOT_FOUND; } catch (IOException ex) { View.showMessageDialog(null, "Cannot open file", "Error", JOptionPane.ERROR_MESSAGE); return OpenFileResult.ERROR; @@ -378,6 +386,10 @@ public class Main { } public static OpenFileResult openFile(SWFSourceInfo sourceInfo) { + return openFile(new SWFSourceInfo[] { sourceInfo }); + } + + public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) { if (mainFrame != null && !Configuration.openMultiple.get()) { sourceInfos.clear(); mainFrame.closeAll(); @@ -396,9 +408,9 @@ public class Main { }); Main.loadingDialog.setVisible(true); - OpenFileWorker wrk = new OpenFileWorker(sourceInfo); + OpenFileWorker wrk = new OpenFileWorker(newSourceInfos); wrk.execute(); - sourceInfos.add(sourceInfo); + sourceInfos.addAll(Arrays.asList(newSourceInfos)); return OpenFileResult.OK; } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index e28491154..dad95314f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -1009,6 +1009,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T actionPanel.clearSource(); } updateUi(); + updateTagTree(); } public void close(SWF swf) { @@ -1019,6 +1020,12 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T actionPanel.clearSource(); oldValue = null; updateUi(); + updateTagTree(); + } + + private void updateTagTree() { + tagTree.setModel(new TagTreeModel(this, swfs, null)); + expandSwfRoots(); } public void enableDrop(boolean value) { @@ -1048,7 +1055,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T boolean updateNeeded = false; for (TagNode n : nodes) { if (n.tag instanceof ClassesListTreeModel) { - n.tag = new ClassesListTreeModel(abcPanel.classTree.treeList, n.getSwf(), filterField.getText()); + ((ClassesListTreeModel) n.tag).setFilter(filterField.getText()); updateNeeded = true; } } @@ -1473,19 +1480,21 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T public List getASTagNode(JTree tree) { List result = new ArrayList<>(); - TreeModel tm = tree.getModel(); + TagTreeModel tm = (TagTreeModel) tree.getModel(); if (tm == null) { return result; } - Object root = tm.getRoot(); - for (int i = 0; i < tm.getChildCount(root); i++) { - Object node = tm.getChild(root, i); - if (node instanceof TagNode) { - Object tag = ((TagNode) tm.getChild(root, i)).tag; - if (tag != null) { - if ("scripts".equals(((TagNode) node).mark)) { + TreeNode root = tm.getRoot(); + for (int j = 0; j < tm.getChildCount(root); j++) { + SWFRoot swfRoot = (SWFRoot) tm.getChild(root, j); + for (int i = 0; i < tm.getChildCount(swfRoot); i++) { + TreeNode node = tm.getChild(swfRoot, i); + if (node instanceof TagNode) { + TagNode tagNode = (TagNode) node; + TreeElementItem tag = tagNode.tag; + if (tag != null && "scripts".equals(tagNode.mark)) { result.add((TagNode) node); - } + } } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java index f543fe8a8..a97f9e53e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java @@ -49,7 +49,7 @@ public class TagTreeModel implements TreeModel { for (SWF swf : swfs) { List objs = new ArrayList<>(); objs.addAll(swf.tags); - List list = createTagList(objs, null, abcPanel, swf); + List list = createTagList(objs, null, swf); SWFRoot swfRoot = new SWFRoot(swf, new File(swf.file).getName(), list); this.swfs.add(swfRoot); @@ -75,7 +75,7 @@ public class TagTreeModel implements TreeModel { return ret; } - private List createTagList(List list, Object parent, ABCPanel abcPanel, SWF swf) { + private List createTagList(List list, Object parent, SWF swf) { List ret = new ArrayList<>(); List frames = getTagNodesWithType(list, TagType.FRAME, parent, true); List shapes = getTagNodesWithType(list, TagType.SHAPE, parent, true); @@ -88,7 +88,6 @@ public class TagTreeModel implements TreeModel { List movies = getTagNodesWithType(list, TagType.MOVIE, parent, true); List sounds = getTagNodesWithType(list, TagType.SOUND, parent, true); List binaryData = getTagNodesWithType(list, TagType.BINARY_DATA, parent, true); - List actionScript = new ArrayList<>(); for (int i = 0; i < sounds.size(); i++) { if (sounds.get(i).tag instanceof SoundStreamHeadTypeTag) { @@ -118,13 +117,13 @@ public class TagTreeModel implements TreeModel { TagNode tti = new TagNode(t, t.getSwf()); if (((Container) t).getItemCount() > 0) { List subItems = ((Container) t).getSubItems(); - tti.subItems = createTagList(subItems, t, abcPanel, t.getSwf()); + tti.subItems = createTagList(subItems, t, swf); } //ret.add(tti); } } - actionScript = SWF.createASTagList(list, null); + List actionScript = SWF.createASTagList(list, null); TagNode textsNode = new TagNode(new StringNode(translate("node.texts")), swf); textsNode.subItems.addAll(texts); @@ -198,11 +197,13 @@ public class TagTreeModel implements TreeModel { ret.add(framesNode); } - if (abcPanel != null) { + boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty(); + + if (hasAbc) { actionScriptNode.subItems.clear(); - actionScriptNode.tag = abcPanel.classTree.getModel(); + actionScriptNode.tag = swf.classTreeModel; } - if ((!actionScriptNode.subItems.isEmpty()) || (abcPanel != null)) { + if ((!actionScriptNode.subItems.isEmpty()) || hasAbc) { ret.add(actionScriptNode); } @@ -248,7 +249,7 @@ public class TagTreeModel implements TreeModel { } @Override - public Object getRoot() { + public TreeNode getRoot() { return root; } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeRoot.java b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeRoot.java index 3485bfeb9..0b99a3526 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeRoot.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/TagTreeRoot.java @@ -16,14 +16,21 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.SWF; + /** * * @author JPEXS */ -public class TagTreeRoot { +public class TagTreeRoot implements TreeNode { @Override public String toString() { return "root"; } + + @Override + public SWF getSwf() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java index 2ba41f681..c4688ca8e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTree.java @@ -38,7 +38,6 @@ import javax.swing.tree.TreeSelectionModel; public final class ClassesListTree extends JTree implements TreeSelectionListener { - private List abcList; public List> treeList; private ABCPanel abcPanel; private SWF swf; @@ -55,7 +54,6 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene this.abcPanel = abcPanel; addTreeSelectionListener(this); DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer(); - ClassLoader cldr = this.getClass().getClassLoader(); treeRenderer.setLeafIcon(View.getIcon("as16")); setCellRenderer(treeRenderer); } @@ -96,21 +94,21 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene } public void clearDoABCTags() { - this.abcList = null; this.treeList = null; this.swf = null; setModel(null); } public void setDoABCTags(List list, SWF swf) { - this.abcList = list; this.treeList = swf.getAS3Packs(); this.swf = swf; - setModel(new ClassesListTreeModel(this.treeList, swf)); + ClassesListTreeModel model = new ClassesListTreeModel(this.treeList, swf); + this.swf.classTreeModel = model; + setModel(model); } public void applyFilter(String filter) { - setModel(new ClassesListTreeModel(this.treeList, swf, filter)); + getModel().setFilter(filter); } @Override @@ -142,10 +140,10 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene break; } } - abcPanel.navigator.setABC(abcList, scriptLeaf.abc); + abcPanel.navigator.setABC(swf.abcList, scriptLeaf.abc); abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex); abcPanel.setAbc(scriptLeaf.abc); - abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList); + abcPanel.decompiledTextArea.setScript(scriptLeaf, swf.abcList); abcPanel.decompiledTextArea.setClassIndex(classIndex); abcPanel.decompiledTextArea.setNoTrait(); abcPanel.detailPanel.methodTraitPanel.methodCodePanel.clear(); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java index 285f784c3..b105b0f86 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ClassesListTreeModel.java @@ -79,6 +79,7 @@ class ClassIndexVisitor implements TreeVisitor { public class ClassesListTreeModel implements TreeModel, TreeElementItem { + private SWF swf; private Tree classTree; private List> list; @@ -89,8 +90,14 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { public ClassesListTreeModel(List> list, SWF swf) { this(list, swf, null); } - + public ClassesListTreeModel(List> list, SWF swf, String filter) { + this.swf = swf; + this.list = list; + setFilter(filter); + } + + public final void setFilter(String filter) { classTree = new Tree(swf); for (MyEntry item : list) { if (filter != null) { @@ -104,8 +111,6 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem { //String packageName = path.contains(".") ? path.substring(0, path.lastIndexOf(".")) : ""; classTree.add(item.key.className, item.key.packageStr, item.value); } - this.list = list; - } public Object getItemByPath(String fullPath) {