diff --git a/libsrc/jpproxy/nbbuild.xml b/libsrc/jpproxy/nbbuild.xml
index 6579262e5..7369c29a9 100644
--- a/libsrc/jpproxy/nbbuild.xml
+++ b/libsrc/jpproxy/nbbuild.xml
@@ -1,74 +1,73 @@
-
-
-
-
-
-
-
-
-
-
- Builds, tests, and runs the project JPProxy.
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project JPProxy.
+
+
+
diff --git a/libsrc/jpproxy/nbproject/build-impl.xml b/libsrc/jpproxy/nbproject/build-impl.xml
index 4277fdc2e..fa9ad0fbe 100644
--- a/libsrc/jpproxy/nbproject/build-impl.xml
+++ b/libsrc/jpproxy/nbproject/build-impl.xml
@@ -1,1394 +1,1396 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set src.dir
- Must set build.dir
- Must set dist.dir
- Must set build.classes.dir
- Must set dist.javadoc.dir
- Must set build.test.classes.dir
- Must set build.test.results.dir
- Must set build.classes.excludes
- Must set dist.jar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- No tests executed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must set JVM to use for profiling in profiler.info.jvm
- Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- To run this application from the command line without Ant, try:
-
-
-
-
-
-
- java -cp "${run.classpath.with.dist.jar}" ${main.class}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- To run this application from the command line without Ant, try:
-
- java -jar "${dist.jar.resolved}"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set debug.class
-
-
-
-
- Must select one file in the IDE or set debug.class
-
-
-
-
- Must set fix.includes
-
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set profile.class
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
-
-
-
-
- This target only works when run from inside the NetBeans IDE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
-
- Must select some files in the IDE or set test.includes
-
-
-
-
- Must select one file in the IDE or set run.class
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set javac.includes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Some tests failed; see details above.
-
-
-
-
-
-
-
-
- Must select some files in the IDE or set test.includes
-
-
-
- Some tests failed; see details above.
-
-
-
- Must select some files in the IDE or set test.class
- Must select some method in the IDE or set test.method
-
-
-
- Some tests failed; see details above.
-
-
-
-
- Must select one file in the IDE or set test.class
-
-
-
- Must select one file in the IDE or set test.class
- Must select some method in the IDE or set test.method
-
-
-
-
-
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
- Must select one file in the IDE or set applet.url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.dir
+ Must set build.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No tests executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set JVM to use for profiling in profiler.info.jvm
+ Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ java -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set profile.class
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+ Must select some files in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+ Must select one file in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libsrc/jpproxy/nbproject/genfiles.properties b/libsrc/jpproxy/nbproject/genfiles.properties
index dba5b2a05..9e4b5fd3d 100644
--- a/libsrc/jpproxy/nbproject/genfiles.properties
+++ b/libsrc/jpproxy/nbproject/genfiles.properties
@@ -1,8 +1,8 @@
-nbbuild.xml.data.CRC32=0a5363c8
-nbbuild.xml.script.CRC32=e4148738
-nbbuild.xml.stylesheet.CRC32=28e38971@1.38.2.45
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=0a5363c8
-nbproject/build-impl.xml.script.CRC32=949d71fd
-nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46
+nbbuild.xml.data.CRC32=0a5363c8
+nbbuild.xml.script.CRC32=2eebe506
+nbbuild.xml.stylesheet.CRC32=8064a381@1.74.2.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=0a5363c8
+nbproject/build-impl.xml.script.CRC32=13f57099
+nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48
diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
index ad7891373..a701988d7 100644
--- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
@@ -17,12 +17,14 @@
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.exporters.ShapeExporter;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
+import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.timeline.Timeline;
@@ -85,6 +87,14 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
private final List soundPlayers = new ArrayList<>();
private final IconPanel iconPanel;
private int time = 0;
+ private int selectedDepth = -1;
+
+ public void selectDepth(int depth) {
+ if (depth != selectedDepth) {
+ this.selectedDepth = depth;
+ }
+ hideMouseSelection();
+ }
private class IconPanel extends JPanel {
@@ -271,6 +281,26 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
}
}
+ private void showSelectedName() {
+ if (selectedDepth > -1 && frame > -1) {
+ DepthState ds = timelined.getTimeline().frames.get(frame).layers.get(selectedDepth);
+ if (ds != null) {
+ CharacterTag cht = timelined.getTimeline().swf.characters.get(ds.characterId);
+ if (cht != null) {
+ debugLabel.setText(cht.getName());
+ }
+ }
+ }
+ }
+
+ public void hideMouseSelection() {
+ if (selectedDepth > -1) {
+ showSelectedName();
+ } else {
+ debugLabel.setText(" - ");
+ }
+ }
+
public ImagePanel() {
super(new BorderLayout());
//iconPanel.setHorizontalAlignment(JLabel.CENTER);
@@ -301,8 +331,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void mouseExited(MouseEvent e) {
stateUnderCursor = null;
+ lastMouseEvent = null;
drawFrame();
- debugLabel.setText(" - ");
+ hideMouseSelection();
}
@Override
@@ -489,8 +520,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
}
}
- private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton) {
- String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
+ private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton, int selectedDepth) {
+ String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_depth" + selectedDepth + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
SerializableImage img = SWF.getFromCache(key);
if (img == null) {
if (drawable instanceof BoundedTag) {
@@ -514,6 +545,30 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
List dss = new ArrayList<>();
List os = new ArrayList<>();
+ DepthState ds = drawable.getTimeline().frames.get(frame).layers.get(selectedDepth);
+ if (ds != null) {
+ CharacterTag cht = swf.characters.get(ds.characterId);
+ if (cht != null) {
+ if (cht instanceof DrawableTag) {
+ DrawableTag dt = (DrawableTag) cht;
+ Shape outline = dt.getOutline(0, ds.time, ds.ratio, stateUnderCursor, mouseButton, new Matrix(ds.matrix));
+ Rectangle bounds = outline.getBounds();
+ bounds.x /= 20;
+ bounds.y /= 20;
+ bounds.width /= 20;
+ bounds.height /= 20;
+ bounds.x -= rect.Xmin / 20;
+ bounds.y -= rect.Ymin / 20;
+ //SHAPERECORD.resizeSHAPE(outline, 1/20)
+ gg.setStroke(new BasicStroke(2.0f,
+ BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER,
+ 10.0f, new float[]{10.0f}, 0.0f));
+ gg.setPaint(Color.red);
+ gg.draw(bounds);
+ }
+ }
+ }
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
//gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
@@ -544,7 +599,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
mat.translateX = swf.displayRect.Xmin;
mat.translateY = swf.displayRect.Ymin;
updatePos(lastMouseEvent, false);
- SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton);
+ SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton, selectedDepth);
List sounds = new ArrayList<>();
List soundClasses = new ArrayList<>();
timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses);
diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
index b65e2223f..3ab485b69 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java
@@ -48,6 +48,7 @@ import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
+import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
@@ -122,6 +123,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
static final String ACTION_CHECK_RESOURCES = "CHECKRESOURCES";
static final String ACTION_VIEWMODE_RESOURCES = "VIEWMODERESOURCES";
static final String ACTION_VIEWMODE_HEX = "VIEWMODEHEX";
+ static final String ACTION_VIEWMODE_TIMELINE = "VIEWMODETIMELINE";
static final String ACTION_DEOBFUSCATION_MODE_OLD = "DEOBFUSCATIONMODEOLD";
static final String ACTION_DEOBFUSCATION_MODE_NEW = "DEOBFUSCATIONMODENEW";
@@ -153,10 +155,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
private JCommandButton globalrenameCommandButton;
private JCommandButton deobfuscationCommandButton;
private JCommandButton searchCommandButton;
- private JCommandButton timeLineCommandButton;
+ private JCommandToggleButton timeLineToggleButton;
+ private CommandToggleButtonGroup timeLineToggleGroup;
private JCommandButton gotoDocumentClassCommandButton;
private JCommandButton clearRecentFilesCommandButton;
+ private CommandToggleButtonGroup viewModeToggleGroup;
+
RibbonApplicationMenuEntryPrimary exportFlaMenu;
RibbonApplicationMenuEntryPrimary exportAllMenu;
RibbonApplicationMenuEntryPrimary exportSelMenu;
@@ -280,7 +285,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
resizePolicies.add(new BaseRibbonBandResizePolicy(ribbonBand.getControlPanel()) {
@Override
public int getPreferredWidth(int i, int i1) {
- return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle())+20;
+ return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle()) + 20;
}
@Override
@@ -357,7 +362,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
JRibbonBand viewBand = new JRibbonBand(translate("menu.view"), null);
viewBand.setResizePolicies(getResizePolicies(viewBand));
- CommandToggleButtonGroup grpViewMode = new CommandToggleButtonGroup();
+ viewModeToggleGroup = new CommandToggleButtonGroup();
viewModeResourcesToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.resources")), View.getResizableIcon("viewresources16"));
assignListener(viewModeResourcesToggleButton, ACTION_VIEWMODE_RESOURCES);
@@ -365,13 +370,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
viewModeHexToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.hex")), View.getResizableIcon("viewhex16"));
assignListener(viewModeHexToggleButton, ACTION_VIEWMODE_HEX);
- grpViewMode.add(viewModeResourcesToggleButton);
- grpViewMode.add(viewModeHexToggleButton);
+ viewModeToggleGroup.add(viewModeResourcesToggleButton);
+ viewModeToggleGroup.add(viewModeHexToggleButton);
if (Configuration.dumpView.get()) {
- grpViewMode.setSelected(viewModeHexToggleButton, true);
+ viewModeToggleGroup.setSelected(viewModeHexToggleButton, true);
} else {
- grpViewMode.setSelected(viewModeResourcesToggleButton, true);
+ viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, true);
}
viewBand.addCommandButton(viewModeResourcesToggleButton, RibbonElementPriority.MEDIUM);
@@ -389,8 +394,11 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.search")), View.getResizableIcon("search32"));
assignListener(searchCommandButton, ACTION_SEARCH);
- timeLineCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
- assignListener(timeLineCommandButton, ACTION_TIMELINE);
+ timeLineToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
+ assignListener(timeLineToggleButton, ACTION_TIMELINE);
+
+ timeLineToggleGroup = new CommandToggleButtonGroup();
+ timeLineToggleGroup.add(timeLineToggleButton);
gotoDocumentClassCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.gotodocumentclass")), View.getResizableIcon("gotomainclass32"));
assignListener(gotoDocumentClassCommandButton, ACTION_GOTO_DOCUMENT_CLASS);
@@ -405,7 +413,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
assignListener(loadCacheCommandButton, ACTION_LOAD_CACHE);
toolsBand.addCommandButton(searchCommandButton, RibbonElementPriority.TOP);
- toolsBand.addCommandButton(timeLineCommandButton, RibbonElementPriority.TOP);
+ toolsBand.addCommandButton(timeLineToggleButton, RibbonElementPriority.TOP);
toolsBand.addCommandButton(gotoDocumentClassCommandButton, RibbonElementPriority.TOP);
toolsBand.addCommandButton(proxyCommandButton, RibbonElementPriority.MEDIUM);
toolsBand.addCommandButton(loadMemoryCommandButton, RibbonElementPriority.MEDIUM);
@@ -614,7 +622,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
globalrenameCommandButton.setEnabled(swfLoaded);
deobfuscationCommandButton.setEnabled(swfLoaded);
searchCommandButton.setEnabled(swfLoaded);
- timeLineCommandButton.setEnabled(swfLoaded);
+ timeLineToggleButton.setEnabled(swfLoaded);
gotoDocumentClassCommandButton.setEnabled(hasAbc);
deobfuscationCommandButton.setEnabled(hasAbc);
@@ -705,11 +713,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
case ACTION_VIEWMODE_RESOURCES:
Configuration.dumpView.set(false);
- mainFrame.panel.showDumpView(false);
+ mainFrame.panel.showView(MainPanel.VIEW_RESOURCES);
+ timeLineToggleGroup.setSelected(timeLineToggleButton, false);
break;
case ACTION_VIEWMODE_HEX:
Configuration.dumpView.set(true);
- mainFrame.panel.showDumpView(true);
+ mainFrame.panel.showView(MainPanel.VIEW_DUMP);
+ timeLineToggleGroup.setSelected(timeLineToggleButton, false);
break;
case ACTION_DEOBFUSCATION_MODE_OLD:
Configuration.deobfuscationMode.set(0);
@@ -719,15 +729,28 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
Configuration.deobfuscationMode.set(1);
mainFrame.panel.autoDeobfuscateChanged();
break;
- case ACTION_DUMP_VIEW_SWITCH:
- Configuration.dumpView.set(miDumpView.isSelected());
- mainFrame.panel.showDumpView(miDumpView.isSelected());
- break;
case ACTION_SEARCH:
mainFrame.panel.searchAs();
break;
case ACTION_TIMELINE:
- mainFrame.panel.timeline();
+ timeLineToggleGroup.setSelected(timeLineToggleButton, timeLineToggleGroup.getSelected() == timeLineToggleButton);
+ if (timeLineToggleGroup.getSelected() == timeLineToggleButton) {
+ if (!mainFrame.panel.showView(MainPanel.VIEW_TIMELINE)) {
+ timeLineToggleGroup.setSelected(timeLineToggleButton, false);
+ } else {
+ viewModeToggleGroup.setSelected(viewModeHexToggleButton, false);
+ viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, false);
+ }
+ } else {
+ if (Configuration.dumpView.get()) {
+ viewModeToggleGroup.setSelected(viewModeHexToggleButton, true);
+ mainFrame.panel.showView(MainPanel.VIEW_DUMP);
+ } else {
+ viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, true);
+ mainFrame.panel.showView(MainPanel.VIEW_RESOURCES);
+ }
+
+ }
break;
case ACTION_AUTO_DEOBFUSCATE:
if (View.showConfirmDialog(mainFrame.panel, translate("message.confirm.autodeobfuscate") + "\r\n" + (miAutoDeobfuscation.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
index c04f03b27..c9d54b1a2 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
@@ -63,7 +63,8 @@ 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.timeline.TimelineViewPanel;
+import com.jpexs.decompiler.flash.gui.timeline.TimelinePanel;
import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode;
import com.jpexs.decompiler.flash.gui.treenodes.SWFNode;
import com.jpexs.decompiler.flash.gui.treenodes.StringNode;
@@ -219,6 +220,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
private ABCPanel abcPanel;
private ActionPanel actionPanel;
private final JPanel welcomePanel;
+ private final TimelineViewPanel timelineViewPanel;
private final MainFrameStatusPanel statusPanel;
private final MainFrameMenu mainMenu;
private final JProgressBar progressBar = new JProgressBar(0, 100);
@@ -241,6 +243,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
private static final String DETAILCARDEMPTYPANEL = "Empty card";
private static final String SPLIT_PANE1 = "SPLITPANE1";
private static final String WELCOME_PANEL = "WELCOMEPANEL";
+ private static final String TIMELINE_PANEL = "TIMELINEPANEL";
private final JSplitPane splitPane1;
private final JSplitPane splitPane2;
private boolean splitsInited = false;
@@ -560,10 +563,13 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
}
});
+ timelineViewPanel = new TimelineViewPanel();
+
CardLayout cl3 = new CardLayout();
contentPanel = new JPanel(cl3);
contentPanel.add(welcomePanel, WELCOME_PANEL);
contentPanel.add(splitPane1, SPLIT_PANE1);
+ contentPanel.add(timelineViewPanel, TIMELINE_PANEL);
add(contentPanel);
cl3.show(contentPanel, WELCOME_PANEL);
@@ -578,7 +584,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
});
detailPanel.setVisible(false);
- showDumpView(Configuration.dumpView.get());
+ showView(Configuration.dumpView.get() ? VIEW_DUMP : VIEW_RESOURCES);
updateUi();
//Opening files with drag&drop to main window
@@ -2143,19 +2149,52 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
return mainMenu.isInternalFlashViewerSelected();
}
- public void showDumpView(boolean show) {
- treePanel.removeAll();
- if (show) {
- treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER);
- treePanelMode = TreePanelMode.DUMP_TREE;
- showDetail(DETAILCARDEMPTYPANEL);
- } else {
- treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER);
- treePanel.add(searchPanel, BorderLayout.SOUTH);
- treePanelMode = TreePanelMode.TAG_TREE;
+ public static final int VIEW_RESOURCES = 0;
+ public static final int VIEW_DUMP = 1;
+ public static final int VIEW_TIMELINE = 2;
+
+ public boolean showView(int view) {
+
+ CardLayout cl = (CardLayout) (contentPanel.getLayout());
+ switch (view) {
+ case VIEW_DUMP:
+ if (!isWelcomeScreen) {
+ cl.show(contentPanel, SPLIT_PANE1);
+ }
+ treePanel.removeAll();
+ treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER);
+ treePanelMode = TreePanelMode.DUMP_TREE;
+ showDetail(DETAILCARDEMPTYPANEL);
+ reload(true);
+ treePanel.revalidate();
+ return true;
+ case VIEW_RESOURCES:
+ if (!isWelcomeScreen) {
+ cl.show(contentPanel, SPLIT_PANE1);
+ }
+ treePanel.removeAll();
+ treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER);
+ treePanel.add(searchPanel, BorderLayout.SOUTH);
+ treePanelMode = TreePanelMode.TAG_TREE;
+ reload(true);
+ treePanel.revalidate();
+ return true;
+ case VIEW_TIMELINE:
+ final SWF swf = getCurrentSwf();
+ if (swf != null) {
+ TreeItem item = tagTree.getCurrentTreeItem();
+ if (item instanceof DefineSpriteTag) {
+ timelineViewPanel.setTimelined((DefineSpriteTag) item);
+ } else {
+ timelineViewPanel.setTimelined(swf);
+ }
+ cl.show(contentPanel, TIMELINE_PANEL);
+ return true;
+ }
+ return false;
}
- reload(true);
- treePanel.revalidate();
+ return false;
+
}
private void dumpViewReload(boolean forceReload) {
@@ -2499,21 +2538,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
statusPanel.setErrorState(errorState);
}
- public void timeline() {
- final SWF swf = getCurrentSwf();
- if (swf != null) {
- TreeItem item = tagTree.getCurrentTreeItem();
- if (item instanceof DefineSpriteTag) {
- TimelineFrame tf = new TimelineFrame((DefineSpriteTag) item);
- tf.setVisible(true);
- return;
- }
-
- TimelineFrame tf = new TimelineFrame(swf);
- tf.setVisible(true);
- }
- }
-
public static Timelined makeTimelined(final Tag tag) {
return new Timelined() {
diff --git a/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java b/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java
index 36b4e8b5c..2a39af5f7 100644
--- a/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java
+++ b/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java
@@ -141,7 +141,7 @@ public class NewVersionDialog extends AppDialog implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == ACTION_OK) {
- String url;
+ String url;
if (latestVersion.updateLink != null) {
url = latestVersion.updateLink;
} else {
diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java
index 04ea9cc20..1b921ac91 100644
--- a/src/com/jpexs/decompiler/flash/gui/View.java
+++ b/src/com/jpexs/decompiler/flash/gui/View.java
@@ -537,8 +537,7 @@ public class View {
}
}
}
-
+
return false;
}
}
-
diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
index 81c8ee31c..11914de31 100644
--- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
@@ -49,7 +49,7 @@ public class DumpViewPanel extends JPanel {
super(new BorderLayout());
this.dumpTree = dumpTree;
-
+
selectedByteInfo = new JLabel();
selectedByteInfo.setMinimumSize(new Dimension(100, 20));
selectedByteInfo.setText("-");
@@ -64,13 +64,13 @@ public class DumpViewPanel extends JPanel {
dumpViewHexTable.addListener(new HexViewListener() {
private int lastAddressUnderCursor = -1;
-
+
@Override
public void byteValueChanged(int address, byte b) {
if (skipValueChange) {
return;
}
-
+
if (address != -1) {
TreeModel model = dumpTree.getModel();
DumpInfo di = DumpInfoSwfNode.getSwfNode(selectedDumpInfo);
@@ -100,7 +100,7 @@ public class DumpViewPanel extends JPanel {
dumpTree.setSelectionPath(tp);
dumpTree.scrollPathToVisible(tp);
}
-
+
byte[] data = dumpViewHexTable.getData();
byteMouseMoved(lastAddressUnderCursor, lastAddressUnderCursor == -1 ? 0 : data[lastAddressUnderCursor]);
}
@@ -115,20 +115,20 @@ public class DumpViewPanel extends JPanel {
b = data[address];
}
}
-
+
if (address != -1) {
int b2 = b & 0xff;
- selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8) +
- " Hex: " + Helper.padZeros(Integer.toHexString(b2), 2) +
- " Dec: " + b2 +
- " Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8) +
- " Ascii: " + (char) b2);
+ selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8)
+ + " Hex: " + Helper.padZeros(Integer.toHexString(b2), 2)
+ + " Dec: " + b2
+ + " Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8)
+ + " Ascii: " + (char) b2);
} else {
selectedByteInfo.setText("-");
}
}
});
-
+
add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
}
@@ -137,7 +137,7 @@ public class DumpViewPanel extends JPanel {
skipNextScroll = false;
return;
}
-
+
this.selectedDumpInfo = dumpInfo;
byte[] data = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData;
List dumpInfos = new ArrayList<>();
diff --git a/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java b/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java
index a981ed27d..b07599270 100644
--- a/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java
+++ b/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java
@@ -50,11 +50,11 @@ public class HexView extends JTable {
private final Color bgColorAlternate = Color.decode("#EDEDED");
private int mouseOverIdx = -1;
private HexViewListener listener;
-
+
private class HighlightCellRenderer extends DefaultTableCellRenderer {
public int byteIndex;
-
+
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
@@ -81,7 +81,7 @@ public class HexView extends JTable {
foreground = Color.black;
background = row % 2 == 0 ? bgColor : bgColorAlternate;
}
-
+
if (idx != -1 && idx == mouseOverIdx) {
foreground = new Color(255 - foreground.getRed(), 255 - foreground.getGreen(), 255 - foreground.getBlue());
background = new Color(255 - background.getRed(), 255 - background.getGreen(), 255 - background.getBlue());
@@ -92,18 +92,18 @@ public class HexView extends JTable {
return l;
}
}
-
+
private class HexViewSelectionListener implements ListSelectionListener {
private final HexView table;
-
+
public HexViewSelectionListener(HexView table) {
this.table = table;
}
-
+
@Override
public void valueChanged(ListSelectionEvent e) {
-
+
int col = table.getSelectedColumn();
int row = table.getSelectedRow();
@@ -118,7 +118,7 @@ public class HexView extends JTable {
@Override
public void mouseExited(MouseEvent e) {
- HexView table = (HexView) e.getSource();
+ HexView table = (HexView) e.getSource();
Point point = e.getPoint();
int col = table.columnAtPoint(point);
int row = table.rowAtPoint(point);
@@ -131,17 +131,17 @@ public class HexView extends JTable {
}
private class HexViewMouseMotionAdapter extends MouseMotionAdapter {
-
+
@Override
public void mouseMoved(MouseEvent e) {
- HexView table = (HexView) e.getSource();
+ HexView table = (HexView) e.getSource();
Point point = e.getPoint();
int col = table.columnAtPoint(point);
int row = table.rowAtPoint(point);
int idx = getIdxByColAndRow(row, col);
mouseOverIdx = idx;
getModel().fireTableCellUpdated(row, col);
-
+
if (listener != null) {
listener.byteMouseMoved(idx, idx == -1 ? 0 : getModel().getData()[idx]);
}
@@ -182,7 +182,7 @@ public class HexView extends JTable {
column.setMaxWidth(10);
column.setCellRenderer(cellRenderer);
}
-
+
addMouseListener(new HexViewMouseAdapter());
addMouseMotionListener(new HexViewMouseMotionAdapter());
ListSelectionModel rowSelModel = getSelectionModel();
@@ -195,9 +195,9 @@ public class HexView extends JTable {
@Override
public HexViewTableModel getModel() {
TableModel model = super.getModel();
- return (HexViewTableModel) model;
+ return (HexViewTableModel) model;
}
-
+
public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) {
if ((highlightStarts == null) ^ (highlightEnds == null)) {
@@ -216,7 +216,7 @@ public class HexView extends JTable {
public byte[] getData() {
return getModel().getData();
}
-
+
public void scrollToByte(long byteNum) {
int row = (int) (byteNum / bytesInRow);
@@ -237,7 +237,7 @@ public class HexView extends JTable {
}
return idx;
}
-
+
public int getFocusedByteIdx() {
int col = getSelectedColumn();
int row = getSelectedRow();
@@ -245,7 +245,7 @@ public class HexView extends JTable {
int idx = getIdxByColAndRow(row, col);
return idx;
}
-
+
public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) {
for (int i = 0; i < byteNumStarts.length; i++) {
scrollToByte(byteNumStarts[i]);
@@ -253,7 +253,7 @@ public class HexView extends JTable {
scrollToByte(byteNumStarts[i]);
}
}
-
+
public void addListener(HexViewListener listener) {
this.listener = listener;
}
diff --git a/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java
index d5588b777..b35a9d442 100644
--- a/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java
+++ b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java
@@ -23,7 +23,7 @@ import javax.swing.table.AbstractTableModel;
* @author JPEXS
*/
public class HexViewTableModel extends AbstractTableModel {
-
+
private byte[] data;
private final int bytesInRow;
@@ -79,15 +79,15 @@ public class HexViewTableModel extends AbstractTableModel {
return null;
}
}
-
+
public byte[] getData() {
return data;
}
-
+
public void setData(byte[] data) {
this.data = data;
}
-
+
@Override
public void fireTableCellUpdated(int row, int columnd) {
super.fireTableCellUpdated(bytesInRow, bytesInRow);
diff --git a/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java b/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java
index d11184d41..6510f226e 100644
--- a/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java
+++ b/src/com/jpexs/decompiler/flash/gui/proxy/ProxyFrame.java
@@ -369,9 +369,9 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe
if ((!sniffOSCheckBox.isSelected()) && (contentType.equals("application/octet-stream"))) {
return null;
}
-
+
byte[] result = null;
-
+
if (!listModel.contains(url)) {
try {
byte[] hdr = new byte[3];
@@ -387,16 +387,16 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe
try (FileOutputStream fos = new FileOutputStream(new File(tempFilePath))) {
fos.write(dataArray);
}
-
+
result = SWFDecompilerPlugin.fireProxyFileCatched(dataArray);
-
+
Replacement r = new Replacement(url, tempFilePath);
r.lastAccess = Calendar.getInstance();
listModel.addURL(r);
} catch (IOException e) {
}
}
-
+
return result;
}
diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java
index 1aeb0f642..6ebc516c0 100644
--- a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java
@@ -1,273 +1,311 @@
-/*
- * 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 .
- */
-package com.jpexs.decompiler.flash.gui.timeline;
-
-import com.jpexs.decompiler.flash.timeline.DepthState;
-import com.jpexs.decompiler.flash.timeline.Timeline;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.JPanel;
-
-/**
- *
- * @author JPEXS
- */
-public class TimelineBodyPanel extends JPanel implements MouseListener {
-
- private final Timeline timeLine;
-
- public static Color frameColor = Color.lightGray;
- public static Color emptyFrameColor = Color.white;
- public static Color emptyFrameSecondColor = new Color(0xed, 0xed, 0xed);
- public static Color borderColor = Color.black;
- public static Color emptyBorderColor = Color.lightGray;
- public static Color keyColor = Color.black;
- public static Color aColor = Color.black;
- public static Color stopColor = Color.white;
- public static Color stopBorderColor = Color.black;
- public static Color borderLinesColor = new Color(0xde, 0xde, 0xde);
-
- public static Color selectedColor = new Color(113, 174, 235);
- public static final int borderLinesLength = 2;
- public static final float fontSize = 10.0f;
-
- private final List listeners = new ArrayList<>();
-
- public Point cursor = null;
-
- public void addFrameSelectionListener(FrameSelectionListener l) {
- listeners.add(l);
- }
-
- public void removeFrameSelectionListener(FrameSelectionListener l) {
- listeners.remove(l);
- }
-
- public TimelineBodyPanel(Timeline timeLine) {
-
- this.timeLine = timeLine;
- Dimension dim = new Dimension(TimelinePanel.FRAME_WIDTH * timeLine.getFrameCount() + 1, TimelinePanel.FRAME_HEIGHT * timeLine.getMaxDepth());
- setSize(dim);
- setPreferredSize(dim);
- addMouseListener(this);
- }
-
- @Override
- protected void paintComponent(Graphics g1) {
- Graphics2D g = (Graphics2D) g1;
- g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
- g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
- g.setColor(TimelinePanel.backgroundColor);
- g.fillRect(0, 0, getWidth(), getHeight());
- Rectangle clip = g.getClipBounds();
- int start_f = clip.x / TimelinePanel.FRAME_WIDTH;
- int start_d = clip.y / TimelinePanel.FRAME_HEIGHT;
- int end_f = (clip.x + clip.width) / TimelinePanel.FRAME_WIDTH;
- int end_d = (clip.y + clip.height) / TimelinePanel.FRAME_HEIGHT;
-
- int max_d = timeLine.getMaxDepth();
- if (max_d < end_d) {
- end_d = max_d;
- }
- int max_f = timeLine.getFrameCount() - 1;
- if (max_f < end_f) {
- end_f = max_f;
- }
-
- if (end_d - start_d + 1 < 0) {
- return;
- }
-
- boolean keyfound[] = new boolean[end_d - start_d + 1];
-
- for (int f = start_f; f <= end_f; f++) {
- for (int d = start_d; d <= end_d; d++) {
- DepthState fl = timeLine.frames.get(f).layers.get(d);
- if (fl == null) {
- if ((f + 1) % 5 == 0) {
- g.setColor(emptyFrameSecondColor);
- } else {
- g.setColor(emptyFrameColor);
- }
- g.fillRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
- g.setColor(emptyBorderColor);
- g.drawRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
- }
- }
- }
- for (int f = start_f; f <= end_f; f++) {
- for (int d = start_d; d <= end_d; d++) {
- DepthState fl = timeLine.frames.get(f).layers.get(d);
- DepthState flNext = null;
- if (f < max_f) {
- flNext = timeLine.frames.get(f + 1).layers.get(d);
- }
- boolean selected = false;
- if (cursor != null) {
- if (f == cursor.x && d == cursor.y) {
- selected = true;
- }
- }
- if (selected) {
- if (!(fl != null && (flNext == null || flNext.key))) {
- g.setColor(selectedColor);
- g.fillRect(f * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
- }
- }
-
- if (fl == null) {
-
- if (d == 0) {
- if (timeLine.frames.get(f).action != null) {
- g.setColor(aColor);
- g.setFont(getFont().deriveFont(fontSize));
- int awidth = g.getFontMetrics().stringWidth("a");
- g.drawString("a", f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2 - awidth / 2, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 + fontSize / 2);
- }
- }
- continue;
- } else {
-
- int draw_f = 0;
- if (fl.key) {
- draw_f = f;
- keyfound[d - start_d] = true;
- } else if (!keyfound[d - start_d]) {
- for (int k = f - 1; k >= 0; k--) {
- fl = timeLine.frames.get(k).layers.get(d);
- if (fl == null) {
- break;
- }
- if (fl.key) {
- keyfound[d - start_d] = true;
- draw_f = k;
- break;
- }
- }
- } else {
- continue;
- }
- int num_frames = 1;
- for (int n = draw_f + 1; n < timeLine.getFrameCount(); n++) {
- fl = timeLine.frames.get(n).layers.get(d);
- if (fl == null) {
- break;
- }
- if (fl.key) {
- break;
- }
- num_frames++;
- }
- g.setColor(frameColor);
- g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
-
- if (selected) {
- g.setColor(selectedColor);
- g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
- }
-
- g.setColor(borderColor);
- g.drawRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
- g.setColor(keyColor);
- g.fillOval(draw_f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT * 3 / 4 - TimelinePanel.FRAME_WIDTH / 2 / 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_WIDTH / 2);
- if (num_frames > 1) {
- if (cursor != null && cursor.y == d && cursor.x == f + num_frames - 1) {
- g.setColor(selectedColor);
- g.fillRect((f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
- }
- g.setColor(stopColor);
- g.fillRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
- g.setColor(stopBorderColor);
- g.drawRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
-
- g.setColor(borderLinesColor);
- for (int n = draw_f + 1; n < draw_f + num_frames; n++) {
- g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + borderLinesLength);
- g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - borderLinesLength);
- }
- }
- }
- }
- }
-
- if (cursor != null && cursor.x >= start_f && cursor.x <= end_f) {
- g.setColor(TimelinePanel.selectedBorderColor);
- g.drawLine(cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, 0, cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, getHeight());
- }
- }
-
- @Override
- public void mouseClicked(MouseEvent e) {
-
- }
-
- public void frameSelect(int frame, int depth) {
- if (cursor != null && cursor.x == frame && (cursor.y == depth || depth == -1)) {
- return;
- }
- if (depth == -1 && cursor != null) {
- depth = cursor.y;
- }
- cursor = new Point(frame, depth);
- for (FrameSelectionListener l : listeners) {
- l.frameSelected(frame, -1);
- }
- repaint();
- }
-
- @Override
- public void mousePressed(MouseEvent e) {
- Point p = e.getPoint();
- p.x = p.x / TimelinePanel.FRAME_WIDTH;
- p.y = p.y / TimelinePanel.FRAME_HEIGHT;
- if (p.x >= timeLine.getFrameCount()) {
- p.x = timeLine.getFrameCount() - 1;
- }
- int maxDepth = timeLine.getMaxDepth();
- if (p.y > maxDepth) {
- p.y = maxDepth;
- }
- frameSelect(p.x, p.y);
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
-
- }
-
- @Override
- public void mouseEntered(MouseEvent e) {
-
- }
-
- @Override
- public void mouseExited(MouseEvent e) {
-
- }
-
-}
+/*
+ * 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 .
+ */
+package com.jpexs.decompiler.flash.gui.timeline;
+
+import com.jpexs.decompiler.flash.timeline.DepthState;
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JPanel;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListener {
+
+ private final Timeline timeLine;
+
+ public static Color frameColor = new Color(0xbd, 0xd8, 0xfc);
+ public static Color emptyFrameColor = Color.white;
+ public static Color emptyFrameSecondColor = new Color(0xea, 0xf2, 0xfc);
+ public static Color borderColor = Color.black;
+ public static Color emptyBorderColor = new Color(0xbd, 0xd8, 0xfc);
+ public static Color keyColor = Color.black;
+ public static Color aColor = Color.black;
+ public static Color stopColor = Color.white;
+ public static Color stopBorderColor = Color.black;
+ public static Color borderLinesColor = new Color(0xde, 0xde, 0xde);
+
+ public static Color selectedColor = new Color(113, 174, 235);
+ public static final int borderLinesLength = 2;
+ public static final float fontSize = 10.0f;
+
+ private final List listeners = new ArrayList<>();
+
+ public Point cursor = null;
+
+ public void addFrameSelectionListener(FrameSelectionListener l) {
+ listeners.add(l);
+ }
+
+ public void removeFrameSelectionListener(FrameSelectionListener l) {
+ listeners.remove(l);
+ }
+
+ public TimelineBodyPanel(Timeline timeLine) {
+
+ this.timeLine = timeLine;
+ Dimension dim = new Dimension(TimelinePanel.FRAME_WIDTH * timeLine.getFrameCount() + 1, TimelinePanel.FRAME_HEIGHT * timeLine.getMaxDepth());
+ setSize(dim);
+ setPreferredSize(dim);
+ addMouseListener(this);
+ addKeyListener(this);
+ setFocusable(true);
+ }
+
+ @Override
+ protected void paintComponent(Graphics g1) {
+ Graphics2D g = (Graphics2D) g1;
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ g.setColor(TimelinePanel.backgroundColor);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ Rectangle clip = g.getClipBounds();
+ int start_f = clip.x / TimelinePanel.FRAME_WIDTH;
+ int start_d = clip.y / TimelinePanel.FRAME_HEIGHT;
+ int end_f = (clip.x + clip.width) / TimelinePanel.FRAME_WIDTH;
+ int end_d = (clip.y + clip.height) / TimelinePanel.FRAME_HEIGHT;
+
+ int max_d = timeLine.getMaxDepth();
+ if (max_d < end_d) {
+ end_d = max_d;
+ }
+ int max_f = timeLine.getFrameCount() - 1;
+ if (max_f < end_f) {
+ end_f = max_f;
+ }
+
+ if (end_d - start_d + 1 < 0) {
+ return;
+ }
+
+ boolean keyfound[] = new boolean[end_d - start_d + 1];
+
+ for (int f = start_f; f <= end_f; f++) {
+ for (int d = start_d; d <= end_d; d++) {
+ DepthState fl = timeLine.frames.get(f).layers.get(d);
+ if (fl == null) {
+ if ((f + 1) % 5 == 0) {
+ g.setColor(emptyFrameSecondColor);
+ } else {
+ g.setColor(emptyFrameColor);
+ }
+ g.fillRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
+ g.setColor(emptyBorderColor);
+ g.drawRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
+ }
+ }
+ }
+ for (int f = start_f; f <= end_f; f++) {
+ for (int d = start_d; d <= end_d; d++) {
+ DepthState fl = timeLine.frames.get(f).layers.get(d);
+ DepthState flNext = null;
+ if (f < max_f) {
+ flNext = timeLine.frames.get(f + 1).layers.get(d);
+ }
+ boolean selected = false;
+ if (cursor != null) {
+ if (f == cursor.x && d == cursor.y) {
+ selected = true;
+ }
+ }
+ if (selected) {
+ if (!(fl != null && (flNext == null || flNext.key))) {
+ g.setColor(selectedColor);
+ g.fillRect(f * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
+ }
+ }
+
+ if (fl == null) {
+
+ if (d == 0) {
+ if (timeLine.frames.get(f).action != null) {
+ g.setColor(aColor);
+ g.setFont(getFont().deriveFont(fontSize));
+ int awidth = g.getFontMetrics().stringWidth("a");
+ g.drawString("a", f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2 - awidth / 2, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 + fontSize / 2);
+ }
+ }
+ continue;
+ } else {
+
+ int draw_f = 0;
+ if (fl.key) {
+ draw_f = f;
+ keyfound[d - start_d] = true;
+ } else if (!keyfound[d - start_d]) {
+ for (int k = f - 1; k >= 0; k--) {
+ fl = timeLine.frames.get(k).layers.get(d);
+ if (fl == null) {
+ break;
+ }
+ if (fl.key) {
+ keyfound[d - start_d] = true;
+ draw_f = k;
+ break;
+ }
+ }
+ } else {
+ continue;
+ }
+ int num_frames = 1;
+ for (int n = draw_f + 1; n < timeLine.getFrameCount(); n++) {
+ fl = timeLine.frames.get(n).layers.get(d);
+ if (fl == null) {
+ break;
+ }
+ if (fl.key) {
+ break;
+ }
+ num_frames++;
+ }
+ g.setColor(frameColor);
+ g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
+
+ if (selected) {
+ g.setColor(selectedColor);
+ g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
+ }
+
+ g.setColor(borderColor);
+ g.drawRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
+ g.setColor(keyColor);
+ g.fillOval(draw_f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT * 3 / 4 - TimelinePanel.FRAME_WIDTH / 2 / 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_WIDTH / 2);
+ if (num_frames > 1) {
+ if (cursor != null && cursor.y == d && cursor.x == f + num_frames - 1) {
+ g.setColor(selectedColor);
+ g.fillRect((f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
+ }
+ g.setColor(stopColor);
+ g.fillRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
+ g.setColor(stopBorderColor);
+ g.drawRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
+
+ g.setColor(borderLinesColor);
+ for (int n = draw_f + 1; n < draw_f + num_frames; n++) {
+ g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + borderLinesLength);
+ g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - borderLinesLength);
+ }
+ }
+ }
+ }
+ }
+
+ if (cursor != null && cursor.x >= start_f && cursor.x <= end_f) {
+ g.setColor(TimelinePanel.selectedBorderColor);
+ g.drawLine(cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, 0, cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, getHeight());
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+
+ }
+
+ public void frameSelect(int frame, int depth) {
+ if (cursor != null && cursor.x == frame && (cursor.y == depth || depth == -1)) {
+ return;
+ }
+ if (depth == -1 && cursor != null) {
+ depth = cursor.y;
+ }
+ cursor = new Point(frame, depth);
+ for (FrameSelectionListener l : listeners) {
+ l.frameSelected(frame, depth);
+ }
+ repaint();
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ Point p = e.getPoint();
+ p.x = p.x / TimelinePanel.FRAME_WIDTH;
+ p.y = p.y / TimelinePanel.FRAME_HEIGHT;
+ if (p.x >= timeLine.getFrameCount()) {
+ p.x = timeLine.getFrameCount() - 1;
+ }
+ int maxDepth = timeLine.getMaxDepth();
+ if (p.y > maxDepth) {
+ p.y = maxDepth;
+ }
+ frameSelect(p.x, p.y);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ switch (e.getKeyCode()) {
+ case 37: //left
+ if (cursor.x > 0) {
+ frameSelect(cursor.x - 1, cursor.y);
+ }
+ break;
+ case 39: //right
+ if (cursor.x < timeLine.frames.size() - 1) {
+ frameSelect(cursor.x + 1, cursor.y);
+ }
+ break;
+ case 38: //up
+ if (cursor.y > 0) {
+ frameSelect(cursor.x, cursor.y - 1);
+ }
+ break;
+ case 40: //down
+ if (cursor.y < timeLine.getMaxDepth()) {
+ frameSelect(cursor.x, cursor.y + 1);
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineFrame.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineFrame.java
deleted file mode 100644
index 538b93b79..000000000
--- a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineFrame.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 .
- */
-package com.jpexs.decompiler.flash.gui.timeline;
-
-import com.jpexs.decompiler.flash.gui.AppFrame;
-import com.jpexs.decompiler.flash.gui.View;
-import com.jpexs.decompiler.flash.timeline.Timelined;
-import java.awt.BorderLayout;
-import java.awt.Container;
-import java.awt.Image;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author JPEXS
- */
-public class TimelineFrame extends AppFrame {
-
- public TimelinePanel timeline;
-
- public TimelineFrame(Timelined timelined) {
- setSize(800, 600);
- View.setWindowIcon(this);
- View.centerScreen(this);
- setTitle(translate("dialog.title"));
- Container cnt = getContentPane();
- cnt.setLayout(new BorderLayout());
- cnt.add(timeline = new TimelinePanel(timelined), BorderLayout.CENTER);
-
- List images = new ArrayList<>();
- images.add(View.loadImage("timeline16"));
- images.add(View.loadImage("timeline32"));
- setIconImages(images);
- }
-}
diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java
index ae35bddfa..16814a317 100644
--- a/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java
@@ -1,106 +1,124 @@
-/*
- * 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 .
- */
-package com.jpexs.decompiler.flash.gui.timeline;
-
-import com.jpexs.decompiler.flash.timeline.Timeline;
-import com.jpexs.decompiler.flash.timeline.Timelined;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.event.AdjustmentEvent;
-import java.awt.event.AdjustmentListener;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-
-/**
- *
- * @author JPEXS
- */
-public class TimelinePanel extends JPanel {
-
- public TimelineBodyPanel timelineBodyPanel;
- public TimelineTimePanel timePanel;
- public TimelineDepthPanel depthPanel;
- public Timeline timeline;
-
- public static final int FRAME_WIDTH = 8;
- public static final int FRAME_HEIGHT = 18;
-
- public static Color selectedColor = new Color(0xff, 0x99, 0x99);
- public static Color selectedBorderColor = new Color(0xcc, 0, 0);
- public static Color backgroundColor = new Color(0xee, 0xee, 0xee);
-
- public TimelinePanel(Timelined timelined) {
- timeline = timelined.getTimeline();
- timelineBodyPanel = new TimelineBodyPanel(timeline);
- setLayout(new BorderLayout());
-
- JScrollPane sp = new JScrollPane(timelineBodyPanel);
-
- depthPanel = new TimelineDepthPanel(timeline);
-
- timePanel = new TimelineTimePanel();
-
- JPanel row1Panel = new JPanel();
- row1Panel.setLayout(new BorderLayout());
- JPanel sepPanel = new JPanel();
- sepPanel.setBackground(TimelinePanel.backgroundColor);
- sepPanel.setPreferredSize(new Dimension(depthPanel.getWidth(), timePanel.getHeight()));
- row1Panel.add(sepPanel, BorderLayout.WEST);
- row1Panel.add(timePanel, BorderLayout.CENTER);
-
- JPanel row2Panel = new JPanel();
- row2Panel.setLayout(new BorderLayout());
- row2Panel.add(depthPanel, BorderLayout.WEST);
- row2Panel.add(sp, BorderLayout.CENTER);
-
- add(row1Panel, BorderLayout.NORTH);
- add(row2Panel, BorderLayout.CENTER);
-
- sp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
- @Override
- public void adjustmentValueChanged(AdjustmentEvent e) {
- timePanel.scroll(e.getValue());
- }
- });
- sp.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
-
- @Override
- public void adjustmentValueChanged(AdjustmentEvent e) {
- depthPanel.scroll(e.getValue());
- }
- });
-
- final TimelineTimePanel ftime = timePanel;
- timelineBodyPanel.addFrameSelectionListener(new FrameSelectionListener() {
-
- @Override
- public void frameSelected(int frame, int depth) {
- ftime.frameSelect(frame);
- }
- });
- final TimelineBodyPanel ftimeline = timelineBodyPanel;
- timePanel.addFrameSelectionListener(new FrameSelectionListener() {
-
- @Override
- public void frameSelected(int frame, int depth) {
- ftimeline.frameSelect(frame, depth);
- }
- });
-
- }
-}
+/*
+ * 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 .
+ */
+package com.jpexs.decompiler.flash.gui.timeline;
+
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import com.jpexs.decompiler.flash.timeline.Timelined;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class TimelinePanel extends JPanel {
+
+ private TimelineBodyPanel timelineBodyPanel;
+ private TimelineTimePanel timePanel;
+ private TimelineDepthPanel depthPanel;
+ private Timeline timeline;
+
+ public static final int FRAME_WIDTH = 8;
+ public static final int FRAME_HEIGHT = 18;
+
+ public static Color selectedColor = new Color(0xff, 0x99, 0x99);
+ public static Color selectedBorderColor = new Color(0xcc, 0, 0);
+ public static Color backgroundColor = new Color(0xd9, 0xe7, 0xfa);
+
+ public Timeline getTimeline() {
+ return timeline;
+ }
+
+ public void addFrameSelectionListener(FrameSelectionListener l) {
+ timelineBodyPanel.addFrameSelectionListener(l);
+ }
+
+ public void removeFrameSelectionListener(FrameSelectionListener l) {
+ timelineBodyPanel.removeFrameSelectionListener(l);
+ }
+
+ public void setTimelined(Timelined timelined) {
+ this.removeAll();
+ if (timelined == null) {
+ this.revalidate();
+ return;
+ }
+ timeline = timelined.getTimeline();
+ timelineBodyPanel = new TimelineBodyPanel(timeline);
+ setLayout(new BorderLayout());
+
+ JScrollPane sp = new JScrollPane(timelineBodyPanel);
+
+ depthPanel = new TimelineDepthPanel(timeline);
+
+ timePanel = new TimelineTimePanel();
+
+ JPanel row1Panel = new JPanel();
+ row1Panel.setLayout(new BorderLayout());
+ JPanel sepPanel = new JPanel();
+ sepPanel.setBackground(TimelinePanel.backgroundColor);
+ sepPanel.setPreferredSize(new Dimension(depthPanel.getWidth(), timePanel.getHeight()));
+ row1Panel.add(sepPanel, BorderLayout.WEST);
+ row1Panel.add(timePanel, BorderLayout.CENTER);
+
+ JPanel row2Panel = new JPanel();
+ row2Panel.setLayout(new BorderLayout());
+ row2Panel.add(depthPanel, BorderLayout.WEST);
+ row2Panel.add(sp, BorderLayout.CENTER);
+
+ add(row1Panel, BorderLayout.NORTH);
+ add(row2Panel, BorderLayout.CENTER);
+
+ sp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
+ @Override
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ timePanel.scroll(e.getValue());
+ }
+ });
+ sp.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
+
+ @Override
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ depthPanel.scroll(e.getValue());
+ }
+ });
+
+ final TimelineTimePanel ftime = timePanel;
+ timelineBodyPanel.addFrameSelectionListener(new FrameSelectionListener() {
+
+ @Override
+ public void frameSelected(int frame, int depth) {
+ ftime.frameSelect(frame);
+ }
+ });
+ final TimelineBodyPanel ftimeline = timelineBodyPanel;
+ timePanel.addFrameSelectionListener(new FrameSelectionListener() {
+
+ @Override
+ public void frameSelected(int frame, int depth) {
+ ftimeline.frameSelect(frame, depth);
+ }
+ });
+ this.revalidate();
+ }
+
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java
new file mode 100644
index 000000000..b88ebdbdf
--- /dev/null
+++ b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java
@@ -0,0 +1,71 @@
+/*
+ * 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 .
+ */
+package com.jpexs.decompiler.flash.gui.timeline;
+
+import com.jpexs.decompiler.flash.gui.AppFrame;
+import com.jpexs.decompiler.flash.gui.ImagePanel;
+import com.jpexs.decompiler.flash.gui.View;
+import com.jpexs.decompiler.flash.timeline.Timelined;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class TimelineViewPanel extends JPanel {
+
+ public TimelinePanel timeline;
+ public ImagePanel previewPanel;
+
+ public TimelineViewPanel() {
+
+ }
+
+ public void setTimelined(Timelined timelined) {
+ removeAll();
+ if (timelined == null) {
+ revalidate();
+ return;
+ }
+ setLayout(new BorderLayout());
+ timeline = new TimelinePanel();
+ timeline.setTimelined(timelined);
+ add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, timeline, previewPanel = new ImagePanel()));
+
+ previewPanel.setTimelined(timelined, timelined.getTimeline().swf, 0);
+ //previewPanel.setPreferredSize(new Dimension(400,300));
+ previewPanel.pause();
+ previewPanel.gotoFrame(0);
+ timeline.addFrameSelectionListener(new FrameSelectionListener() {
+
+ @Override
+ public void frameSelected(int frame, int depth) {
+ previewPanel.selectDepth(depth);
+ previewPanel.pause();
+ previewPanel.gotoFrame(frame);
+ }
+ });
+ revalidate();
+ }
+}
diff --git a/src/com/jpexs/process/win32/Win32ProcessTools.java b/src/com/jpexs/process/win32/Win32ProcessTools.java
index 4248e2339..8dab1da15 100644
--- a/src/com/jpexs/process/win32/Win32ProcessTools.java
+++ b/src/com/jpexs/process/win32/Win32ProcessTools.java
@@ -390,11 +390,11 @@ public class Win32ProcessTools extends ProcessTools {
for (int pg = 0; pg < pages.size(); pg++) {
MEMORY_BASIC_INFORMATION mbi = pages.get(pg);
if (pageReadable(mbi)) {
- long addr = pointerToAddress(mbi.baseAddress);
+ long addr = pointerToAddress(mbi.baseAddress);
int maxsize = mbi.regionSize.intValue();
long pos = 0;
- long bufSize = 1024*512;
- do {
+ long bufSize = 1024 * 512;
+ do {
NativeLongByReference bytesReadRef = new NativeLongByReference();
Memory buf = new Memory(bufSize);
boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, new Pointer(addr + pos), buf, new NativeLong(bufSize), bytesReadRef);
@@ -530,7 +530,7 @@ public class Win32ProcessTools extends ProcessTools {
private final List pages;
private int currentPage = 0;
private long pagePos = 0;
- private static final int BUFFER_SIZE = 1024*512;
+ private static final int BUFFER_SIZE = 1024 * 512;
private byte[] buf;
private int bufPos;
private final HANDLE hOtherProcess;