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

Last change on this file since 2725 was 2621, checked in by Gubaer, 14 years ago

Moved layer listener management from Layer to MapView
Made sure that listeners also unregister when they register for layer change events.

This will certainly break plugins. Plugin updates will follow later.

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