mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-29 18:34:42 +00:00
Added
- #1649 Moving SWF files (and bundles) up and down - Moving tags up and down (context menuitem + ALT up/down shortcut)
This commit is contained in:
@@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Move tag with dependencies
|
||||
- Copy/Move tag operation has select position dialog
|
||||
- Select position dialog has target file in its title
|
||||
- [#1649] Moving SWF files (and bundles) up and down (comtext menuitem + ALT up/down shortcut)
|
||||
- Moving tags up and down (context menuitem + ALT up/down shortcut)
|
||||
|
||||
### Fixed
|
||||
- Exception when bundle selected
|
||||
@@ -2538,6 +2540,7 @@ All notable changes to this project will be documented in this file.
|
||||
[alpha 9]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha8...alpha9
|
||||
[alpha 8]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha7...alpha8
|
||||
[alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7
|
||||
[#1649]: https://www.free-decompiler.com/flash/issues/1649
|
||||
[#1863]: https://www.free-decompiler.com/flash/issues/1863
|
||||
[#1414]: https://www.free-decompiler.com/flash/issues/1414
|
||||
[#1755]: https://www.free-decompiler.com/flash/issues/1755
|
||||
|
||||
@@ -399,6 +399,63 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
private boolean clipboardCut = false;
|
||||
|
||||
private void handleTreeKeyReleased(KeyEvent e) {
|
||||
AbstractTagTree tree = (AbstractTagTree) e.getSource();
|
||||
if ((e.getKeyCode() == KeyEvent.VK_UP
|
||||
|| e.getKeyCode() == KeyEvent.VK_DOWN)
|
||||
&& e.isAltDown() && !e.isControlDown() && !e.isShiftDown()) {
|
||||
TreePath paths[] = tree.getSelectionPaths();
|
||||
if (paths == null || paths.length != 1) {
|
||||
return;
|
||||
}
|
||||
TreeItem item = (TreeItem) paths[0].getLastPathComponent();
|
||||
if (e.getKeyCode() == KeyEvent.VK_UP) {
|
||||
contextPopupMenu.moveUpDown(item, true);
|
||||
}
|
||||
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
|
||||
contextPopupMenu.moveUpDown(item, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void moveSwfListUpDown(TreeItem item, boolean up) {
|
||||
SWFList swfList = null;
|
||||
if (item instanceof SWF) {
|
||||
SWF swf = (SWF) item;
|
||||
if (swf.swfList != null && !swf.swfList.isBundle() && swf.swfList.size() == 1) {
|
||||
swfList = swf.swfList;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (item instanceof SWFList) {
|
||||
swfList = (SWFList) item;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
int index = swfs.indexOf(swfList);
|
||||
|
||||
List<List<String>> expandedTagTree = View.getExpandedNodes(tagTree);
|
||||
List<List<String>> expandedTagListTree = View.getExpandedNodes(tagListTree);
|
||||
|
||||
if (up) {
|
||||
if (index <= 0) {
|
||||
return;
|
||||
}
|
||||
swfs.move(index, index - 1);
|
||||
} else {
|
||||
if (index < 0 || index >= swfs.size() - 1) {
|
||||
return;
|
||||
}
|
||||
swfs.move(index, index + 2);
|
||||
}
|
||||
View.expandTreeNodes(tagTree, expandedTagTree);
|
||||
View.expandTreeNodes(tagListTree, expandedTagListTree);
|
||||
TreePath path = getCurrentTree().getModel().getTreePath(item);
|
||||
getCurrentTree().setSelectionPath(path);
|
||||
getCurrentTree().scrollPathToVisible(path);
|
||||
repaintTree();
|
||||
}
|
||||
|
||||
private void handleTreeKeyPressed(KeyEvent e) {
|
||||
AbstractTagTree tree = (AbstractTagTree) e.getSource();
|
||||
if ((e.getKeyCode() == 'C' || e.getKeyCode() == 'X') && (e.isControlDown())) {
|
||||
@@ -943,6 +1000,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
showContentPanelCard(WELCOME_PANEL);
|
||||
|
||||
tagTree.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
handleTreeKeyReleased(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if ((e.getKeyCode() == 'F') && (e.isControlDown())) {
|
||||
@@ -984,6 +1046,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
});
|
||||
tagListTree.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
handleTreeKeyReleased(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
handleTreeKeyPressed(e);
|
||||
|
||||
@@ -22,5 +22,5 @@ package com.jpexs.decompiler.flash.gui.helpers;
|
||||
*/
|
||||
public enum CollectionChangedAction {
|
||||
|
||||
ADD, REMOVE, RESET
|
||||
ADD, REMOVE, RESET, MOVE
|
||||
}
|
||||
|
||||
@@ -49,6 +49,14 @@ public class CollectionChangedEvent<E> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public CollectionChangedEvent(CollectionChangedAction action, E oldItem, E newItem, int oldIndex, int newIndex) {
|
||||
this.action = action;
|
||||
this.oldItem = oldItem;
|
||||
this.newItem = newItem;
|
||||
this.oldIndex = oldIndex;
|
||||
this.newIndex = newIndex;
|
||||
}
|
||||
|
||||
public CollectionChangedAction getAction() {
|
||||
return action;
|
||||
|
||||
@@ -79,6 +79,55 @@ public class ObservableList<E> implements List<E> {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** * Move item to desired position.0 A
|
||||
1 B
|
||||
2 C
|
||||
3 D
|
||||
4 E
|
||||
|
||||
|
||||
move(1, 3)
|
||||
|
||||
0 A
|
||||
1 C
|
||||
2 B
|
||||
3 D
|
||||
4 E
|
||||
|
||||
move(3, 1)
|
||||
0 A
|
||||
1 D
|
||||
2 B
|
||||
3 C
|
||||
4 E
|
||||
* @param oldIndex
|
||||
* @param newIndex
|
||||
* @return
|
||||
*/
|
||||
public boolean move(int oldIndex, int newIndex) {
|
||||
if (oldIndex == newIndex) {
|
||||
return true;
|
||||
}
|
||||
if (oldIndex < 0 || oldIndex >= size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(oldIndex);
|
||||
}
|
||||
if (newIndex < 0 || newIndex > size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(newIndex);
|
||||
}
|
||||
E item = list.remove(oldIndex);
|
||||
if (newIndex > oldIndex) {
|
||||
list.add(newIndex - 1, item);
|
||||
} else {
|
||||
list.add(newIndex, item);
|
||||
}
|
||||
fireCollectionChanged(new CollectionChangedEvent<>(CollectionChangedAction.MOVE, item, item, oldIndex, newIndex));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean move(E item, int newIndex) {
|
||||
return move(indexOf(item), newIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
|
||||
@@ -945,4 +945,6 @@ clipboard.items = %count% items
|
||||
clipboard.clear = Clear the tag clipboard
|
||||
|
||||
#after 16.2.0
|
||||
contextmenu.moveTagWithDependencies = Move tag with dependencies to
|
||||
contextmenu.moveTagWithDependencies = Move tag with dependencies to
|
||||
contextmenu.moveUp = Move up
|
||||
contextmenu.moveDown = Move down
|
||||
@@ -917,4 +917,6 @@ clipboard.items = %count% polo\u017eek
|
||||
clipboard.clear = Vy\u010distit tagovou schr\u00e1nku
|
||||
|
||||
#after 16.2.0
|
||||
contextmenu.moveTagWithDependencies = P\u0159esunout tag se z\u00e1vislostmi do
|
||||
contextmenu.moveTagWithDependencies = P\u0159esunout tag se z\u00e1vislostmi do
|
||||
contextmenu.moveUp = Posunout nahoru
|
||||
contextmenu.moveDown = Posunout dol\u016f
|
||||
@@ -175,7 +175,8 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
|
||||
@Override
|
||||
public void updateSwfs(CollectionChangedEvent e) {
|
||||
if (e.getAction() != CollectionChangedAction.ADD) {
|
||||
if (e.getAction() != CollectionChangedAction.ADD &&
|
||||
e.getAction() != CollectionChangedAction.MOVE) {
|
||||
List<SWF> toRemove = new ArrayList<>();
|
||||
for (SWF swf : swfHeaders.keySet()) {
|
||||
SWF swf2 = swf.getRootSwf();
|
||||
@@ -200,6 +201,12 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
fireTreeNodesRemoved(new TreeModelEvent(this, rootPath, new int[]{e.getOldIndex()}, new Object[]{e.getOldItem()}));
|
||||
break;
|
||||
}
|
||||
/*case MOVE: {
|
||||
TreePath rootPath = new TreePath(new Object[]{root});
|
||||
fireTreeNodesRemoved(new TreeModelEvent(this, rootPath, new int[]{e.getOldIndex()}, new Object[]{e.getOldItem()}));
|
||||
fireTreeNodesInserted(new TreeModelEvent(this, rootPath, new int[]{e.getNewIndex()}, new Object[]{e.getNewItem()}));
|
||||
break;
|
||||
}*/
|
||||
default:
|
||||
fireTreeStructureChanged(new TreeModelEvent(this, new TreePath(root)));
|
||||
}
|
||||
|
||||
@@ -169,7 +169,11 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
private JMenu moveTagToMenu;
|
||||
|
||||
private JMenu moveTagToWithDependenciesMenu;
|
||||
|
||||
|
||||
private JMenuItem moveUpMenuItem;
|
||||
|
||||
private JMenuItem moveDownMenuItem;
|
||||
|
||||
private JMenu copyTagToMenu;
|
||||
|
||||
private JMenu copyTagToWithDependenciesMenu;
|
||||
@@ -207,7 +211,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
private JMenuItem addFramesAfterMenuItem;
|
||||
|
||||
private static final int KIND_MOVETO = 0;
|
||||
private static final int KIND_MOVETODEPS = 1;
|
||||
private static final int KIND_MOVETODEPS = 1;
|
||||
private static final int KIND_COPYTO = 2;
|
||||
private static final int KIND_COPYTODEPS = 3;
|
||||
|
||||
@@ -357,7 +361,16 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
moveTagToWithDependenciesMenu.setIcon(View.getIcon("move16"));
|
||||
add(moveTagToWithDependenciesMenu);
|
||||
|
||||
|
||||
moveUpMenuItem = new JMenuItem(mainPanel.translate("contextmenu.moveUp")+" (ALT + UP)");
|
||||
moveUpMenuItem.setIcon(View.getIcon("arrowup16"));
|
||||
moveUpMenuItem.addActionListener(this::moveUpActionPerformed);
|
||||
add(moveUpMenuItem);
|
||||
|
||||
moveDownMenuItem = new JMenuItem(mainPanel.translate("contextmenu.moveDown") + " (ALT + DOWN)");
|
||||
moveDownMenuItem.setIcon(View.getIcon("arrowdown16"));
|
||||
moveDownMenuItem.addActionListener(this::moveDownActionPerformed);
|
||||
add(moveDownMenuItem);
|
||||
|
||||
copyTagToMenu = new JMenu(mainPanel.translate("contextmenu.copyTag"));
|
||||
copyTagToMenu.setIcon(View.getIcon("copy16"));
|
||||
add(copyTagToMenu);
|
||||
@@ -673,6 +686,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
addTagAfterMenu.setVisible(false);
|
||||
moveTagToMenu.setVisible(false);
|
||||
moveTagToWithDependenciesMenu.setVisible(false);
|
||||
moveUpMenuItem.setVisible(false);
|
||||
moveDownMenuItem.setVisible(false);
|
||||
copyTagToMenu.setVisible(false);
|
||||
copyTagToWithDependenciesMenu.setVisible(false);
|
||||
cutTagToClipboardMenuItem.setVisible(false);
|
||||
@@ -854,6 +869,22 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
pasteBeforeMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((firstItem instanceof Tag) && (getTree() == mainPanel.tagListTree)) {
|
||||
moveUpMenuItem.setVisible(true);
|
||||
moveDownMenuItem.setVisible(true);
|
||||
}
|
||||
if (firstItem instanceof SWF) {
|
||||
SWF firstSwf = (SWF) firstItem;
|
||||
if (firstSwf.swfList != null && !firstSwf.swfList.isBundle() && firstSwf.swfList.size() == 1) {
|
||||
moveUpMenuItem.setVisible(true);
|
||||
moveDownMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
if (firstItem instanceof SWFList) {
|
||||
moveUpMenuItem.setVisible(true);
|
||||
moveDownMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
moveTagToMenu.removeAll();
|
||||
@@ -1210,7 +1241,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
t.setTimelined(timelined);
|
||||
timelined.resetTimeline();
|
||||
|
||||
timelined.setFrameCount(timelined.getTimeline().getFrameCount());
|
||||
timelined.setFrameCount(timelined.getTimeline().getFrameCount());
|
||||
}
|
||||
|
||||
swf.updateCharacters();
|
||||
@@ -1296,7 +1327,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
tag.setSwf(targetSwf, true);
|
||||
tag.setTimelined(timelined);
|
||||
checkUniqueCharacterId(tag);
|
||||
int positionInt = position == null ? timelined.getTags().size() : timelined.indexOfTag(position);
|
||||
int positionInt = position == null ? timelined.getTags().size() : timelined.indexOfTag(position);
|
||||
timelined.addTag(positionInt, tag);
|
||||
targetSwf.updateCharacters();
|
||||
tag.setModified(true);
|
||||
@@ -1312,9 +1343,9 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
targetSwf.updateCharacters();
|
||||
sourceSwf.resetTimelines(sourceSwf);
|
||||
targetSwf.resetTimelines(targetSwf);
|
||||
|
||||
|
||||
timelined.setFrameCount(timelined.getTimeline().getFrameCount());
|
||||
|
||||
|
||||
mainPanel.refreshTree(new SWF[]{sourceSwf, targetSwf});
|
||||
}
|
||||
|
||||
@@ -1325,29 +1356,29 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
}
|
||||
Tag position = selectPositionDialog.getSelectedTag();
|
||||
Timelined timelined = selectPositionDialog.getSelectedTimelined();
|
||||
copyOrMoveTags(new LinkedHashSet<TreeItem>(items), false, timelined, position);
|
||||
copyOrMoveTags(new LinkedHashSet<TreeItem>(items), false, timelined, position);
|
||||
}
|
||||
|
||||
private void copyTagWithDependenciesToActionPerformed(ActionEvent evt, List<TreeItem> items, SWF targetSwf) {
|
||||
private void copyTagWithDependenciesToActionPerformed(ActionEvent evt, List<TreeItem> items, SWF targetSwf) {
|
||||
SelectTagPositionDialog selectPositionDialog = new SelectTagPositionDialog(mainPanel.getMainFrame().getWindow(), targetSwf, true);
|
||||
if (selectPositionDialog.showDialog() != AppDialog.OK_OPTION) {
|
||||
return;
|
||||
}
|
||||
Tag position = selectPositionDialog.getSelectedTag();
|
||||
Timelined timelined = selectPositionDialog.getSelectedTimelined();
|
||||
|
||||
copyOrMoveTags(getDependenciesSet(items), false, timelined, position);
|
||||
|
||||
copyOrMoveTags(getDependenciesSet(items), false, timelined, position);
|
||||
}
|
||||
|
||||
private void moveTagWithDependenciesToActionPerformed(ActionEvent evt, List<TreeItem> items, SWF targetSwf) {
|
||||
|
||||
private void moveTagWithDependenciesToActionPerformed(ActionEvent evt, List<TreeItem> items, SWF targetSwf) {
|
||||
SelectTagPositionDialog selectPositionDialog = new SelectTagPositionDialog(mainPanel.getMainFrame().getWindow(), targetSwf, true);
|
||||
if (selectPositionDialog.showDialog() != AppDialog.OK_OPTION) {
|
||||
return;
|
||||
}
|
||||
Tag position = selectPositionDialog.getSelectedTag();
|
||||
Timelined timelined = selectPositionDialog.getSelectedTimelined();
|
||||
|
||||
copyOrMoveTags(getDependenciesSet(items), true, timelined, position);
|
||||
|
||||
copyOrMoveTags(getDependenciesSet(items), true, timelined, position);
|
||||
}
|
||||
|
||||
private void openSwfInsideActionPerformed(ActionEvent evt) {
|
||||
@@ -2558,7 +2589,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
break;
|
||||
case KIND_MOVETODEPS:
|
||||
moveTagWithDependenciesToActionPerformed(ae, items, targetSwf);
|
||||
break;
|
||||
break;
|
||||
case KIND_COPYTO:
|
||||
copyTagToActionPerformed(ae, items, targetSwf);
|
||||
break;
|
||||
@@ -2856,4 +2887,76 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
mainPanel.importSymbolClass(swf);
|
||||
}
|
||||
|
||||
public void moveUpActionPerformed(ActionEvent evt) {
|
||||
moveUpDown(getTree().getCurrentTreeItem(), true);
|
||||
}
|
||||
|
||||
public void moveDownActionPerformed(ActionEvent evt) {
|
||||
moveUpDown(getTree().getCurrentTreeItem(), false);
|
||||
}
|
||||
|
||||
public void moveUpDown(TreeItem item, boolean up) {
|
||||
if ((item instanceof SWF) || (item instanceof SWFList)) {
|
||||
mainPanel.moveSwfListUpDown(item, up);
|
||||
return;
|
||||
}
|
||||
if (!(item instanceof Tag)) {
|
||||
return;
|
||||
}
|
||||
if (getTree() != mainPanel.tagListTree) {
|
||||
return;
|
||||
}
|
||||
Set<TreeItem> itemsToMove = new HashSet<>();
|
||||
itemsToMove.add(item);
|
||||
Tag tag = (Tag) item;
|
||||
int index = tag.getTimelined().indexOfTag(tag);
|
||||
Tag position = null;
|
||||
Timelined timelined = null;
|
||||
ReadOnlyTagList tags = tag.getTimelined().getTags();
|
||||
if (up) {
|
||||
|
||||
if (index == 0) {
|
||||
if (tag.getTimelined() instanceof SWF) {
|
||||
return;
|
||||
}
|
||||
//move one level UP
|
||||
position = (DefineSpriteTag) tag.getTimelined();
|
||||
} else {
|
||||
index = tag.getTimelined().indexOfTag(tag);
|
||||
index--;
|
||||
|
||||
position = tag.getTimelined().getTags().get(index);
|
||||
}
|
||||
timelined = position.getTimelined();
|
||||
} else {
|
||||
if (index == tags.size() - 1) {
|
||||
if (tag.getTimelined() instanceof SWF) {
|
||||
return;
|
||||
}
|
||||
timelined = ((DefineSpriteTag) tag.getTimelined()).getTimelined();
|
||||
index = timelined.getTags().indexOf((DefineSpriteTag) tag.getTimelined());
|
||||
index++;
|
||||
if (index >= timelined.getTags().size()) {
|
||||
position = null;
|
||||
} else {
|
||||
position = timelined.getTags().get(index);
|
||||
}
|
||||
} else {
|
||||
timelined = tag.getTimelined();
|
||||
index = timelined.indexOfTag(tag);
|
||||
index += 2;
|
||||
if (index >= timelined.getTags().size()) {
|
||||
position = null;
|
||||
} else {
|
||||
position = timelined.getTags().get(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
copyOrMoveTags(itemsToMove, true, timelined, position);
|
||||
|
||||
TreePath path = getTree().getModel().getTreePath(item);
|
||||
getTree().setSelectionPath(path);
|
||||
getTree().scrollPathToVisible(path);
|
||||
mainPanel.repaintTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
}
|
||||
|
||||
public void updateSwfs(CollectionChangedEvent e) {
|
||||
if (e.getAction() != CollectionChangedAction.ADD) {
|
||||
if (e.getAction() != CollectionChangedAction.ADD &&
|
||||
e.getAction() != CollectionChangedAction.MOVE) {
|
||||
List<SWF> toRemove = new ArrayList<>();
|
||||
for (SWF swf : swfInfos.keySet()) {
|
||||
SWF swf2 = swf.getRootSwf();
|
||||
@@ -134,6 +135,12 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
fireTreeNodesRemoved(new TreeModelEvent(this, rootPath, new int[]{e.getOldIndex()}, new Object[]{e.getOldItem()}));
|
||||
break;
|
||||
}
|
||||
/*case MOVE: {
|
||||
TreePath rootPath = new TreePath(new Object[]{root});
|
||||
fireTreeNodesRemoved(new TreeModelEvent(this, rootPath, new int[]{e.getOldIndex()}, new Object[]{e.getOldItem()}));
|
||||
fireTreeNodesInserted(new TreeModelEvent(this, rootPath, new int[]{e.getNewIndex()}, new Object[]{e.getNewItem()}));
|
||||
break;
|
||||
}*/
|
||||
default:
|
||||
fireTreeStructureChanged(new TreeModelEvent(this, new TreePath(root)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user