Ticket #13036: commands-layerv2.patch

File commands-layerv2.patch, 73.8 KB (added by Don-vip, 3 months ago)
  • src/org/openstreetmap/josm/Main.java

     
    136136    /**
    137137     * The commands undo/redo handler.
    138138     */
    139     public final UndoRedoHandler undoRedo = MainApplication.undoRedo;
     139    public final UndoRedoHandler undoRedo = new UndoRedoHandler();
    140140
    141141    /**
    142142     * The main menu bar at top of screen.
     
    629629    }
    630630
    631631    /**
    632      * Gets the data set of the active edit layer.
    633      * @return That data set, <code>null</code> if there is no edit layer.
     632     * Gets the active edit data set.
     633     * @return That data set, <code>null</code>.
    634634     * @since 12691
    635635     */
    636     public DataSet getEditDataSet() {
    637         return null;
    638     }
     636    public abstract DataSet getEditDataSet();
     637
     638    /**
     639     * Sets the active data set.
     640     * @param ds New edit data set, or <code>null</code>
     641     * @since xxx
     642     */
     643    public abstract void setEditDataSet(DataSet ds);
     644
     645    /**
     646     * Determines if the list of data sets managed by JOSM contains {@code ds}.
     647     * @param ds the data set to look for
     648     * @return {@code true} if the list of data sets managed by JOSM contains {@code ds}
     649     * @since xxx
     650     */
     651    public abstract boolean containsDataSet(DataSet ds);
     652
     653    /**
     654     * This needs to be called whenever the content of the data set was invalidated.
     655     * It triggers a repaint of the components that display it.
     656     * @param ds the data set to invalidate
     657     * @since xxx
     658     */
     659    public abstract void invalidateDataSet(DataSet ds);
    639660
    640661    /**
    641662     * Registers a {@code JosmAction} and its shortcut.
  • src/org/openstreetmap/josm/actions/JoinAreasAction.java

     
    692692
    693693        // Delete the discarded inner ways
    694694        if (!discardedWays.isEmpty()) {
    695             Command deleteCmd = DeleteCommand.delete(getLayerManager().getEditLayer(), discardedWays, true);
     695            Command deleteCmd = DeleteCommand.delete(discardedWays, true);
    696696            if (deleteCmd != null) {
    697697                cmds.add(deleteCmd);
    698698                commitCommands(marktr("Delete Ways that are not part of an inner multipolygon"));
     
    10171017        List<List<Node>> chunks = buildNodeChunks(way, nodes);
    10181018
    10191019        if (chunks.size() > 1) {
    1020             SplitWayResult split = SplitWayAction.splitWay(getLayerManager().getEditLayer(), way, chunks,
     1020            SplitWayResult split = SplitWayAction.splitWay(way, chunks,
    10211021                    Collections.<OsmPrimitive>emptyList(), SplitWayAction.Strategy.keepFirstChunk());
    10221022
    10231023            if (split != null) {
     
    14661466        for (Way w : inner) {
    14671467            newRel.addMember(new RelationMember("inner", w));
    14681468        }
    1469         cmds.add(layer != null ? new AddCommand(layer, newRel) :
     1469        cmds.add(layer != null ? new AddCommand(layer.data, newRel) :
    14701470            new AddCommand(inner.iterator().next().getDataSet(), newRel));
    14711471        addedRelations.add(newRel);
    14721472
     
    15371537            cmds.add(new ChangeCommand(r.rel, newRel));
    15381538        }
    15391539
    1540         OsmDataLayer layer = getLayerManager().getEditLayer();
    15411540        Relation newRel;
    15421541        switch (multiouters.size()) {
    15431542        case 0:
     
    15661565                relationsToDelete.add(r.rel);
    15671566            }
    15681567            newRel.addMember(new RelationMember("outer", outer));
    1569             cmds.add(layer != null ? new AddCommand(layer, newRel) : new AddCommand(outer.getDataSet(), newRel));
     1568            cmds.add(new AddCommand(outer.getDataSet(), newRel));
    15701569        }
    15711570    }
    15721571
  • src/org/openstreetmap/josm/actions/PurgeAction.java

     
    117117    public PurgeCommand getPurgeCommand(Collection<OsmPrimitive> sel) {
    118118        layer = getLayerManager().getEditLayer();
    119119        toPurgeAdditionally = new ArrayList<>();
    120         PurgeCommand cmd = PurgeCommand.build(layer, sel, toPurgeAdditionally);
     120        PurgeCommand cmd = PurgeCommand.build(sel, toPurgeAdditionally);
    121121        modified = cmd.getParticipatingPrimitives().stream().anyMatch(OsmPrimitive::isModified);
    122122        return cmd;
    123123    }
  • src/org/openstreetmap/josm/actions/RedoAction.java

     
    88import java.awt.event.KeyEvent;
    99
    1010import org.openstreetmap.josm.Main;
     11import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    1112import org.openstreetmap.josm.gui.MainApplication;
    1213import org.openstreetmap.josm.gui.MapFrame;
    13 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1414import org.openstreetmap.josm.tools.Shortcut;
    1515
    1616/**
     
    1818 *
    1919 * @author imi
    2020 */
    21 public class RedoAction extends JosmAction implements OsmDataLayer.CommandQueueListener {
     21public class RedoAction extends JosmAction implements CommandQueueListener {
    2222
    2323    /**
    2424     * Construct the action with "Redo" as label.
  • src/org/openstreetmap/josm/actions/SplitWayAction.java

     
    213213                }
    214214            }
    215215            if (wayToKeep != null) {
    216                 final SplitWayResult result = doSplitWay(getLayerManager().getEditLayer(), selectedWay, wayToKeep, newWays, sel);
     216                final SplitWayResult result = doSplitWay(selectedWay, wayToKeep, newWays, sel);
    217217                MainApplication.undoRedo.add(result.getCommand());
    218218                if (!result.getNewSelection().isEmpty()) {
    219219                    getLayerManager().getEditDataSet().setSelected(result.getNewSelection());
     
    293293            super.buttonAction(buttonIndex, evt);
    294294            toggleSaveState(); // necessary since #showDialog() does not handle it due to the non-modal dialog
    295295            if (getValue() == 1) {
    296                 SplitWayResult result = doSplitWay(MainApplication.getLayerManager().getEditLayer(),
    297                         selectedWay, list.getSelectedValue(), newWays, selection);
     296                SplitWayResult result = doSplitWay(selectedWay, list.getSelectedValue(), newWays, selection);
    298297                MainApplication.undoRedo.add(result.getCommand());
    299298                if (!result.getNewSelection().isEmpty()) {
    300299                    MainApplication.getLayerManager().getEditDataSet().setSelected(result.getNewSelection());
     
    497496     * @param wayChunks the list of way chunks into the way is split. Must not be null.
    498497     * @param selection The list of currently selected primitives
    499498     * @return the result from the split operation
     499     * @deprecated to be removed end of 2017. Use {@link #splitWay(Way, List, Collection)} instead
    500500     */
     501    @Deprecated
    501502    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks,
    502503            Collection<? extends OsmPrimitive> selection) {
    503         return splitWay(layer, way, wayChunks, selection, Strategy.keepLongestChunk());
     504        return splitWay(way, wayChunks, selection);
     505    }
     506
     507    /**
     508     * Splits the way {@code way} into chunks of {@code wayChunks} and replies
     509     * the result of this process in an instance of {@link SplitWayResult}.
     510     *
     511     * Note that changes are not applied to the data yet. You have to
     512     * submit the command in {@link SplitWayResult#getCommand()} first,
     513     * i.e. {@code Main.main.undoredo.add(result.getCommand())}.
     514     *
     515     * @param way the way to split. Must not be null.
     516     * @param wayChunks the list of way chunks into the way is split. Must not be null.
     517     * @param selection The list of currently selected primitives
     518     * @return the result from the split operation
     519     * @since xxx
     520     */
     521    public static SplitWayResult splitWay(Way way, List<List<Node>> wayChunks,
     522            Collection<? extends OsmPrimitive> selection) {
     523        return splitWay(way, wayChunks, selection, Strategy.keepLongestChunk());
    504524    }
    505525
    506526    /**
     
    520540     * @param splitStrategy The strategy used to determine which way chunk should reuse the old id and its history
    521541     * @return the result from the split operation
    522542     * @since 8954
     543     * @deprecated to be removed end of 2017. Use {@link #splitWay(Way, List, Collection, Strategy)} instead
    523544     */
     545    @Deprecated
    524546    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks,
    525547            Collection<? extends OsmPrimitive> selection, Strategy splitStrategy) {
     548        return splitWay(way, wayChunks, selection, splitStrategy);
     549    }
     550
     551    /**
     552     * Splits the way {@code way} into chunks of {@code wayChunks} and replies
     553     * the result of this process in an instance of {@link SplitWayResult}.
     554     * The {@link org.openstreetmap.josm.actions.SplitWayAction.Strategy} is used to determine which
     555     * way chunk should reuse the old id and its history.
     556     *
     557     * Note that changes are not applied to the data yet. You have to
     558     * submit the command in {@link SplitWayResult#getCommand()} first,
     559     * i.e. {@code Main.main.undoredo.add(result.getCommand())}.
     560     *
     561     * @param way the way to split. Must not be null.
     562     * @param wayChunks the list of way chunks into the way is split. Must not be null.
     563     * @param selection The list of currently selected primitives
     564     * @param splitStrategy The strategy used to determine which way chunk should reuse the old id and its history
     565     * @return the result from the split operation
     566     * @since xxx
     567     */
     568    public static SplitWayResult splitWay(Way way, List<List<Node>> wayChunks,
     569            Collection<? extends OsmPrimitive> selection, Strategy splitStrategy) {
    526570        // build a list of commands, and also a new selection list
    527571        final List<OsmPrimitive> newSelection = new ArrayList<>(selection.size() + wayChunks.size());
    528572        newSelection.addAll(selection);
     
    533577        // Determine which part reuses the existing way
    534578        final Way wayToKeep = splitStrategy.determineWayToKeep(newWays);
    535579
    536         return wayToKeep != null ? doSplitWay(layer, way, wayToKeep, newWays, newSelection) : null;
     580        return wayToKeep != null ? doSplitWay(way, wayToKeep, newWays, newSelection) : null;
    537581    }
    538582
    539     static SplitWayResult doSplitWay(OsmDataLayer layer, Way way, Way wayToKeep, List<Way> newWays,
    540                                    List<OsmPrimitive> newSelection) {
     583    static SplitWayResult doSplitWay(Way way, Way wayToKeep, List<Way> newWays, List<OsmPrimitive> newSelection) {
    541584
    542585        Collection<Command> commandList = new ArrayList<>(newWays.size());
    543586        Collection<String> nowarnroles = Main.pref.getCollection("way.split.roles.nowarn",
     
    549592        // Change the original way
    550593        final Way changedWay = new Way(way);
    551594        changedWay.setNodes(wayToKeep.getNodes());
    552         commandList.add(layer != null ? new ChangeCommand(layer, way, changedWay) : new ChangeCommand(way.getDataSet(), way, changedWay));
     595        commandList.add(new ChangeCommand(way.getDataSet(), way, changedWay));
    553596        if (!isMapModeDraw && !newSelection.contains(way)) {
    554597            newSelection.add(way);
    555598        }
     
    560603            newSelection.addAll(newWays);
    561604        }
    562605        for (Way wayToAdd : newWays) {
    563             commandList.add(layer != null ? new AddCommand(layer, wayToAdd) : new AddCommand(way.getDataSet(), wayToAdd));
     606            commandList.add(new AddCommand(way.getDataSet(), wayToAdd));
    564607        }
    565608
    566609        boolean warnmerole = false;
     
    687730            }
    688731
    689732            if (c != null) {
    690                 commandList.add(layer != null ? new ChangeCommand(layer, r, c) : new ChangeCommand(r.getDataSet(), r, c));
     733                commandList.add(new ChangeCommand(r.getDataSet(), r, c));
    691734            }
    692735        }
    693736        if (warnmerole) {
     
    740783     * @param atNodes the list of nodes where the way is split. Must not be null.
    741784     * @param selection The list of currently selected primitives
    742785     * @return the result from the split operation
     786     * @deprecated to be removed end of 2017. Use {@link #split(Way, List, Collection) instead}
    743787     */
     788    @Deprecated
    744789    public static SplitWayResult split(OsmDataLayer layer, Way way, List<Node> atNodes, Collection<? extends OsmPrimitive> selection) {
     790        return split(way, atNodes, selection);
     791    }
     792
     793    /**
     794     * Splits the way {@code way} at the nodes in {@code atNodes} and replies
     795     * the result of this process in an instance of {@link SplitWayResult}.
     796     *
     797     * Note that changes are not applied to the data yet. You have to
     798     * submit the command in {@link SplitWayResult#getCommand()} first,
     799     * i.e. {@code Main.main.undoredo.add(result.getCommand())}.
     800     *
     801     * Replies null if the way couldn't be split at the given nodes.
     802     *
     803     * @param way the way to split. Must not be null.
     804     * @param atNodes the list of nodes where the way is split. Must not be null.
     805     * @param selection The list of currently selected primitives
     806     * @return the result from the split operation
     807     * @since xxx
     808     */
     809    public static SplitWayResult split(Way way, List<Node> atNodes, Collection<? extends OsmPrimitive> selection) {
    745810        List<List<Node>> chunks = buildSplitChunks(way, atNodes);
    746         return chunks != null ? splitWay(layer, way, chunks, selection) : null;
     811        return chunks != null ? splitWay(way, chunks, selection) : null;
    747812    }
    748813
    749814    @Override
  • src/org/openstreetmap/josm/actions/UndoAction.java

     
    88import java.awt.event.KeyEvent;
    99
    1010import org.openstreetmap.josm.Main;
     11import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    1112import org.openstreetmap.josm.gui.MainApplication;
    1213import org.openstreetmap.josm.gui.MapFrame;
    13 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1414import org.openstreetmap.josm.tools.Shortcut;
    1515
    1616/**
     
    1818 *
    1919 * @author imi
    2020 */
    21 public class UndoAction extends JosmAction implements OsmDataLayer.CommandQueueListener {
     21public class UndoAction extends JosmAction implements CommandQueueListener {
    2222
    2323    /**
    2424     * Construct the action with "Undo" as label.
  • src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java

     
    150150
    151151        Command c;
    152152        if (ctrl) {
    153             c = DeleteCommand.deleteWithReferences(editLayer, lm.getEditDataSet().getSelected());
     153            c = DeleteCommand.deleteWithReferences(lm.getEditDataSet().getSelected());
    154154        } else {
    155             c = DeleteCommand.delete(editLayer, lm.getEditDataSet().getSelected(), !alt /* also delete nodes in way */);
     155            c = DeleteCommand.delete(lm.getEditDataSet().getSelected(), !alt /* also delete nodes in way */);
    156156        }
    157157        // if c is null, an error occurred or the user aborted. Don't do anything in that case.
    158158        if (c != null) {
     
    351351        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    352352        CheckParameterUtil.ensureParameterNotNull(toDelete, "toDelete");
    353353
    354         final Command cmd = DeleteCommand.delete(layer, toDelete);
     354        final Command cmd = DeleteCommand.delete(toDelete);
    355355        if (cmd != null) {
    356356            // cmd can be null if the user cancels dialogs DialogCommand displays
    357357            MainApplication.undoRedo.add(cmd);
     
    403403     */
    404404    private Command buildDeleteCommands(MouseEvent e, int modifiers, boolean silent) {
    405405        DeleteParameters parameters = getDeleteParameters(e, modifiers);
    406         OsmDataLayer editLayer = getLayerManager().getEditLayer();
    407406        switch (parameters.mode) {
    408407        case node:
    409             return DeleteCommand.delete(editLayer, Collections.singleton(parameters.nearestNode), false, silent);
     408            return DeleteCommand.delete(Collections.singleton(parameters.nearestNode), false, silent);
    410409        case node_with_references:
    411             return DeleteCommand.deleteWithReferences(editLayer, Collections.singleton(parameters.nearestNode), silent);
     410            return DeleteCommand.deleteWithReferences(Collections.singleton(parameters.nearestNode), silent);
    412411        case segment:
    413             return DeleteCommand.deleteWaySegment(editLayer, parameters.nearestSegment);
     412            return DeleteCommand.deleteWaySegment(parameters.nearestSegment);
    414413        case way:
    415             return DeleteCommand.delete(editLayer, Collections.singleton(parameters.nearestSegment.way), false, silent);
     414            return DeleteCommand.delete(Collections.singleton(parameters.nearestSegment.way), false, silent);
    416415        case way_with_nodes:
    417             return DeleteCommand.delete(editLayer, Collections.singleton(parameters.nearestSegment.way), true, silent);
     416            return DeleteCommand.delete(Collections.singleton(parameters.nearestSegment.way), true, silent);
    418417        case way_with_references:
    419             return DeleteCommand.deleteWithReferences(editLayer, Collections.singleton(parameters.nearestSegment.way), true);
     418            return DeleteCommand.deleteWithReferences(Collections.singleton(parameters.nearestSegment.way), true);
    420419        default:
    421420            return null;
    422421        }
  • src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java

     
    487487                    nodes.remove(candidateNode);
    488488                    newWay.setNodes(nodes);
    489489                    if (nodes.size() < 2) {
    490                         final Command deleteCmd = DeleteCommand.delete(getLayerManager().getEditLayer(), Collections.singleton(targetWay), true);
     490                        final Command deleteCmd = DeleteCommand.delete(Collections.singleton(targetWay), true);
    491491                        if (deleteCmd != null) {
    492492                            MainApplication.undoRedo.add(deleteCmd);
    493493                        }
     
    499499                            tr("Cannot delete node that has tags"),
    500500                            tr("Error"), JOptionPane.ERROR_MESSAGE);
    501501                } else {
    502                     final Command deleteCmd = DeleteCommand.delete(getLayerManager().getEditLayer(), Collections.singleton(candidateNode), true);
     502                    final Command deleteCmd = DeleteCommand.delete(Collections.singleton(candidateNode), true);
    503503                    if (deleteCmd != null) {
    504504                        MainApplication.undoRedo.add(deleteCmd);
    505505                    }
  • src/org/openstreetmap/josm/actions/relation/RecentRelationsAction.java

     
    1818import javax.swing.plaf.basic.BasicArrowButton;
    1919
    2020import org.openstreetmap.josm.actions.JosmAction;
     21import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    2122import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
    2223import org.openstreetmap.josm.data.osm.Relation;
    2324import org.openstreetmap.josm.gui.MainApplication;
    2425import org.openstreetmap.josm.gui.SideButton;
    2526import org.openstreetmap.josm.gui.layer.Layer;
    2627import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    27 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
    2828import org.openstreetmap.josm.tools.ImageProvider;
    2929import org.openstreetmap.josm.tools.Shortcut;
    3030
  • src/org/openstreetmap/josm/command/AddCommand.java

     
    4444     * Creates the command and specify the element to add in the context of the given data layer.
    4545     * @param layer The data layer. Must not be {@code null}
    4646     * @param osm The primitive to add
     47     * @deprecated to be removed end of 2017. Use {@link #AddCommand(DataSet, OsmPrimitive)} instead
    4748     */
     49    @Deprecated
    4850    public AddCommand(OsmDataLayer layer, OsmPrimitive osm) {
    4951        super(layer);
    5052        this.osm = Objects.requireNonNull(osm, "osm");
  • src/org/openstreetmap/josm/command/AddPrimitivesCommand.java

     
    5858     * @param data The OSM primitives data to add. Must not be {@code null}
    5959     * @param toSelect The OSM primitives to select at the end. Can be {@code null}
    6060     * @param layer The target data layer. Must not be {@code null}
     61     * @deprecated to be removed end of 2017. Use {@link #AddPrimitivesCommand(List, List, DataSet)} instead
    6162     */
     63    @Deprecated
    6264    public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, OsmDataLayer layer) {
    6365        super(layer);
    6466        init(data, toSelect);
    6567    }
    6668
     69    /**
     70     * Constructs a new {@code AddPrimitivesCommand} to add data to the given data set.
     71     * @param data The OSM primitives data to add. Must not be {@code null}
     72     * @param toSelect The OSM primitives to select at the end. Can be {@code null}
     73     * @param ds The target data set. Must not be {@code null}
     74     * @since xxx
     75     */
     76    public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, DataSet ds) {
     77        super(ds);
     78        init(data, toSelect);
     79    }
     80
    6781    private void init(List<PrimitiveData> data, List<PrimitiveData> toSelect) {
    6882        CheckParameterUtil.ensureParameterNotNull(data, "data");
    6983        this.data = new ArrayList<>(data);
  • src/org/openstreetmap/josm/command/ChangeCommand.java

     
    4444     * @param layer The data layer
    4545     * @param osm The existing primitive to modify
    4646     * @param newOsm The new primitive
     47     * @deprecated to be removed end of 2017. Use {@link #ChangeCommand(DataSet, OsmPrimitive, OsmPrimitive)} instead
    4748     */
     49    @Deprecated
    4850    public ChangeCommand(OsmDataLayer layer, OsmPrimitive osm, OsmPrimitive newOsm) {
    4951        super(layer);
    5052        this.osm = osm;
  • src/org/openstreetmap/josm/command/Command.java

     
    3434 * Classes implementing Command modify a dataset in a specific way. A command is
    3535 * one atomic action on a specific dataset, such as move or delete.
    3636 *
    37  * The command remembers the {@link OsmDataLayer} it is operating on.
     37 * The command remembers the {@link DataSet} it is operating on.
    3838 *
    3939 * @author imi
    4040 * @since 21 (creation)
     
    134134    /** the map of OsmPrimitives in the original state to OsmPrimitives in cloned state */
    135135    private Map<OsmPrimitive, PrimitiveData> cloneMap = new HashMap<>();
    136136
    137     /** the layer which this command is applied to */
     137    /**
     138     * the layer which this command is applied to
     139     * @deprecated to be removed end of 2017. Use {@link #data} instead
     140     */
     141    @Deprecated
    138142    private final OsmDataLayer layer;
    139143
    140144    /** the dataset which this command is applied to */
     
    145149     */
    146150    public Command() {
    147151        this.layer = MainApplication.getLayerManager().getEditLayer();
    148         this.data = layer != null ? layer.data : null;
     152        this.data = layer != null ? layer.data : Main.main.getEditDataSet();
    149153    }
    150154
    151155    /**
     
    153157     *
    154158     * @param layer the data layer. Must not be null.
    155159     * @throws IllegalArgumentException if layer is null
     160     * @deprecated to be removed end of 2017. Use {@link #Command(DataSet)} instead
    156161     */
     162    @Deprecated
    157163    public Command(OsmDataLayer layer) {
    158164        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    159165        this.layer = layer;
     
    215221     *
    216222     * @param oldLayer the old layer that was removed
    217223     * @return true if this command is invalid after that layer is removed.
     224     * @deprecated to be removed end of 2017. Use {@link #invalidBecauseDatasetRemoved} instead
    218225     */
     226    @Deprecated
    219227    public boolean invalidBecauselayerRemoved(Layer oldLayer) {
    220228        return layer == oldLayer;
    221229    }
    222230
    223231    /**
     232     * Called when a dataset has been removed to have the command remove itself from
     233     * any buffer if it is not longer applicable to it (e.g. it was part of
     234     * the removed dataset)
     235     *
     236     * @param oldDataset the old data set that was removed
     237     * @return true if this command is invalid after that data set is removed.
     238     * @since xxx
     239     */
     240    public boolean invalidBecauseDatasetRemoved(DataSet oldDataset) {
     241        return data == oldDataset;
     242    }
     243
     244    /**
    224245     * Lets other commands access the original version
    225246     * of the object. Usually for undoing.
    226247     * @param osm The requested OSM object
     
    233254    /**
    234255     * Replies the layer this command is (or was) applied to.
    235256     * @return the layer this command is (or was) applied to
     257     * @deprecated to be removed end of 2017. Use {@link #getAffectedDataSet} instead
    236258     */
     259    @Deprecated
    237260    protected OsmDataLayer getLayer() {
    238261        return layer;
    239262    }
     
    370393    /**
    371394     * Invalidate all layers that were affected by this command.
    372395     * @see Layer#invalidate()
     396     * @deprecated to be removed end of 2017. Use {@link #invalidateAffectedDataSet} instead
    373397     */
     398    @Deprecated
    374399    public void invalidateAffectedLayers() {
    375400        OsmDataLayer layer = getLayer();
    376401        if (layer != null) {
    377402            layer.invalidate();
    378403        }
    379404    }
     405
     406    /**
     407     * Invalidate data set that was affected by this command.
     408     * @see Main#invalidateDataSet
     409     * @since xxx
     410     */
     411    public void invalidateAffectedDataSet() {
     412        Main.main.invalidateDataSet(data);
     413    }
    380414}
  • src/org/openstreetmap/josm/command/DeleteCommand.java

     
    107107    }
    108108
    109109    /**
    110      * Constructor for a single data item. Use the collection constructor to delete multiple
    111      * objects.
     110     * Constructor for a single data item. Use the collection constructor to delete multiple objects.
    112111     *
    113112     * @param layer the layer context for deleting this primitive. Must not be null.
    114113     * @param data the primitive to delete. Must not be null.
    115114     * @throws IllegalArgumentException if data is null
    116115     * @throws IllegalArgumentException if layer is null
     116     * @deprecated to be removed end of 2017. Use {@link #DeleteCommand(DataSet, OsmPrimitive)} instead
    117117     */
     118    @Deprecated
    118119    public DeleteCommand(OsmDataLayer layer, OsmPrimitive data) {
    119120        this(layer, Collections.singleton(data));
    120121    }
    121122
    122123    /**
    123      * Constructor for a collection of data to be deleted in the context of
    124      * a specific layer
     124     * Constructor for a single data item. Use the collection constructor to delete multiple objects.
     125     *
     126     * @param dataset the data set context for deleting this primitive. Must not be null.
     127     * @param data the primitive to delete. Must not be null.
     128     * @throws IllegalArgumentException if data is null
     129     * @throws IllegalArgumentException if layer is null
     130     * @since xxx
     131     */
     132    public DeleteCommand(DataSet dataset, OsmPrimitive data) {
     133        this(dataset, Collections.singleton(data));
     134    }
     135
     136    /**
     137     * Constructor for a collection of data to be deleted in the context of a specific layer
    125138     *
    126139     * @param layer the layer context for deleting these primitives. Must not be null.
    127140     * @param data the primitives to delete. Must neither be null nor empty.
    128141     * @throws IllegalArgumentException if layer is null
    129142     * @throws IllegalArgumentException if data is null or empty
     143     * @deprecated to be removed end of 2017. Use {@link #DeleteCommand(DataSet, Collection)} instead
    130144     */
     145    @Deprecated
    131146    public DeleteCommand(OsmDataLayer layer, Collection<? extends OsmPrimitive> data) {
    132147        super(layer);
    133148        CheckParameterUtil.ensureParameterNotNull(data, "data");
     
    136151    }
    137152
    138153    /**
    139      * Constructor for a collection of data to be deleted in the context of
    140      * a specific data set
     154     * Constructor for a collection of data to be deleted in the context of a specific data set
    141155     *
    142156     * @param dataset the dataset context for deleting these primitives. Must not be null.
    143157     * @param data the primitives to delete. Must neither be null nor empty.
     
    285299     * @param silent  Set to true if the user should not be bugged with additional dialogs
    286300     * @return command A command to perform the deletions, or null of there is nothing to delete.
    287301     * @throws IllegalArgumentException if layer is null
     302     * @deprecated to be removed end of 2017. Use {@link #deleteWithReferences(Collection, boolean)} instead
    288303     */
     304    @Deprecated
    289305    public static Command deleteWithReferences(OsmDataLayer layer, Collection<? extends OsmPrimitive> selection, boolean silent) {
    290         CheckParameterUtil.ensureParameterNotNull(layer, "layer");
     306        return deleteWithReferences(selection, silent);
     307    }
     308
     309    /**
     310     * Delete the primitives and everything they reference.
     311     *
     312     * If a node is deleted, the node and all ways and relations the node is part of are deleted as well.
     313     * If a way is deleted, all relations the way is member of are also deleted.
     314     * If a way is deleted, only the way and no nodes are deleted.
     315     *
     316     * @param selection The list of all object to be deleted.
     317     * @param silent  Set to true if the user should not be bugged with additional dialogs
     318     * @return command A command to perform the deletions, or null of there is nothing to delete.
     319     * @throws IllegalArgumentException if layer is null
     320     * @since xxx
     321     */
     322    public static Command deleteWithReferences(Collection<? extends OsmPrimitive> selection, boolean silent) {
    291323        if (selection == null || selection.isEmpty()) return null;
    292324        Set<OsmPrimitive> parents = OsmPrimitive.getReferrer(selection);
    293325        parents.addAll(selection);
     
    296328            return null;
    297329        if (!silent && !checkAndConfirmOutlyingDelete(parents, null))
    298330            return null;
    299         return new DeleteCommand(layer, parents);
     331        return new DeleteCommand(parents.iterator().next().getDataSet(), parents);
    300332    }
    301333
    302334    /**
     
    306338     * If a way is deleted, all relations the way is member of are also deleted.
    307339     * If a way is deleted, only the way and no nodes are deleted.
    308340     *
    309      * @param layer the {@link OsmDataLayer} in whose context primitives are deleted. Must not be null.
     341     * @param layer unused
    310342     * @param selection The list of all object to be deleted.
    311343     * @return command A command to perform the deletions, or null of there is nothing to delete.
    312344     * @throws IllegalArgumentException if layer is null
     345     * @deprecated to be removed end of 2017. Use {@link #deleteWithReferences(Collection)} instead
    313346     */
     347    @Deprecated
    314348    public static Command deleteWithReferences(OsmDataLayer layer, Collection<? extends OsmPrimitive> selection) {
    315         return deleteWithReferences(layer, selection, false);
     349        return deleteWithReferences(selection);
     350    }
     351
     352    /**
     353     * Delete the primitives and everything they reference.
     354     *
     355     * If a node is deleted, the node and all ways and relations the node is part of are deleted as well.
     356     * If a way is deleted, all relations the way is member of are also deleted.
     357     * If a way is deleted, only the way and no nodes are deleted.
     358     *
     359     * @param selection The list of all object to be deleted.
     360     * @return command A command to perform the deletions, or null of there is nothing to delete.
     361     * @throws IllegalArgumentException if layer is null
     362     * @since xxx
     363     */
     364    public static Command deleteWithReferences(Collection<? extends OsmPrimitive> selection) {
     365        return deleteWithReferences(selection, false);
    316366    }
    317367
    318368    /**
     
    324374     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
    325375     * they are part of a relation, inform the user and do not delete.
    326376     *
    327      * @param layer the {@link OsmDataLayer} in whose context the primitives are deleted
     377     * @param layer unused
    328378     * @param selection the objects to delete.
    329379     * @return command a command to perform the deletions, or null if there is nothing to delete.
     380     * @deprecated to be removed end of 2017. Use {@link #delete(Collection)} instead
    330381     */
     382    @Deprecated
    331383    public static Command delete(OsmDataLayer layer, Collection<? extends OsmPrimitive> selection) {
    332         return delete(layer, selection, true, false);
     384        return delete(selection);
     385    }
     386
     387    /**
     388     * Try to delete all given primitives.
     389     *
     390     * If a node is used by a way, it's removed from that way. If a node or a way is used by a
     391     * relation, inform the user and do not delete.
     392     *
     393     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
     394     * they are part of a relation, inform the user and do not delete.
     395     *
     396     * @param selection the objects to delete.
     397     * @return command a command to perform the deletions, or null if there is nothing to delete.
     398     * @since xxx
     399     */
     400    public static Command delete(Collection<? extends OsmPrimitive> selection) {
     401        return delete(selection, true, false);
    333402    }
    334403
    335404    /**
     
    375444     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
    376445     * they are part of a relation, inform the user and do not delete.
    377446     *
    378      * @param layer the {@link OsmDataLayer} in whose context the primitives are deleted
     447     * @param layer unused
    379448     * @param selection the objects to delete.
    380449     * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
    381450     * @return command a command to perform the deletions, or null if there is nothing to delete.
     451     * @deprecated to be removed end of 2017. Use {@link #delete(Collection, boolean)} instead
    382452     */
     453    @Deprecated
    383454    public static Command delete(OsmDataLayer layer, Collection<? extends OsmPrimitive> selection,
    384455            boolean alsoDeleteNodesInWay) {
    385         return delete(layer, selection, alsoDeleteNodesInWay, false /* not silent */);
     456        return delete(selection, alsoDeleteNodesInWay);
     457    }
     458
     459    /**
     460     * Try to delete all given primitives.
     461     *
     462     * If a node is used by a way, it's removed from that way. If a node or a way is used by a
     463     * relation, inform the user and do not delete.
     464     *
     465     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
     466     * they are part of a relation, inform the user and do not delete.
     467     *
     468     * @param selection the objects to delete.
     469     * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
     470     * @return command a command to perform the deletions, or null if there is nothing to delete.
     471     * @since xxx
     472     */
     473    public static Command delete(Collection<? extends OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {
     474        return delete(selection, alsoDeleteNodesInWay, false /* not silent */);
    386475    }
    387476
    388477    /**
     
    394483     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
    395484     * they are part of a relation, inform the user and do not delete.
    396485     *
    397      * @param layer the {@link OsmDataLayer} in whose context the primitives are deleted
     486     * @param layer unused
    398487     * @param selection the objects to delete.
    399488     * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
    400489     * @param silent set to true if the user should not be bugged with additional questions
    401490     * @return command a command to perform the deletions, or null if there is nothing to delete.
     491     * @deprecated to be removed end of 2017. Use {@link #delete(Collection, boolean, boolean)} instead
    402492     */
     493    @Deprecated
    403494    public static Command delete(OsmDataLayer layer, Collection<? extends OsmPrimitive> selection,
    404495            boolean alsoDeleteNodesInWay, boolean silent) {
     496        return delete(selection, alsoDeleteNodesInWay, silent);
     497    }
     498
     499    /**
     500     * Try to delete all given primitives.
     501     *
     502     * If a node is used by a way, it's removed from that way. If a node or a way is used by a
     503     * relation, inform the user and do not delete.
     504     *
     505     * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If
     506     * they are part of a relation, inform the user and do not delete.
     507     *
     508     * @param selection the objects to delete.
     509     * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
     510     * @param silent set to true if the user should not be bugged with additional questions
     511     * @return command a command to perform the deletions, or null if there is nothing to delete.
     512     * @since xxx
     513     */
     514    public static Command delete(Collection<? extends OsmPrimitive> selection, boolean alsoDeleteNodesInWay, boolean silent) {
    405515        if (selection == null || selection.isEmpty())
    406516            return null;
    407517
     
    459569        // build the delete command
    460570        //
    461571        if (!primitivesToDelete.isEmpty()) {
    462             cmds.add(layer != null ? new DeleteCommand(layer, primitivesToDelete) :
    463                 new DeleteCommand(primitivesToDelete.iterator().next().getDataSet(), primitivesToDelete));
     572            cmds.add(new DeleteCommand(primitivesToDelete.iterator().next().getDataSet(), primitivesToDelete));
    464573        }
    465574
    466575        return new SequenceCommand(tr("Delete"), cmds);
     
    468577
    469578    /**
    470579     * Create a command that deletes a single way segment. The way may be split by this.
    471      * @param layer The layer the segment is in.
     580     * @param layer unused
    472581     * @param ws The way segment that should be deleted
    473582     * @return A matching command to safely delete that segment.
     583     * @deprecated to be removed end of 2017. Use {@link #deleteWaySegment(WaySegment)} instead
    474584     */
     585    @Deprecated
    475586    public static Command deleteWaySegment(OsmDataLayer layer, WaySegment ws) {
     587        return deleteWaySegment(ws);
     588    }
     589
     590    /**
     591     * Create a command that deletes a single way segment. The way may be split by this.
     592     * @param ws The way segment that should be deleted
     593     * @return A matching command to safely delete that segment.
     594     * @since xxx
     595     */
     596    public static Command deleteWaySegment(WaySegment ws) {
    476597        if (ws.way.getNodesCount() < 3)
    477             return delete(layer, Collections.singleton(ws.way), false);
     598            return delete(Collections.singleton(ws.way), false);
    478599
    479600        if (ws.way.isClosed()) {
    480601            // If the way is circular (first and last nodes are the same), the way shouldn't be splitted
     
    505626            wnew.setNodes(n1);
    506627            return new ChangeCommand(ws.way, wnew);
    507628        } else {
    508             SplitWayResult split = SplitWayAction.splitWay(layer, ws.way, Arrays.asList(n1, n2), Collections.<OsmPrimitive>emptyList());
     629            SplitWayResult split = SplitWayAction.splitWay(ws.way, Arrays.asList(n1, n2), Collections.<OsmPrimitive>emptyList());
    509630            return split != null ? split.getCommand() : null;
    510631        }
    511632    }
  • src/org/openstreetmap/josm/command/PurgeCommand.java

     
    5353     * @param layer OSM data layer
    5454     * @param toPurge primitives to purge
    5555     * @param makeIncomplete primitives to make incomplete
     56     * @deprecated to be removed end of 2017. Use {@link #PurgeCommand(DataSet, Collection, Collection)} instead
    5657     */
     58    @Deprecated
    5759    public PurgeCommand(OsmDataLayer layer, Collection<OsmPrimitive> toPurge, Collection<OsmPrimitive> makeIncomplete) {
    5860        super(layer);
    5961        init(toPurge, makeIncomplete);
     
    318320     * @param toPurgeAdditionally optional list that will be filled with primitives to be purged that have not been in the selection
    319321     * @return command to purge selected OSM primitives
    320322     * @since 12688
     323     * @deprecated to be removed end of 2017. Use {@link #build(Collection, List)} instead
    321324     */
     325    @Deprecated
    322326    public static PurgeCommand build(OsmDataLayer layer, Collection<OsmPrimitive> sel, List<OsmPrimitive> toPurgeAdditionally) {
     327        return build(sel, toPurgeAdditionally);
     328    }
     329
     330    /**
     331     * Creates a new {@code PurgeCommand} to purge selected OSM primitives.
     332     * @param sel selected OSM primitives
     333     * @param toPurgeAdditionally optional list that will be filled with primitives to be purged that have not been in the selection
     334     * @return command to purge selected OSM primitives
     335     * @since xxx
     336     */
     337    public static PurgeCommand build(Collection<OsmPrimitive> sel, List<OsmPrimitive> toPurgeAdditionally) {
    323338        Set<OsmPrimitive> toPurge = new HashSet<>(sel);
    324339        // finally, contains all objects that are purged
    325340        Set<OsmPrimitive> toPurgeChecked = new HashSet<>();
     
    422437            }
    423438        }
    424439
    425         return layer != null ? new PurgeCommand(layer, toPurgeChecked, makeIncomplete)
    426                 : new PurgeCommand(toPurgeChecked.iterator().next().getDataSet(), toPurgeChecked, makeIncomplete);
     440        return new PurgeCommand(toPurgeChecked.iterator().next().getDataSet(), toPurgeChecked, makeIncomplete);
    427441    }
    428442
    429443    private static boolean hasOnlyIncompleteMembers(
  • src/org/openstreetmap/josm/command/SequenceCommand.java

     
    1111import javax.swing.Icon;
    1212
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
     14import org.openstreetmap.josm.gui.layer.Layer;
    1415import org.openstreetmap.josm.tools.ImageProvider;
    1516import org.openstreetmap.josm.tools.Utils;
    1617
     
    135136        this.sequenceComplete = sequenceComplete;
    136137    }
    137138
     139    /**
     140     * Invalidate all layers that were affected by this command.
     141     * @see Layer#invalidate()
     142     * @deprecated to be removed end of 2017. Use {@link #invalidateAffectedDataSet} instead
     143     */
    138144    @Override
     145    @Deprecated
    139146    public void invalidateAffectedLayers() {
    140147        super.invalidateAffectedLayers();
    141148        for (Command c : sequence) {
     
    144151    }
    145152
    146153    @Override
     154    public void invalidateAffectedDataSet() {
     155        super.invalidateAffectedDataSet();
     156        for (Command c : sequence) {
     157            c.invalidateAffectedDataSet();
     158        }
     159    }
     160
     161    @Override
    147162    public int hashCode() {
    148163        return Objects.hash(super.hashCode(), Arrays.hashCode(sequence), sequenceComplete, name, continueOnError);
    149164    }
  • src/org/openstreetmap/josm/command/conflict/ConflictAddCommand.java

     
    1515import org.openstreetmap.josm.data.osm.DataSet;
    1616import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
    1717import org.openstreetmap.josm.data.osm.OsmPrimitive;
    18 import org.openstreetmap.josm.gui.MainApplication;
    1918import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2019import org.openstreetmap.josm.tools.ImageProvider;
    2120import org.openstreetmap.josm.tools.Logging;
     
    3231     * Constructs a new {@code ConflictAddCommand}.
    3332     * @param layer the data layer. Must not be null.
    3433     * @param conflict the conflict to add
     34     * @deprecated to be removed end of 2017. Use {@link #ConflictAddCommand(DataSet, Conflict)} instead
    3535     */
     36    @Deprecated
    3637    public ConflictAddCommand(OsmDataLayer layer, Conflict<? extends OsmPrimitive> conflict) {
    3738        super(layer);
    3839        this.conflict = conflict;
     
    5556                tr("<html>Layer ''{0}'' already has a conflict for object<br>"
    5657                        + "''{1}''.<br>"
    5758                        + "This conflict cannot be added.</html>",
    58                         Utils.escapeReservedCharactersHTML(getLayer().getName()),
     59                        Utils.escapeReservedCharactersHTML(getAffectedDataSet().getName()),
    5960                        Utils.escapeReservedCharactersHTML(conflict.getMy().getDisplayName(DefaultNameFormatter.getInstance()))
    6061                ),
    6162                tr("Double conflict"),
     
    7677
    7778    @Override
    7879    public void undoCommand() {
    79         if (MainApplication.isDisplayingMapView() && !MainApplication.getLayerManager().containsLayer(getLayer())) {
     80        DataSet ds = getAffectedDataSet();
     81        if (!Main.main.containsDataSet(ds)) {
    8082            Logging.warn(tr("Layer ''{0}'' does not exist any more. Cannot remove conflict for object ''{1}''.",
    81                     getLayer().getName(),
     83                    ds.getName(),
    8284                    conflict.getMy().getDisplayName(DefaultNameFormatter.getInstance())
    8385            ));
    8486            return;
    8587        }
    86         getAffectedDataSet().getConflicts().remove(conflict);
     88        ds.getConflicts().remove(conflict);
    8789    }
    8890
    8991    @Override
  • src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java

     
    55
    66import java.util.Objects;
    77
     8import org.openstreetmap.josm.Main;
    89import org.openstreetmap.josm.command.Command;
    910import org.openstreetmap.josm.data.conflict.Conflict;
    1011import org.openstreetmap.josm.data.conflict.ConflictCollection;
    1112import org.openstreetmap.josm.data.osm.DataSet;
    12 import org.openstreetmap.josm.gui.MainApplication;
    1313import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1414import org.openstreetmap.josm.tools.Logging;
    1515
     
    2323 */
    2424public abstract class ConflictResolveCommand extends Command {
    2525    /** the list of resolved conflicts */
    26     private final ConflictCollection resolvedConflicts;
     26    private final ConflictCollection resolvedConflicts = new ConflictCollection();
    2727
    2828    /**
    2929     * Constructs a new {@code ConflictResolveCommand} in the context of the current edit layer, if any.
    3030     */
    3131    public ConflictResolveCommand() {
    32         super();
    33         resolvedConflicts = new ConflictCollection();
     32        // Do nothing
    3433    }
    3534
    3635    /**
    3736     * Constructs a new {@code ConflictResolveCommand} in the context of a given data layer.
    3837     * @param layer the data layer. Must not be null.
     38     * @deprecated to be removed end of 2017. Use {@link #ConflictResolveCommand(DataSet)} instead
    3939     */
     40    @Deprecated
    4041    public ConflictResolveCommand(OsmDataLayer layer) {
    4142        super(layer);
    42         resolvedConflicts = new ConflictCollection();
     43    }
     44
     45    /**
     46     * Constructs a new {@code ConflictResolveCommand} in the context of a given data set.
     47     * @param ds the data set. Must not be null.
     48     */
     49    public ConflictResolveCommand(DataSet ds) {
     50        super(ds);
    4351    }
    4452
    4553    /**
     
    5563
    5664    /**
    5765     * reconstitutes all remembered conflicts. Add the remembered conflicts to the
    58      * set of conflicts of the {@link OsmDataLayer} this command was applied to.
     66     * set of conflicts of the {@link DataSet} this command was applied to.
    5967     *
    6068     */
    6169    protected void reconstituteConflicts() {
     
    7179    public void undoCommand() {
    7280        super.undoCommand();
    7381
    74         if (MainApplication.isDisplayingMapView()) {
    75             if (!MainApplication.getLayerManager().containsLayer(getLayer())) {
    76                 Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
    77                         this.toString(),
    78                         getLayer().toString()
    79                 ));
    80                 return;
    81             }
    82 
    83             MainApplication.getLayerManager().setActiveLayer(getLayer());
     82        DataSet ds = getAffectedDataSet();
     83        if (!Main.main.containsDataSet(ds)) {
     84            Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
     85                    this.toString(),
     86                    ds.getName()
     87            ));
     88            return;
    8489        }
     90
     91        Main.main.setEditDataSet(ds);
    8592        reconstituteConflicts();
    8693    }
    8794
  • src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java

     
    99
    1010import javax.swing.Icon;
    1111
     12import org.openstreetmap.josm.Main;
    1213import org.openstreetmap.josm.data.conflict.Conflict;
    1314import org.openstreetmap.josm.data.osm.DataSet;
    1415import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1516import org.openstreetmap.josm.data.osm.Relation;
    1617import org.openstreetmap.josm.data.osm.RelationMember;
    17 import org.openstreetmap.josm.gui.MainApplication;
    18 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1918import org.openstreetmap.josm.tools.ImageProvider;
    2019import org.openstreetmap.josm.tools.Logging;
    2120
     
    7170
    7271    @Override
    7372    public void undoCommand() {
    74         OsmDataLayer layer = getLayer();
    75         if (!MainApplication.getLayerManager().containsLayer(layer)) {
     73        DataSet editDs = getAffectedDataSet();
     74        if (!Main.main.containsDataSet(editDs)) {
    7675            Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
    7776                    this.toString(),
    78                     layer.toString()
     77                    editDs.getName()
    7978            ));
    8079            return;
    8180        }
    8281
    83         MainApplication.getLayerManager().setActiveLayer(layer);
    84         DataSet editDs = MainApplication.getLayerManager().getEditDataSet();
     82        Main.main.setEditDataSet(editDs);
    8583
    8684        // restore the former state
    8785        //
  • src/org/openstreetmap/josm/data/UndoRedoHandler.java

     
    1010import org.openstreetmap.josm.command.Command;
    1111import org.openstreetmap.josm.data.osm.DataSet;
    1212import org.openstreetmap.josm.data.osm.OsmPrimitive;
    13 import org.openstreetmap.josm.gui.MainApplication;
    14 import org.openstreetmap.josm.gui.layer.Layer;
    15 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    16 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    17 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    18 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    19 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    20 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
    2113import org.openstreetmap.josm.tools.CheckParameterUtil;
    2214
    2315/**
    24  * This is the global undo/redo handler for all {@link OsmDataLayer}s.
     16 * This is the global undo/redo handler for all {@link DataSet}s.
    2517 * <p>
    26  * 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.
     18 * If you want to change a data set, you can use {@link #add(Command)} to execute a command on it and make that command undoable.
    2719 */
    28 public class UndoRedoHandler implements LayerChangeListener {
     20public class UndoRedoHandler {
    2921
    3022    /**
    3123     * All commands that were made on the dataset. Don't write from outside!
     
    4436     * Constructs a new {@code UndoRedoHandler}.
    4537     */
    4638    public UndoRedoHandler() {
    47         MainApplication.getLayerManager().addLayerChangeListener(this);
     39        // Do nothing
     40    }
     41
     42    /**
     43     * A listener that gets notified of command queue (undo/redo) size changes.
     44     * @since xxx (moved from {@code OsmDataLayer}
     45     */
     46    @FunctionalInterface
     47    public interface CommandQueueListener {
     48        /**
     49         * Notifies the listener about the new queue size
     50         * @param queueSize Undo stack size
     51         * @param redoSize Redo stack size
     52         */
     53        void commandChanged(int queueSize, int redoSize);
    4854    }
    4955
    5056    /**
     
    9197            oldSelection = ds.getSelected();
    9298        }
    9399        addNoRedraw(c);
    94         c.invalidateAffectedLayers();
     100        c.invalidateAffectedDataSet();
    95101        afterAdd();
    96102
    97103        // the command may have changed the selection so tell the listeners about the current situation
     
    124130            for (int i = 1; i <= num; ++i) {
    125131                final Command c = commands.removeLast();
    126132                c.undoCommand();
    127                 c.invalidateAffectedLayers();
     133                c.invalidateAffectedDataSet();
    128134                redoCommands.addFirst(c);
    129135                if (commands.isEmpty()) {
    130136                    break;
     
    160166        for (int i = 0; i < num; ++i) {
    161167            final Command c = redoCommands.removeFirst();
    162168            c.executeCommand();
    163             c.invalidateAffectedLayers();
     169            c.invalidateAffectedDataSet();
    164170            commands.add(c);
    165171            if (redoCommands.isEmpty()) {
    166172                break;
     
    196202    }
    197203
    198204    /**
    199      * Resets all commands that affect the given layer.
    200      * @param layer The layer that was affected.
     205     * Resets all commands that affect the given dataset.
     206     * @param dataSet The data set that was affected.
     207     * @since xxx
    201208     */
    202     public void clean(Layer layer) {
    203         if (layer == null)
     209    public void clean(DataSet dataSet) {
     210        if (dataSet == null)
    204211            return;
    205212        boolean changed = false;
    206213        for (Iterator<Command> it = commands.iterator(); it.hasNext();) {
    207             if (it.next().invalidBecauselayerRemoved(layer)) {
     214            if (it.next().invalidBecauseDatasetRemoved(dataSet)) {
    208215                it.remove();
    209216                changed = true;
    210217            }
    211218        }
    212219        for (Iterator<Command> it = redoCommands.iterator(); it.hasNext();) {
    213             if (it.next().invalidBecauselayerRemoved(layer)) {
     220            if (it.next().invalidBecauseDatasetRemoved(dataSet)) {
    214221                it.remove();
    215222                changed = true;
    216223            }
     
    220227        }
    221228    }
    222229
    223     @Override
    224     public void layerRemoving(LayerRemoveEvent e) {
    225         clean(e.getRemovedLayer());
    226     }
    227 
    228     @Override
    229     public void layerAdded(LayerAddEvent e) {
    230         // Do nothing
    231     }
    232 
    233     @Override
    234     public void layerOrderChanged(LayerOrderChangeEvent e) {
    235         // Do nothing
    236     }
    237 
    238230    /**
    239231     * Removes a command queue listener.
    240232     * @param l The command queue listener to remove
  • src/org/openstreetmap/josm/data/osm/DataSet.java

     
    168168    // Events that occurred while dataset was locked but should be fired after write lock is released
    169169    private final List<AbstractDatasetChangedEvent> cachedEvents = new ArrayList<>();
    170170
     171    private String name;
    171172    private UploadPolicy uploadPolicy;
    172173
    173174    private final ReadWriteLock lock = new ReentrantReadWriteLock();
     
    13591360        return conflicts;
    13601361    }
    13611362
     1363    /**
     1364     * Returns the name of this data set (optional).
     1365     * @return the name of this data set. Can be {@code null}
     1366     * @since xxx
     1367     */
     1368    public String getName() {
     1369        return name;
     1370    }
     1371
     1372    /**
     1373     * Sets the name of this data set.
     1374     * @param name the new name of this data set. Can be {@code null} to reset it
     1375     * @since xxx
     1376     */
     1377    public void setName(String name) {
     1378        this.name = name;
     1379    }
     1380
    13621381    /* --------------------------------------------------------------------------------- */
    13631382    /* interface ProjectionChangeListner                                                 */
    13641383    /* --------------------------------------------------------------------------------- */
  • src/org/openstreetmap/josm/data/validation/Test.java

     
    2222import org.openstreetmap.josm.data.osm.Way;
    2323import org.openstreetmap.josm.data.osm.search.SearchCompiler.NotOutsideDataSourceArea;
    2424import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    25 import org.openstreetmap.josm.gui.MainApplication;
    2625import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2726import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2827import org.openstreetmap.josm.tools.GBC;
     
    330329            }
    331330        }
    332331        if (!primitivesToDelete.isEmpty()) {
    333             return DeleteCommand.delete(MainApplication.getLayerManager().getEditLayer(), primitivesToDelete);
     332            return DeleteCommand.delete(primitivesToDelete);
    334333        } else {
    335334            return null;
    336335        }
  • src/org/openstreetmap/josm/gui/MainApplication.java

     
    3939import java.util.concurrent.ExecutorService;
    4040import java.util.concurrent.Executors;
    4141import java.util.concurrent.Future;
     42import java.util.function.Consumer;
    4243import java.util.logging.Level;
    4344import java.util.stream.Collectors;
    4445import java.util.stream.Stream;
     
    7172import org.openstreetmap.josm.actions.search.SearchAction;
    7273import org.openstreetmap.josm.data.Bounds;
    7374import org.openstreetmap.josm.data.UndoRedoHandler;
     75import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    7476import org.openstreetmap.josm.data.Version;
    7577import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
    7678import org.openstreetmap.josm.data.osm.DataSet;
     
    8385import org.openstreetmap.josm.gui.io.CustomConfigurator.XMLCommandProcessor;
    8486import org.openstreetmap.josm.gui.io.SaveLayersDialog;
    8587import org.openstreetmap.josm.gui.layer.AutosaveTask;
     88import org.openstreetmap.josm.gui.layer.Layer;
     89import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
     90import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
     91import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
     92import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    8693import org.openstreetmap.josm.gui.layer.MainLayerManager;
    87 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
     94import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    8895import org.openstreetmap.josm.gui.layer.TMSLayer;
    8996import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
    9097import org.openstreetmap.josm.gui.preferences.display.LafPreference;
     
    186193
    187194    /**
    188195     * The commands undo/redo handler.
    189      * @since 12641 (as a replacement to {@code Main.main.undoRedo})
     196     * @since 12641
    190197     */
    191     public static final UndoRedoHandler undoRedo = new UndoRedoHandler(); // Must be declared after layerManager
     198    public static UndoRedoHandler undoRedo;
    192199
    193200    /**
    194201     * Listener that sets the enabled state of undo/redo menu entries.
     
    212219     */
    213220    public MainApplication(MainFrame mainFrame) {
    214221        this.mainFrame = mainFrame;
     222        undoRedo = super.undoRedo;
     223        getLayerManager().addLayerChangeListener(new LayerChangeListener() {
     224            @Override
     225            public void layerRemoving(LayerRemoveEvent e) {
     226                Layer layer = e.getRemovedLayer();
     227                if (layer instanceof OsmDataLayer) {
     228                    undoRedo.clean(((OsmDataLayer) layer).data);
     229                }
     230            }
     231
     232            @Override
     233            public void layerOrderChanged(LayerOrderChangeEvent e) {
     234                // Do nothing
     235            }
     236
     237            @Override
     238            public void layerAdded(LayerAddEvent e) {
     239                // Do nothing
     240            }
     241        });
    215242    }
    216243
    217244    /**
     
    406433        return getLayerManager().getEditDataSet();
    407434    }
    408435
     436    @Override
     437    public void setEditDataSet(DataSet ds) {
     438        consumeDataSet(ds, l -> getLayerManager().setActiveLayer(l));
     439    }
     440
     441    @Override
     442    public boolean containsDataSet(DataSet ds) {
     443        return getLayerManager().getLayersOfType(OsmDataLayer.class).stream().anyMatch(l -> l.data.equals(ds));
     444    }
     445
     446    @Override
     447    public void invalidateDataSet(DataSet ds) {
     448        consumeDataSet(ds, OsmDataLayer::invalidate);
     449    }
     450
     451    private static void consumeDataSet(DataSet ds, Consumer<OsmDataLayer> consumer) {
     452        Optional<OsmDataLayer> layer = getLayerManager().getLayersOfType(OsmDataLayer.class).stream()
     453                .filter(l -> l.data.equals(ds)).findFirst();
     454        if (layer.isPresent()) {
     455            consumer.accept(layer.get());
     456        }
     457    }
     458
    409459    /**
    410460     * Returns the command-line arguments used to run the application.
    411461     * @return the command-line arguments used to run the application
  • src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java

     
    8282                throw BugReport.intercept(e).put("data", data);
    8383            }
    8484        }
    85         return new AddPrimitivesCommand(bufferCopy, toSelect, layer);
     85        return new AddPrimitivesCommand(bufferCopy, toSelect, layer.data);
    8686    }
    8787
    8888    private static EnumMap<OsmPrimitiveType, Map<Long, Long>> generateNewPrimitives(PrimitiveTransferData pasteBuffer,
  • src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java

     
    3838import org.openstreetmap.josm.actions.AutoScaleAction;
    3939import org.openstreetmap.josm.command.Command;
    4040import org.openstreetmap.josm.command.PseudoCommand;
     41import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    4142import org.openstreetmap.josm.data.osm.DataSet;
    4243import org.openstreetmap.josm.data.osm.OsmPrimitive;
    4344import org.openstreetmap.josm.gui.MainApplication;
    4445import org.openstreetmap.josm.gui.SideButton;
    4546import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    46 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
    4747import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    4848import org.openstreetmap.josm.tools.GBC;
    4949import org.openstreetmap.josm.tools.ImageProvider;
  • src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java

     
    1010import javax.swing.JOptionPane;
    1111
    1212import org.openstreetmap.josm.Main;
     13import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    1314import org.openstreetmap.josm.data.osm.Relation;
    1415import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    1516import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
     
    1819import org.openstreetmap.josm.gui.dialogs.relation.MemberTable;
    1920import org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel;
    2021import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    21 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
    2222import org.openstreetmap.josm.gui.tagging.TagEditorModel;
    2323import org.openstreetmap.josm.tools.ImageProvider;
    2424import org.openstreetmap.josm.tools.Shortcut;
  • src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java

     
    7272        // tags, don't add an empty relation
    7373        if (newRelation.getMembersCount() == 0 && !newRelation.hasKeys())
    7474            return;
    75         MainApplication.undoRedo.add(new AddCommand(layer, newRelation));
     75        MainApplication.undoRedo.add(new AddCommand(layer.data, newRelation));
    7676
    7777        // make sure everybody is notified about the changes
    7878        //
     
    9494        tagEditorModel.applyToPrimitive(editedRelation);
    9595        memberTableModel.applyToRelation(editedRelation);
    9696        Conflict<Relation> conflict = new Conflict<>(editor.getRelation(), editedRelation);
    97         MainApplication.undoRedo.add(new ConflictAddCommand(layer, conflict));
     97        MainApplication.undoRedo.add(new ConflictAddCommand(layer.data, conflict));
    9898    }
    9999
    100100    /**
  • src/org/openstreetmap/josm/gui/layer/Layer.java

     
    338338     *
    339339     * @param name the name. If null, the name is set to the empty string.
    340340     */
    341     public final void setName(String name) {
     341    public void setName(String name) {
    342342        if (this.name != null) {
    343343            removeColorPropertyListener();
    344344        }
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    294294    }
    295295
    296296    /**
    297      * A listener that gets notified of command queue (undo/redo) size changes.
    298      */
    299     @FunctionalInterface
    300     public interface CommandQueueListener {
    301         /**
    302          * Notifies the listener about the new queue size
    303          * @param queueSize Undo stack size
    304          * @param redoSize Redo stack size
    305          */
    306         void commandChanged(int queueSize, int redoSize);
    307     }
    308 
    309     /**
    310297     * Listener called when a state of this layer has changed.
    311298     * @since 10600 (functional interface)
    312299     */
     
    400387        super(name);
    401388        CheckParameterUtil.ensureParameterNotNull(data, "data");
    402389        this.data = data;
     390        this.data.setName(name);
    403391        this.setAssociatedFile(associatedFile);
    404392        data.addDataSetListener(new DataSetListenerAdapter(this));
    405393        data.addDataSetListener(MultipolygonCache.getInstance());
     
    602590        if (processed == null || processed.isEmpty())
    603591            return;
    604592
    605         MainApplication.undoRedo.clean(this);
     593        MainApplication.undoRedo.clean(data);
    606594
    607595        // if uploaded, clean the modified flags as well
    608596        data.cleanupDeletedPrimitives();
     
    11451133    public void highlightUpdated(HighlightUpdateEvent e) {
    11461134        invalidate();
    11471135    }
     1136
     1137    @Override
     1138    public void setName(String name) {
     1139        if (data != null) {
     1140            data.setName(name);
     1141        }
     1142        super.setName(name);
     1143    }
    11481144}
  • src/org/openstreetmap/josm/tools/Geometry.java

     
    3636import org.openstreetmap.josm.data.projection.Projections;
    3737import org.openstreetmap.josm.gui.MainApplication;
    3838import org.openstreetmap.josm.gui.MapFrame;
    39 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    4039
    4140/**
    4241 * Some tools for geometry related tasks.
     
    102101            changedWays[pos] = false;
    103102        }
    104103
    105         OsmDataLayer layer = MainApplication.getLayerManager().getEditLayer();
    106104        DataSet dataset = ways.get(0).getDataSet();
    107105
    108106        //iterate over all way pairs and introduce the intersections
     
    209207                                intersectionNodes.add(intNode);
    210208
    211209                                if (intNode == newNode) {
    212                                     cmds.add(layer != null ? new AddCommand(layer, intNode) : new AddCommand(dataset, intNode));
     210                                    cmds.add(new AddCommand(dataset, intNode));
    213211                                }
    214212                            }
    215213                        } else if (test && !intersectionNodes.isEmpty())
  • src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java

     
    103103            w.removeAll();
    104104        }
    105105        // Purge all other ways and relations so dataset only contains lefthand traffic data
    106         PurgeCommand.build(null, toPurge, null).executeCommand();
     106        PurgeCommand.build(toPurge, null).executeCommand();
    107107        // Combine adjacent countries into a single polygon
    108108        Collection<Way> optimizedWays = new ArrayList<>();
    109109        List<Multipolygon> areas = JoinAreasAction.collectMultipolygons(ways);
  • test/unit/org/openstreetmap/josm/command/CommandTest.java

     
    4949    }
    5050
    5151    /**
    52      * Test {@link Command#invalidBecauselayerRemoved(org.openstreetmap.josm.gui.layer.Layer)}
     52     * Test {@link Command#invalidBecauseDatasetRemoved}
    5353     */
    5454    @Test
    55     public void testInvalidBecauselayerRemoved() {
     55    public void testInvalidBecauseDatasetRemoved() {
    5656        OsmDataLayer layer2 = new OsmDataLayer(new DataSet(), "test", null);
    5757
    5858        Command command = new NopCommand();
    59         assertFalse(command.invalidBecauselayerRemoved(layer2));
    60         assertTrue(command.invalidBecauselayerRemoved(testData.layer));
     59        assertFalse(command.invalidBecauseDatasetRemoved(layer2.data));
     60        assertTrue(command.invalidBecauseDatasetRemoved(testData.layer.data));
    6161
    62         Command command2 = new NopCommand(layer2);
    63         assertTrue(command2.invalidBecauselayerRemoved(layer2));
    64         assertFalse(command2.invalidBecauselayerRemoved(testData.layer));
     62        Command command2 = new NopCommand(layer2.data);
     63        assertTrue(command2.invalidBecauseDatasetRemoved(layer2.data));
     64        assertFalse(command2.invalidBecauseDatasetRemoved(testData.layer.data));
    6565    }
    6666
    6767    /**
    6868     * Test {@link Command#getLayer()}
     69     * @deprecated to be removed end of 2017
    6970     */
    7071    @Test
     72    @Deprecated
    7173    public void testGetLayer() {
    7274        OsmDataLayer layer2 = new OsmDataLayer(new DataSet(), "test", null);
    7375        Command command = new NopCommand();
    74         Command command2 = new NopCommand(layer2);
     76        Command command2 = new NopCommand(layer2.data);
    7577        assertSame(testData.layer, command.getLayer());
    7678        assertSame(layer2, command2.getLayer());
    7779    }
     
    9799            super();
    98100        }
    99101
    100         NopCommand(OsmDataLayer layer) {
    101             super(layer);
     102        NopCommand(DataSet dataset) {
     103            super(dataset);
    102104        }
    103105
    104106        @Override