Added Indices in brackets for items with same name (like two subsequent DoAction tags)

Changed DoInitAction is not shown in resources/sprites section, only in scripts
This commit is contained in:
Jindra Petřík
2022-11-19 19:25:04 +01:00
parent f964eeb7f5
commit 29c65c195f
14 changed files with 214 additions and 59 deletions

View File

@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- [#1822], [#1803] AS3 direct editation - optional using AIR (airglobal.swc) to compile
- [#1501] Bulk import shapes
- [#1680] Pinning items
- Indices in brackets for items with same name (like two subsequent DoAction tags)
### Fixed
- [#1869] Replace references now replaces all references, not just PlaceObject
@@ -42,6 +43,7 @@ All notable changes to this project will be documented in this file.
### Changed
- GFX - DefineExternalImage2 no longer handled as character
- Raw editor does not show tag name in the tree (it's now in the new pinnable head)
- DoInitAction is not shown in resources/sprites section, only in scripts
## [16.3.1] - 2022-11-14
### Fixed

Binary file not shown.

Binary file not shown.

View File

@@ -1020,7 +1020,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
pinsPanel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setTagTreeSelectedNode(getCurrentTree(), pinsPanel.getCurrent());
TreeItem item = pinsPanel.getCurrent();
if ((getCurrentTree() == tagListTree) && (item instanceof TagScript)) {
item = ((TagScript) item).getTag();
}
setTagTreeSelectedNode(getCurrentTree(), item);
}
});
rightPanel.add(pinsPanel, BorderLayout.NORTH);
@@ -1225,6 +1229,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
doFilter();
reload(false);
View.expandTreeNodes(tagTree, expandedNodes);
pinsPanel.load();
}
public void load(SWFList newSwfs, boolean first) {
@@ -2596,7 +2601,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
public void setTagTreeSelectedNode(AbstractTagTree tree, TreeItem treeItem) {
AbstractTagTreeModel ttm = tree.getModel();
AbstractTagTreeModel ttm = tree.getModel();
TreePath tp = ttm.getTreePath(treeItem);
if (tp != null) {
tree.setSelectionPath(tp);
@@ -3558,6 +3563,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
reload(true);
pinsPanel.refresh();
}
public void refreshTree(SWF swf) {
@@ -3587,6 +3593,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
reload(true);
updateMissingNeededCharacters();
pinsPanel.refresh();
}
public void refreshDecompiled() {
@@ -4737,10 +4744,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
} else if (!(treeItem instanceof ScriptPack)){
showCard(CARDEMPTYPANEL);
}
if (treeItem instanceof TreeRoot) {
if (oldItem instanceof TreeRoot) {
pinsPanel.setCurrent(null);
} else {
pinsPanel.setCurrent(treeItem);
pinsPanel.setCurrent(oldItem);
}
}
@@ -5229,4 +5236,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
}
public String itemToString(TreeItem item) {
int index = getCurrentTree().getModel().getItemIndex(item);
String itemToStr = item.toString();
if (index > 1) {
return itemToStr + " [" + index + "]";
}
return itemToStr;
}
}

View File

@@ -73,8 +73,10 @@ public class PinButton extends JPanel {
private Color textColor;
private JLabel label;
private MainPanel mainPanel;
public PinButton(TreeItem item, boolean pinned) {
public PinButton(MainPanel mainPanel, TreeItem item, boolean pinned) {
this.mainPanel = mainPanel;
//setBorder(raisedBorder);
setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
this.item = item;
@@ -112,7 +114,7 @@ public class PinButton extends JPanel {
label = new JLabel();
label.setIcon(AbstractTagTree.getIconFor(item));
label.setText(item.toString());
label.setText(mainPanel.itemToString(item));
button = new JLabel();
button.setMinimumSize(new Dimension(10 + 16, 16));
@@ -317,4 +319,7 @@ public class PinButton extends JPanel {
}
}
public void refresh() {
label.setText(mainPanel.itemToString(item));
}
}

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.tagtree.TreeRoot;
import com.jpexs.decompiler.flash.timeline.TagScript;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -46,13 +47,12 @@ public class PinsPanel extends JPanel {
private MainPanel mainPanel;
private PinButton lastSelectedButton;
private PinButton currentUnpinnedButton;
private List<PinButton> buttons = new ArrayList<>();
private List<PinButton> buttons = new ArrayList<>();
private List<ChangeListener> changeListeners = new ArrayList<>();
private List<String> missingTagTreePaths = new ArrayList<>();
private List<String> missingTagListPaths = new ArrayList<>();
private static final String PATHS_SEPARATOR = "{#sep#}";
public PinsPanel(MainPanel mainPanel) {
@@ -69,10 +69,10 @@ public class PinsPanel extends JPanel {
rebuild();
save();
}
/**
* Removes all items reference, saves them as paths.
*
*
*/
public void clear() {
for (TreeItem item : items) {
@@ -98,9 +98,20 @@ public class PinsPanel extends JPanel {
if (lastSelectedButton != null) {
lastSelectedButton.setSelected(false);
}
TreeItem itemNoTs = item;
if (item instanceof TagScript) {
itemNoTs = ((TagScript) item).getTag();
}
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == item) {
this.current = item;
TreeItem item2 = items.get(i);
TreeItem item2NoTs = item2;
if (item2 instanceof TagScript) {
item2NoTs = ((TagScript) item2).getTag();
}
if (item2NoTs == itemNoTs) {
this.current = items.get(i);
buttons.get(i).setSelected(true);
lastSelectedButton = buttons.get(i);
if (currentUnpinnedButton != null) {
@@ -111,12 +122,18 @@ public class PinsPanel extends JPanel {
return;
}
}
if (this.current == item) {
TreeItem currentNoTs = this.current;
if (currentNoTs instanceof TagScript) {
currentNoTs = ((TagScript) currentNoTs).getTag();
}
if (currentNoTs == itemNoTs) {
return;
}
this.current = item;
rebuild();
}
@@ -130,7 +147,7 @@ public class PinsPanel extends JPanel {
if (pathString.length() > 0) {
pathString.append(" / ");
}
pathString.append(path.getPathComponent(i).toString());
pathString.append(mainPanel.itemToString((TreeItem) path.getPathComponent(i)));
}
return pathString.toString();
}
@@ -141,7 +158,7 @@ public class PinsPanel extends JPanel {
currentUnpinnedButton = null;
boolean currentPinned = false;
for (TreeItem item : items) {
PinButton pinButton = new PinButton(item, true);
PinButton pinButton = new PinButton(mainPanel, item, true);
pinButton.setToolTipText(getTreeItemPath(item));
pinButton.addMouseListener(new MouseAdapter() {
@Override
@@ -155,10 +172,10 @@ public class PinsPanel extends JPanel {
items.remove(item);
rebuild();
fireChange();
}
}
});
pinMenu.add(unpinMenuItem);
JMenuItem unpinAllMenuItem = new JMenuItem(AppStrings.translate("contextmenu.unpin.all"));
unpinAllMenuItem.addActionListener(new ActionListener() {
@Override
@@ -166,12 +183,12 @@ public class PinsPanel extends JPanel {
items.clear();
rebuild();
fireChange();
}
}
});
if (items.size() > 1) {
pinMenu.add(unpinAllMenuItem);
}
JMenuItem unpinOthersMenuItem = new JMenuItem(AppStrings.translate("contextmenu.unpin.others"));
unpinOthersMenuItem.addActionListener(new ActionListener() {
@Override
@@ -180,7 +197,7 @@ public class PinsPanel extends JPanel {
items.add(item);
rebuild();
fireChange();
}
}
});
if (items.size() > 1) {
pinMenu.add(unpinOthersMenuItem);
@@ -188,14 +205,14 @@ public class PinsPanel extends JPanel {
pinMenu.show(pinButton, e.getX(), e.getY());
}
}
});
pinButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (!pinButton.isPinned()) {
items.remove(item);
rebuild();
rebuild();
}
save();
fireChange();
@@ -204,7 +221,7 @@ public class PinsPanel extends JPanel {
pinButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
current = pinButton.getItem();
current = pinButton.getItem();
if (lastSelectedButton != null) {
lastSelectedButton.setSelected(false);
if (!lastSelectedButton.isPinned()) {
@@ -227,7 +244,7 @@ public class PinsPanel extends JPanel {
}
}
if (!currentPinned && current != null) {
currentUnpinnedButton = new PinButton(current, false);
currentUnpinnedButton = new PinButton(mainPanel, current, false);
lastSelectedButton = currentUnpinnedButton;
add(currentUnpinnedButton);
currentUnpinnedButton.setToolTipText(getTreeItemPath(current));
@@ -273,14 +290,14 @@ public class PinsPanel extends JPanel {
this.items = new ArrayList<>(items);
rebuild();
}
public void save() {
StringBuilder tagTreePathsBuilder = new StringBuilder();
StringBuilder tagListPathsBuilder = new StringBuilder();
boolean first = true;
for (int i = 0; i < missingTagTreePaths.size(); i++) {
if (!first) {
if (!first) {
tagTreePathsBuilder.append(PATHS_SEPARATOR);
tagListPathsBuilder.append(PATHS_SEPARATOR);
}
@@ -288,18 +305,23 @@ public class PinsPanel extends JPanel {
tagListPathsBuilder.append(missingTagListPaths.get(i));
first = false;
}
for (TreeItem item : items) {
String tagTreePath = mainPanel.tagTree.getItemPathString(item);
if (tagTreePath == null) {
tagTreePath = "";
}
String tagListPath = mainPanel.tagListTree.getItemPathString(item);
TreeItem tagListItem = item;
if (item instanceof TagScript) {
tagListItem = ((TagScript) item).getTag();
}
String tagListPath = mainPanel.tagListTree.getItemPathString(tagListItem);
if (tagListPath == null) {
tagListPath = "";
}
if (!first) {
if (!first) {
tagTreePathsBuilder.append(PATHS_SEPARATOR);
tagListPathsBuilder.append(PATHS_SEPARATOR);
}
@@ -307,19 +329,19 @@ public class PinsPanel extends JPanel {
tagListPathsBuilder.append(tagListPath);
first = false;
}
Configuration.pinnedItemsTagTreePaths.set(tagTreePathsBuilder.toString());
Configuration.pinnedItemsTagListPaths.set(tagListPathsBuilder.toString());
}
public void load() {
final String PATHS_END = "{finish}";
List<String> missingTagTreePaths = new ArrayList<>();
List<String> missingTagListPaths = new ArrayList<>();
String tagTreePathsCombined = Configuration.pinnedItemsTagTreePaths.get() + PATHS_SEPARATOR + PATHS_END;
String tagListPathsCombined = Configuration.pinnedItemsTagListPaths.get() + PATHS_SEPARATOR + PATHS_END;
String tagListPathsCombined = Configuration.pinnedItemsTagListPaths.get() + PATHS_SEPARATOR + PATHS_END;
String[] tagTreePaths = tagTreePathsCombined.split(Pattern.quote(PATHS_SEPARATOR));
String[] tagListPaths = tagListPathsCombined.split(Pattern.quote(PATHS_SEPARATOR));
if (tagTreePaths.length != tagListPaths.length) {
@@ -328,7 +350,7 @@ public class PinsPanel extends JPanel {
List<TreeItem> items = new ArrayList<>();
for (int i = 0; i < tagTreePaths.length - 1; i++) {
String tagTreePath = tagTreePaths[i];
String tagListPath = tagListPaths[i];
String tagListPath = tagListPaths[i];
TreeItem item = mainPanel.tagTree.getTreeItemFromPathString(tagTreePath);
if (item == null || (item instanceof TreeRoot)) {
item = mainPanel.tagListTree.getTreeItemFromPathString(tagListPath);
@@ -344,14 +366,14 @@ public class PinsPanel extends JPanel {
this.missingTagTreePaths = missingTagTreePaths;
this.missingTagListPaths = missingTagListPaths;
rebuild();
}
}
public void removeSwf(SWF swf) {
for (int i = 0; i < items.size(); i++) {
TreeItem item = items.get(i);
SWF itemSwf = item.getSwf();
if (itemSwf == swf || itemSwf == null) {
String tagTreePath = mainPanel.tagTree.getItemPathString(item);
if (tagTreePath == null) {
tagTreePath = "";
@@ -361,17 +383,17 @@ public class PinsPanel extends JPanel {
if (tagListPath == null) {
tagListPath = "";
}
missingTagTreePaths.add(tagTreePath);
missingTagListPaths.add(tagListPath);
items.remove(i);
i--;
}
}
save();
}
public void replaceItem(TreeItem oldItem, TreeItem newItem) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == oldItem) {
@@ -381,14 +403,31 @@ public class PinsPanel extends JPanel {
}
}
}
public void removeItem(TreeItem item) {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == item) {
TreeItem item2 = items.get(i);
if (item2 instanceof TagScript) {
item2 = ((TagScript) item2).getTag();
}
if (item2 == item) {
items.remove(i);
rebuild();
rebuild();
break;
}
}
}
public void refresh() {
for (PinButton button : buttons) {
button.refresh();
}
if (currentUnpinnedButton != null) {
currentUnpinnedButton.refresh();
}
}
}

View File

@@ -17,6 +17,8 @@
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
@@ -538,7 +540,16 @@ public class View {
int childCount = model.getChildCount(node);
for (int j = 0; j < childCount; j++) {
Object child = model.getChild(node, j);
if (child.toString().equals(name)) {
String childStr = child.toString();
int index = 1;
if (model instanceof AbstractTagTreeModel) {
AbstractTagTreeModel aModel = (AbstractTagTreeModel) model;
index = aModel.getItemIndex((TreeItem) child);
if (index > 1) {
childStr += " [" + index + "]";
}
}
if (childStr.equals(name)) {
node = child;
path.add(node);
break;

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui.taglistview;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree;
import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel;
import com.jpexs.decompiler.flash.gui.tagtree.TagTree;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.Frame;
@@ -146,6 +147,12 @@ public class TagListTreeCellRenderer extends DefaultTreeCellRenderer {
if (aTree.getMainPanel().isClipboardCut() && aTree.getMainPanel().clipboardContains(val)) {
semiTransparent = true;
}
AbstractTagTreeModel model = aTree.getModel();
int itemIndex = model.getItemIndex(val);
if (itemIndex > 1) {
lab.setText(lab.getText() + " [" + itemIndex + "]");
}
}
}
return renderer;

View File

@@ -240,6 +240,7 @@ public class TagListTreeModel extends AbstractTagTreeModel {
default:
fireTreeStructureChanged(new TreeModelEvent(this, new TreePath(root)));
}
calculateCollisions();
}
private Frame searchForFrame(Object parent, SWF swf, Timelined t, int frame) {
@@ -352,5 +353,6 @@ public class TagListTreeModel extends AbstractTagTreeModel {
swfHeaders.clear();
TreePath changedPath = getTreePath(swf == null ? root : swf);
fireTreeStructureChanged(new TreeModelEvent(this, changedPath));
calculateCollisions();
}
}

View File

@@ -605,8 +605,13 @@ public abstract class AbstractTagTree extends JTree {
return pathToString(path);
}
public final void calculateCollisions() {
getModel().calculateCollisions();
}
public String pathToString(TreePath path) {
StringBuilder sb = new StringBuilder();
AbstractTagTreeModel model = getModel();
if (path != null) {
boolean first = true;
for (Object p : path.getPath()) {
@@ -616,6 +621,10 @@ public abstract class AbstractTagTree extends JTree {
first = false;
sb.append(p.toString());
int index = model.getItemIndex((TreeItem) p);
if (index > 1) {
sb.append(" [").append(index).append("]");
}
}
}
return sb.toString();

View File

@@ -18,11 +18,16 @@ package com.jpexs.decompiler.flash.gui.tagtree;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedEvent;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.TagScript;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
@@ -37,6 +42,43 @@ public abstract class AbstractTagTreeModel implements TreeModel {
protected final List<TreeModelListener> listeners = new ArrayList<>();
public abstract void updateSwfs(CollectionChangedEvent e);
private Map<TreeItem, Integer> indices = new WeakHashMap<>();
public final void calculateCollisions() {
Map<TreeItem, Integer> indices = new WeakHashMap<>();
calculateCollisions(getRoot(), indices);
this.indices = indices;
}
private void calculateCollisions(Object parent, Map<TreeItem, Integer> indices) {
List<? extends TreeItem> items = getAllChildren(parent);
Map<String, Integer> counts = new HashMap<>();
for (TreeItem item: items) {
String str = item.toString();
int count = counts.containsKey(str) ? counts.get(str) : 0;
count++;
counts.put(str, count);
if (count > 1) {
indices.put(item, count);
if (item instanceof TagScript) {
Tag tag = ((TagScript) item).getTag();
indices.put(tag, count);
}
}
calculateCollisions(item, indices);
}
}
public final int getItemIndex(TreeItem item) {
if (item instanceof TagScript) {
item = ((TagScript) item).getTag();
}
if (indices.containsKey(item)) {
return indices.get(item);
}
return 1;
}
protected void fireTreeNodesRemoved(TreeModelEvent e) {
for (TreeModelListener listener : listeners) {

View File

@@ -224,6 +224,10 @@ public class TagTree extends AbstractTagTree {
if (aTree.getMainPanel().isClipboardCut() && aTree.getMainPanel().clipboardContains(val)) {
semiTransparent = true;
}
int itemIndex = aTree.getModel().getItemIndex(val);
if (itemIndex > 1) {
setText(val.toString() + " [" + itemIndex + "]");
}
return this;
}

View File

@@ -2340,6 +2340,7 @@ public class TagTreeContextMenu extends JPopupMenu {
r.run();
mainPanel.refreshTree();
}
mainPanel.savePins();
}
}
}

View File

@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedAction;
import com.jpexs.decompiler.flash.gui.helpers.CollectionChangedEvent;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -144,6 +145,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
default:
fireTreeStructureChanged(new TreeModelEvent(this, new TreePath(root)));
}
calculateCollisions();
}
@Override
@@ -151,6 +153,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
swfInfos.clear();
TreePath changedPath = getTreePath(swf == null ? root : swf);
fireTreeStructureChanged(new TreeModelEvent(this, changedPath));
calculateCollisions();
}
private void walkTimelinedTagList(Timelined timelined,
@@ -397,7 +400,7 @@ public class TagTreeModel extends AbstractTagTreeModel {
if (n instanceof AS3ClassTreeItem) {
AS3ClassTreeItem te = (AS3ClassTreeItem) n;
if (obj.equals(te)) {
if (obj == te) {
return newPath;
}
}
@@ -406,19 +409,26 @@ public class TagTreeModel extends AbstractTagTreeModel {
// FolderItems are always recreated, so compare them by name and swf
FolderItem nds = (FolderItem) n;
FolderItem objs = (FolderItem) obj;
if (objs.getName().equals(nds.getName()) && objs.swf.equals(nds.swf)) {
if (objs.getName().equals(nds.getName()) && objs.swf == nds.swf) {
return newPath;
}
} else {
if (obj.equals(n)) {
return newPath;
TreeItem objNoTs = obj;
if (obj instanceof TagScript) {
objNoTs = ((TagScript) obj).getTag();
}
TreeItem nNoTs = n;
if (n instanceof TagScript) {
if (obj.equals(((TagScript) n).getTag())) {
return newPath;
}
nNoTs = ((TagScript) n).getTag();
}
if (objNoTs == nNoTs) {
return newPath;
}
}
ret = searchTreeItem(obj, n, newPath);
@@ -463,6 +473,13 @@ public class TagTreeModel extends AbstractTagTreeModel {
if (mapped == null) {
mapped = new ArrayList<>();
}
mapped = new ArrayList<>(mapped);
for (int i = 0; i < mapped.size(); i++) {
if (mapped.get(i) instanceof DoInitActionTag) {
mapped.remove(i);
i--;
}
}
return mapped;
}