Ticket #13019: patch-layer-command-implicit-redraw.patch

File patch-layer-command-implicit-redraw.patch, 10.8 KB (added by michael2402, 8 years ago)
  • src/org/openstreetmap/josm/command/Command.java

    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 {  
    147147    /**
    148148     * Executes the command on the dataset. This implementation will remember all
    149149     * 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.
    150152     * @return true
    151153     */
    152154    public boolean executeCommand() {
    public abstract class Command extends PseudoCommand {  
    299301        return Objects.equals(cloneMap, command.cloneMap) &&
    300302                Objects.equals(layer, command.layer);
    301303    }
     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    }
    302315}
  • src/org/openstreetmap/josm/command/SequenceCommand.java

    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 {  
    125125    }
    126126
    127127    @Override
     128    public void invalidateAffectedLayers() {
     129        super.invalidateAffectedLayers();
     130        for (Command c : sequence) {
     131            c.invalidateAffectedLayers();
     132        }
     133    }
     134
     135    @Override
    128136    public int hashCode() {
    129137        return Objects.hash(super.hashCode(), Arrays.hashCode(sequence), sequenceComplete, name, continueOnError);
    130138    }
  • src/org/openstreetmap/josm/data/UndoRedoHandler.java

    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;  
    1414import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    1515import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    1616import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
     17import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1718import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
    1819import org.openstreetmap.josm.tools.CheckParameterUtil;
    1920
     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 */
    2026public class UndoRedoHandler implements LayerChangeListener {
    2127
    2228    /**
    public class UndoRedoHandler implements LayerChangeListener {  
    4450    public void addNoRedraw(final Command c) {
    4551        CheckParameterUtil.ensureParameterNotNull(c, "c");
    4652        c.executeCommand();
     53        c.invalidateAffectedLayers();
    4754        commands.add(c);
    4855        // Limit the number of commands in the undo list.
    4956        // Currently you have to undo the commands one by one. If
    public class UndoRedoHandler implements LayerChangeListener {  
    5461        redoCommands.clear();
    5562    }
    5663
     64    /**
     65     * Fires a commands change event after adding a command.
     66     */
    5767    public void afterAdd() {
    5868        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         }
    6569    }
    6670
    6771    /**
    public class UndoRedoHandler implements LayerChangeListener {  
    6973     * @param c The command to execute. Must not be {@code null}.
    7074     */
    7175    public synchronized void add(final Command c) {
     76        DataSet ds = Main.getLayerManager().getEditDataSet();
     77        Collection<? extends OsmPrimitive> oldSelection = ds.getSelected();
    7278        addNoRedraw(c);
    7379        afterAdd();
     80
     81        // the command may have changed the selection so tell the listeners about the current situation
     82        fireIfSelectionChanged(ds, oldSelection);
    7483    }
    7584
    7685    /**
    public class UndoRedoHandler implements LayerChangeListener {  
    8796    public synchronized void undo(int num) {
    8897        if (commands.isEmpty())
    8998            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();
    92102        try {
    93103            for (int i = 1; i <= num; ++i) {
    94104                final Command c = commands.removeLast();
    95105                c.undoCommand();
     106                c.invalidateAffectedLayers();
    96107                redoCommands.addFirst(c);
    97108                if (commands.isEmpty()) {
    98109                    break;
    99110                }
    100111            }
    101112        } finally {
    102             Main.getLayerManager().getEditDataSet().endUpdate();
     113            ds.endUpdate();
    103114        }
    104115        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);
    109117    }
    110118
    111119    /**
    public class UndoRedoHandler implements LayerChangeListener {  
    122130    public void redo(int num) {
    123131        if (redoCommands.isEmpty())
    124132            return;
    125         Collection<? extends OsmPrimitive> oldSelection = Main.getLayerManager().getEditDataSet().getSelected();
     133        DataSet ds = Main.getLayerManager().getEditDataSet();
     134        Collection<? extends OsmPrimitive> oldSelection = ds.getSelected();
    126135        for (int i = 0; i < num; ++i) {
    127136            final Command c = redoCommands.removeFirst();
    128137            c.executeCommand();
     138            c.invalidateAffectedLayers();
    129139            commands.add(c);
    130140            if (redoCommands.isEmpty()) {
    131141                break;
    132142            }
    133143        }
    134144        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();
    136150        if (!oldSelection.equals(newSelection)) {
    137             Main.getLayerManager().getEditDataSet().fireSelectionChanged();
     151            ds.fireSelectionChanged();
    138152        }
    139153    }
    140154
    141     public void fireCommandsChanged() {
     155    /**
     156     * Fires a command change to all listeners.
     157     */
     158    private void fireCommandsChanged() {
    142159        for (final CommandQueueListener l : listenerCommands) {
    143160            l.commandChanged(commands.size(), redoCommands.size());
    144161        }
    145162    }
    146163
     164    /**
     165     * Resets the undo/redo list.
     166     */
    147167    public void clean() {
    148168        redoCommands.clear();
    149169        commands.clear();
    150170        fireCommandsChanged();
    151171    }
    152172
     173    /**
     174     * Resets all commands that affect the given layer.
     175     * @param layer The layer that was affected.
     176     */
    153177    public void clean(Layer layer) {
    154178        if (layer == null)
    155179            return;
  • src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java

    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  
    607607        }
    608608
    609609        @Override
    610         protected void realRun() throws SAXException, IOException,
    611         OsmTransferException {
     610        protected void realRun() throws SAXException, IOException, OsmTransferException {
    612611            ProgressMonitor monitor = getProgressMonitor();
    613612            try {
    614613                monitor.setTicksCount(testErrors.size());
     614                final DataSet ds = Main.getLayerManager().getEditDataSet();
    615615                int i = 0;
    616616                SwingUtilities.invokeAndWait(new Runnable() {
    617617                    @Override
    618618                    public void run() {
    619                         Main.getLayerManager().getEditDataSet().beginUpdate();
     619                        ds.beginUpdate();
    620620                    }
    621621                });
    622622                try {
    public class ValidatorDialog extends ToggleDialog implements SelectionChangedLis  
    632632                    SwingUtilities.invokeAndWait(new Runnable() {
    633633                        @Override
    634634                        public void run() {
    635                             Main.getLayerManager().getEditDataSet().endUpdate();
     635                            ds.endUpdate();
    636636                        }
    637637                    });
    638638                }
    public class ValidatorDialog extends ToggleDialog implements SelectionChangedLis  
    643643                        Main.main.undoRedo.afterAdd();
    644644                        Main.map.repaint();
    645645                        tree.resetErrors();
    646                         Main.getLayerManager().getEditDataSet().fireSelectionChanged();
     646                        ds.fireSelectionChanged();
    647647                    }
    648648                });
    649649            } catch (InterruptedException | InvocationTargetException e) {
  • test/unit/org/openstreetmap/josm/actions/mapmode/DrawActionTest.java

    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 {  
    5252    public void testTicket12011() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
    5353        DataSet dataSet = new DataSet();
    5454        OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
     55        Main.getLayerManager().addLayer(layer);
    5556
    5657        Field mapView = MapFrame.class.getDeclaredField("mapView");
    5758        Utils.setObjectsAccessible(mapView);
    public class DrawActionTest {  
    6768        w.setNodes(Arrays.asList(new Node[] {n1, n2}));
    6869        dataSet.addPrimitive(w);
    6970
    70         Main.getLayerManager().addLayer(layer);
    7171        try {
    7272            assertTrue(Main.map.selectDrawTool(false));
    7373