Changeset 1024 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2008-10-05T17:14:00+02:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
r1023 r1024 29 29 30 30 /** 31 * Dup e a node that is used my multiple ways, so each way has its own node.31 * Duplicate nodes that are used by multiple ways. 32 32 * 33 33 * Resulting nodes are identical, up to their position. … … 36 36 */ 37 37 38 public class UnGlueAction extends JosmAction implements SelectionChangedListener {38 public class UnGlueAction extends JosmAction { //implements SelectionChangedListener { 39 39 40 40 private Node selectedNode; 41 41 private Way selectedWay; 42 43 /** 44 * Create a new SplitWayAction. 42 private ArrayList<Node> selectedNodes; 43 44 /** 45 * Create a new UnGlueAction. 45 46 */ 46 47 public UnGlueAction() { 47 super(tr("UnGlue Ways"), "unglueways", tr("Duplicate the selected node so each way using it has its own copy."),48 super(tr("UnGlue Ways"), "unglueways", tr("Duplicate nodes that are used by multiple ways."), 48 49 ShortCut.registerShortCut("tools:unglue", tr("Tool: Unglue"), KeyEvent.VK_G, ShortCut.GROUP_EDIT), true); 49 DataSet.selListeners.add(this);50 //DataSet.selListeners.add(this); 50 51 } 51 52 … … 53 54 * Called when the action is executed. 54 55 * 55 * This method just collects the single node selected and calls theunGlueWay method.56 * This method does some checking on the selection and calls the matching unGlueWay method. 56 57 */ 57 58 public void actionPerformed(ActionEvent e) { … … 59 60 Collection<OsmPrimitive> selection = Main.ds.getSelected(); 60 61 61 if (!checkSelection(selection)) { 62 JOptionPane.showMessageDialog(Main.parent, tr("The current selection cannot be used for unglueing.")); 63 return; 64 } 65 66 int count = 0; 67 for (Way w : Main.ds.ways) { 68 if (w.deleted || w.incomplete || w.nodes.size() < 1) continue; 69 if (!w.nodes.contains(selectedNode)) continue; 70 count++; 71 } 72 if (count < 2) { 73 JOptionPane.showMessageDialog(Main.parent, tr("You must select a node that is used by at least 2 ways.")); 74 return; 75 } 76 77 // and then do the work. 78 unglueWays(); 62 if (checkSelection(selection)) { 63 int count = 0; 64 for (Way w : Main.ds.ways) { 65 if (w.deleted || w.incomplete || w.nodes.size() < 1) continue; 66 if (!w.nodes.contains(selectedNode)) continue; 67 count++; 68 } 69 if (count < 2) { 70 JOptionPane.showMessageDialog(Main.parent, tr("This node is not glued to anything else.")); 71 } else { 72 // and then do the work. 73 unglueWays(); 74 } 75 } else if (checkSelection2(selection)) { 76 ArrayList<Node> tmpNodes = new ArrayList<Node>(); 77 for (Node n : selectedNodes) { 78 int count = 0; 79 for (Way w : Main.ds.ways) { 80 if (w.deleted || w.incomplete || w.nodes.size() < 1) continue; 81 if (!w.nodes.contains(n)) continue; 82 count++; 83 } 84 if (count >= 2) { 85 tmpNodes.add(n); 86 } 87 } 88 if (tmpNodes.size() < 1) { 89 if (selection.size() > 1) { 90 JOptionPane.showMessageDialog(Main.parent, tr("None of these nodes is glued to anything else.")); 91 } else { 92 JOptionPane.showMessageDialog(Main.parent, tr("None of this way's nodes is glued to anything else.")); 93 } 94 } else { 95 // and then do the work. 96 selectedNodes = tmpNodes; 97 unglueWays2(); 98 } 99 } else { 100 JOptionPane.showMessageDialog(Main.parent, 101 tr("The current selection cannot be used for unglueing.")+"\n"+ 102 "\n"+ 103 tr("Select either:")+"\n"+ 104 tr("* One node that is used by more than one way, or")+"\n"+ 105 tr("* One node that is used by more than one way and one of those ways, or")+"\n"+ 106 tr("* One way that has one or more nodes that are used by more than one way, or")+"\n"+ 107 tr("* One way and one or more of its nodes that are used by more than one way.")+"\n"+ 108 "\n"+ 109 tr("Note: If a way is selected, this way will get fresh copies of the unglued\n"+ 110 "nodes and the new nodes will be selected. Otherwise, all ways will get their\n"+ 111 "own copy and all nodes will be selected.") 112 ); 113 } 114 selectedNode = null; 115 selectedWay = null; 116 selectedNodes = null; 79 117 } 80 118 … … 85 123 * input for splitting (this would be too expensive to be carried 86 124 * out from the selectionChanged listener). 125 * 126 * If this method returns "true", selectedNode and selectedWay will 127 * be set. 128 * 129 * Returns true if either one node is selected or one node and one 130 * way are selected and the node is part of the way. 131 * 132 * The way will be put into the object variable "selectedWay", the 133 * node into "selectedNode". 87 134 */ 88 135 private boolean checkSelection(Collection<? extends OsmPrimitive> selection) { … … 110 157 } 111 158 112 private boolean modifyWay(boolean firstway, Way w, List<Command> cmds, 113 List<Node> newNodes) { 159 /** 160 * Checks if the selection consists of something we can work with. 161 * Checks only if the number and type of items selected looks good; 162 * does not check whether the selected items are really a valid 163 * input for splitting (this would be too expensive to be carried 164 * out from the selectionChanged listener). 165 * 166 * Returns true if one way and any number of nodes that are part of 167 * that way are selected. Note: "any" can be none, then all nodes of 168 * the way are used. 169 * 170 * The way will be put into the object variable "selectedWay", the 171 * nodes into "selectedNodes". 172 */ 173 private boolean checkSelection2(Collection<? extends OsmPrimitive> selection) { 174 if (selection.size() < 1) 175 return false; 176 177 selectedWay = null; 178 for (OsmPrimitive p : selection) { 179 if (p instanceof Way) { 180 if (selectedWay != null) { 181 return false; 182 } 183 selectedWay = (Way) p; 184 } 185 } 186 if (selectedWay == null) { 187 return false; 188 } 189 190 selectedNodes = new ArrayList<Node>(); 191 for (OsmPrimitive p : selection) { 192 if (p instanceof Node) { 193 Node n = (Node) p; 194 if (!selectedWay.nodes.contains(n)) { 195 return false; 196 } 197 selectedNodes.add(n); 198 } 199 } 200 201 if (selectedNodes.size() < 1) { 202 selectedNodes.addAll(selectedWay.nodes); 203 } 204 205 return true; 206 } 207 208 /** 209 * dupe the given node of the given way 210 * 211 * -> the new node will be put into the parameter newNodes. 212 * -> the add-node command will be put into the parameter cmds. 213 * -> the changed way will be returned and must be put into cmds by the caller! 214 */ 215 private Way modifyWay(Node originalNode, Way w, List<Command> cmds, List<Node> newNodes) { 114 216 ArrayList<Node> nn = new ArrayList<Node>(); 115 217 for (Node pushNode : w.nodes) { 116 if (selectedNode == pushNode) { 117 if (firstway) { 118 // reuse the old node for the first (==a random) way 119 firstway = false; 120 } else { 121 // clone the node for all other ways 122 pushNode = new Node(selectedNode); 123 pushNode.id = 0; 124 newNodes.add(pushNode); 125 cmds.add(new AddCommand(pushNode)); 126 } 218 if (originalNode == pushNode) { 219 // clone the node for all other ways 220 pushNode = new Node(pushNode); 221 pushNode.id = 0; 222 newNodes.add(pushNode); 223 cmds.add(new AddCommand(pushNode)); 127 224 } 128 225 nn.add(pushNode); … … 131 228 newWay.nodes.clear(); 132 229 newWay.nodes.addAll(nn); 133 cmds.add(new ChangeCommand(w, newWay)); 134 135 return firstway; 136 } 137 138 /** 139 * see above 140 */ 141 private void unglueWays() { 142 143 LinkedList<Command> cmds = new LinkedList<Command>(); 144 List<Node> newNodes = new LinkedList<Node>(); 145 146 if (selectedWay == null) { 147 148 boolean firstway = true; 149 // modify all ways containing the nodes 150 for (Way w : Main.ds.ways) { 151 if (w.deleted || w.incomplete || w.nodes.size() < 1) continue; 152 if (!w.nodes.contains(selectedNode)) continue; 153 154 firstway = modifyWay(firstway, w, cmds, newNodes); 155 } 156 } else { 157 modifyWay(false, selectedWay, cmds, newNodes); 158 } 159 230 231 return newWay; 232 } 233 234 /** 235 * put all newNodes into the same relation(s) that originalNode is in 236 */ 237 private void fixRelations(Node originalNode, List<Command> cmds, List<Node> newNodes) { 160 238 // modify all relations containing the node 161 239 Relation newRel = null; … … 167 245 for (RelationMember rm : r.members) { 168 246 if (rm.member instanceof Node) { 169 if (rm.member == selectedNode) {247 if (rm.member == originalNode) { 170 248 if (newRel == null) { 171 249 newRel = new Relation(r); … … 191 269 } 192 270 } 193 194 newNodes.add(selectedNode); // just for the next 2 lines 195 Main.main.undoRedo.add(new SequenceCommand(tr("Dupe into {0} nodes", newNodes.size()), cmds)); 271 } 272 273 274 /** 275 * dupe a single node into as many nodes as there are ways using it, OR 276 * 277 * dupe a single node once, and put the copy on the selected way 278 */ 279 private void unglueWays() { 280 LinkedList<Command> cmds = new LinkedList<Command>(); 281 List<Node> newNodes = new LinkedList<Node>(); 282 283 if (selectedWay == null) { 284 boolean firstway = true; 285 // modify all ways containing the nodes 286 for (Way w : Main.ds.ways) { 287 if (w.deleted || w.incomplete || w.nodes.size() < 1) continue; 288 if (!w.nodes.contains(selectedNode)) continue; 289 if (!firstway) cmds.add(new ChangeCommand(w, modifyWay(selectedNode, w, cmds, newNodes))); 290 firstway = false; 291 } 292 } else { 293 cmds.add(new ChangeCommand(selectedWay, modifyWay(selectedNode, selectedWay, cmds, newNodes))); 294 } 295 296 fixRelations(selectedNode, cmds, newNodes); 297 298 Main.main.undoRedo.add(new SequenceCommand(tr("Dupe into {0} nodes", newNodes.size()+1), cmds)); 299 if (selectedWay == null) { // if a node has been selected, new selection is ALL nodes 300 newNodes.add(selectedNode); 301 } // if a node and a way has been selected, new selection is only the new node that was added to the selected way 196 302 Main.ds.setSelected(newNodes); 197 198 } 199 200 /** 201 * Enable the "split way" menu option if the selection looks like we could use it. 202 */ 203 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 204 setEnabled(checkSelection(newSelection)); 205 } 303 } 304 305 /** 306 * dupe all nodes that are selected, and put the copies on the selected way 307 * 308 */ 309 private void unglueWays2() { 310 LinkedList<Command> cmds = new LinkedList<Command>(); 311 List<Node> allNewNodes = new LinkedList<Node>(); 312 Way tmpWay = selectedWay; 313 314 for (Node n : selectedNodes) { 315 List<Node> newNodes = new LinkedList<Node>(); 316 tmpWay = modifyWay(n, tmpWay, cmds, newNodes); 317 fixRelations(n, cmds, newNodes); 318 allNewNodes.addAll(newNodes); 319 } 320 cmds.add(new ChangeCommand(selectedWay, tmpWay)); // only one changeCommand for a way, else garbage will happen 321 322 Main.main.undoRedo.add(new SequenceCommand(tr("Dupe {0} nodes into {1} nodes", selectedNodes.size(), selectedNodes.size()+allNewNodes.size()), cmds)); 323 Main.ds.setSelected(allNewNodes); 324 } 325 326 // Disabled because we have such a nice help text that would not be shown otherwise. 327 // 328 // /** 329 // * Enable the menu option if the selection looks like we could use it. 330 // */ 331 // public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 332 // setEnabled(checkSelection(newSelection) || checkSelection2(newSelection)); 333 // selectedNode = null; 334 // selectedWay = null; 335 // selectedNodes = null; 336 // } 206 337 }
Note:
See TracChangeset
for help on using the changeset viewer.