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

Last change on this file since 9128 was 8510, checked in by Don-vip, 9 years ago

checkstyle: enable relevant whitespace checks and fix them

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