Undo per SWF

This commit is contained in:
Jindra Petřík
2024-10-29 16:55:43 +01:00
parent d4078d3a0c
commit dda394ef52
4 changed files with 89 additions and 52 deletions
@@ -46,7 +46,8 @@ public class EasyPanel extends JPanel {
tabSwitcher.clear();
for (SWF swf : swfs) {
tabSwitcher.addTab(swf, swf.getShortPathTitle(), View.getIcon("flash16"));
}
}
easySwfPanel.clearUndos();
}
public void setSwf(SWF swf) {
@@ -169,7 +169,7 @@ public class EasySwfPanel extends JPanel {
public String getDescription() {
return EasyStrings.translate(transformEnabled ? "action.transform" : "action.move");
}
});
}, timelined.getSwf());
}
@@ -274,7 +274,7 @@ public class EasySwfPanel extends JPanel {
return EasyStrings.translate("action.addToStage");
}
});
}, timelined.getSwf());
return true;
}
@@ -299,7 +299,7 @@ public class EasySwfPanel extends JPanel {
undoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
undoManager.undo();
undoManager.undo(timelined.getSwf());
}
});
@@ -309,7 +309,7 @@ public class EasySwfPanel extends JPanel {
redoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
undoManager.redo();
undoManager.redo(timelined.getSwf());
}
});
@@ -321,22 +321,7 @@ public class EasySwfPanel extends JPanel {
Runnable undoChangeListener = new Runnable() {
@Override
public void run() {
undoButton.setEnabled(undoManager.canUndo());
redoButton.setEnabled(undoManager.canRedo());
if (undoManager.canUndo()) {
undoButton.setToolTipText(EasyStrings.translate("undo").replace("%action%",undoManager.getUndoName()));
} else {
undoButton.setToolTipText(EasyStrings.translate("undo.cannot"));
}
if (undoManager.canRedo()) {
redoButton.setToolTipText(EasyStrings.translate("redo").replace("%action%", undoManager.getRedoName()));
} else {
redoButton.setToolTipText(EasyStrings.translate("redo.cannot"));
}
if (stagePanel.getTimelined() == null) {
return;
}
Main.getMainFrame().getPanel().updateUiWithCurrentOpenable();
updateUndos();
}
};
@@ -472,7 +457,7 @@ public class EasySwfPanel extends JPanel {
private boolean transformEnabled() {
return rightTabbedPane.getSelectedIndex() == 1;
}
}
public void setTimelined(Timelined timelined) {
this.timelined = timelined;
@@ -487,10 +472,33 @@ public class EasySwfPanel extends JPanel {
stagePanel.gotoFrame(0);
timelinePanel.setTimelined(swf);
}
undoManager.clear();
updateUndos();
}
public Openable getOpenable() {
return timelined.getSwf();
}
public void clearUndos() {
undoManager.clear();
}
private void updateUndos() {
undoButton.setEnabled(timelined != null && undoManager.canUndo(timelined.getSwf()));
redoButton.setEnabled(timelined != null && undoManager.canRedo(timelined.getSwf()));
if (timelined != null && undoManager.canUndo(timelined.getSwf())) {
undoButton.setToolTipText(EasyStrings.translate("undo").replace("%action%",undoManager.getUndoName(timelined.getSwf())));
} else {
undoButton.setToolTipText(EasyStrings.translate("undo.cannot"));
}
if (timelined != null && undoManager.canRedo(timelined.getSwf())) {
redoButton.setToolTipText(EasyStrings.translate("redo").replace("%action%", undoManager.getRedoName(timelined.getSwf())));
} else {
redoButton.setToolTipText(EasyStrings.translate("redo.cannot"));
}
if (stagePanel.getTimelined() == null) {
return;
}
Main.getMainFrame().getPanel().updateUiWithCurrentOpenable();
}
}
@@ -727,7 +727,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
public String getDescription() {
return EasyStrings.translate("action.removeFrame");
}
});
}, timeline.timelined.getSwf());
}
private void addKeyFrame(ActionEvent e) {
@@ -799,7 +799,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
public String getDescription() {
return EasyStrings.translate("action.addKeyFrame");
}
});
}, timeline.timelined.getSwf());
}
private void addKeyFrameEmptyBefore(ActionEvent e) {
@@ -863,7 +863,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
public String getDescription() {
return EasyStrings.translate("action.addKeyFrame"); //Intentionally not "...with blank frames before"
}
});
}, timeline.timelined.getSwf());
}
private void addFrame(ActionEvent e) {
@@ -1030,7 +1030,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
public String getDescription() {
return EasyStrings.translate("action.addFrame");
}
});
}, timeline.timelined.getSwf());
}
@Override
@@ -16,16 +16,19 @@
*/
package com.jpexs.decompiler.flash.easygui;
import com.jpexs.decompiler.flash.SWF;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
/**
*
* @author JPEXS
*/
public class UndoManager {
private int historyPos = 0;
private final List<DoableOperation> history = new ArrayList<>();
private final Map<SWF, Integer> historyPosMap = new WeakHashMap<>();
private final Map<SWF, List<DoableOperation>> historyMap = new WeakHashMap<>();
private final List<Runnable> changeListeners = new ArrayList<>();
@@ -43,61 +46,86 @@ public class UndoManager {
}
}
public void doOperation(DoableOperation doableOperation) {
public void doOperation(DoableOperation doableOperation, SWF swf) {
if (!historyMap.containsKey(swf)) {
historyMap.put(swf, new ArrayList<>());
}
if (!historyPosMap.containsKey(swf)) {
historyPosMap.put(swf, 0);
}
int historyPos = historyPosMap.get(swf);
List<DoableOperation> history = historyMap.get(swf);
//drop redos
while(history.size() > historyPos) {
history.remove(historyPos);
}
history.add(doableOperation);
historyPos++;
historyMap.get(swf).add(doableOperation);
historyPosMap.put(swf, historyPosMap.get(swf) + 1);
doableOperation.doOperation();
fireChange();
}
public boolean canUndo() {
return historyPos > 0;
public boolean canUndo(SWF swf) {
if (!historyPosMap.containsKey(swf)) {
return false;
}
return historyPosMap.get(swf) > 0;
}
public String getUndoName() {
if (!canUndo()) {
public String getUndoName(SWF swf) {
if (!canUndo(swf)) {
return null;
}
return history.get(historyPos - 1).getDescription();
return historyMap.get(swf).get(historyPosMap.get(swf) - 1).getDescription();
}
public void undo() {
if (historyPos == 0) {
public void undo(SWF swf) {
if (!canUndo(swf)) {
return;
}
historyPos--;
history.get(historyPos).undoOperation();
historyPosMap.put(swf, historyPosMap.get(swf) - 1);
historyMap.get(swf).get(historyPosMap.get(swf)).undoOperation();
fireChange();
}
public void redo() {
if (!canRedo()) {
public void redo(SWF swf) {
if (!canRedo(swf)) {
return;
}
history.get(historyPos).doOperation();
historyPos++;
historyMap.get(swf).get(historyPosMap.get(swf)).doOperation();
historyPosMap.put(swf, historyPosMap.get(swf) + 1);
fireChange();
}
public String getRedoName() {
if (!canRedo()) {
public String getRedoName(SWF swf) {
if (!canRedo(swf)) {
return null;
}
return history.get(historyPos).getDescription();
return historyMap.get(swf).get(historyPosMap.get(swf)).getDescription();
}
public boolean canRedo() {
return history.size() > historyPos;
public boolean canRedo(SWF swf) {
if (!historyMap.containsKey(swf)) {
return false;
}
return historyMap.get(swf).size() > historyPosMap.get(swf);
}
public void clear() {
history.clear();
historyPos = 0;
historyMap.clear();
historyPosMap.clear();
fireChange();
}
public void clear(SWF swf) {
if (!historyMap.containsKey(swf)) {
return;
}
historyMap.get(swf).clear();
historyPosMap.put(swf, 0);
fireChange();
}
}