Ticket #23305: 23305.patch
| File 23305.patch, 11.6 KB (added by , 2 years ago) |
|---|
-
src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java
3 3 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;7 6 8 7 import java.awt.BorderLayout; 9 8 import java.awt.Component; … … 16 15 import java.beans.PropertyChangeEvent; 17 16 import java.beans.PropertyChangeListener; 18 17 import java.util.Collection; 18 import java.util.HashSet; 19 19 import java.util.LinkedList; 20 20 import java.util.List; 21 21 import java.util.Set; 22 import java.util.stream.Collectors;23 22 24 23 import javax.swing.AbstractAction; 25 24 import javax.swing.Action; … … 26 25 import javax.swing.JButton; 27 26 import javax.swing.JDialog; 28 27 import javax.swing.JLabel; 29 import javax.swing.JOptionPane;30 28 import javax.swing.JPanel; 31 29 import javax.swing.JSplitPane; 32 30 33 import org.openstreetmap.josm.actions.ExpertToggleAction;34 31 import org.openstreetmap.josm.command.Command; 35 32 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 36 33 import org.openstreetmap.josm.data.osm.Node; … … 38 35 import org.openstreetmap.josm.data.osm.Relation; 39 36 import org.openstreetmap.josm.data.osm.TagCollection; 40 37 import org.openstreetmap.josm.data.osm.Way; 41 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;42 38 import org.openstreetmap.josm.gui.MainApplication; 43 39 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 44 40 import org.openstreetmap.josm.gui.help.HelpUtil; … … 45 41 import org.openstreetmap.josm.gui.util.GuiHelper; 46 42 import org.openstreetmap.josm.gui.util.WindowGeometry; 47 43 import org.openstreetmap.josm.gui.widgets.AutoAdjustingSplitPane; 44 import org.openstreetmap.josm.spi.preferences.Config; 48 45 import org.openstreetmap.josm.tools.CheckParameterUtil; 49 46 import org.openstreetmap.josm.tools.ImageProvider; 50 47 import org.openstreetmap.josm.tools.InputMapUtils; 51 import org.openstreetmap.josm.tools.StreamUtils;52 48 import org.openstreetmap.josm.tools.UserCancelException; 53 import org.openstreetmap.josm.tools.Utils;54 49 55 50 /** 56 51 * This dialog helps to resolve conflicts occurring when ways are combined or … … 471 466 * by displaying if necessary a {@link CombinePrimitiveResolverDialog} to the user. 472 467 * This dialog will allow the user to choose conflict resolution actions. 473 468 * 474 * Non-expert users are informed first of the meaning of these operations, allowing them to cancel.475 *476 469 * @param tagsOfPrimitives The tag collection of the primitives to be combined. 477 470 * Should generally be equal to {@code TagCollection.unionOfAllPrimitives(primitives)} 478 471 * @param primitives The primitives to be combined … … 496 489 TagConflictResolutionUtil.completeTagCollectionForEditing(tagsToEdit); 497 490 498 491 final Set<Relation> parentRelations = OsmPrimitive.getParentRelations(primitives); 499 500 // Show information dialogs about conflicts to non-experts501 if (!ExpertToggleAction.isExpert()) {502 // Tag conflicts503 if (!completeWayTags.isApplicableToPrimitive()) {504 informAboutTagConflicts(primitives, completeWayTags);505 }506 // Relation membership conflicts507 if (!parentRelations.isEmpty()) {508 informAboutRelationMembershipConflicts(primitives, parentRelations);509 }510 }511 512 492 final List<Command> cmds = new LinkedList<>(); 513 493 514 494 final TagConflictResolverModel tagModel = new TagConflictResolverModel(); … … 516 496 517 497 tagModel.populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues(), false); 518 498 relModel.populate(parentRelations, primitives, false); 519 tagModel.prepareDefaultTagDecisions(false); 499 if (Config.getPref().getBoolean("combine-conflict-precise", true)) { 500 tagModel.prepareDefaultTagDecisions(getResolvableKeys(tagsOfPrimitives.getKeys(), primitives)); 501 } else { 502 tagModel.prepareDefaultTagDecisions(false); 503 } 520 504 relModel.prepareDefaultRelationDecisions(false); 521 505 522 506 if (tagModel.isResolvedCompletely() && relModel.isResolvedCompletely()) { … … 566 550 } 567 551 568 552 /** 569 * Inform a non-expert user about what relation membership conflict resolution means.570 * @param primitives The primitives to be combined571 * @param p arentRelations The parent relations of theprimitives572 * @ throws UserCancelException If the user cancels the dialog.553 * See #23305: Find those tag keys for which no conflict exists. 554 * @param keysToDecide the keys of tags which might be shown in the conflict dialog 555 * @param primitives the collection of primitives 556 * @return the keys which can be resolved using the only available value 573 557 */ 574 protected static void informAboutRelationMembershipConflicts( 575 final Collection<? extends OsmPrimitive> primitives, 576 final Set<Relation> parentRelations) throws UserCancelException { 577 /* I18n: object count < 2 is not possible */ 578 String msg = trn("You are about to combine {1} object, " 579 + "which is part of {0} relation:<br/>{2}" 580 + "Combining these objects may break this relation. If you are unsure, please cancel this operation.<br/>" 581 + "If you want to continue, you are shown a dialog to decide how to adapt the relation.<br/><br/>" 582 + "Do you want to continue?", 583 "You are about to combine {1} objects, " 584 + "which are part of {0} relations:<br/>{2}" 585 + "Combining these objects may break these relations. If you are unsure, please cancel this operation.<br/>" 586 + "If you want to continue, you are shown a dialog to decide how to adapt the relations.<br/><br/>" 587 + "Do you want to continue?", 588 parentRelations.size(), parentRelations.size(), primitives.size(), 589 DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(parentRelations, 20)); 590 591 if (!ConditionalOptionPaneUtil.showConfirmationDialog( 592 "combine_tags", 593 MainApplication.getMainFrame(), 594 "<html>" + msg + "</html>", 595 tr("Combine confirmation"), 596 JOptionPane.YES_NO_OPTION, 597 JOptionPane.QUESTION_MESSAGE, 598 JOptionPane.YES_OPTION)) { 599 throw new UserCancelException(); 558 private static Set<String> getResolvableKeys(Set<String> keysToDecide, Collection<? extends OsmPrimitive> primitives) { 559 Set<String> easyKeys = new HashSet<>(); 560 // determine the number of objects which have any of the tags which require a decision 561 int countTagged = 0; 562 for (OsmPrimitive p : primitives) { 563 for (String key : keysToDecide) { 564 if (p.hasTag(key)) { 565 ++countTagged; 566 break; 567 } 568 } 600 569 } 601 } 602 603 /** 604 * Inform a non-expert user about what tag conflict resolution means. 605 * @param primitives The primitives to be combined 606 * @param normalizedTags The normalized tag collection of the primitives to be combined 607 * @throws UserCancelException If the user cancels the dialog. 608 */ 609 protected static void informAboutTagConflicts( 610 final Collection<? extends OsmPrimitive> primitives, 611 final TagCollection normalizedTags) throws UserCancelException { 612 String conflicts = normalizedTags.getKeysWithMultipleValues().stream().map( 613 key -> getKeyDescription(key, normalizedTags)).collect(StreamUtils.toHtmlList()); 614 String msg = /* for correct i18n of plural forms - see #9110 */ trn("You are about to combine {0} objects, " 615 + "but the following tags are used conflictingly:<br/>{1}" 616 + "If these objects are combined, the resulting object may have unwanted tags.<br/>" 617 + "If you want to continue, you are shown a dialog to fix the conflicting tags.<br/><br/>" 618 + "Do you want to continue?", "You are about to combine {0} objects, " 619 + "but the following tags are used conflictingly:<br/>{1}" 620 + "If these objects are combined, the resulting object may have unwanted tags.<br/>" 621 + "If you want to continue, you are shown a dialog to fix the conflicting tags.<br/><br/>" 622 + "Do you want to continue?", 623 primitives.size(), primitives.size(), conflicts); 624 625 if (!ConditionalOptionPaneUtil.showConfirmationDialog( 626 "combine_tags", 627 MainApplication.getMainFrame(), 628 "<html>" + msg + "</html>", 629 tr("Combine confirmation"), 630 JOptionPane.YES_NO_OPTION, 631 JOptionPane.QUESTION_MESSAGE, 632 JOptionPane.YES_OPTION)) { 633 throw new UserCancelException(); 570 for (String key : keysToDecide) { 571 Set<String> values = new HashSet<>(); 572 int num = 0; 573 for (OsmPrimitive p : primitives) { 574 String val = p.get(key); 575 if (val != null) { 576 num++; 577 values.add(val); 578 } 579 } 580 if (values.size() == 1 && num == countTagged) { 581 // there is only one value and all tagged objects have that value -> easy to solve 582 easyKeys.add(key); 583 } 634 584 } 585 return easyKeys; 635 586 } 636 587 637 private static String getKeyDescription(String key, TagCollection normalizedTags) {638 String values = normalizedTags.getValues(key)639 .stream()640 .map(x -> Utils.isEmpty(x) ? tr("<i>missing</i>") : x)641 .collect(Collectors.joining(tr(", ")));642 return tr("{0} ({1})", key, values);643 }644 645 588 @Override 646 589 public void dispose() { 647 590 setTargetPrimitive(null, false); -
src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java
275 275 /** 276 276 * Prepare the default decisions for the current model 277 277 * @param fireEvent {@code true} to call {@code fireTableDataChanged} (can be a slow operation) 278 * @since 1162 6278 * @since 11627 279 279 */ 280 280 void prepareDefaultTagDecisions(boolean fireEvent) { 281 281 for (MultiValueResolutionDecision decision: decisions.values()) { … … 292 292 } 293 293 294 294 /** 295 * Prepare the default decisions for the current model. 296 * @param decidedKeys set of tag keys for which the first value should be used 297 * @since xxx 298 */ 299 public void prepareDefaultTagDecisions(Set<String> decidedKeys) { 300 for (MultiValueResolutionDecision decision : decisions.values()) { 301 if (!decidedKeys.contains(decision.getKey())) 302 continue; 303 List<String> values = decision.getValues(); 304 if (!values.isEmpty()) { 305 decision.keepOne(values.iterator().next()); 306 } 307 } 308 rebuild(false); 309 } 310 311 /** 295 312 * Returns the set of keys in conflict. 296 313 * @return the set of keys in conflict. 297 314 * @since 6616
