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

Last change on this file since 2602 was 2552, checked in by bastiK, 14 years ago

cleanup for r2539 and r2541. See #3520

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data;
3
4import java.util.Collection;
5import java.util.Iterator;
6import java.util.List;
7import java.util.LinkedList;
8import java.util.Stack;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.command.Command;
12import org.openstreetmap.josm.data.osm.DataSet;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.gui.layer.Layer;
15import org.openstreetmap.josm.gui.layer.OsmDataLayer;
16import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
17import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
18
19public class UndoRedoHandler implements LayerChangeListener {
20
21 /**
22 * All commands that were made on the dataset. Don't write from outside!
23 */
24 public final LinkedList<Command> commands = new LinkedList<Command>();
25 /**
26 * The stack for redoing commands
27 */
28 private final Stack<Command> redoCommands = new Stack<Command>();
29
30 public final LinkedList<CommandQueueListener> listenerCommands = new LinkedList<CommandQueueListener>();
31
32 public UndoRedoHandler() {
33 Layer.listeners.add(this);
34 }
35
36 /**
37 * Execute the command and add it to the intern command queue.
38 */
39 public void addNoRedraw(final Command c) {
40 c.executeCommand();
41 commands.add(c);
42 redoCommands.clear();
43 }
44
45 public void afterAdd() {
46 if (Main.map != null && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
47 OsmDataLayer data = (OsmDataLayer)Main.map.mapView.getActiveLayer();
48 data.fireDataChange();
49 }
50 fireCommandsChanged();
51
52 // the command may have changed the selection so tell the listeners about the current situation
53 Main.main.getCurrentDataSet().fireSelectionChanged();
54 }
55
56 /**
57 * Execute the command and add it to the intern command queue.
58 */
59 public void add(final Command c) {
60 addNoRedraw(c);
61 afterAdd();
62 }
63
64 /**
65 * Undoes the last added command.
66 */
67 public void undo() {
68 if (commands.isEmpty())
69 return;
70 Collection<? extends OsmPrimitive> oldSelection = Main.main.getCurrentDataSet().getSelected();
71 final Command c = commands.removeLast();
72 c.undoCommand();
73 redoCommands.push(c);
74 if (Main.map != null && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
75 OsmDataLayer data = (OsmDataLayer)Main.map.mapView.getActiveLayer();
76 data.fireDataChange();
77 }
78 fireCommandsChanged();
79 Collection<? extends OsmPrimitive> newSelection = Main.main.getCurrentDataSet().getSelected();
80 if (!oldSelection.equals(newSelection)) {
81 Main.main.getCurrentDataSet().fireSelectionChanged();
82 }
83 }
84
85 /**
86 * Redoes the last undoed command.
87 * TODO: This has to be moved to a central place in order to support multiple layers.
88 */
89 public void redo() {
90 if (redoCommands.isEmpty())
91 return;
92 Collection<? extends OsmPrimitive> oldSelection = Main.main.getCurrentDataSet().getSelected();
93 final Command c = redoCommands.pop();
94 c.executeCommand();
95 commands.add(c);
96 if (Main.map != null && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
97 OsmDataLayer data = (OsmDataLayer)Main.map.mapView.getActiveLayer();
98 data.fireDataChange();
99 }
100 fireCommandsChanged();
101 Collection<? extends OsmPrimitive> newSelection = Main.main.getCurrentDataSet().getSelected();
102 if (!oldSelection.equals(newSelection)) {
103 Main.main.getCurrentDataSet().fireSelectionChanged();
104 }
105 }
106
107 public void fireCommandsChanged() {
108 for (final CommandQueueListener l : listenerCommands) {
109 l.commandChanged(commands.size(), redoCommands.size());
110 }
111 }
112
113 public void clean() {
114 redoCommands.clear();
115 commands.clear();
116 fireCommandsChanged();
117 }
118
119 public void clean(Layer layer) {
120 if (layer == null)
121 return;
122 boolean changed = false;
123 for (Iterator<Command> it = commands.iterator(); it.hasNext();) {
124 if (it.next().invalidBecauselayerRemoved(layer)) {
125 it.remove();
126 changed = true;
127 }
128 }
129 for (Iterator<Command> it = redoCommands.iterator(); it.hasNext();) {
130 if (it.next().invalidBecauselayerRemoved(layer)) {
131 it.remove();
132 changed = true;
133 }
134 }
135 if (changed) {
136 fireCommandsChanged();
137 }
138 }
139
140 public void layerRemoved(Layer oldLayer) {
141 clean(oldLayer);
142 }
143
144 public void layerAdded(Layer newLayer) {}
145 public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
146}
Note: See TracBrowser for help on using the repository browser.