Changeset 9292 in josm
- Timestamp:
- 2016-01-04T00:17:06+01:00 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
r9291 r9292 6 6 import static org.openstreetmap.josm.tools.I18n.trn; 7 7 8 import java.awt.GridBagLayout; 8 9 import java.awt.event.ActionEvent; 9 10 import java.awt.event.KeyEvent; … … 18 19 import java.util.Set; 19 20 21 import javax.swing.AbstractButton; 22 import javax.swing.ButtonGroup; 23 import javax.swing.JLabel; 20 24 import javax.swing.JOptionPane; 21 25 import javax.swing.JPanel; 26 import javax.swing.JToggleButton; 22 27 23 28 import org.openstreetmap.josm.Main; … … 32 37 import org.openstreetmap.josm.data.osm.RelationMember; 33 38 import org.openstreetmap.josm.data.osm.Way; 39 import org.openstreetmap.josm.gui.ExtendedDialog; 34 40 import org.openstreetmap.josm.gui.MapView; 35 41 import org.openstreetmap.josm.gui.Notification; 42 import org.openstreetmap.josm.tools.GBC; 43 import org.openstreetmap.josm.tools.ImageProvider; 44 import org.openstreetmap.josm.tools.Predicate; 36 45 import org.openstreetmap.josm.tools.Shortcut; 46 import org.openstreetmap.josm.tools.UserCancelException; 47 import org.openstreetmap.josm.tools.Utils; 37 48 38 49 /** … … 163 174 164 175 /** 176 * Provides toggle buttons to allow the user choose the existing node, the new nodes, or all of them. 177 */ 178 private static class ExistingBothNewChoice { 179 final AbstractButton oldNode = new JToggleButton(tr("Existing node"), ImageProvider.get("dialogs/conflict/tagkeeptheir")); 180 final AbstractButton bothNodes = new JToggleButton(tr("Both nodes"), ImageProvider.get("dialogs/conflict/tagundecide")); 181 final AbstractButton newNode = new JToggleButton(tr("New node"), ImageProvider.get("dialogs/conflict/tagkeepmine")); 182 183 ExistingBothNewChoice(final boolean preselectNew) { 184 final ButtonGroup tagsGroup = new ButtonGroup(); 185 tagsGroup.add(oldNode); 186 tagsGroup.add(bothNodes); 187 tagsGroup.add(newNode); 188 tagsGroup.setSelected((preselectNew ? newNode : oldNode).getModel(), true); 189 } 190 } 191 192 /** 193 * A dialog allowing the user decide whether the tags/memberships of the existing node should afterwards be at 194 * the existing node, the new nodes, or all of them. 195 */ 196 static final class PropertiesMembershipDialog extends ExtendedDialog { 197 198 final ExistingBothNewChoice tags; 199 final ExistingBothNewChoice memberships; 200 201 private PropertiesMembershipDialog(boolean preselectNew, boolean queryTags, boolean queryMemberships) { 202 super(Main.parent, tr("Tags / Memberships"), new String[]{tr("Unglue"), tr("Cancel")}); 203 setButtonIcons(new String[]{"unglueways", "cancel"}); 204 205 final JPanel content = new JPanel(new GridBagLayout()); 206 207 if (queryTags) { 208 content.add(new JLabel(tr("Where should the tags of the node be put?")), GBC.std(1, 1).span(3).insets(0, 20, 0, 0)); 209 tags = new ExistingBothNewChoice(preselectNew); 210 content.add(tags.oldNode, GBC.std(1, 2)); 211 content.add(tags.bothNodes, GBC.std(2, 2)); 212 content.add(tags.newNode, GBC.std(3, 2)); 213 } else { 214 tags = null; 215 } 216 217 if (queryMemberships) { 218 content.add(new JLabel(tr("Where should the memberships of this node be put?")), GBC.std(1, 3).span(3).insets(0, 20, 0, 0)); 219 memberships = new ExistingBothNewChoice(preselectNew); 220 content.add(memberships.oldNode, GBC.std(1, 4)); 221 content.add(memberships.bothNodes, GBC.std(2, 4)); 222 content.add(memberships.newNode, GBC.std(3, 4)); 223 } else { 224 memberships = null; 225 } 226 227 setContent(content); 228 setResizable(false); 229 } 230 231 static PropertiesMembershipDialog showIfNecessary(Iterable<Node> selectedNodes, boolean preselectNew) throws UserCancelException { 232 final boolean tagged = isTagged(selectedNodes); 233 final boolean usedInRelations = isUsedInRelations(selectedNodes); 234 if (tagged || usedInRelations) { 235 final PropertiesMembershipDialog dialog = new PropertiesMembershipDialog(preselectNew, tagged, usedInRelations); 236 dialog.showDialog(); 237 if (dialog.getValue() != 1) { 238 throw new UserCancelException(); 239 } 240 return dialog; 241 } 242 return null; 243 } 244 245 private static boolean isTagged(final Iterable<Node> existingNodes) { 246 return Utils.exists(existingNodes, new Predicate<Node>() { 247 @Override 248 public boolean evaluate(final Node selectedNode) { 249 return selectedNode.hasKeys(); 250 } 251 }); 252 } 253 254 private static boolean isUsedInRelations(final Iterable<Node> existingNodes) { 255 return Utils.exists(existingNodes, new Predicate<Node>() { 256 @Override 257 public boolean evaluate(final Node selectedNode) { 258 return Utils.exists(selectedNode.getReferrers(), OsmPrimitive.relationPredicate); 259 } 260 }); 261 } 262 263 void update(final Node existingNode, final List<Node> newNodes, final Collection<Command> cmds) { 264 updateMemberships(existingNode, newNodes, cmds); 265 updateProperties(existingNode, newNodes, cmds); 266 } 267 268 private void updateProperties(final Node existingNode, final Iterable<Node> newNodes, final Collection<Command> cmds) { 269 if (tags != null && tags.newNode.isSelected()) { 270 final Node newSelectedNode = new Node(existingNode); 271 newSelectedNode.removeAll(); 272 cmds.add(new ChangeCommand(existingNode, newSelectedNode)); 273 } else if (tags != null && tags.oldNode.isSelected()) { 274 for (Node newNode : newNodes) { 275 newNode.removeAll(); 276 } 277 } 278 } 279 280 private void updateMemberships(final Node existingNode, final List<Node> newNodes, final Collection<Command> cmds) { 281 if (memberships != null && memberships.bothNodes.isSelected()) { 282 fixRelations(existingNode, cmds, newNodes, false); 283 } else if (memberships != null && memberships.newNode.isSelected()) { 284 fixRelations(existingNode, cmds, newNodes, true); 285 } 286 } 287 } 288 289 /** 165 290 * Assumes there is one tagged Node stored in selectedNode that it will try to unglue. 166 291 * (i.e. copy node and remove all tags from the old one. Relations will not be removed) … … 170 295 List<Command> cmds = new LinkedList<>(); 171 296 172 Node c = new Node(selectedNode); 173 c.removeAll(); 174 getCurrentDataSet().clearSelection(c); 175 cmds.add(new ChangeCommand(selectedNode, c)); 176 177 Node n = new Node(selectedNode, true); 297 final PropertiesMembershipDialog dialog; 298 try { 299 dialog = PropertiesMembershipDialog.showIfNecessary(Collections.singleton(selectedNode), true); 300 } catch (UserCancelException e1) { 301 return; 302 } 303 304 final Node n = new Node(selectedNode, true); 305 306 cmds.add(new AddCommand(n)); 307 if (dialog != null) { 308 dialog.update(selectedNode, Collections.singletonList(n), cmds); 309 } 178 310 179 311 // If this wasn't called from menu, place it where the cursor is/was … … 182 314 n.setCoor(mv.getLatLon(mv.lastMEvent.getX(), mv.lastMEvent.getY())); 183 315 } 184 185 cmds.add(new AddCommand(n));186 187 fixRelations(selectedNode, cmds, Collections.singletonList(n));188 316 189 317 Main.main.undoRedo.add(new SequenceCommand(tr("Unglued Node"), cmds)); … … 334 462 * @param newNodes List of nodes that contain the new node 335 463 */ 336 private void fixRelations(Node originalNode, List<Command> cmds, List<Node> newNodes) {464 private static void fixRelations(Node originalNode, Collection<Command> cmds, List<Node> newNodes, boolean removeOldMember) { 337 465 // modify all relations containing the node 338 466 for (Relation r : OsmPrimitive.getFilteredList(originalNode.getReferrers(), Relation.class)) { … … 357 485 if (newRel != null) { 358 486 if (rolesToReAdd != null) { 359 for ( Node n : newNodes) {360 for ( Map.Entry<String, Integer> role : rolesToReAdd.entrySet()) {487 for (Map.Entry<String, Integer> role : rolesToReAdd.entrySet()) { 488 for (Node n : newNodes) { 361 489 newRel.addMember(role.getValue() + 1, new RelationMember(role.getKey(), n)); 490 } 491 if (removeOldMember) { 492 newRel.removeMember(role.getValue()); 362 493 } 363 494 } … … 376 507 List<Command> cmds = new LinkedList<>(); 377 508 List<Node> newNodes = new LinkedList<>(); 509 510 final PropertiesMembershipDialog dialog; 511 try { 512 dialog = PropertiesMembershipDialog.showIfNecessary(Collections.singleton(selectedNode), false); 513 } catch (UserCancelException e) { 514 return; 515 } 378 516 379 517 if (selectedWay == null) { … … 400 538 } 401 539 402 fixRelations(selectedNode, cmds, newNodes); 540 if (dialog != null) { 541 dialog.update(selectedNode, newNodes, cmds); 542 } 543 403 544 execCommands(cmds, newNodes); 404 545 } … … 457 598 } 458 599 cmds.add(new ChangeNodesCommand(way, newNodes)); 459 // Update relation 460 fixRelations(selectedNode, cmds, addNodes); 461 execCommands(cmds, addNodes); 462 return true; 463 } 600 try { 601 final PropertiesMembershipDialog dialog = PropertiesMembershipDialog.showIfNecessary(Collections.singleton(selectedNode), false); 602 if (dialog != null) { 603 dialog.update(selectedNode, addNodes, cmds); 604 } 605 execCommands(cmds, addNodes); 606 return true; 607 } catch (UserCancelException ignore) { 608 Main.debug(ignore.getMessage()); 609 } 610 return false; 611 } 464 612 465 613 /** … … 472 620 Way tmpWay = selectedWay; 473 621 622 final PropertiesMembershipDialog dialog; 623 try { 624 dialog = PropertiesMembershipDialog.showIfNecessary(selectedNodes, false); 625 } catch (UserCancelException e) { 626 return; 627 } 628 474 629 for (Node n : selectedNodes) { 475 630 List<Node> newNodes = new LinkedList<>(); 476 631 tmpWay = modifyWay(n, tmpWay, cmds, newNodes); 477 fixRelations(n, cmds, newNodes); 632 if (dialog != null) { 633 dialog.update(n, newNodes, cmds); 634 } 478 635 allNewNodes.addAll(newNodes); 479 636 }
Note:
See TracChangeset
for help on using the changeset viewer.