- Timestamp:
- 2012-03-29T23:22:07+02:00 (13 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
r4982 r5132 2 2 package org.openstreetmap.josm.actions; 3 3 4 import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.combineTigerTags;5 import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.completeTagCollectionForEditing;6 import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing;7 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 8 5 import static org.openstreetmap.josm.tools.I18n.tr; … … 34 31 import org.openstreetmap.josm.data.osm.Node; 35 32 import org.openstreetmap.josm.data.osm.OsmPrimitive; 36 import org.openstreetmap.josm.data.osm.Relation;37 33 import org.openstreetmap.josm.data.osm.TagCollection; 38 34 import org.openstreetmap.josm.data.osm.Way; … … 93 89 } 94 90 return targetWay; 95 }96 97 /**98 * Replies the set of referring relations99 *100 * @return the set of referring relations101 */102 public static Set<Relation> getParentRelations(Collection<Way> ways) {103 HashSet<Relation> ret = new HashSet<Relation>();104 for (Way w: ways) {105 ret.addAll(OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class));106 }107 return ret;108 91 } 109 92 … … 194 177 modifiedTargetWay.setNodes(path); 195 178 196 TagCollection completeWayTags = new TagCollection(wayTags); 197 combineTigerTags(completeWayTags); 198 normalizeTagCollectionBeforeEditing(completeWayTags, ways); 199 TagCollection tagsToEdit = new TagCollection(completeWayTags); 200 completeTagCollectionForEditing(tagsToEdit); 201 202 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 203 dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues()); 204 dialog.setTargetPrimitive(targetWay); 205 Set<Relation> parentRelations = getParentRelations(ways); 206 dialog.getRelationMemberConflictResolverModel().populate( 207 parentRelations, 208 ways 209 ); 210 dialog.prepareDefaultDecisions(); 211 212 // resolve tag conflicts if necessary 213 // 214 if (!completeWayTags.isApplicableToPrimitive() || !parentRelations.isEmpty()) { 215 dialog.setVisible(true); 216 if (dialog.isCanceled()) 217 throw new UserCancelException(); 218 } 179 List<Command> resolution = CombinePrimitiveResolverDialog.launchIfNecessary(wayTags, ways, Collections.singleton(targetWay)); 219 180 220 181 LinkedList<Command> cmds = new LinkedList<Command>(); … … 223 184 224 185 cmds.add(new ChangeCommand(targetWay, modifiedTargetWay)); 225 cmds.addAll( dialog.buildResolutionCommands());186 cmds.addAll(resolution); 226 187 cmds.add(new DeleteCommand(deletedWays)); 227 188 final SequenceCommand sequenceCommand = new SequenceCommand(tr("Combine {0} ways", ways.size()), cmds); -
trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
r4982 r5132 43 43 import org.openstreetmap.josm.data.osm.Way; 44 44 import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog; 45 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil;46 45 import org.openstreetmap.josm.tools.Geometry; 47 46 import org.openstreetmap.josm.tools.Pair; … … 538 537 } 539 538 540 if (ways.size() < 2) 539 if (ways.size() < 2) { 541 540 return true; 542 543 //mostly copied from CombineWayAction.java. 541 } 542 544 543 TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways); 545 TagCollection completeWayTags = new TagCollection(wayTags); 546 TagConflictResolutionUtil.combineTigerTags(completeWayTags); 547 TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing(completeWayTags, ways); 548 TagCollection tagsToEdit = new TagCollection(completeWayTags); 549 TagConflictResolutionUtil.completeTagCollectionForEditing(tagsToEdit); 550 551 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 552 dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues()); 553 dialog.setTargetPrimitive(ways.get(0)); 554 Collection<Relation> parentRelations = CombineWayAction.getParentRelations(ways); 555 parentRelations = filterOwnMultipolygonRelations(parentRelations, polygons); 556 dialog.getRelationMemberConflictResolverModel().populate( 557 parentRelations, 558 ways 559 ); 560 dialog.prepareDefaultDecisions(); 561 562 // resolve tag conflicts if necessary 563 // 564 if (!completeWayTags.isApplicableToPrimitive() || !parentRelations.isEmpty()) { 565 dialog.setVisible(true); 566 if (dialog.isCanceled()) 567 return false; 568 } 569 570 for (Way way : ways) { 571 dialog.setTargetPrimitive(way); 572 cmds.addAll(dialog.buildResolutionCommands()); 573 } 574 575 commitCommands(marktr("Fix tag conflicts")); 576 return true; 544 try { 545 cmds.addAll(CombinePrimitiveResolverDialog.launchIfNecessary(wayTags, ways, ways)); 546 commitCommands(marktr("Fix tag conflicts")); 547 return true; 548 } catch (UserCancelException ex) { 549 return false; 550 } 577 551 } 578 552 … … 1209 1183 Set<Way> processedInnerWays = new LinkedHashSet<Way>(); 1210 1184 1211 for (Relation r : CombineWayAction.getParentRelations(selectedWays)) {1185 for (Relation r : OsmPrimitive.getParentRelations(selectedWays)) { 1212 1186 if (r.isDeleted() || !r.isMultipolygon()) { 1213 1187 continue; -
trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
r5059 r5132 9 9 import java.util.ArrayList; 10 10 import java.util.Collection; 11 import java.util.Collections; 11 12 import java.util.HashSet; 12 13 import java.util.LinkedList; … … 22 23 import org.openstreetmap.josm.command.DeleteCommand; 23 24 import org.openstreetmap.josm.command.SequenceCommand; 25 import org.openstreetmap.josm.corrector.UserCancelException; 24 26 import org.openstreetmap.josm.data.coor.EastNorth; 25 27 import org.openstreetmap.josm.data.coor.LatLon; … … 33 35 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec; 34 36 import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog; 35 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil;36 37 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 37 38 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 256 257 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 257 258 CheckParameterUtil.ensureParameterNotNull(targetNode, "targetNode"); 258 if (nodes == null) 259 if (nodes == null) { 259 260 return null; 261 } 260 262 261 263 Set<RelationToChildReference> relationToNodeReferences = RelationToChildReference.getRelationToChildReferences(nodes); 262 264 263 // build the tag collection 264 // 265 TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes); 266 TagConflictResolutionUtil.combineTigerTags(nodeTags); 267 TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing(nodeTags, nodes); 268 TagCollection nodeTagsToEdit = new TagCollection(nodeTags); 269 TagConflictResolutionUtil.completeTagCollectionForEditing(nodeTagsToEdit); 270 271 // launch a conflict resolution dialog, if necessary 272 // 273 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 274 dialog.getTagConflictResolverModel().populate(nodeTagsToEdit, nodeTags.getKeysWithMultipleValues()); 275 dialog.getRelationMemberConflictResolverModel().populate(relationToNodeReferences); 276 dialog.setTargetPrimitive(targetNode); 277 dialog.prepareDefaultDecisions(); 278 // conflict resolution is necessary if there are conflicts in the merged tags 279 // or if at least one of the merged nodes is referred to by a relation 280 // 281 if (! nodeTags.isApplicableToPrimitive() || relationToNodeReferences.size() > 1) { 282 dialog.setVisible(true); 283 if (dialog.isCanceled()) 265 try { 266 TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes); 267 List<Command> resultion = CombinePrimitiveResolverDialog.launchIfNecessary(nodeTags, nodes, Collections.singleton(targetNode)); 268 LinkedList<Command> cmds = new LinkedList<Command>(); 269 270 // the nodes we will have to delete 271 // 272 Collection<Node> nodesToDelete = new HashSet<Node>(nodes); 273 nodesToDelete.remove(targetNode); 274 275 // fix the ways referring to at least one of the merged nodes 276 // 277 Collection<Way> waysToDelete = new HashSet<Way>(); 278 List<Command> wayFixCommands = fixParentWays( 279 nodesToDelete, 280 targetNode); 281 if (wayFixCommands == null) { 284 282 return null; 285 } 286 LinkedList<Command> cmds = new LinkedList<Command>(); 287 288 // the nodes we will have to delete 289 // 290 Collection<Node> nodesToDelete = new HashSet<Node>(nodes); 291 nodesToDelete.remove(targetNode); 292 293 // fix the ways referring to at least one of the merged nodes 294 // 295 Collection<Way> waysToDelete= new HashSet<Way>(); 296 List<Command> wayFixCommands = fixParentWays( 297 nodesToDelete, 298 targetNode 299 ); 300 if (wayFixCommands == null) 283 } 284 cmds.addAll(wayFixCommands); 285 286 // build the commands 287 // 288 if (targetNode != targetLocationNode) { 289 Node newTargetNode = new Node(targetNode); 290 newTargetNode.setCoor(targetLocationNode.getCoor()); 291 cmds.add(new ChangeCommand(targetNode, newTargetNode)); 292 } 293 cmds.addAll(resultion); 294 if (!nodesToDelete.isEmpty()) { 295 cmds.add(new DeleteCommand(nodesToDelete)); 296 } 297 if (!waysToDelete.isEmpty()) { 298 cmds.add(new DeleteCommand(waysToDelete)); 299 } 300 Command cmd = new SequenceCommand(tr("Merge {0} nodes", nodes.size()), cmds); 301 return cmd; 302 } catch (UserCancelException ex) { 301 303 return null; 302 cmds.addAll(wayFixCommands); 303 304 // build the commands 305 // 306 if (targetNode != targetLocationNode) { 307 Node newTargetNode = new Node(targetNode); 308 newTargetNode.setCoor(targetLocationNode.getCoor()); 309 cmds.add(new ChangeCommand(targetNode, newTargetNode)); 310 } 311 cmds.addAll(dialog.buildResolutionCommands()); 312 if (!nodesToDelete.isEmpty()) { 313 cmds.add(new DeleteCommand(nodesToDelete)); 314 } 315 if (!waysToDelete.isEmpty()) { 316 cmds.add(new DeleteCommand(waysToDelete)); 317 } 318 Command cmd = new SequenceCommand(tr("Merge {0} nodes", nodes.size()), cmds); 319 return cmd; 304 } 320 305 } 321 306 -
trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r4895 r5132 1135 1135 } 1136 1136 1137 /** 1138 * Replies the set of referring relations 1139 * 1140 * @return the set of referring relations 1141 */ 1142 public static Set<Relation> getParentRelations(Collection<? extends OsmPrimitive> primitives) { 1143 HashSet<Relation> ret = new HashSet<Relation>(); 1144 for (OsmPrimitive w : primitives) { 1145 ret.addAll(OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class)); 1146 } 1147 return ret; 1148 } 1137 1149 } -
trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java
r5083 r5132 37 37 import org.openstreetmap.josm.tools.I18n; 38 38 import org.openstreetmap.josm.tools.TaggingPresetNameTemplateList; 39 import org.openstreetmap.josm.tools.Utils; 40 import org.openstreetmap.josm.tools.Utils.Function; 39 41 40 42 /** … … 686 688 687 689 public String formatAsHtmlUnorderedList(Collection<? extends OsmPrimitive> primitives) { 688 StringBuilder sb = newStringBuilder(1024);689 sb.append("<ul>"); 690 for (OsmPrimitive i : primitives) {691 sb.append("<li>").append(i.getDisplayName(this)).append("</li>");692 }693 sb.append("</ul>");694 return sb.toString();690 return Utils.joinAsHtmlUnorderedList(Utils.transform(primitives, new Function<OsmPrimitive, String>() { 691 692 @Override 693 public String apply(OsmPrimitive x) { 694 return x.getDisplayName(DefaultNameFormatter.this); 695 } 696 })); 695 697 } 696 698 -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java
r4310 r5132 4 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 5 5 import static org.openstreetmap.josm.tools.I18n.tr; 6 import static org.openstreetmap.josm.tools.I18n.trn; 6 7 7 8 import java.awt.BorderLayout; … … 16 17 import java.beans.PropertyChangeEvent; 17 18 import java.beans.PropertyChangeListener; 19 import java.util.Collection; 18 20 import java.util.HashSet; 19 21 import java.util.LinkedList; … … 30 32 31 33 import org.openstreetmap.josm.Main; 34 import org.openstreetmap.josm.actions.ExpertToggleAction; 32 35 import org.openstreetmap.josm.command.ChangePropertyCommand; 33 36 import org.openstreetmap.josm.command.Command; 37 import org.openstreetmap.josm.corrector.UserCancelException; 38 import org.openstreetmap.josm.data.osm.NameFormatter; 34 39 import org.openstreetmap.josm.data.osm.Node; 35 40 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 37 42 import org.openstreetmap.josm.data.osm.TagCollection; 38 43 import org.openstreetmap.josm.data.osm.Way; 44 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 39 45 import org.openstreetmap.josm.gui.DefaultNameFormatter; 40 46 import org.openstreetmap.josm.gui.SideButton; … … 42 48 import org.openstreetmap.josm.gui.help.HelpUtil; 43 49 import org.openstreetmap.josm.tools.ImageProvider; 50 import org.openstreetmap.josm.tools.Utils; 51 import org.openstreetmap.josm.tools.Utils.Function; 44 52 import org.openstreetmap.josm.tools.WindowGeometry; 45 53 … … 47 55 * This dialog helps to resolve conflicts occurring when ways are combined or 48 56 * nodes are merged. 57 * 58 * Usage: {@link #launchIfNecessary} followed by {@link #buildResolutionCommands}. 59 * 60 * Prior to {@link #launchIfNecessary}, the following usage sequence was needed: 49 61 * 50 62 * There is a singleton instance of this dialog which can be retrieved using … … 82 94 * 83 95 * @return the unique instance of the dialog 96 * @deprecated use {@link #launchIfNecessary} instead. 84 97 */ 98 @Deprecated 85 99 public static CombinePrimitiveResolverDialog getInstance() { 86 100 if (instance == null) { … … 421 435 } 422 436 } 437 438 public static List<Command> launchIfNecessary( 439 final TagCollection tagsOfPrimitives, 440 final Collection<? extends OsmPrimitive> primitives, 441 final Collection<? extends OsmPrimitive> targetPrimitives) throws UserCancelException { 442 443 final TagCollection completeWayTags = new TagCollection(tagsOfPrimitives); 444 TagConflictResolutionUtil.combineTigerTags(completeWayTags); 445 TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing(completeWayTags, primitives); 446 final TagCollection tagsToEdit = new TagCollection(completeWayTags); 447 TagConflictResolutionUtil.completeTagCollectionForEditing(tagsToEdit); 448 449 final CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 450 451 dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues()); 452 453 final Set<Relation> parentRelations = OsmPrimitive.getParentRelations(primitives); 454 dialog.getRelationMemberConflictResolverModel().populate(parentRelations, primitives); 455 dialog.prepareDefaultDecisions(); 456 457 // show information dialog to non-experts 458 if (!completeWayTags.isApplicableToPrimitive() && !ExpertToggleAction.isExpert()) { 459 String conflicts = Utils.joinAsHtmlUnorderedList(Utils.transform(completeWayTags.getKeysWithMultipleValues(), new Function<String, String>() { 460 461 @Override 462 public String apply(String key) { 463 return tr("{0} ({1})", key, Utils.join(tr(", "), Utils.transform(completeWayTags.getValues(key), new Function<String, String>() { 464 465 @Override 466 public String apply(String x) { 467 return x == null || x.isEmpty() ? tr("<i>missing</i>") : x; 468 } 469 }))); 470 } 471 })); 472 String msg = tr("You are about to combine {0} objects, " 473 + "but the following tags are used conflictingly:<br/>{1}" 474 + "If these objects are combined, the resulting object may have unwanted tags.<br/>" 475 + "If you want to continue, you are shown a dialog to fix the conflicting tags.<br/><br/>" 476 + "Do you want to continue?", 477 primitives.size(), conflicts); 478 if (!ConditionalOptionPaneUtil.showConfirmationDialog( 479 "combine_tags", 480 Main.parent, 481 "<html>" + msg + "</html>", 482 tr("Combine confirmation"), 483 JOptionPane.YES_NO_OPTION, 484 JOptionPane.QUESTION_MESSAGE, 485 JOptionPane.YES_OPTION)) { 486 throw new UserCancelException(); 487 } 488 } 489 490 if (!parentRelations.isEmpty() && !ExpertToggleAction.isExpert()) { 491 String msg = trn("You are about to combine {1} objects, " 492 + "which are part of {0} relation:<br/>{2}" 493 + "Combining these objects may break this relation. If you are unsure, please cancel this operation.<br/>" 494 + "If you want to continue, you are shown a dialog to decide how to adapt the relation.<br/><br/>" 495 + "Do you want to continue?", 496 "You are about to combine {1} objects, " 497 + "which are part of {0} relations:<br/>{2}" 498 + "Combining these objects may break these relations. If you are unsure, please cancel this operation.<br/>" 499 + "If you want to continue, you are shown a dialog to decide how to adapt the relations.<br/><br/>" 500 + "Do you want to continue?", 501 parentRelations.size(), parentRelations.size(), primitives.size(), 502 DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(parentRelations)); 503 if (!ConditionalOptionPaneUtil.showConfirmationDialog( 504 "combine_tags", 505 Main.parent, 506 "<html>" + msg + "</html>", 507 tr("Combine confirmation"), 508 JOptionPane.YES_NO_OPTION, 509 JOptionPane.QUESTION_MESSAGE, 510 JOptionPane.YES_OPTION)) { 511 throw new UserCancelException(); 512 } 513 } 514 515 // resolve tag conflicts if necessary 516 if (!completeWayTags.isApplicableToPrimitive() || !parentRelations.isEmpty()) { 517 dialog.setVisible(true); 518 if (dialog.isCanceled()) { 519 throw new UserCancelException(); 520 } 521 } 522 List<Command> cmds = new LinkedList<Command>(); 523 for (OsmPrimitive i : targetPrimitives) { 524 dialog.setTargetPrimitive(i); 525 cmds.addAll(dialog.buildResolutionCommands()); 526 } 527 return cmds; 528 } 423 529 } -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolver.java
r3083 r5132 28 28 /** the model for the tag conflict resolver */ 29 29 private TagConflictResolverModel model; 30 /** selects wheter only tags with conflicts are displayed */ 30 /** selects whether only tags with conflicts are displayed */ 31 31 private JCheckBox cbShowTagsWithConflictsOnly; 32 32 private JCheckBox cbShowTagsWithMultiValuesOnly; … … 41 41 gc.weightx = 1.0; 42 42 gc.anchor = GridBagConstraints.LINE_START; 43 gc.gridwidth = 2; 43 44 pnl.add(new JLabel(tr("<html>Please select the values to keep for the following tags.</html>")), gc); 44 45 46 gc.gridwidth = 1; 45 47 gc.gridy = 1; 46 48 gc.fill = GridBagConstraints.HORIZONTAL; -
trunk/src/org/openstreetmap/josm/tools/Utils.java
r4816 r5132 23 23 import java.util.Iterator; 24 24 import java.util.List; 25 import org.openstreetmap.josm.data.osm.OsmPrimitive; 25 26 26 27 /** … … 166 167 } 167 168 169 public static String joinAsHtmlUnorderedList(Collection<?> values) { 170 StringBuilder sb = new StringBuilder(1024); 171 sb.append("<ul>"); 172 for (Object i : values) { 173 sb.append("<li>").append(i).append("</li>"); 174 } 175 sb.append("</ul>"); 176 return sb.toString(); 177 } 178 168 179 /** 169 180 * convert Color to String … … 423 434 * @return the transformed unmodifiable collection 424 435 */ 425 public static <A, B> Collection<B> transform(final Collection<A> c, final Function<A, B> f) { 436 public static <A, B> Collection<B> transform(final Collection<? extends A> c, final Function<A, B> f) { 426 437 return new Collection<B>() { 427 438 … … 460 471 return new Iterator<B>() { 461 472 462 private Iterator<A> it = c.iterator(); 473 private Iterator<? extends A> it = c.iterator(); 463 474 464 475 @Override
Note:
See TracChangeset
for help on using the changeset viewer.