Changeset 358 in josm


Ignore:
Timestamp:
2007-10-11T12:46:00+02:00 (17 years ago)
Author:
gebner
Message:

Beginnings of the implementation of ticket #11.

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
5 deleted
3 edited

Legend:

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

    r343 r358  
    1313import java.util.HashSet;
    1414import java.util.LinkedList;
     15import java.util.List;
    1516import java.util.Map.Entry;
    1617
     
    1819
    1920import org.openstreetmap.josm.Main;
     21import org.openstreetmap.josm.command.AddCommand;
    2022import org.openstreetmap.josm.command.ChangeCommand;
    2123import org.openstreetmap.josm.command.Command;
     
    2527import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2628import org.openstreetmap.josm.data.osm.Way;
     29import org.openstreetmap.josm.data.osm.WaySegment;
     30import org.openstreetmap.josm.data.osm.Relation;
    2731import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
    2832import org.openstreetmap.josm.gui.MapFrame;
     
    7478                super.actionPerformed(e);
    7579                boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    76                 if (ctrl)
    77                         deleteWithReferences(Main.ds.getSelected());
    78                 else
    79                         delete(Main.ds.getSelected(), false, false);
     80
     81                Command c;
     82                if (ctrl) {
     83                        c = deleteWithReferences(Main.ds.getSelected());
     84                } else {
     85                        c = delete(Main.ds.getSelected());
     86                }
     87                if (c != null) {
     88                        Main.main.undoRedo.add(c);
     89                }
     90
    8091                Main.map.repaint();
    8192        }
     
    8899                if (e.getButton() != MouseEvent.BUTTON1)
    89100                        return;
     101                boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    90102               
    91                 OsmPrimitive sel = Main.map.mapView.getNearest(e.getPoint());
    92                 if (sel == null)
    93                         return;
    94 
    95                 if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0)
    96                         deleteWithReferences(Collections.singleton(sel));
    97                 else
    98                         delete(Collections.singleton(sel), true, true);
     103                OsmPrimitive sel = Main.map.mapView.getNearestNode(e.getPoint());
     104                Command c;
     105                if (sel == null) {
     106                        WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
     107                        c = deleteWaySegment(ws);
     108                } else if (ctrl) {
     109                        c = deleteWithReferences(Collections.singleton(sel));
     110                } else {
     111                        c = delete(Collections.singleton(sel));
     112                }
     113                if (c != null) {
     114                        Main.main.undoRedo.add(c);
     115                }
    99116
    100117                Main.map.mapView.repaint();
     
    112129         *
    113130         * @param selection The list of all object to be deleted.
    114          */
    115         private void deleteWithReferences(Collection<OsmPrimitive> selection) {
     131         * @return command A command to perform the deletions, or null of there is
     132         * nothing to delete.
     133         */
     134        private Command deleteWithReferences(Collection<OsmPrimitive> selection) {
    116135                CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
    117136                for (OsmPrimitive osm : selection)
    118137                        osm.visit(v);
    119138                v.data.addAll(selection);
    120                 if (!v.data.isEmpty())
    121                         Main.main.undoRedo.add(new DeleteCommand(v.data));
    122         }
    123 
    124         /**
    125          * Try to delete all given primitives. If a primitive is
    126          * used somewhere and that "somewhere" is not going to be deleted,
    127          * inform the user and do not delete.
    128          *
    129          * If a node is to be deleted which is in the middle of exactly one way,
    130          * the node is removed from the way's node list and after that removed
    131          * itself.
     139                if (v.data.isEmpty()) {
     140                        return null;
     141                } else {
     142                        return new DeleteCommand(v.data);
     143                }
     144        }
     145
     146        /**
     147         * Try to delete all given primitives.
     148         *
     149         * If a node is used by a way, it's removed from that way.  If a node or a
     150         * way is used by a relation, inform the user and do not delete.
     151         *
     152         * If this would cause ways with less than 2 nodes to be created, delete
     153         * these ways instead.  If they are part of a relation, inform the user
     154         * and do not delete.
    132155         *
    133156         * @param selection The objects to delete.
    134          * @param msgBox Whether a message box for errors should be shown
    135          */
    136         private void delete(Collection<OsmPrimitive> selection, boolean msgBox, boolean joinIfPossible) {
    137                 Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>();
    138                 for (OsmPrimitive osm : selection) {
    139                         CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
     157         * @return command A command to perform the deletions, or null of there is
     158         * nothing to delete.
     159         */
     160        private Command delete(Collection<OsmPrimitive> selection) {
     161                if (selection.isEmpty()) return null;
     162
     163                Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);
     164                Collection<Way> waysToBeChanged = new HashSet<Way>();
     165                for (OsmPrimitive osm : del) {
     166                        CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
    140167                        osm.visit(v);
    141                         if (!selection.containsAll(v.data)) {
    142                                 if (osm instanceof Node && joinIfPossible) {
    143                                         String reason = deleteNodeAndJoinWay((Node)osm);
    144                                         if (reason != null && msgBox) {
    145                                                 JOptionPane.showMessageDialog(Main.parent,tr("Cannot delete node.")+" "+reason);
    146                                                 return;
     168                        for (OsmPrimitive ref : v.data) {
     169                                if (del.contains(ref)) continue;
     170                                if (ref instanceof Way) {
     171                                        waysToBeChanged.add((Way) ref);
     172                                } else if (ref instanceof Relation) {
     173                                        JOptionPane.showMessageDialog(Main.parent,
     174                                                tr("Cannot delete: Selection is used by relation"));
     175                                        return null;
     176                                } else {
     177                                        return null;
     178                                }
     179                        }
     180                }
     181
     182                Collection<Command> cmds = new LinkedList<Command>();
     183                for (Way w : waysToBeChanged) {
     184                        Way wnew = new Way(w);
     185                        wnew.nodes.removeAll(del);
     186                        if (wnew.nodes.size() < 2) {
     187                                del.add(w);
     188
     189                                CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
     190                                w.visit(v);
     191                                for (OsmPrimitive ref : v.data) {
     192                                        if (del.contains(ref)) continue;
     193                                        if (ref instanceof Relation) {
     194                                                JOptionPane.showMessageDialog(Main.parent,
     195                                                        tr("Cannot delete: Selection is used by relation"));
     196                                        } else {
     197                                                return null;
    147198                                        }
    148                                 } else if (msgBox) {
    149                                         JOptionPane.showMessageDialog(Main.parent, tr("This object is in use."));
    150                                         return;
    151199                                }
    152200                        } else {
    153                                 del.addAll(v.data);
    154                                 del.add(osm);
     201                                cmds.add(new ChangeCommand(w, wnew));
    155202                        }
    156203                }
    157                 if (!del.isEmpty())
    158                         Main.main.undoRedo.add(new DeleteCommand(del));
    159         }
    160 
    161         private String deleteNodeAndJoinWay(Node n) {
    162                 ArrayList<Way> ways = new ArrayList<Way>(1);
    163                 for (Way w : Main.ds.ways) {
    164                         if (!w.deleted && w.nodes.contains(n)) {
    165                                 ways.add(w);
    166                 }
    167                 }
    168 
    169                 if (ways.size() > 1)
    170                         return tr("Used by more than one way.");
    171                
    172                 if (ways.size() == 1) {
    173                         // node in way
    174                         Way w = ways.get(0);
    175 
    176                         int i = w.nodes.indexOf(n);
    177                         if (w.nodes.lastIndexOf(n) != i)
    178                                 return tr("Occurs more than once in the same way.");
    179                         if (i == 0 || i == w.nodes.size() - 1)
    180                                 return tr("Is at the end of a way");
    181 
    182                         Way wnew = new Way(w);
    183                         wnew.nodes.remove(i);
    184 
    185                         Collection<Command> cmds = new LinkedList<Command>();
    186                         cmds.add(new ChangeCommand(w, wnew));
    187                         cmds.add(new DeleteCommand(Collections.singleton(n)));
    188                         Main.main.undoRedo.add(new SequenceCommand(tr("Delete Node"), cmds));
    189                 } else {
    190                         // unwayed node
    191                         Main.main.undoRedo.add(new DeleteCommand(Collections.singleton(n)));   
    192                 }
    193                 return null;
    194     }
     204
     205                if (!del.isEmpty()) cmds.add(new DeleteCommand(del));
     206
     207                return new SequenceCommand(tr("Delete"), cmds);
     208        }
     209
     210        private Command deleteWaySegment(WaySegment ws) {
     211                List<Node> n1 = new ArrayList<Node>(),
     212                        n2 = new ArrayList<Node>();
     213
     214                n1.addAll(ws.way.nodes.subList(0, ws.lowerIndex + 1));
     215                n2.addAll(ws.way.nodes.subList(ws.lowerIndex + 1, ws.way.nodes.size()));
     216
     217                if (n1.size() < 2 && n2.size() < 2) {
     218                        return new DeleteCommand(Collections.singleton(ws.way));
     219                } else {
     220                        Way wnew = new Way(ws.way);
     221                        wnew.nodes.clear();
     222
     223                        if (n1.size() < 2) {
     224                                wnew.nodes.addAll(n2);
     225                                return new ChangeCommand(ws.way, wnew);
     226                        } else if (n2.size() < 2) {
     227                                wnew.nodes.addAll(n1);
     228                                return new ChangeCommand(ws.way, wnew);
     229                        } else {
     230                                Collection<Command> cmds = new LinkedList<Command>();
     231
     232                                wnew.nodes.addAll(n1);
     233                                cmds.add(new ChangeCommand(ws.way, wnew));
     234
     235                                Way wnew2 = new Way();
     236                                wnew2.nodes.addAll(n2);
     237                                cmds.add(new AddCommand(wnew2));
     238
     239                                return new SequenceCommand(tr("Split way segment"), cmds);
     240                        }
     241                }
     242        }
    195243}
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java

    r343 r358  
    2222
    2323        private final DataSet ds;
     24        private final boolean indirectRefs;
    2425
    2526        /**
     
    3536        public CollectBackReferencesVisitor(DataSet ds) {
    3637                this.ds = ds;
     38                this.indirectRefs = true;
     39        }
     40
     41        public CollectBackReferencesVisitor(DataSet ds, boolean indirectRefs) {
     42                this.ds = ds;
     43                this.indirectRefs = indirectRefs;
    3744        }
    3845
     
    4451                                if (n == n2) {
    4552                                        data.add(w);
     53                                        if (indirectRefs) {
     54                                                visit(w);
     55                                        }
    4656                                }
    4757                        }
     
    6575                        for (RelationMember m : r.members) {
    6676                                if (m.member == p) {
    67                                         data.add(r);
    68                                         // move up the tree (there might be relations
    69                                         // referring to this relation)
    70                                         checkRelationMembership(r);
     77                                        if (!data.contains(r)) {
     78                                                data.add(r);
     79                                                if (indirectRefs) {
     80                                                        // move up the tree (there might be relations
     81                                                        // referring to this relation)
     82                                                        checkRelationMembership(r);
     83                                                }
     84                                        }
    7185                                        break;
    7286                                }
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r343 r358  
    1414
    1515import org.openstreetmap.josm.Main;
    16 import org.openstreetmap.josm.actions.mapmode.AddSegmentAction;
    1716import org.openstreetmap.josm.actions.mapmode.DeleteAction;
     17import org.openstreetmap.josm.actions.mapmode.DrawAction;
    1818import org.openstreetmap.josm.actions.mapmode.MapMode;
    19 import org.openstreetmap.josm.actions.mapmode.SelectionAction;
    2019import org.openstreetmap.josm.actions.mapmode.ZoomAction;
    21 import org.openstreetmap.josm.actions.mapmode.AddNodeAction.AddNodeGroup;
    22 import org.openstreetmap.josm.actions.mapmode.MoveAction.MoveGroup;
     20import org.openstreetmap.josm.actions.mapmode.SelectAction.SelectGroup;
    2321import org.openstreetmap.josm.gui.dialogs.CommandStackDialog;
    2422import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
     
    8078                toolBarActions.setFloatable(false);
    8179                toolBarActions.add(new IconToggleButton(new ZoomAction(this)));
    82                 final Action selectionAction = new SelectionAction.Group(this);
    83                 toolBarActions.add(new IconToggleButton(selectionAction));
    84                 toolBarActions.add(new IconToggleButton(new MoveGroup(this)));
    85                 toolBarActions.add(new IconToggleButton(new AddNodeGroup(this)));
    86                 toolBarActions.add(new IconToggleButton(new AddSegmentAction(this)));
     80                toolBarActions.add(new IconToggleButton(new SelectGroup(this)));
     81                toolBarActions.add(new IconToggleButton(new DrawAction(this)));
    8782                toolBarActions.add(new IconToggleButton(new DeleteAction(this)));
    8883
Note: See TracChangeset for help on using the changeset viewer.