source: josm/trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java@ 8250

Last change on this file since 8250 was 7937, checked in by bastiK, 9 years ago

add subversion property svn:eol=native

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1//License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.List;
14
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.command.RemoveNodesCommand;
19import org.openstreetmap.josm.data.osm.Node;
20import org.openstreetmap.josm.data.osm.OsmPrimitive;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.tools.Shortcut;
23
24/**
25 * Disconnect nodes from a way they currently belong to.
26 * @since 6253
27 */
28public class UnJoinNodeWayAction extends JosmAction {
29
30 /**
31 * Constructs a new {@code UnJoinNodeWayAction}.
32 */
33 public UnJoinNodeWayAction() {
34 super(tr("Disconnect Node from Way"), "unjoinnodeway",
35 tr("Disconnect nodes from a way they currently belong to"),
36 Shortcut.registerShortcut("tools:unjoinnodeway",
37 tr("Tool: {0}", tr("Disconnect Node from Way")), KeyEvent.VK_J, Shortcut.ALT), true);
38 putValue("help", ht("/Action/UnJoinNodeWay"));
39 }
40
41 @Override
42 public void actionPerformed(ActionEvent e) {
43
44 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
45
46 List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
47 List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class);
48 List<Way> applicableWays = getApplicableWays(selectedWays, selectedNodes);
49
50 if (applicableWays == null) {
51 JOptionPane.showMessageDialog(
52 Main.parent,
53 tr("Select at least one node to be disconnected."),
54 tr("Warning"),
55 JOptionPane.WARNING_MESSAGE);
56 return;
57 } else if (applicableWays.isEmpty()) {
58 JOptionPane.showMessageDialog(Main.parent,
59 trn("Selected node cannot be disconnected from anything.",
60 "Selected nodes cannot be disconnected from anything.",
61 selectedNodes.size()),
62 tr("Warning"),
63 JOptionPane.WARNING_MESSAGE);
64 return;
65 } else if (applicableWays.size() > 1) {
66 JOptionPane.showMessageDialog(Main.parent,
67 trn("There is more than one way using the node you selected. Please select the way also.",
68 "There is more than one way using the nodes you selected. Please select the way also.",
69 selectedNodes.size()),
70 tr("Warning"),
71 JOptionPane.WARNING_MESSAGE);
72 return;
73 } else if (applicableWays.get(0).getRealNodesCount() < selectedNodes.size() + 2) {
74 // there is only one affected way, but removing the selected nodes would only leave it
75 // with less than 2 nodes
76 JOptionPane.showMessageDialog(Main.parent,
77 trn("The affected way would disappear after disconnecting the selected node.",
78 "The affected way would disappear after disconnecting the selected nodes.",
79 selectedNodes.size()),
80 tr("Warning"),
81 JOptionPane.WARNING_MESSAGE);
82 return;
83 }
84
85
86 // Finally, applicableWays contains only one perfect way
87 Way selectedWay = applicableWays.get(0);
88
89 // I'm sure there's a better way to handle this
90 Main.main.undoRedo.add(new RemoveNodesCommand(selectedWay, selectedNodes));
91 Main.map.repaint();
92 }
93
94 // Find ways to which the disconnect can be applied. This is the list of ways with more
95 // than two nodes which pass through all the given nodes, intersected with the selected ways (if any)
96 private List<Way> getApplicableWays(List<Way> selectedWays, List<Node> selectedNodes) {
97 if (selectedNodes.isEmpty())
98 return null;
99
100 // List of ways shared by all nodes
101 List<Way> result = new ArrayList<>(OsmPrimitive.getFilteredList(selectedNodes.get(0).getReferrers(), Way.class));
102 for (int i=1; i<selectedNodes.size(); i++) {
103 List<OsmPrimitive> ref = selectedNodes.get(i).getReferrers();
104 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
105 if (!ref.contains(it.next())) {
106 it.remove();
107 }
108 }
109 }
110
111 // Remove broken ways
112 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
113 if (it.next().getNodesCount() <= 2) {
114 it.remove();
115 }
116 }
117
118 if (selectedWays.isEmpty())
119 return result;
120 else {
121 // Return only selected ways
122 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
123 if (!selectedWays.contains(it.next())) {
124 it.remove();
125 }
126 }
127 return result;
128 }
129 }
130
131 @Override
132 protected void updateEnabledState() {
133 if (getCurrentDataSet() == null) {
134 setEnabled(false);
135 } else {
136 updateEnabledState(getCurrentDataSet().getSelected());
137 }
138 }
139
140 @Override
141 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
142 setEnabled(selection != null && !selection.isEmpty());
143 }
144}
Note: See TracBrowser for help on using the repository browser.