Ignore:
Timestamp:
2009-11-27T21:46:49+01:00 (14 years ago)
Author:
jttt
Message:

Fixed #3704 Relation memberships are not handled at all when a way is splitted or deleted by deleting a segment, rewritten DeleteAction a bit (delete commands are no longer build in updateCursor())

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java

    r2512 r2521  
    1313import java.awt.event.KeyEvent;
    1414import java.awt.event.MouseEvent;
    15 import java.util.Collection;
    1615import java.util.Collections;
    17 import java.util.HashSet;
    1816
    1917import org.openstreetmap.josm.Main;
     
    2119import org.openstreetmap.josm.command.DeleteCommand;
    2220import org.openstreetmap.josm.data.osm.Node;
    23 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2421import org.openstreetmap.josm.data.osm.Relation;
    25 import org.openstreetmap.josm.data.osm.Way;
    2622import org.openstreetmap.josm.data.osm.WaySegment;
    2723import org.openstreetmap.josm.gui.MapFrame;
     
    6359    private MouseEvent oldEvent = null;
    6460
    65     private enum Cursors {
    66         none,
    67         node,
    68         segment,
    69         way_node_only,
    70         way_normal,
    71         way_only;
    72 
    73         private Cursor c = null;
    74         // This loads and caches the cursor for each
     61    private enum DeleteMode {
     62        none("delete"),
     63        segment("delete_segment"),
     64        node("delete_node"),
     65        node_with_references("delete_node"),
     66        way("delete_way_only"),
     67        way_with_references("delete_way_normal"),
     68        way_with_nodes("delete_way_node_only");
     69
     70        private final Cursor c;
     71
     72        private DeleteMode(String cursorName) {
     73            c = ImageProvider.getCursor("normal", cursorName);
     74        }
     75
    7576        public Cursor cursor() {
    76             if(c == null) {
    77                 String nm = "delete_" + this.name().toLowerCase();
    78                 // "None" has no special icon
    79                 nm = nm.equals("delete_none") ? "delete" : nm;
    80                 this.c = ImageProvider.getCursor("normal", nm);
    81             }
    8277            return c;
    8378        }
    8479    }
    85     private Cursors currCursor = Cursors.none;
     80    private DeleteMode currentMode = DeleteMode.none;
     81
     82    private static class DeleteParameters {
     83        DeleteMode mode;
     84        Node nearestNode;
     85        WaySegment nearestSegment;
     86    }
    8687
    8788    /**
     
    110111        try {
    111112            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
    112         } catch (SecurityException ex) {}
    113 
    114         currCursor = Cursors.none;
     113        } catch (SecurityException ex) {
     114            System.out.println(ex);
     115        }
     116
     117        currentMode = DeleteMode.none;
    115118    }
    116119
     
    121124        try {
    122125            Toolkit.getDefaultToolkit().removeAWTEventListener(this);
    123         } catch (SecurityException ex) {}
     126        } catch (SecurityException ex) {
     127            System.out.println(ex);
     128        }
    124129    }
    125130
     
    172177     *
    173178     * @param MouseEvent
    174      * @parm int modifiers
     179     * @param int modifiers
    175180     */
    176181    private void updateCursor(MouseEvent e, int modifiers) {
    177         if (!Main.isDisplayingMapView()) {
    178             return;
    179         }
     182        if (!Main.isDisplayingMapView())
     183            return;
    180184        if(!Main.map.mapView.isActiveLayerVisible() || e == null)
    181185            return;
     
    184188        //cleanOldHighlights();
    185189
    186         Command c = buildDeleteCommands(e, modifiers, true);
    187         if(c == null) {
    188             setCursor(Cursors.none);
    189             return;
    190         }
    191 
    192         Collection<OsmPrimitive> prims = new HashSet<OsmPrimitive>();
    193         Collection<OsmPrimitive> mods = new HashSet<OsmPrimitive>();
    194         c.fillModifiedData(mods, prims, prims);
    195 
    196         if(prims.size() == 0 && mods.size() == 0) {
    197             // Default-Cursor
    198             setCursor(Cursors.none);
    199             return;
    200         }
    201 
    202         // There are no deleted parts if solely a way segment is deleted
    203         // This is no the case when actually deleting only a segment but that
    204         // segment happens to be the whole way. This is an acceptable error
    205         // though
    206         if(prims.size() == 0) {
    207             setCursor(Cursors.segment);
    208         } else if(prims.size() == 1 && prims.toArray()[0] instanceof Node) {
    209             setCursor(Cursors.node);
    210         } else if(prims.size() == 1 && prims.toArray()[0] instanceof Way) {
    211             setCursor(Cursors.way_only);
    212         } else {
    213             // Decide between non-accel click where "useless" nodes are deleted
    214             // and ctrl-click where nodes and ways are deleted
    215             boolean ctrl = (modifiers & ActionEvent.CTRL_MASK) != 0;
    216             if(ctrl) {
    217                 setCursor(Cursors.way_node_only);
    218             } else {
    219                 setCursor(Cursors.way_normal);
    220             }
    221 
    222         }
     190        DeleteParameters parameters = getDeleteParameters(e, modifiers);
     191        setCursor(parameters.mode);
    223192
    224193        // Needs to implement WaySegment highlight first
     
    306275    }
    307276
     277    private DeleteParameters getDeleteParameters(MouseEvent e, int modifiers) {
     278        // Note: CTRL is the only modifier that is checked in MouseMove, don't
     279        // forget updating it there
     280        boolean ctrl = (modifiers & ActionEvent.CTRL_MASK) != 0;
     281        boolean shift = (modifiers & ActionEvent.SHIFT_MASK) != 0;
     282        boolean alt = (modifiers & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0;
     283
     284        DeleteParameters result = new DeleteParameters();
     285
     286        result.nearestNode = Main.map.mapView.getNearestNode(e.getPoint());
     287        if (result.nearestNode == null) {
     288            result.nearestSegment = Main.map.mapView.getNearestWaySegment(e.getPoint());
     289            if (result.nearestSegment != null) {
     290                if (shift) {
     291                    result.mode = DeleteMode.segment;
     292                } else if (ctrl) {
     293                    result.mode = DeleteMode.way_with_references;
     294                } else {
     295                    result.mode = alt?DeleteMode.way:DeleteMode.way_with_nodes;
     296                }
     297            } else {
     298                result.mode = DeleteMode.none;
     299            }
     300        } else if (ctrl) {
     301            result.mode = DeleteMode.node_with_references;
     302        } else {
     303            result.mode = DeleteMode.node;
     304        }
     305
     306        return result;
     307    }
     308
    308309    /**
    309310     * This function takes any mouse event argument and builds the list of elements
     
    316317     */
    317318    private Command buildDeleteCommands(MouseEvent e, int modifiers, boolean silent) {
    318         // Note: CTRL is the only modifier that is checked in MouseMove, don't
    319         // forget updating it there
    320         boolean ctrl = (modifiers & ActionEvent.CTRL_MASK) != 0;
    321         boolean shift = (modifiers & ActionEvent.SHIFT_MASK) != 0;
    322         boolean alt = (modifiers & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0;
    323 
    324         OsmPrimitive sel = Main.map.mapView.getNearestNode(e.getPoint());
    325         Command c = null;
    326         if (sel == null) {
    327             WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
    328             if (ws != null) {
    329                 if (shift) {
    330                     c = DeleteCommand.deleteWaySegment(getEditLayer(),ws);
    331                 } else if (ctrl) {
    332                     c = DeleteCommand.deleteWithReferences(getEditLayer(),Collections.singleton((OsmPrimitive)ws.way),true);
    333                 } else {
    334                     c = DeleteCommand.delete(getEditLayer(),Collections.singleton((OsmPrimitive)ws.way), !alt, silent);
    335                 }
    336             }
    337         } else if (ctrl) {
    338             c = DeleteCommand.deleteWithReferences(getEditLayer(),Collections.singleton(sel));
    339         } else {
    340             c = DeleteCommand.delete(getEditLayer(),Collections.singleton(sel), !alt, silent);
    341         }
    342 
    343         return c;
     319        DeleteParameters parameters = getDeleteParameters(e, modifiers);
     320        switch (parameters.mode) {
     321        case node:
     322            return DeleteCommand.delete(getEditLayer(),Collections.singleton(parameters.nearestNode), false, silent);
     323        case node_with_references:
     324            return DeleteCommand.deleteWithReferences(getEditLayer(),Collections.singleton(parameters.nearestNode));
     325        case segment:
     326            return DeleteCommand.deleteWaySegment(getEditLayer(), parameters.nearestSegment);
     327        case way:
     328            return DeleteCommand.delete(getEditLayer(), Collections.singleton(parameters.nearestSegment.way), false, silent);
     329        case way_with_nodes:
     330            return DeleteCommand.delete(getEditLayer(), Collections.singleton(parameters.nearestSegment.way), true, silent);
     331        case way_with_references:
     332            return DeleteCommand.deleteWithReferences(getEditLayer(),Collections.singleton(parameters.nearestSegment.way),true);
     333        default:
     334            return null;
     335        }
    344336    }
    345337
     
    351343     * @param c
    352344     */
    353     private void setCursor(final Cursors c) {
    354         if(currCursor.equals(c) || (!drawTargetCursor && currCursor.equals(Cursors.none)))
     345    private void setCursor(final DeleteMode c) {
     346        if(currentMode.equals(c) || (!drawTargetCursor && currentMode.equals(DeleteMode.none)))
    355347            return;
    356348        try {
     
    366358                }
    367359            });
    368             currCursor = c;
     360            currentMode = c;
    369361        } catch(Exception e) {}
    370362    }
Note: See TracChangeset for help on using the changeset viewer.