source: josm/trunk/src/org/openstreetmap/josm/data/UndoRedoHandler.java@ 6336

Last change on this file since 6336 was 6084, checked in by bastiK, 11 years ago

see #8902 - add missing @Override annotations (patch by shinigami)

  • Property svn:eol-style set to native
File size: 5.2 KB
RevLine 
[304]1//License: GPL. Copyright 2007 by Immanuel Scholz and others
[301]2package org.openstreetmap.josm.data;
3
[2539]4import java.util.Collection;
[304]5import java.util.Iterator;
[301]6import java.util.LinkedList;
7
8import org.openstreetmap.josm.Main;
9import org.openstreetmap.josm.command.Command;
[2539]10import org.openstreetmap.josm.data.osm.OsmPrimitive;
[2621]11import org.openstreetmap.josm.gui.MapView;
[304]12import org.openstreetmap.josm.gui.layer.Layer;
[301]13import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
14
[2621]15public class UndoRedoHandler implements MapView.LayerChangeListener {
[301]16
[1169]17 /**
18 * All commands that were made on the dataset. Don't write from outside!
19 */
20 public final LinkedList<Command> commands = new LinkedList<Command>();
21 /**
22 * The stack for redoing commands
23 */
[3262]24 public final LinkedList<Command> redoCommands = new LinkedList<Command>();
[301]25
[4908]26 private final LinkedList<CommandQueueListener> listenerCommands = new LinkedList<CommandQueueListener>();
[301]27
[1169]28 public UndoRedoHandler() {
[2621]29 MapView.addLayerChangeListener(this);
[1169]30 }
[304]31
[1169]32 /**
33 * Execute the command and add it to the intern command queue.
34 */
[2098]35 public void addNoRedraw(final Command c) {
[1169]36 c.executeCommand();
37 commands.add(c);
[3143]38 // Limit the number of commands in the undo list.
39 // Currently you have to undo the commands one by one. If
40 // this changes, a higher default value may be reasonable.
41 if (commands.size() > Main.pref.getInteger("undo.max", 1000)) {
42 commands.removeFirst();
43 }
[1169]44 redoCommands.clear();
[2098]45 }
46
47 public void afterAdd() {
[1169]48 fireCommandsChanged();
[1877]49
50 // the command may have changed the selection so tell the listeners about the current situation
[2348]51 Main.main.getCurrentDataSet().fireSelectionChanged();
[1169]52 }
[304]53
[1169]54 /**
[2098]55 * Execute the command and add it to the intern command queue.
56 */
[2975]57 synchronized public void add(final Command c) {
[2098]58 addNoRedraw(c);
59 afterAdd();
60 }
61
62 /**
[1169]63 * Undoes the last added command.
64 */
[3262]65 public void undo() {
66 undo(1);
67 }
68
69 /**
70 * Undoes multiple commands.
71 */
72 synchronized public void undo(int num) {
[1169]73 if (commands.isEmpty())
74 return;
[2552]75 Collection<? extends OsmPrimitive> oldSelection = Main.main.getCurrentDataSet().getSelected();
[3910]76 Main.main.getCurrentDataSet().beginUpdate();
77 try {
78 for (int i=1; i<=num; ++i) {
79 final Command c = commands.removeLast();
80 c.undoCommand();
81 redoCommands.addFirst(c);
82 if (commands.isEmpty()) {
83 break;
84 }
[3479]85 }
[3262]86 }
[3910]87 finally {
88 Main.main.getCurrentDataSet().endUpdate();
89 }
[1169]90 fireCommandsChanged();
[2552]91 Collection<? extends OsmPrimitive> newSelection = Main.main.getCurrentDataSet().getSelected();
92 if (!oldSelection.equals(newSelection)) {
93 Main.main.getCurrentDataSet().fireSelectionChanged();
[2539]94 }
[1169]95 }
[301]96
[1169]97 /**
98 * Redoes the last undoed command.
99 */
100 public void redo() {
[3262]101 redo(1);
102 }
103
104 /**
105 * Redoes multiple commands.
106 */
107 public void redo(int num) {
[1169]108 if (redoCommands.isEmpty())
109 return;
[2552]110 Collection<? extends OsmPrimitive> oldSelection = Main.main.getCurrentDataSet().getSelected();
[3262]111 for (int i=0; i<num; ++i) {
[3275]112 final Command c = redoCommands.removeFirst();
[3262]113 c.executeCommand();
114 commands.add(c);
[3479]115 if (redoCommands.isEmpty()) {
[3262]116 break;
[3479]117 }
[3262]118 }
[1169]119 fireCommandsChanged();
[2552]120 Collection<? extends OsmPrimitive> newSelection = Main.main.getCurrentDataSet().getSelected();
121 if (!oldSelection.equals(newSelection)) {
122 Main.main.getCurrentDataSet().fireSelectionChanged();
123 }
[1169]124 }
[301]125
[1169]126 public void fireCommandsChanged() {
[1814]127 for (final CommandQueueListener l : listenerCommands) {
[1169]128 l.commandChanged(commands.size(), redoCommands.size());
[1814]129 }
[1169]130 }
[301]131
[1169]132 public void clean() {
133 redoCommands.clear();
134 commands.clear();
135 fireCommandsChanged();
136 }
[304]137
[1894]138 public void clean(Layer layer) {
139 if (layer == null)
140 return;
[1169]141 boolean changed = false;
142 for (Iterator<Command> it = commands.iterator(); it.hasNext();) {
[1894]143 if (it.next().invalidBecauselayerRemoved(layer)) {
[1169]144 it.remove();
145 changed = true;
146 }
147 }
148 for (Iterator<Command> it = redoCommands.iterator(); it.hasNext();) {
[1894]149 if (it.next().invalidBecauselayerRemoved(layer)) {
[1169]150 it.remove();
151 changed = true;
152 }
153 }
[1814]154 if (changed) {
[1169]155 fireCommandsChanged();
[1814]156 }
[1169]157 }
[304]158
[6084]159 @Override
[1894]160 public void layerRemoved(Layer oldLayer) {
161 clean(oldLayer);
162 }
163
[6084]164 @Override
[1169]165 public void layerAdded(Layer newLayer) {}
[6084]166 @Override
[1169]167 public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
[4908]168
169 public void removeCommandQueueListener(CommandQueueListener l) {
170 listenerCommands.remove(l);
171 }
172
173 public boolean addCommandQueueListener(CommandQueueListener l) {
174 return listenerCommands.add(l);
175 }
[301]176}
Note: See TracBrowser for help on using the repository browser.