[6380] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[626] | 2 | package org.openstreetmap.josm.actions.mapmode;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
[2026] | 6 | import java.awt.Cursor;
|
---|
[626] | 7 | import java.awt.event.ActionEvent;
|
---|
| 8 | import java.awt.event.KeyEvent;
|
---|
| 9 | import java.awt.event.MouseEvent;
|
---|
[9472] | 10 | import java.util.Collection;
|
---|
[626] | 11 | import java.util.Collections;
|
---|
[4327] | 12 | import java.util.HashSet;
|
---|
| 13 | import java.util.Set;
|
---|
[626] | 14 |
|
---|
[988] | 15 | import org.openstreetmap.josm.command.Command;
|
---|
| 16 | import org.openstreetmap.josm.command.DeleteCommand;
|
---|
[4327] | 17 | import org.openstreetmap.josm.data.osm.DataSet;
|
---|
[2026] | 18 | import org.openstreetmap.josm.data.osm.Node;
|
---|
[3177] | 19 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
[1856] | 20 | import org.openstreetmap.josm.data.osm.Relation;
|
---|
[626] | 21 | import org.openstreetmap.josm.data.osm.WaySegment;
|
---|
[12630] | 22 | import org.openstreetmap.josm.gui.MainApplication;
|
---|
| 23 | import org.openstreetmap.josm.gui.MapFrame;
|
---|
| 24 | import org.openstreetmap.josm.gui.MapView;
|
---|
[1856] | 25 | import org.openstreetmap.josm.gui.dialogs.relation.RelationDialogManager;
|
---|
[1379] | 26 | import org.openstreetmap.josm.gui.layer.Layer;
|
---|
[10448] | 27 | import org.openstreetmap.josm.gui.layer.MainLayerManager;
|
---|
[1379] | 28 | import org.openstreetmap.josm.gui.layer.OsmDataLayer;
|
---|
[6026] | 29 | import org.openstreetmap.josm.gui.util.HighlightHelper;
|
---|
[12517] | 30 | import org.openstreetmap.josm.gui.util.ModifierExListener;
|
---|
[12846] | 31 | import org.openstreetmap.josm.spi.preferences.Config;
|
---|
[2842] | 32 | import org.openstreetmap.josm.tools.CheckParameterUtil;
|
---|
[988] | 33 | import org.openstreetmap.josm.tools.ImageProvider;
|
---|
[1084] | 34 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
[626] | 35 |
|
---|
| 36 | /**
|
---|
[5275] | 37 | * A map mode that enables the user to delete nodes and other objects.
|
---|
[626] | 38 | *
|
---|
[1023] | 39 | * The user can click on an object, which gets deleted if possible. When Ctrl is
|
---|
[8470] | 40 | * pressed when releasing the button, the objects and all its references are deleted.
|
---|
[626] | 41 | *
|
---|
| 42 | * If the user did not press Ctrl and the object has any references, the user
|
---|
| 43 | * is informed and nothing is deleted.
|
---|
| 44 | *
|
---|
| 45 | * If the user enters the mapmode and any object is selected, all selected
|
---|
[5275] | 46 | * objects are deleted, if possible.
|
---|
[1023] | 47 | *
|
---|
[626] | 48 | * @author imi
|
---|
| 49 | */
|
---|
[12517] | 50 | public class DeleteAction extends MapMode implements ModifierExListener {
|
---|
[8470] | 51 | // Cache previous mouse event (needed when only the modifier keys are pressed but the mouse isn't moved)
|
---|
[8840] | 52 | private MouseEvent oldEvent;
|
---|
[2026] | 53 |
|
---|
[4327] | 54 | /**
|
---|
| 55 | * elements that have been highlighted in the previous iteration. Used
|
---|
| 56 | * to remove the highlight from them again as otherwise the whole data
|
---|
| 57 | * set would have to be checked.
|
---|
| 58 | */
|
---|
[8840] | 59 | private transient WaySegment oldHighlightedWaySegment;
|
---|
[4327] | 60 |
|
---|
[12537] | 61 | private static final HighlightHelper HIGHLIGHT_HELPER = new HighlightHelper();
|
---|
[4327] | 62 | private boolean drawTargetHighlight;
|
---|
| 63 |
|
---|
[11978] | 64 | enum DeleteMode {
|
---|
[7668] | 65 | none(/* ICON(cursor/modifier/) */ "delete"),
|
---|
| 66 | segment(/* ICON(cursor/modifier/) */ "delete_segment"),
|
---|
| 67 | node(/* ICON(cursor/modifier/) */ "delete_node"),
|
---|
| 68 | node_with_references(/* ICON(cursor/modifier/) */ "delete_node"),
|
---|
| 69 | way(/* ICON(cursor/modifier/) */ "delete_way_only"),
|
---|
| 70 | way_with_references(/* ICON(cursor/modifier/) */ "delete_way_normal"),
|
---|
| 71 | way_with_nodes(/* ICON(cursor/modifier/) */ "delete_way_node_only");
|
---|
[2026] | 72 |
|
---|
[2521] | 73 | private final Cursor c;
|
---|
| 74 |
|
---|
[8674] | 75 | DeleteMode(String cursorName) {
|
---|
[2521] | 76 | c = ImageProvider.getCursor("normal", cursorName);
|
---|
| 77 | }
|
---|
| 78 |
|
---|
[11978] | 79 | /**
|
---|
| 80 | * Returns the mode cursor.
|
---|
| 81 | * @return the mode cursor
|
---|
| 82 | */
|
---|
[2026] | 83 | public Cursor cursor() {
|
---|
| 84 | return c;
|
---|
| 85 | }
|
---|
| 86 | }
|
---|
| 87 |
|
---|
[2521] | 88 | private static class DeleteParameters {
|
---|
[8285] | 89 | private DeleteMode mode;
|
---|
| 90 | private Node nearestNode;
|
---|
| 91 | private WaySegment nearestSegment;
|
---|
[2521] | 92 | }
|
---|
| 93 |
|
---|
[1169] | 94 | /**
|
---|
| 95 | * Construct a new DeleteAction. Mnemonic is the delete - key.
|
---|
[11713] | 96 | * @since 11713
|
---|
[1169] | 97 | */
|
---|
[11713] | 98 | public DeleteAction() {
|
---|
[1169] | 99 | super(tr("Delete Mode"),
|
---|
| 100 | "delete",
|
---|
| 101 | tr("Delete nodes or ways."),
|
---|
[8510] | 102 | Shortcut.registerShortcut("mapmode:delete", tr("Mode: {0}", tr("Delete")),
|
---|
[4982] | 103 | KeyEvent.VK_DELETE, Shortcut.CTRL),
|
---|
[1169] | 104 | ImageProvider.getCursor("normal", "delete"));
|
---|
| 105 | }
|
---|
[626] | 106 |
|
---|
[11713] | 107 | @Override
|
---|
| 108 | public void enterMode() {
|
---|
[1169] | 109 | super.enterMode();
|
---|
[1821] | 110 | if (!isEnabled())
|
---|
| 111 | return;
|
---|
[2026] | 112 |
|
---|
[12846] | 113 | drawTargetHighlight = Config.getPref().getBoolean("draw.target-highlight", true);
|
---|
[4327] | 114 |
|
---|
[12630] | 115 | MapFrame map = MainApplication.getMap();
|
---|
| 116 | map.mapView.addMouseListener(this);
|
---|
| 117 | map.mapView.addMouseMotionListener(this);
|
---|
[2026] | 118 | // This is required to update the cursors when ctrl/shift/alt is pressed
|
---|
[12630] | 119 | map.keyDetector.addModifierExListener(this);
|
---|
[1169] | 120 | }
|
---|
[626] | 121 |
|
---|
[6889] | 122 | @Override
|
---|
| 123 | public void exitMode() {
|
---|
[1169] | 124 | super.exitMode();
|
---|
[12630] | 125 | MapFrame map = MainApplication.getMap();
|
---|
| 126 | map.mapView.removeMouseListener(this);
|
---|
| 127 | map.mapView.removeMouseMotionListener(this);
|
---|
| 128 | map.keyDetector.removeModifierExListener(this);
|
---|
[4327] | 129 | removeHighlighting();
|
---|
[1169] | 130 | }
|
---|
[626] | 131 |
|
---|
[6889] | 132 | @Override
|
---|
| 133 | public void actionPerformed(ActionEvent e) {
|
---|
[1169] | 134 | super.actionPerformed(e);
|
---|
| 135 | doActionPerformed(e);
|
---|
| 136 | }
|
---|
[768] | 137 |
|
---|
[7434] | 138 | /**
|
---|
| 139 | * Invoked when the action occurs.
|
---|
| 140 | * @param e Action event
|
---|
| 141 | */
|
---|
[12504] | 142 | public void doActionPerformed(ActionEvent e) {
|
---|
[12636] | 143 | MainLayerManager lm = MainApplication.getLayerManager();
|
---|
[10467] | 144 | OsmDataLayer editLayer = lm.getEditLayer();
|
---|
| 145 | if (editLayer == null) {
|
---|
[1169] | 146 | return;
|
---|
[10467] | 147 | }
|
---|
| 148 |
|
---|
[12526] | 149 | updateKeyModifiers(e);
|
---|
[626] | 150 |
|
---|
[1169] | 151 | Command c;
|
---|
| 152 | if (ctrl) {
|
---|
[12718] | 153 | c = DeleteCommand.deleteWithReferences(lm.getEditDataSet().getSelected());
|
---|
[1169] | 154 | } else {
|
---|
[12718] | 155 | c = DeleteCommand.delete(lm.getEditDataSet().getSelected(), !alt /* also delete nodes in way */);
|
---|
[1169] | 156 | }
|
---|
[5076] | 157 | // if c is null, an error occurred or the user aborted. Don't do anything in that case.
|
---|
[1169] | 158 | if (c != null) {
|
---|
[12641] | 159 | MainApplication.undoRedo.add(c);
|
---|
[10467] | 160 | //FIXME: This should not be required, DeleteCommand should update the selection, otherwise undo/redo won't work.
|
---|
[10448] | 161 | lm.getEditDataSet().setSelected();
|
---|
[1169] | 162 | }
|
---|
| 163 | }
|
---|
[626] | 164 |
|
---|
[7434] | 165 | @Override
|
---|
| 166 | public void mouseDragged(MouseEvent e) {
|
---|
[2692] | 167 | mouseMoved(e);
|
---|
| 168 | }
|
---|
| 169 |
|
---|
[1169] | 170 | /**
|
---|
[2026] | 171 | * Listen to mouse move to be able to update the cursor (and highlights)
|
---|
[5275] | 172 | * @param e The mouse event that has been captured
|
---|
[2026] | 173 | */
|
---|
[7434] | 174 | @Override
|
---|
| 175 | public void mouseMoved(MouseEvent e) {
|
---|
[2026] | 176 | oldEvent = e;
|
---|
[4327] | 177 | giveUserFeedback(e);
|
---|
[2026] | 178 | }
|
---|
| 179 |
|
---|
| 180 | /**
|
---|
[4327] | 181 | * removes any highlighting that may have been set beforehand.
|
---|
| 182 | */
|
---|
[10448] | 183 | private void removeHighlighting() {
|
---|
[12537] | 184 | HIGHLIGHT_HELPER.clear();
|
---|
[10448] | 185 | DataSet ds = getLayerManager().getEditDataSet();
|
---|
[8510] | 186 | if (ds != null) {
|
---|
[4327] | 187 | ds.clearHighlightedWaySegments();
|
---|
| 188 | }
|
---|
| 189 | }
|
---|
| 190 |
|
---|
| 191 | /**
|
---|
| 192 | * handles everything related to highlighting primitives and way
|
---|
[8470] | 193 | * segments for the given pointer position (via MouseEvent) and modifiers.
|
---|
| 194 | * @param e current mouse event
|
---|
[12517] | 195 | * @param modifiers extended mouse modifiers, not necessarly taken from the given mouse event
|
---|
[4327] | 196 | */
|
---|
| 197 | private void addHighlighting(MouseEvent e, int modifiers) {
|
---|
[8510] | 198 | if (!drawTargetHighlight)
|
---|
[4327] | 199 | return;
|
---|
| 200 |
|
---|
[7005] | 201 | Set<OsmPrimitive> newHighlights = new HashSet<>();
|
---|
[4327] | 202 | DeleteParameters parameters = getDeleteParameters(e, modifiers);
|
---|
| 203 |
|
---|
[8510] | 204 | if (parameters.mode == DeleteMode.segment) {
|
---|
[4327] | 205 | // deleting segments is the only action not working on OsmPrimitives
|
---|
| 206 | // so we have to handle them separately.
|
---|
[5102] | 207 | repaintIfRequired(newHighlights, parameters.nearestSegment);
|
---|
[4327] | 208 | } else {
|
---|
| 209 | // don't call buildDeleteCommands for DeleteMode.segment because it doesn't support
|
---|
| 210 | // silent operation and SplitWayAction will show dialogs. A lot.
|
---|
| 211 | Command delCmd = buildDeleteCommands(e, modifiers, true);
|
---|
[8510] | 212 | if (delCmd != null) {
|
---|
[8470] | 213 | // all other cases delete OsmPrimitives directly, so we can safely do the following
|
---|
[8510] | 214 | for (OsmPrimitive osm : delCmd.getParticipatingPrimitives()) {
|
---|
[5102] | 215 | newHighlights.add(osm);
|
---|
| 216 | }
|
---|
[4327] | 217 | }
|
---|
[5102] | 218 | repaintIfRequired(newHighlights, null);
|
---|
| 219 | }
|
---|
| 220 | }
|
---|
[4327] | 221 |
|
---|
[5102] | 222 | private void repaintIfRequired(Set<OsmPrimitive> newHighlights, WaySegment newHighlightedWaySegment) {
|
---|
| 223 | boolean needsRepaint = false;
|
---|
[10467] | 224 | OsmDataLayer editLayer = getLayerManager().getEditLayer();
|
---|
[5102] | 225 |
|
---|
[8510] | 226 | if (newHighlightedWaySegment == null && oldHighlightedWaySegment != null) {
|
---|
[10467] | 227 | if (editLayer != null) {
|
---|
| 228 | editLayer.data.clearHighlightedWaySegments();
|
---|
[5102] | 229 | needsRepaint = true;
|
---|
[4327] | 230 | }
|
---|
[5102] | 231 | oldHighlightedWaySegment = null;
|
---|
[8510] | 232 | } else if (newHighlightedWaySegment != null && !newHighlightedWaySegment.equals(oldHighlightedWaySegment)) {
|
---|
[10467] | 233 | if (editLayer != null) {
|
---|
| 234 | editLayer.data.setHighlightedWaySegments(Collections.singleton(newHighlightedWaySegment));
|
---|
[5102] | 235 | needsRepaint = true;
|
---|
| 236 | }
|
---|
| 237 | oldHighlightedWaySegment = newHighlightedWaySegment;
|
---|
[4327] | 238 | }
|
---|
[12537] | 239 | needsRepaint |= HIGHLIGHT_HELPER.highlightOnly(newHighlights);
|
---|
[10467] | 240 | if (needsRepaint && editLayer != null) {
|
---|
| 241 | editLayer.invalidate();
|
---|
[5101] | 242 | }
|
---|
| 243 | }
|
---|
| 244 |
|
---|
[4327] | 245 | /**
|
---|
[8470] | 246 | * This function handles all work related to updating the cursor and highlights
|
---|
[2512] | 247 | *
|
---|
[8470] | 248 | * @param e current mouse event
|
---|
[12517] | 249 | * @param modifiers extended mouse modifiers, not necessarly taken from the given mouse event
|
---|
[2026] | 250 | */
|
---|
| 251 | private void updateCursor(MouseEvent e, int modifiers) {
|
---|
[12630] | 252 | if (!MainApplication.isDisplayingMapView())
|
---|
[2343] | 253 | return;
|
---|
[12630] | 254 | MapFrame map = MainApplication.getMap();
|
---|
| 255 | if (!map.mapView.isActiveLayerVisible() || e == null)
|
---|
[2026] | 256 | return;
|
---|
| 257 |
|
---|
[2521] | 258 | DeleteParameters parameters = getDeleteParameters(e, modifiers);
|
---|
[12630] | 259 | map.mapView.setNewCursor(parameters.mode.cursor(), this);
|
---|
[2026] | 260 | }
|
---|
[7434] | 261 |
|
---|
[4327] | 262 | /**
|
---|
| 263 | * Gives the user feedback for the action he/she is about to do. Currently
|
---|
| 264 | * calls the cursor and target highlighting routines. Allows for modifiers
|
---|
| 265 | * not taken from the given mouse event.
|
---|
[6069] | 266 | *
|
---|
[4327] | 267 | * Normally the mouse event also contains the modifiers. However, when the
|
---|
| 268 | * mouse is not moved and only modifier keys are pressed, no mouse event
|
---|
| 269 | * occurs. We can use AWTEvent to catch those but still lack a proper
|
---|
[8470] | 270 | * mouseevent. Instead we copy the previous event and only update the modifiers.
|
---|
[9230] | 271 | * @param e mouse event
|
---|
| 272 | * @param modifiers mouse modifiers
|
---|
[4327] | 273 | */
|
---|
| 274 | private void giveUserFeedback(MouseEvent e, int modifiers) {
|
---|
| 275 | updateCursor(e, modifiers);
|
---|
| 276 | addHighlighting(e, modifiers);
|
---|
| 277 | }
|
---|
[2026] | 278 |
|
---|
| 279 | /**
|
---|
[4327] | 280 | * Gives the user feedback for the action he/she is about to do. Currently
|
---|
| 281 | * calls the cursor and target highlighting routines. Extracts modifiers
|
---|
| 282 | * from mouse event.
|
---|
[9230] | 283 | * @param e mouse event
|
---|
[4327] | 284 | */
|
---|
| 285 | private void giveUserFeedback(MouseEvent e) {
|
---|
[12517] | 286 | giveUserFeedback(e, e.getModifiersEx());
|
---|
[4327] | 287 | }
|
---|
| 288 |
|
---|
| 289 | /**
|
---|
[1169] | 290 | * If user clicked with the left button, delete the nearest object.
|
---|
| 291 | */
|
---|
[7434] | 292 | @Override
|
---|
| 293 | public void mouseReleased(MouseEvent e) {
|
---|
[1169] | 294 | if (e.getButton() != MouseEvent.BUTTON1)
|
---|
| 295 | return;
|
---|
[12630] | 296 | MapFrame map = MainApplication.getMap();
|
---|
| 297 | if (!map.mapView.isActiveLayerVisible())
|
---|
[1169] | 298 | return;
|
---|
[1935] | 299 |
|
---|
| 300 | // request focus in order to enable the expected keyboard shortcuts
|
---|
| 301 | //
|
---|
[12630] | 302 | map.mapView.requestFocus();
|
---|
[1935] | 303 |
|
---|
[12526] | 304 | Command c = buildDeleteCommands(e, e.getModifiersEx(), false);
|
---|
[1169] | 305 | if (c != null) {
|
---|
[12641] | 306 | MainApplication.undoRedo.add(c);
|
---|
[1169] | 307 | }
|
---|
[626] | 308 |
|
---|
[10382] | 309 | getLayerManager().getEditDataSet().setSelected();
|
---|
[4327] | 310 | giveUserFeedback(e);
|
---|
[1169] | 311 | }
|
---|
[1023] | 312 |
|
---|
[7434] | 313 | @Override
|
---|
| 314 | public String getModeHelpText() {
|
---|
[8540] | 315 | // CHECKSTYLE.OFF: LineLength
|
---|
[2842] | 316 | return tr("Click to delete. Shift: delete way segment. Alt: do not delete unused nodes when deleting a way. Ctrl: delete referring objects.");
|
---|
[8540] | 317 | // CHECKSTYLE.ON: LineLength
|
---|
[1169] | 318 | }
|
---|
[1677] | 319 |
|
---|
[7434] | 320 | @Override
|
---|
| 321 | public boolean layerIsSupported(Layer l) {
|
---|
[13434] | 322 | return isEditableDataLayer(l);
|
---|
[1379] | 323 | }
|
---|
[1821] | 324 |
|
---|
| 325 | @Override
|
---|
| 326 | protected void updateEnabledState() {
|
---|
[12630] | 327 | setEnabled(MainApplication.isDisplayingMapView() && MainApplication.getMap().mapView.isActiveLayerDrawable());
|
---|
[1821] | 328 | }
|
---|
[1856] | 329 |
|
---|
| 330 | /**
|
---|
[5275] | 331 | * Deletes the relation in the context of the given layer.
|
---|
[2512] | 332 | *
|
---|
[1856] | 333 | * @param layer the layer in whose context the relation is deleted. Must not be null.
|
---|
[9472] | 334 | * @param toDelete the relation to be deleted. Must not be null.
|
---|
[8291] | 335 | * @throws IllegalArgumentException if layer is null
|
---|
[9472] | 336 | * @throws IllegalArgumentException if toDelete is null
|
---|
[1856] | 337 | */
|
---|
| 338 | public static void deleteRelation(OsmDataLayer layer, Relation toDelete) {
|
---|
[9472] | 339 | deleteRelations(layer, Collections.singleton(toDelete));
|
---|
| 340 | }
|
---|
| 341 |
|
---|
| 342 | /**
|
---|
| 343 | * Deletes the relations in the context of the given layer.
|
---|
| 344 | *
|
---|
| 345 | * @param layer the layer in whose context the relations are deleted. Must not be null.
|
---|
[9496] | 346 | * @param toDelete the relations to be deleted. Must not be null.
|
---|
[9472] | 347 | * @throws IllegalArgumentException if layer is null
|
---|
| 348 | * @throws IllegalArgumentException if toDelete is null
|
---|
| 349 | */
|
---|
| 350 | public static void deleteRelations(OsmDataLayer layer, Collection<Relation> toDelete) {
|
---|
[2842] | 351 | CheckParameterUtil.ensureParameterNotNull(layer, "layer");
|
---|
| 352 | CheckParameterUtil.ensureParameterNotNull(toDelete, "toDelete");
|
---|
[2026] | 353 |
|
---|
[12718] | 354 | final Command cmd = DeleteCommand.delete(toDelete);
|
---|
[1856] | 355 | if (cmd != null) {
|
---|
| 356 | // cmd can be null if the user cancels dialogs DialogCommand displays
|
---|
[12641] | 357 | MainApplication.undoRedo.add(cmd);
|
---|
[9472] | 358 | for (Relation relation : toDelete) {
|
---|
[9496] | 359 | if (layer.data.getSelectedRelations().contains(relation)) {
|
---|
| 360 | layer.data.toggleSelected(relation);
|
---|
[9472] | 361 | }
|
---|
| 362 | RelationDialogManager.getRelationDialogManager().close(layer, relation);
|
---|
[4475] | 363 | }
|
---|
[1856] | 364 | }
|
---|
| 365 | }
|
---|
[2026] | 366 |
|
---|
[2521] | 367 | private DeleteParameters getDeleteParameters(MouseEvent e, int modifiers) {
|
---|
[12517] | 368 | updateKeyModifiersEx(modifiers);
|
---|
[2026] | 369 |
|
---|
[2521] | 370 | DeleteParameters result = new DeleteParameters();
|
---|
| 371 |
|
---|
[12630] | 372 | MapView mapView = MainApplication.getMap().mapView;
|
---|
| 373 | result.nearestNode = mapView.getNearestNode(e.getPoint(), OsmPrimitive::isSelectable);
|
---|
[2521] | 374 | if (result.nearestNode == null) {
|
---|
[12630] | 375 | result.nearestSegment = mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive::isSelectable);
|
---|
[2521] | 376 | if (result.nearestSegment != null) {
|
---|
[2026] | 377 | if (shift) {
|
---|
[2521] | 378 | result.mode = DeleteMode.segment;
|
---|
[2026] | 379 | } else if (ctrl) {
|
---|
[2521] | 380 | result.mode = DeleteMode.way_with_references;
|
---|
[2026] | 381 | } else {
|
---|
[8510] | 382 | result.mode = alt ? DeleteMode.way : DeleteMode.way_with_nodes;
|
---|
[2026] | 383 | }
|
---|
[2521] | 384 | } else {
|
---|
| 385 | result.mode = DeleteMode.none;
|
---|
[2026] | 386 | }
|
---|
| 387 | } else if (ctrl) {
|
---|
[2521] | 388 | result.mode = DeleteMode.node_with_references;
|
---|
[2026] | 389 | } else {
|
---|
[2521] | 390 | result.mode = DeleteMode.node;
|
---|
[2026] | 391 | }
|
---|
| 392 |
|
---|
[2521] | 393 | return result;
|
---|
[2026] | 394 | }
|
---|
| 395 |
|
---|
| 396 | /**
|
---|
[2521] | 397 | * This function takes any mouse event argument and builds the list of elements
|
---|
| 398 | * that should be deleted but does not actually delete them.
|
---|
| 399 | * @param e MouseEvent from which modifiers and position are taken
|
---|
[5909] | 400 | * @param modifiers For explanation, see {@link #updateCursor}
|
---|
[8470] | 401 | * @param silent Set to true if the user should not be bugged with additional dialogs
|
---|
[5909] | 402 | * @return delete command
|
---|
[2521] | 403 | */
|
---|
| 404 | private Command buildDeleteCommands(MouseEvent e, int modifiers, boolean silent) {
|
---|
| 405 | DeleteParameters parameters = getDeleteParameters(e, modifiers);
|
---|
| 406 | switch (parameters.mode) {
|
---|
| 407 | case node:
|
---|
[12718] | 408 | return DeleteCommand.delete(Collections.singleton(parameters.nearestNode), false, silent);
|
---|
[2521] | 409 | case node_with_references:
|
---|
[12718] | 410 | return DeleteCommand.deleteWithReferences(Collections.singleton(parameters.nearestNode), silent);
|
---|
[2521] | 411 | case segment:
|
---|
[12718] | 412 | return DeleteCommand.deleteWaySegment(parameters.nearestSegment);
|
---|
[2521] | 413 | case way:
|
---|
[12718] | 414 | return DeleteCommand.delete(Collections.singleton(parameters.nearestSegment.way), false, silent);
|
---|
[2521] | 415 | case way_with_nodes:
|
---|
[12718] | 416 | return DeleteCommand.delete(Collections.singleton(parameters.nearestSegment.way), true, silent);
|
---|
[2521] | 417 | case way_with_references:
|
---|
[12718] | 418 | return DeleteCommand.deleteWithReferences(Collections.singleton(parameters.nearestSegment.way), true);
|
---|
[2521] | 419 | default:
|
---|
| 420 | return null;
|
---|
| 421 | }
|
---|
| 422 | }
|
---|
| 423 |
|
---|
| 424 | /**
|
---|
[2026] | 425 | * This is required to update the cursors when ctrl/shift/alt is pressed
|
---|
| 426 | */
|
---|
[6084] | 427 | @Override
|
---|
[12517] | 428 | public void modifiersExChanged(int modifiers) {
|
---|
[7434] | 429 | if (oldEvent == null)
|
---|
[4327] | 430 | return;
|
---|
[7434] | 431 | // We don't have a mouse event, so we pass the old mouse event but the new modifiers.
|
---|
[7217] | 432 | giveUserFeedback(oldEvent, modifiers);
|
---|
[2026] | 433 | }
|
---|
[626] | 434 | }
|
---|