|
|||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| CommandHistory.java | 100% | 94.1% | 87.5% | 93.1% |
|
||||||||||||||
| 1 |
package abbot.editor.actions;
|
|
| 2 |
|
|
| 3 |
import java.util.ArrayList;
|
|
| 4 |
|
|
| 5 |
/** Keep a history of commands, enabling potentially unlimited undo.
|
|
| 6 |
This class is not synchronized.<p>
|
|
| 7 |
|
|
| 8 |
Note that undo is itself an undoable action.<p>
|
|
| 9 |
*/
|
|
| 10 |
|
|
| 11 |
public class CommandHistory { |
|
| 12 |
private ArrayList list = new ArrayList(); |
|
| 13 |
/** The index of the most recent command "undone", or the size of the
|
|
| 14 |
* history if the most recent action was "execute".
|
|
| 15 |
*/
|
|
| 16 |
private int cursor = 0; |
|
| 17 |
|
|
| 18 | 14 |
private Command get(int idx) { |
| 19 | 14 |
return ((Command)list.get(idx));
|
| 20 |
} |
|
| 21 |
|
|
| 22 | 12 |
public boolean canUndo() { |
| 23 | 12 |
return cursor > 0 && (get(cursor-1) instanceof Undoable); |
| 24 |
} |
|
| 25 |
|
|
| 26 | 4 |
public void undo() throws NoUndoException { |
| 27 | 4 |
if (canUndo()) {
|
| 28 | 3 |
UndoableCommand undoable = (UndoableCommand)get(--cursor); |
| 29 | 3 |
undoable.undo(); |
| 30 |
// Add the undo to the end of the history
|
|
| 31 | 3 |
list.add(new CommandComplement(undoable));
|
| 32 |
} |
|
| 33 |
else {
|
|
| 34 |
// Reset the cursor to the end of the history
|
|
| 35 | 1 |
cursor = list.size(); |
| 36 | 1 |
throw new NoUndoException(); |
| 37 |
} |
|
| 38 |
} |
|
| 39 |
|
|
| 40 |
/** Add the given command to the command history. */
|
|
| 41 | 3 |
public void add(Command command) { |
| 42 |
// If the command can't be undone, then clear the undo history
|
|
| 43 | 3 |
if (!(command instanceof Undoable)) { |
| 44 | 2 |
clear(); |
| 45 |
} |
|
| 46 | 3 |
list.add(command); |
| 47 |
// Put the cursor at the end of the command history
|
|
| 48 | 3 |
cursor = list.size(); |
| 49 |
} |
|
| 50 |
|
|
| 51 | 2 |
public void clear() { |
| 52 | 2 |
list.clear(); |
| 53 | 2 |
cursor = 0; |
| 54 |
} |
|
| 55 |
|
|
| 56 |
/** Simple wrapper around an existing command to swap the sense of its
|
|
| 57 |
execute/undo.
|
|
| 58 |
*/
|
|
| 59 |
private class CommandComplement implements UndoableCommand { |
|
| 60 |
private UndoableCommand cmd;
|
|
| 61 | 3 |
public CommandComplement(UndoableCommand orig) {
|
| 62 | 3 |
cmd = orig; |
| 63 |
} |
|
| 64 | 0 |
public void execute() { |
| 65 | 0 |
cmd.undo(); |
| 66 |
} |
|
| 67 | 1 |
public void undo() { |
| 68 | 1 |
cmd.execute(); |
| 69 |
} |
|
| 70 |
} |
|
| 71 |
} |
|
| 72 |
|
|
||||||||||