Ticket #18670: 18670.3.patch
| File 18670.3.patch, 8.3 KB (added by , 6 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/UnGlueAction.java
108 108 } 109 109 // If there aren't enough ways, maybe the user wanted to unglue the nodes 110 110 // (= copy tags to a new node) 111 if (!selfCrossing) 112 if ( checkForUnglueNode(selection)) {111 if (!selfCrossing) { 112 if (selection.size() == 1 && selectedNode.isTagged()) { 113 113 unglueOneNodeAtMostOneWay(e); 114 114 } else { 115 115 errorTime = Notification.TIME_SHORT; 116 116 errMsg = tr("This node is not glued to anything else."); 117 117 } 118 } 118 119 } else { 119 120 // and then do the work. 120 121 unglueWays(); … … 245 246 } 246 247 247 248 /** 248 * Checks if selection is suitable for ungluing. This is the case when there's a single,249 * tagged node selected that's part of at least one way (ungluing an unconnected node does250 * not make sense. Due to the call order in actionPerformed, this is only called when the251 * node is only part of one or less ways.252 *253 * @param selection The selection to check against254 * @return {@code true} if selection is suitable255 */256 private boolean checkForUnglueNode(Collection<? extends OsmPrimitive> selection) {257 if (selection.size() != 1)258 return false;259 OsmPrimitive n = (OsmPrimitive) selection.toArray()[0];260 if (!(n instanceof Node))261 return false;262 if (((Node) n).getParentWays().isEmpty())263 return false;264 265 selectedNode = (Node) n;266 return selectedNode.isTagged();267 }268 269 /**270 249 * Checks if the selection consists of something we can work with. 271 250 * Checks only if the number and type of items selected looks good. 272 251 * … … 291 270 for (OsmPrimitive p : selection) { 292 271 if (p instanceof Node) { 293 272 selectedNode = (Node) p; 294 if (size == 1 || selectedWay != null)295 return size == 1 || selectedWay.containsNode(selectedNode);273 if (size == 1 || (selectedWay != null && selectedWay.containsNode(selectedNode))) 274 return true; 296 275 } else if (p instanceof Way) { 297 276 selectedWay = (Way) p; 298 277 if (size == 2 && selectedNode != null) … … 359 338 * @param w parent way 360 339 * @param cmds List of commands that will contain the new "add node" command 361 340 * @param newNodes List of nodes that will contain the new node 362 * @return new way The modified way. Change command mus be handled by the caller341 * @return new way The modified way. Change command must be handled by the caller 363 342 */ 364 343 private static Way modifyWay(Node originalNode, Way w, List<Command> cmds, List<Node> newNodes) { 365 344 // clone the node for the way … … 445 424 List<Command> cmds = new LinkedList<>(); 446 425 List<Node> newNodes = new LinkedList<>(); 447 426 if (selectedWay == null) { 448 Way wayWithSelectedNode = null; 449 LinkedList<Way> parentWays = new LinkedList<>(); 450 for (OsmPrimitive osm : selectedNode.getReferrers()) { 451 if (osm.isUsable() && osm instanceof Way) { 452 Way w = (Way) osm; 453 if (wayWithSelectedNode == null && !w.isFirstLastNode(selectedNode)) { 454 wayWithSelectedNode = w; 455 } else { 456 parentWays.add(w); 457 } 427 LinkedList<Way> parentWays = selectedNode.referrers(Way.class).filter(Way::isUsable) 428 .collect(Collectors.toCollection(LinkedList::new)); 429 // see #5452 and #18670 430 parentWays.sort((o1, o2) -> { 431 int d = Boolean.compare(!o1.isNew() && !o1.isModified() , !o2.isNew() && !o2.isModified()); 432 if (d == 0) { 433 d = Integer.compare(o2.getReferrers().size(), o1.getReferrers().size()); // reversed 458 434 } 459 } 460 if (wayWithSelectedNode == null) { 461 parentWays.removeFirst(); 462 } 435 if (d == 0) { 436 d = Boolean.compare(o1.isFirstLastNode(selectedNode), o2.isFirstLastNode(selectedNode)); 437 } 438 return d; 439 }); 440 // first way should not be changed, preferring older ways and those with fewer parents 441 parentWays.removeFirst(); 442 443 Set<Way> warnParents = new HashSet<>(); 463 444 for (Way w : parentWays) { 445 if (w.isFirstLastNode(selectedNode)) 446 warnParents.add(w); 464 447 cmds.add(new ChangeCommand(w, modifyWay(selectedNode, w, cmds, newNodes))); 465 448 } 466 notifyWayPartOfRelation( parentWays);449 notifyWayPartOfRelation(warnParents); 467 450 } else { 468 cmds.add(new ChangeCommand(selectedWay, modifyWay(selectedNode, selectedWay, cmds, newNodes)));469 notifyWayPartOfRelation(Collections.singleton(selectedWay));451 Way modWay = modifyWay(selectedNode, selectedWay, cmds, newNodes); 452 addCheckedChangeNodesCmd(cmds, selectedWay, modWay.getNodes()); 470 453 } 471 454 472 455 if (dialog != null) { … … 527 510 // selectedNode doesn't need unglue 528 511 return false; 529 512 } 530 cmds.add(new ChangeNodesCommand(way, newNodes)); 531 notifyWayPartOfRelation(Collections.singleton(way)); 513 addCheckedChangeNodesCmd(cmds, way, newNodes); 532 514 try { 533 515 final PropertiesMembershipChoiceDialog dialog = PropertiesMembershipChoiceDialog.showIfNecessary( 534 516 Collections.singleton(selectedNode), false); … … 568 550 } 569 551 allNewNodes.addAll(newNodes); 570 552 } 571 cmds.add(new ChangeCommand(selectedWay, tmpWay));// only one changeCommand for a way, else garbage will happen572 notifyWayPartOfRelation(Collections.singleton(selectedWay));553 // only one changeCommand for a way, else garbage will happen 554 addCheckedChangeNodesCmd(cmds, selectedWay, tmpWay.getNodes()); 573 555 574 556 UndoRedoHandler.getInstance().add(new SequenceCommand( 575 557 trn("Dupe {0} node into {1} nodes", "Dupe {0} nodes into {1} nodes", … … 577 559 getLayerManager().getEditDataSet().setSelected(allNewNodes); 578 560 } 579 561 562 private void addCheckedChangeNodesCmd(List<Command> cmds, Way w, List<Node> nodes) { 563 boolean relationCheck = w.firstNode() != nodes.get(0) || w.lastNode() != nodes.get(nodes.size() - 1); 564 cmds.add(new ChangeNodesCommand(w, nodes)); 565 if (relationCheck) { 566 notifyWayPartOfRelation(Collections.singleton(w)); 567 } 568 } 569 580 570 @Override 581 571 protected void updateEnabledState() { 582 572 updateEnabledStateOnCurrentSelection(); … … 621 611 } 622 612 623 613 final int size = affectedRelations.size(); 624 final String msg1 = trn("Unglueing affected {0} relation: {1}", "Unglueingaffected {0} relations: {1}",614 final String msg1 = trn("Unglueing possibly affected {0} relation: {1}", "Unglueing possibly affected {0} relations: {1}", 625 615 size, size, Utils.joinAsHtmlUnorderedList(affectedRelations)); 626 616 final String msg2 = trn("Ensure that the relation has not been broken!", "Ensure that the relations have not been broken!", 627 617 size); -
test/unit/org/openstreetmap/josm/actions/UnGlueActionTest.java
30 30 */ 31 31 @Rule 32 32 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 33 public JOSMTestRules test = new JOSMTestRules().main() ;33 public JOSMTestRules test = new JOSMTestRules().main().projection().preferences(); 34 34 35 35 /** 36 36 * Setup test.
