Ignore:
Timestamp:
2005-10-27T00:38:03+02:00 (19 years ago)
Author:
imi
Message:
  • added commands to support undo later
  • added Edit-Layer concept
  • painting of deleted objects
File:
1 edited

Legend:

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

    r22 r23  
    44import java.awt.event.MouseEvent;
    55import java.util.ArrayList;
    6 import java.util.HashMap;
     6import java.util.Collection;
    77import java.util.LinkedList;
    8 import java.util.Map;
    98
    109import javax.swing.JOptionPane;
    1110
    1211import org.openstreetmap.josm.Main;
    13 import org.openstreetmap.josm.data.osm.Key;
     12import org.openstreetmap.josm.command.CombineAndDeleteCommand;
     13import org.openstreetmap.josm.command.DeleteCommand;
     14import org.openstreetmap.josm.command.CombineAndDeleteCommand.LineSegmentCombineEntry;
    1415import org.openstreetmap.josm.data.osm.LineSegment;
    1516import org.openstreetmap.josm.data.osm.Node;
     
    133134                if (osm instanceof Node) {
    134135                        // delete any track and line segment the node is in.
    135                         for (Track t : Main.main.ds.tracks())
    136                                 for (LineSegment ls : t.segments())
    137                                         if (ls.getStart() == osm || ls.getEnd() == osm)
     136                        for (Track t : Main.main.ds.tracks)
     137                                for (LineSegment ls : t.segments)
     138                                        if (ls.start == osm || ls.end == osm)
    138139                                                tracksToDelete.add(t);
    139                         for (LineSegment ls : Main.main.ds.pendingLineSegments())
    140                                 if (ls.getStart() == osm || ls.getEnd() == osm)
     140                        for (LineSegment ls : Main.main.ds.pendingLineSegments)
     141                                if (ls.start == osm || ls.end == osm)
    141142                                        lineSegmentsToDelete.add(ls);
    142143                               
     
    144145                        LineSegment lineSegment = (LineSegment)osm;
    145146                        lineSegmentsToDelete.add(lineSegment);
    146                         for (Track t : Main.main.ds.tracks())
    147                                 for (LineSegment ls : t.segments())
     147                        for (Track t : Main.main.ds.tracks)
     148                                for (LineSegment ls : t.segments)
    148149                                        if (lineSegment == ls)
    149150                                                tracksToDelete.add(t);
     
    154155                ArrayList<Node> checkUnreferencing = new ArrayList<Node>();
    155156                for (Track t : tracksToDelete) {
    156                         for (LineSegment ls : t.segments()) {
    157                                 checkUnreferencing.add(ls.getStart());
    158                                 checkUnreferencing.add(ls.getEnd());
     157                        for (LineSegment ls : t.segments) {
     158                                checkUnreferencing.add(ls.start);
     159                                checkUnreferencing.add(ls.end);
    159160                        }
    160161                }
    161162                for (LineSegment ls : lineSegmentsToDelete) {
    162                         checkUnreferencing.add(ls.getStart());
    163                         checkUnreferencing.add(ls.getEnd());
    164                 }
    165                
    166                 // delete tracks and areas
    167                 for (Track t : tracksToDelete)
    168                         Main.main.ds.removeTrack(t);
    169                 for (LineSegment ls : lineSegmentsToDelete)
    170                         Main.main.ds.destroyPendingLineSegment(ls);
    171 
     163                        checkUnreferencing.add(ls.start);
     164                        checkUnreferencing.add(ls.end);
     165                }
     166               
     167                Collection<OsmPrimitive> deleteData = new LinkedList<OsmPrimitive>();
     168                deleteData.addAll(tracksToDelete);
     169                deleteData.addAll(lineSegmentsToDelete);
    172170                // removing all unreferenced nodes
    173                 for (Node n : checkUnreferencing) {
     171                for (Node n : checkUnreferencing)
    174172                        if (!isReferenced(n))
    175                                 Main.main.ds.nodes.remove(n);
    176                 }
     173                                deleteData.add(n);
    177174                // now, all references are killed. Delete the node (if it was a node)
    178175                if (osm instanceof Node)
    179                         Main.main.ds.nodes.remove(osm);
     176                        deleteData.add(osm);
     177               
     178                mv.editLayer().add(new DeleteCommand(deleteData));
    180179        }
    181180
     
    188187         */
    189188        private void delete(OsmPrimitive osm) {
    190                 if (osm instanceof Node) {
    191                         Node n = (Node)osm;
    192                         if (isReferenced(n)) {
    193                                 String combined = combine(n);
    194                                 if (combined != null) {
    195                                         JOptionPane.showMessageDialog(Main.main, combined);
    196                                         return;
    197                                 }
    198                         }
    199                         // now, the node isn't referenced anymore, so delete it.
    200                         Main.main.ds.nodes.remove(n);
    201                 } else if (osm instanceof LineSegment) {
    202                         LinkedList<Track> tracksToDelete = new LinkedList<Track>();
    203                         for (Track t : Main.main.ds.tracks()) {
    204                                 t.remove((LineSegment)osm);
    205                                 if (t.segments().isEmpty())
    206                                         tracksToDelete.add(t);
    207                         }
    208                         for (Track t : tracksToDelete)
    209                                 Main.main.ds.removeTrack(t);
    210                         Main.main.ds.destroyPendingLineSegment((LineSegment)osm);
    211                 } else if (osm instanceof Track) {
    212                         Main.main.ds.removeTrack((Track)osm);
    213                         for (LineSegment ls : ((Track)osm).segments())
    214                                 Main.main.ds.addPendingLineSegment(ls);
    215                 }
     189                if (osm instanceof Node && isReferenced((Node)osm)) {
     190                        combineAndDelete((Node)osm);
     191                        return;
     192                }
     193                Collection<OsmPrimitive> c = new LinkedList<OsmPrimitive>();
     194                c.add(osm);
     195                mv.editLayer().add(new DeleteCommand(c));
    216196        }
    217197
     
    223203         */
    224204        private boolean isReferenced(Node n) {
    225                 for (Track t : Main.main.ds.tracks())
    226                         for (LineSegment ls : t.segments())
    227                                 if (ls.getStart() == n || ls.getEnd() == n)
     205                for (Track t : Main.main.ds.tracks)
     206                        for (LineSegment ls : t.segments)
     207                                if (ls.start == n || ls.end == n)
    228208                                        return true;
    229                 for (LineSegment ls : Main.main.ds.pendingLineSegments())
    230                         if (ls.getStart() == n || ls.getEnd() == n)
     209                for (LineSegment ls : Main.main.ds.pendingLineSegments)
     210                        if (ls.start == n || ls.end == n)
    231211                                return true;
    232212                // TODO areas
     
    243223         *              are problems combining the node.
    244224         */
    245         private String combine(Node n) {
     225        private void combineAndDelete(Node n) {
    246226                // first, check for pending line segments
    247                 for (LineSegment ls : Main.main.ds.pendingLineSegments())
    248                         if (n == ls.getStart() || n == ls.getEnd())
    249                                 return "Node used by a line segment which is not part of any track. Remove this first.";
     227                for (LineSegment ls : Main.main.ds.pendingLineSegments)
     228                        if (n == ls.start || n == ls.end) {
     229                                JOptionPane.showMessageDialog(Main.main, "Node used by a line segment which is not part of any track. Remove this first.");
     230                                return;
     231                        }
    250232               
    251233                // These line segments must be combined within the track combining
     
    256238                // These line segments are combinable. The inner arraylist has always
    257239                // two elements. The keys maps to the track, the line segments are in.
    258                 HashMap<ArrayList<LineSegment>, Track> lineSegments = new HashMap<ArrayList<LineSegment>, Track>();
    259                
    260                 for (Track t : Main.main.ds.tracks()) {
     240                Collection<LineSegmentCombineEntry> lineSegments = new ArrayList<LineSegmentCombineEntry>();
     241               
     242                for (Track t : Main.main.ds.tracks) {
    261243                        ArrayList<LineSegment> current = new ArrayList<LineSegment>();
    262                         for (LineSegment ls : t.segments())
    263                                 if (ls.getStart() == n || ls.getEnd() == n)
     244                        for (LineSegment ls : t.segments)
     245                                if (ls.start == n || ls.end == n)
    264246                                        current.add(ls);
    265247                        if (!current.isEmpty()) {
    266                                 if (current.size() > 2)
    267                                         return "Node used by more than two line segments.";
     248                                if (current.size() > 2) {
     249                                        JOptionPane.showMessageDialog(Main.main, "Node used by more than two line segments.");
     250                                        return;
     251                                }
    268252                                if (current.size() == 1 &&
    269253                                                (current.get(0) == t.getStartingSegment() || current.get(0) == t.getEndingSegment()))
    270254                                        pendingLineSegmentsForTrack.add(current.get(0));
    271                                 else if (current.get(0).getEnd() != current.get(1).getStart() &&
    272                                                 current.get(1).getEnd() != current.get(0).getStart())
    273                                         return "Node used by line segments that points together.";
    274                                 else if (!current.get(0).keyPropertiesMergable(current.get(1)))
    275                                         return "Node used by line segments with different properties.";
    276                                 else
    277                                         lineSegments.put(current, t);
     255                                else if (current.get(0).end != current.get(1).start &&
     256                                                current.get(1).end != current.get(0).start) {
     257                                        JOptionPane.showMessageDialog(Main.main, "Node used by line segments that points together.");
     258                                        return;
     259                                } else if (!current.get(0).keyPropertiesMergable(current.get(1))) {
     260                                        JOptionPane.showMessageDialog(Main.main, "Node used by line segments with different properties.");
     261                                        return;
     262                                } else {
     263                                        LineSegmentCombineEntry e = new LineSegmentCombineEntry();
     264                                        e.first = current.get(0);
     265                                        e.second = current.get(1);
     266                                        e.track = t;
     267                                        lineSegments.add(e);
     268                                }
    278269                        }
    279270                }
     
    281272                // try to combine tracks
    282273                ArrayList<Track> tracks = new ArrayList<Track>();
    283                 for (Track t : Main.main.ds.tracks())
     274                for (Track t : Main.main.ds.tracks)
    284275                        if (t.getStartingNode() == n || t.getEndingNode() == n)
    285276                                tracks.add(t);
    286277                if (!tracks.isEmpty()) {
    287                         if (tracks.size() > 2)
    288                                 return "Node used by more than two tracks.";
    289                         if (tracks.size() == 1)
    290                                 return "Node used by a track.";
     278                        if (tracks.size() > 2) {
     279                                JOptionPane.showMessageDialog(Main.main, "Node used by more than two tracks.");
     280                                return;
     281                        }
     282                        if (tracks.size() == 1) {
     283                                JOptionPane.showMessageDialog(Main.main, "Node used by a track.");
     284                                return;
     285                        }
    291286                        Track t1 = tracks.get(0);
    292287                        Track t2 = tracks.get(1);
     
    294289                                        t2.getStartingNode() != t1.getEndingNode()) {
    295290                                if (t1.getStartingNode() == t2.getStartingNode() ||
    296                                                 t1.getEndingNode() == t2.getEndingNode())
    297                                         return "Node used by tracks that point together.";
    298                                 return "Node used by tracks that cannot be combined.";
    299                         }
    300                         if (!t1.keyPropertiesMergable(t2))
    301                                 return "Node used by tracks with different properties.";
     291                                                t1.getEndingNode() == t2.getEndingNode()) {
     292                                        JOptionPane.showMessageDialog(Main.main, "Node used by tracks that point together.");
     293                                        return;
     294                                }
     295                                JOptionPane.showMessageDialog(Main.main, "Node used by tracks that cannot be combined.");
     296                                return;
     297                        }
     298                        if (!t1.keyPropertiesMergable(t2)) {
     299                                JOptionPane.showMessageDialog(Main.main, "Node used by tracks with different properties.");
     300                                return;
     301                        }
    302302                }
    303303               
     
    306306                        LineSegment l1 = pendingLineSegmentsForTrack.get(0);
    307307                        LineSegment l2 = pendingLineSegmentsForTrack.get(1);
    308                         if (l1.getStart() == l2.getStart() || l1.getEnd() == l2.getEnd())
    309                                 return "Node used by line segments that points together.";
    310                         if (l1.getStart() == l2.getEnd() || l2.getStart() == l1.getEnd())
     308                        if (l1.start == l2.start || l1.end == l2.end) {
     309                                JOptionPane.showMessageDialog(Main.main, "Node used by line segments that points together.");
     310                                return;
     311                        }
     312                        if (l1.start == l2.end || l2.start == l1.end)
    311313                                pendingLineSegmentsForTrack.clear(); // resolved.
    312314                }
    313315               
    314316                // still pending line segments?
    315                 if (!pendingLineSegmentsForTrack.isEmpty())
    316                         return "Node used by tracks that cannot be combined.";
     317                if (!pendingLineSegmentsForTrack.isEmpty()) {
     318                        JOptionPane.showMessageDialog(Main.main, "Node used by tracks that cannot be combined.");
     319                        return;
     320                }
    317321
    318322                // Ok, we can combine. Do it.
    319                 // line segments
    320                 for (ArrayList<LineSegment> list : lineSegments.keySet()) {
    321                         LineSegment first = list.get(0);
    322                         LineSegment second = list.get(1);
    323                         if (first.getStart() == second.getEnd()) {
    324                                 first = second;
    325                                 second = list.get(0);
    326                         }
    327                         first.setEnd(second.getEnd());
    328                         first.keys = mergeKeys(first.keys, second.keys);
    329                         lineSegments.get(list).remove(second);
    330                 }
    331                
    332                 // tracks
    333                 if (!tracks.isEmpty()) {
    334                         Track first = tracks.get(0);
    335                         Track second = tracks.get(1);
    336                         if (first.getStartingNode() == second.getEndingNode()) {
    337                                 first = second;
    338                                 second = tracks.get(0);
    339                         }
    340                         // concatenate the line segments.
    341                         LineSegment lastOfFirst = first.getEndingSegment();
    342                         LineSegment firstOfSecond = second.getStartingSegment();
    343                         lastOfFirst.setEnd(firstOfSecond.getEnd());
    344                         lastOfFirst.keys = mergeKeys(lastOfFirst.keys, firstOfSecond.keys);
    345                         second.remove(firstOfSecond);
    346                         // move the remaining line segments to first track.
    347                         first.addAll(second.segments());
    348                         Main.main.ds.removeTrack(second);
    349                 }
    350                
    351                 return null;
    352         }
    353 
    354         /**
    355          * Merges the second parameter into the first and return the merged map.
    356          * @param first The first map that will hold keys.
    357          * @param second The map to merge with the first.
    358          * @return The merged key map.
    359          */
    360         private Map<Key, String> mergeKeys(Map<Key, String> first, Map<Key, String> second) {
    361                 if (first == null)
    362                         first = second;
    363                 else if (second != null && first != null)
    364                         first.putAll(second);
    365                 return first;
    366         }
    367 
    368         @Override
    369         protected boolean isEditMode() {
    370                 return true;
     323                Track firstTrack = tracks.isEmpty() ? null : tracks.get(0);
     324                Track secondTrack = tracks.isEmpty() ? null : tracks.get(1);
     325                mv.editLayer().add(new CombineAndDeleteCommand(n, lineSegments, firstTrack, secondTrack));
    371326        }
    372327}
Note: See TracChangeset for help on using the changeset viewer.