diff --git a/src/org/openstreetmap/josm/command/Command.java b/src/org/openstreetmap/josm/command/Command.java
index 945967a..a865bea 100644
|
a
|
b
|
public abstract class Command extends PseudoCommand {
|
| 147 | 147 | /** |
| 148 | 148 | * Executes the command on the dataset. This implementation will remember all |
| 149 | 149 | * primitives returned by fillModifiedData for restoring them on undo. |
| | 150 | * <p> |
| | 151 | * The layer is invalidated after execution so that it can be re-painted. |
| 150 | 152 | * @return true |
| 151 | 153 | */ |
| 152 | 154 | public boolean executeCommand() { |
| … |
… |
public abstract class Command extends PseudoCommand {
|
| 299 | 301 | return Objects.equals(cloneMap, command.cloneMap) && |
| 300 | 302 | Objects.equals(layer, command.layer); |
| 301 | 303 | } |
| | 304 | |
| | 305 | /** |
| | 306 | * Invalidate all layers that were affected by this command. |
| | 307 | * @see Layer#invalidate() |
| | 308 | */ |
| | 309 | public void invalidateAffectedLayers() { |
| | 310 | OsmDataLayer layer = getLayer(); |
| | 311 | if (layer != null) { |
| | 312 | layer.invalidate(); |
| | 313 | } |
| | 314 | } |
| 302 | 315 | } |
diff --git a/src/org/openstreetmap/josm/command/SequenceCommand.java b/src/org/openstreetmap/josm/command/SequenceCommand.java
index 22428c8..eb74259 100644
|
a
|
b
|
public class SequenceCommand extends Command {
|
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | @Override |
| | 128 | public void invalidateAffectedLayers() { |
| | 129 | super.invalidateAffectedLayers(); |
| | 130 | for (Command c : sequence) { |
| | 131 | c.invalidateAffectedLayers(); |
| | 132 | } |
| | 133 | } |
| | 134 | |
| | 135 | @Override |
| 128 | 136 | public int hashCode() { |
| 129 | 137 | return Objects.hash(super.hashCode(), Arrays.hashCode(sequence), sequenceComplete, name, continueOnError); |
| 130 | 138 | } |
diff --git a/src/org/openstreetmap/josm/data/UndoRedoHandler.java b/src/org/openstreetmap/josm/data/UndoRedoHandler.java
index 7118052..bb39aae 100644
|
a
|
b
|
import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
|
| 14 | 14 | import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; |
| 15 | 15 | import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; |
| 16 | 16 | import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; |
| | 17 | import org.openstreetmap.josm.gui.layer.OsmDataLayer; |
| 17 | 18 | import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener; |
| 18 | 19 | import org.openstreetmap.josm.tools.CheckParameterUtil; |
| 19 | 20 | |
| | 21 | /** |
| | 22 | * This is the global undo/redo handler for all {@link OsmDataLayer}s. |
| | 23 | * <p> |
| | 24 | * If you want to change a data layer, you can use {@link #add(Command)} to execute a command on it and make that command undoable. |
| | 25 | */ |
| 20 | 26 | public class UndoRedoHandler implements LayerChangeListener { |
| 21 | 27 | |
| 22 | 28 | /** |
| … |
… |
public class UndoRedoHandler implements LayerChangeListener {
|
| 44 | 50 | public void addNoRedraw(final Command c) { |
| 45 | 51 | CheckParameterUtil.ensureParameterNotNull(c, "c"); |
| 46 | 52 | c.executeCommand(); |
| | 53 | c.invalidateAffectedLayers(); |
| 47 | 54 | commands.add(c); |
| 48 | 55 | // Limit the number of commands in the undo list. |
| 49 | 56 | // Currently you have to undo the commands one by one. If |
| … |
… |
public class UndoRedoHandler implements LayerChangeListener {
|
| 54 | 61 | redoCommands.clear(); |
| 55 | 62 | } |
| 56 | 63 | |
| | 64 | /** |
| | 65 | * Fires a commands change event after adding a command. |
| | 66 | */ |
| 57 | 67 | public void afterAdd() { |
| 58 | 68 | fireCommandsChanged(); |
| 59 | | |
| 60 | | // the command may have changed the selection so tell the listeners about the current situation |
| 61 | | DataSet ds = Main.getLayerManager().getEditDataSet(); |
| 62 | | if (ds != null) { |
| 63 | | ds.fireSelectionChanged(); |
| 64 | | } |
| 65 | 69 | } |
| 66 | 70 | |
| 67 | 71 | /** |
| … |
… |
public class UndoRedoHandler implements LayerChangeListener {
|
| 69 | 73 | * @param c The command to execute. Must not be {@code null}. |
| 70 | 74 | */ |
| 71 | 75 | public synchronized void add(final Command c) { |
| | 76 | DataSet ds = Main.getLayerManager().getEditDataSet(); |
| | 77 | Collection<? extends OsmPrimitive> oldSelection = ds.getSelected(); |
| 72 | 78 | addNoRedraw(c); |
| 73 | 79 | afterAdd(); |
| | 80 | |
| | 81 | // the command may have changed the selection so tell the listeners about the current situation |
| | 82 | fireIfSelectionChanged(ds, oldSelection); |
| 74 | 83 | } |
| 75 | 84 | |
| 76 | 85 | /** |
| … |
… |
public class UndoRedoHandler implements LayerChangeListener {
|
| 87 | 96 | public synchronized void undo(int num) { |
| 88 | 97 | if (commands.isEmpty()) |
| 89 | 98 | return; |
| 90 | | Collection<? extends OsmPrimitive> oldSelection = Main.getLayerManager().getEditDataSet().getSelected(); |
| 91 | | Main.getLayerManager().getEditDataSet().beginUpdate(); |
| | 99 | DataSet ds = Main.getLayerManager().getEditDataSet(); |
| | 100 | Collection<? extends OsmPrimitive> oldSelection = ds.getSelected(); |
| | 101 | ds.beginUpdate(); |
| 92 | 102 | try { |
| 93 | 103 | for (int i = 1; i <= num; ++i) { |
| 94 | 104 | final Command c = commands.removeLast(); |
| 95 | 105 | c.undoCommand(); |
| | 106 | c.invalidateAffectedLayers(); |
| 96 | 107 | redoCommands.addFirst(c); |
| 97 | 108 | if (commands.isEmpty()) { |
| 98 | 109 | break; |
| 99 | 110 | } |
| 100 | 111 | } |
| 101 | 112 | } finally { |
| 102 | | Main.getLayerManager().getEditDataSet().endUpdate(); |
| | 113 | ds.endUpdate(); |
| 103 | 114 | } |
| 104 | 115 | fireCommandsChanged(); |
| 105 | | Collection<? extends OsmPrimitive> newSelection = Main.getLayerManager().getEditDataSet().getSelected(); |
| 106 | | if (!oldSelection.equals(newSelection)) { |
| 107 | | Main.getLayerManager().getEditDataSet().fireSelectionChanged(); |
| 108 | | } |
| | 116 | fireIfSelectionChanged(ds, oldSelection); |
| 109 | 117 | } |
| 110 | 118 | |
| 111 | 119 | /** |
| … |
… |
public class UndoRedoHandler implements LayerChangeListener {
|
| 122 | 130 | public void redo(int num) { |
| 123 | 131 | if (redoCommands.isEmpty()) |
| 124 | 132 | return; |
| 125 | | Collection<? extends OsmPrimitive> oldSelection = Main.getLayerManager().getEditDataSet().getSelected(); |
| | 133 | DataSet ds = Main.getLayerManager().getEditDataSet(); |
| | 134 | Collection<? extends OsmPrimitive> oldSelection = ds.getSelected(); |
| 126 | 135 | for (int i = 0; i < num; ++i) { |
| 127 | 136 | final Command c = redoCommands.removeFirst(); |
| 128 | 137 | c.executeCommand(); |
| | 138 | c.invalidateAffectedLayers(); |
| 129 | 139 | commands.add(c); |
| 130 | 140 | if (redoCommands.isEmpty()) { |
| 131 | 141 | break; |
| 132 | 142 | } |
| 133 | 143 | } |
| 134 | 144 | fireCommandsChanged(); |
| 135 | | Collection<? extends OsmPrimitive> newSelection = Main.getLayerManager().getEditDataSet().getSelected(); |
| | 145 | fireIfSelectionChanged(ds, oldSelection); |
| | 146 | } |
| | 147 | |
| | 148 | private static void fireIfSelectionChanged(DataSet ds, Collection<? extends OsmPrimitive> oldSelection) { |
| | 149 | Collection<? extends OsmPrimitive> newSelection = ds.getSelected(); |
| 136 | 150 | if (!oldSelection.equals(newSelection)) { |
| 137 | | Main.getLayerManager().getEditDataSet().fireSelectionChanged(); |
| | 151 | ds.fireSelectionChanged(); |
| 138 | 152 | } |
| 139 | 153 | } |
| 140 | 154 | |
| 141 | | public void fireCommandsChanged() { |
| | 155 | /** |
| | 156 | * Fires a command change to all listeners. |
| | 157 | */ |
| | 158 | private void fireCommandsChanged() { |
| 142 | 159 | for (final CommandQueueListener l : listenerCommands) { |
| 143 | 160 | l.commandChanged(commands.size(), redoCommands.size()); |
| 144 | 161 | } |
| 145 | 162 | } |
| 146 | 163 | |
| | 164 | /** |
| | 165 | * Resets the undo/redo list. |
| | 166 | */ |
| 147 | 167 | public void clean() { |
| 148 | 168 | redoCommands.clear(); |
| 149 | 169 | commands.clear(); |
| 150 | 170 | fireCommandsChanged(); |
| 151 | 171 | } |
| 152 | 172 | |
| | 173 | /** |
| | 174 | * Resets all commands that affect the given layer. |
| | 175 | * @param layer The layer that was affected. |
| | 176 | */ |
| 153 | 177 | public void clean(Layer layer) { |
| 154 | 178 | if (layer == null) |
| 155 | 179 | return; |
diff --git a/src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java b/src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java
index 1b37a88..28febcc 100644
|
a
|
b
|
public class ValidatorDialog extends ToggleDialog implements SelectionChangedLis
|
| 607 | 607 | } |
| 608 | 608 | |
| 609 | 609 | @Override |
| 610 | | protected void realRun() throws SAXException, IOException, |
| 611 | | OsmTransferException { |
| | 610 | protected void realRun() throws SAXException, IOException, OsmTransferException { |
| 612 | 611 | ProgressMonitor monitor = getProgressMonitor(); |
| 613 | 612 | try { |
| 614 | 613 | monitor.setTicksCount(testErrors.size()); |
| | 614 | final DataSet ds = Main.getLayerManager().getEditDataSet(); |
| 615 | 615 | int i = 0; |
| 616 | 616 | SwingUtilities.invokeAndWait(new Runnable() { |
| 617 | 617 | @Override |
| 618 | 618 | public void run() { |
| 619 | | Main.getLayerManager().getEditDataSet().beginUpdate(); |
| | 619 | ds.beginUpdate(); |
| 620 | 620 | } |
| 621 | 621 | }); |
| 622 | 622 | try { |
| … |
… |
public class ValidatorDialog extends ToggleDialog implements SelectionChangedLis
|
| 632 | 632 | SwingUtilities.invokeAndWait(new Runnable() { |
| 633 | 633 | @Override |
| 634 | 634 | public void run() { |
| 635 | | Main.getLayerManager().getEditDataSet().endUpdate(); |
| | 635 | ds.endUpdate(); |
| 636 | 636 | } |
| 637 | 637 | }); |
| 638 | 638 | } |
| … |
… |
public class ValidatorDialog extends ToggleDialog implements SelectionChangedLis
|
| 643 | 643 | Main.main.undoRedo.afterAdd(); |
| 644 | 644 | Main.map.repaint(); |
| 645 | 645 | tree.resetErrors(); |
| 646 | | Main.getLayerManager().getEditDataSet().fireSelectionChanged(); |
| | 646 | ds.fireSelectionChanged(); |
| 647 | 647 | } |
| 648 | 648 | }); |
| 649 | 649 | } catch (InterruptedException | InvocationTargetException e) { |
diff --git a/test/unit/org/openstreetmap/josm/actions/mapmode/DrawActionTest.java b/test/unit/org/openstreetmap/josm/actions/mapmode/DrawActionTest.java
index e7ac1b4..1bd00dc 100644
|
a
|
b
|
public class DrawActionTest {
|
| 52 | 52 | public void testTicket12011() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { |
| 53 | 53 | DataSet dataSet = new DataSet(); |
| 54 | 54 | OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null); |
| | 55 | Main.getLayerManager().addLayer(layer); |
| 55 | 56 | |
| 56 | 57 | Field mapView = MapFrame.class.getDeclaredField("mapView"); |
| 57 | 58 | Utils.setObjectsAccessible(mapView); |
| … |
… |
public class DrawActionTest {
|
| 67 | 68 | w.setNodes(Arrays.asList(new Node[] {n1, n2})); |
| 68 | 69 | dataSet.addPrimitive(w); |
| 69 | 70 | |
| 70 | | Main.getLayerManager().addLayer(layer); |
| 71 | 71 | try { |
| 72 | 72 | assertTrue(Main.map.selectDrawTool(false)); |
| 73 | 73 | |