Changeset 2220 in josm
- Timestamp:
- 2009-09-30T20:00:57+02:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
r2210 r2220 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; 4 7 import static org.openstreetmap.josm.tools.I18n.tr; 5 8 … … 30 33 import org.openstreetmap.josm.data.osm.Relation; 31 34 import org.openstreetmap.josm.data.osm.RelationMember; 32 import org.openstreetmap.josm.data.osm.Tag;33 35 import org.openstreetmap.josm.data.osm.TagCollection; 34 import org.openstreetmap.josm.data.osm.TigerUtils;35 36 import org.openstreetmap.josm.data.osm.Way; 36 37 import org.openstreetmap.josm.gui.ExtendedDialog; … … 38 39 import org.openstreetmap.josm.tools.Pair; 39 40 import org.openstreetmap.josm.tools.Shortcut; 40 41 41 /** 42 42 * Combines multiple ways into one. … … 88 88 } 89 89 90 protected static void completeTagCollectionWithMissingTags(TagCollection tc, Collection<? extends OsmPrimitive> merged) {91 for (String key: tc.getKeys()) {92 // make sure the empty value is in the tag set if a tag is not present93 // on all merged nodes94 //95 for (OsmPrimitive p: merged) {96 if (p.get(key) == null) {97 tc.add(new Tag(key)); // add a tag with key and empty value98 }99 }100 }101 // remove irrelevant tags102 //103 tc.removeByKey("created_by");104 }105 106 /**107 * Combines tags from TIGER data108 *109 * @param tc the tag collection110 */111 protected static void combineTigerTags(TagCollection tc) {112 for (String key: tc.getKeys()) {113 if (TigerUtils.isTigerTag(key)) {114 tc.setUniqueForKey(key, TigerUtils.combineTags(key, tc.getValues(key)));115 }116 }117 }118 119 protected static void completeTagCollectionForEditing(TagCollection tc) {120 for (String key: tc.getKeys()) {121 // make sure the empty value is in the tag set such that we can delete the tag122 // in the conflict dialog if necessary123 //124 tc.add(new Tag(key,""));125 }126 }127 90 128 91 public void combineWays(Collection<Way> ways) { … … 170 133 TagCollection completeWayTags = new TagCollection(wayTags); 171 134 combineTigerTags(completeWayTags); 172 completeTagCollectionWithMissingTags(completeWayTags, ways);135 normalizeTagCollectionBeforeEditing(completeWayTags, ways); 173 136 TagCollection tagsToEdit = new TagCollection(completeWayTags); 174 137 completeTagCollectionForEditing(tagsToEdit); 175 138 176 139 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 177 dialog.getTagConflictResolverModel().populate(tagsToEdit );140 dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues()); 178 141 dialog.setTargetPrimitive(targetWay); 179 142 dialog.getRelationMemberConflictResolverModel().populate( -
trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
r2202 r2220 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; 4 7 import static org.openstreetmap.josm.tools.I18n.tr; 5 8 … … 23 26 import org.openstreetmap.josm.data.osm.Node; 24 27 import org.openstreetmap.josm.data.osm.OsmPrimitive; 25 import org.openstreetmap.josm.data.osm.Tag;26 28 import org.openstreetmap.josm.data.osm.TagCollection; 27 import org.openstreetmap.josm.data.osm.TigerUtils;28 29 import org.openstreetmap.josm.data.osm.Way; 29 30 import org.openstreetmap.josm.data.osm.BackreferencedDataSet.RelationToChildReference; … … 59 60 } 60 61 61 62 62 Node targetNode = selectTargetNode(selectedNodes); 63 63 Command cmd = mergeNodes(Main.main.getEditLayer(), selectedNodes, targetNode); … … 65 65 Main.main.undoRedo.add(cmd); 66 66 Main.main.getEditLayer().data.setSelected(targetNode); 67 }68 }69 70 protected static void completeTagCollectionWithMissingTags(TagCollection tc, Collection<Node> mergedNodes) {71 for (String key: tc.getKeys()) {72 // make sure the empty value is in the tag set if a tag is not present73 // on all merged nodes74 //75 for (Node n: mergedNodes) {76 if (n.get(key) == null) {77 tc.add(new Tag(key)); // add a tag with key and empty value78 }79 }80 }81 // remove irrelevant tags82 //83 tc.removeByKey("created_by");84 }85 86 protected static void completeTagCollectionForEditing(TagCollection tc) {87 for (String key: tc.getKeys()) {88 // make sure the empty value is in the tag set such that we can delete the tag89 // in the conflict dialog if necessary90 //91 tc.add(new Tag(key,""));92 }93 }94 95 /**96 * Combines tags from TIGER data97 *98 * @param tc the tag collection99 */100 protected static void combineTigerTags(TagCollection tc) {101 for (String key: tc.getKeys()) {102 if (TigerUtils.isTigerTag(key)) {103 tc.setUniqueForKey(key, TigerUtils.combineTags(key, tc.getValues(key)));104 }105 67 } 106 68 } … … 220 182 221 183 /** 222 * Merges the nodes in <code>node </code> onto one of the nodes. Uses the dataset184 * Merges the nodes in <code>nodes</code> onto one of the nodes. Uses the dataset 223 185 * managed by <code>layer</code> as reference. <code>backreferences</code> is a precomputed 224 186 * collection of all parent/child references in the dataset. … … 250 212 TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes); 251 213 combineTigerTags(nodeTags); 252 completeTagCollectionWithMissingTags(nodeTags, nodes);214 normalizeTagCollectionBeforeEditing(nodeTags, nodes); 253 215 TagCollection nodeTagsToEdit = new TagCollection(nodeTags); 254 216 completeTagCollectionForEditing(nodeTagsToEdit); … … 257 219 // 258 220 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 259 dialog.getTagConflictResolverModel().populate(nodeTagsToEdit );221 dialog.getTagConflictResolverModel().populate(nodeTagsToEdit, nodeTags.getKeysWithMultipleValues()); 260 222 dialog.getRelationMemberConflictResolverModel().populate(relationToNodeReferences); 261 223 dialog.setTargetPrimitive(targetNode); 262 224 dialog.prepareDefaultDecisions(); 225 // conflict resolution is necessary if there are conflicts in the merged tags 226 // or if at least one of the merged nodes is referred to by a relation 227 // 263 228 if (! nodeTags.isApplicableToPrimitive() || relationToNodeReferences.size() > 1) { 264 229 dialog.setVisible(true); … … 283 248 if (wayFixCommands == null) 284 249 return null; 285 else { 286 cmds.addAll(wayFixCommands); 287 } 250 cmds.addAll(wayFixCommands); 288 251 289 252 // build the commands … … 299 262 return cmd; 300 263 } 301 302 264 303 265 /** -
trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
r2070 r2220 38 38 39 39 static private List<Class<? extends OsmPrimitive>> osmPrimitiveClasses; 40 {40 static { 41 41 osmPrimitiveClasses = new ArrayList<Class<? extends OsmPrimitive>>(); 42 42 osmPrimitiveClasses.add(Node.class); … … 60 60 61 61 /** 62 * Replies the subset of {@see OsmPrimitive}s of <code>type</code> from <code>superSet</code>.63 *64 * @param <T>65 * @param superSet the super set of primitives66 * @param type the type67 * @return68 */69 protected <T extends OsmPrimitive> Collection<? extends OsmPrimitive> getSubcollectionByType(Collection<? extends OsmPrimitive> superSet, Class<T> type) {70 Collection<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();71 for (OsmPrimitive p : superSet) {72 if (type.isInstance(p)) {73 ret.add(p);74 }75 }76 return ret;77 }78 79 /**80 62 * Replies all primitives of type <code>type</code> in the current selection. 81 63 * … … 85 67 */ 86 68 protected <T extends OsmPrimitive> Collection<? extends OsmPrimitive> getSourcePrimitivesByType(Class<T> type) { 87 return getSubcollectionByType(Main.pasteBuffer.getSelected(), type);69 return OsmPrimitive.getFilteredList(Main.pasteBuffer.getSelected(), type); 88 70 } 89 71 … … 145 127 HashMap<OsmPrimitiveType, Integer> ret = new HashMap<OsmPrimitiveType, Integer>(); 146 128 for (Class<? extends OsmPrimitive> type: osmPrimitiveClasses) { 147 int count = getSubcollectionByType(getEditLayer().data.getSelected(), type).size();129 int count = OsmPrimitive.getFilteredList(getEditLayer().data.getSelected(), type).size(); 148 130 if (count > 0) { 149 131 ret.put(OsmPrimitiveType.from(type), count); … … 173 155 // no tags found to paste. Abort. 174 156 return; 175 176 157 177 158 if (!tc.isApplicableToPrimitive()) { … … 202 183 * <code>selection</code> 203 184 */ 204 protected <T extends OsmPrimitive> boolean hasTargetPrimitives(Collection< ? extendsOsmPrimitive> selection, Class<T> type) {205 return ! getSubcollectionByType(selection, type).isEmpty();185 protected <T extends OsmPrimitive> boolean hasTargetPrimitives(Collection<OsmPrimitive> selection, Class<T> type) { 186 return !OsmPrimitive.getFilteredList(selection, type).isEmpty(); 206 187 } 207 188 … … 212 193 * @return true if this a heterogeneous source can be pasted without conflicts to targets 213 194 */ 214 protected boolean canPasteFromHeterogeneousSourceWithoutConflict(Collection< ? extendsOsmPrimitive> targets) {195 protected boolean canPasteFromHeterogeneousSourceWithoutConflict(Collection<OsmPrimitive> targets) { 215 196 if (hasTargetPrimitives(targets, Node.class)) { 216 197 TagCollection tc = TagCollection.unionOfAllPrimitives(getSourcePrimitivesByType(Node.class)); … … 237 218 * @param targets the collection of target primitives 238 219 */ 239 protected void pasteFromHeterogeneousSource(Collection< ? extendsOsmPrimitive> targets) {220 protected void pasteFromHeterogeneousSource(Collection<OsmPrimitive> targets) { 240 221 if (canPasteFromHeterogeneousSourceWithoutConflict(targets)) { 241 222 if (hasSourceTagsByType(Node.class) && hasTargetPrimitives(targets, Node.class)) { … … 264 245 return; 265 246 if (hasSourceTagsByType(Node.class) && hasTargetPrimitives(targets, Node.class)) { 266 Command cmd = buildChangeCommand( getSubcollectionByType(targets, Node.class), dialog.getResolution(OsmPrimitiveType.NODE));247 Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Node.class), dialog.getResolution(OsmPrimitiveType.NODE)); 267 248 Main.main.undoRedo.add(cmd); 268 249 } 269 250 if (hasSourceTagsByType(Way.class) && hasTargetPrimitives(targets, Way.class)) { 270 Command cmd = buildChangeCommand( getSubcollectionByType(targets, Way.class), dialog.getResolution(OsmPrimitiveType.WAY));251 Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Way.class), dialog.getResolution(OsmPrimitiveType.WAY)); 271 252 Main.main.undoRedo.add(cmd); 272 253 } 273 254 if (hasSourceTagsByType(Relation.class) && hasTargetPrimitives(targets, Relation.class)) { 274 Command cmd = buildChangeCommand( getSubcollectionByType(targets, Relation.class), dialog.getResolution(OsmPrimitiveType.RELATION));255 Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(targets, Relation.class), dialog.getResolution(OsmPrimitiveType.RELATION)); 275 256 Main.main.undoRedo.add(cmd); 276 257 } -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java
r2157 r2220 8 8 import java.awt.FlowLayout; 9 9 import java.awt.event.ActionEvent; 10 import java.awt.event.HierarchyBoundsListener; 11 import java.awt.event.HierarchyEvent; 10 12 import java.awt.event.WindowAdapter; 11 13 import java.awt.event.WindowEvent; … … 36 38 37 39 /** 38 * This dialog helps to resolve conflicts occurring when ways are combined or e39 * primitives are merged.40 * This dialog helps to resolve conflicts occurring when ways are combined or 41 * nodes are merged. 40 42 * 41 43 * There is a singleton instance of this dialog which can be retrieved using … … 57 59 * merged to, see {@see #setTargetPrimitive(OsmPrimitive)}. 58 60 * 59 * After the dialog closed use {@see #isCancelled()} to check whether the user cancelled61 * After the dialog is closed use {@see #isCancelled()} to check whether the user canceled 60 62 * the dialog. If it wasn't canceled you may build a collection of {@see Command} objects 61 63 * which reflect the conflict resolution decisions the user made in the dialog: … … 66 68 public class CombinePrimitiveResolverDialog extends JDialog { 67 69 70 /** the unique instance of the dialog */ 68 71 static private CombinePrimitiveResolverDialog instance; 69 72 73 /** 74 * Replies the unique instance of the dialog 75 * 76 * @return the unique instance of the dialog 77 */ 70 78 public static CombinePrimitiveResolverDialog getInstance() { 71 79 if (instance == null) { … … 75 83 } 76 84 77 private JSplitPane spTagConflictTypes;85 private AutoAdjustingSplitPane spTagConflictTypes; 78 86 private TagConflictResolver pnlTagConflictResolver; 79 87 private RelationMemberConflictResolver pnlRelationMemberConflictResolver; … … 82 90 private OsmPrimitive targetPrimitive; 83 91 84 85 92 /** 93 * Replies the target primitive the collection of primitives is merged 94 * or combined to. 95 * 96 * @return the target primitive 97 */ 86 98 public OsmPrimitive getTargetPrimitmive() { 87 99 return targetPrimitive; 88 100 } 89 101 102 /** 103 * Sets the primitive the collection of primitives is merged or combined 104 * to. 105 * 106 * @param primitive the target primitive 107 */ 90 108 public void setTargetPrimitive(OsmPrimitive primitive) { 91 109 this.targetPrimitive = primitive; … … 118 136 getContentPane().setLayout(new BorderLayout()); 119 137 updateTitle(); 120 spTagConflictTypes = new JSplitPane(JSplitPane.VERTICAL_SPLIT);138 spTagConflictTypes = new AutoAdjustingSplitPane(JSplitPane.VERTICAL_SPLIT); 121 139 spTagConflictTypes.setTopComponent(buildTagConflictResolverPanel()); 122 140 spTagConflictTypes.setBottomComponent(buildRelationMemberConflictResolverPanel()); … … 218 236 } 219 237 } 220 model.re fresh();238 model.rebuild(); 221 239 } 222 240 … … 245 263 TagConflictResolverModel tagModel = getTagConflictResolverModel(); 246 264 getContentPane().removeAll(); 265 247 266 if (relModel.getNumDecisions() > 0 && tagModel.getNumDecisions() > 0) { 267 // display both, the dialog for resolving relation conflicts and for resolving 268 // tag conflicts 248 269 spTagConflictTypes.setTopComponent(pnlTagConflictResolver); 249 270 spTagConflictTypes.setBottomComponent(pnlRelationMemberConflictResolver); 250 271 getContentPane().add(spTagConflictTypes, BorderLayout.CENTER); 251 272 } else if (relModel.getNumDecisions() > 0) { 273 // relation conflicts only 274 // 252 275 getContentPane().add(pnlRelationMemberConflictResolver, BorderLayout.CENTER); 253 276 } else if (tagModel.getNumDecisions() >0) { 277 // tag conflicts only 278 // 254 279 getContentPane().add(pnlTagConflictResolver, BorderLayout.CENTER); 255 280 } else { 256 281 getContentPane().add(buildEmptyConflictsPanel(), BorderLayout.CENTER); 257 282 } 283 258 284 getContentPane().add(pnlButtons, BorderLayout.SOUTH); 259 285 validate(); … … 348 374 } 349 375 } 376 377 class AutoAdjustingSplitPane extends JSplitPane implements PropertyChangeListener, HierarchyBoundsListener { 378 private double dividerLocation; 379 380 public AutoAdjustingSplitPane(int newOrientation) { 381 super(newOrientation); 382 addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY,this); 383 addHierarchyBoundsListener(this); 384 } 385 386 public void ancestorResized(HierarchyEvent e) { 387 setDividerLocation((int)(dividerLocation * getHeight())); 388 } 389 390 public void ancestorMoved(HierarchyEvent e) { 391 // do nothing 392 } 393 394 public void propertyChange(PropertyChangeEvent evt) { 395 if (evt.getPropertyName().equals(JSplitPane.DIVIDER_LOCATION_PROPERTY)) { 396 int newVal = (Integer)evt.getNewValue(); 397 if (getHeight() != 0) { 398 dividerLocation = (double)newVal / (double)getHeight(); 399 } 400 } 401 } 402 } 350 403 } -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellRenderer.java
r2164 r2220 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Color; 6 7 import java.awt.Component; 7 8 import java.awt.Font; … … 20 21 * This is a {@see TableCellRenderer} for {@see MultiValueResolutionDecision}s. 21 22 * 22 23 23 */ 24 24 public class MultiValueCellRenderer extends JLabel implements TableCellRenderer { 25 26 public final static Color BGCOLOR_UNDECIDED = new Color(255,197,197); 25 27 26 28 private ImageIcon iconDecided; … … 36 38 } 37 39 38 protected void renderColors( boolean selected) {40 protected void renderColors(MultiValueResolutionDecision decision, boolean selected) { 39 41 if (selected) { 40 42 setForeground(UIManager.getColor("Table.selectionForeground")); 41 43 setBackground(UIManager.getColor("Table.selectionBackground")); 42 } else { 43 setForeground(UIManager.getColor("Table.foreground")); 44 setBackground(UIManager.getColor("Table.background")); 44 } else{ 45 switch(decision.getDecisionType()) { 46 case UNDECIDED: 47 setForeground(UIManager.getColor("Table.foreground")); 48 setBackground(BGCOLOR_UNDECIDED); 49 break; 50 case KEEP_NONE: 51 setForeground(UIManager.getColor("Panel.foreground")); 52 setBackground(UIManager.getColor("Panel.background")); 53 break; 54 default: 55 setForeground(UIManager.getColor("Table.foreground")); 56 setBackground(UIManager.getColor("Table.background")); 57 break; 58 } 45 59 } 46 60 } … … 49 63 model.removeAllElements(); 50 64 switch(decision.getDecisionType()) { 51 case UNDECIDED:52 model.addElement(tr("Choose a value"));53 setFont(getFont().deriveFont(Font.ITALIC));54 setToolTipText(tr("Please decidedwhich values to keep"));55 cbDecisionRenderer.setSelectedIndex(0);56 break;57 case KEEP_ONE:58 model.addElement(decision.getChosenValue());59 setToolTipText(tr("Value ''{0}'' is going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey()));60 cbDecisionRenderer.setSelectedIndex(0);61 break;62 case KEEP_NONE:63 model.addElement(tr("deleted"));64 setFont(getFont().deriveFont(Font.ITALIC));65 setToolTipText(tr("The key ''{0}'' and all its values are going to be removed", decision.getKey()));66 cbDecisionRenderer.setSelectedIndex(0);67 break;68 case KEEP_ALL:69 model.addElement(decision.getChosenValue());70 setToolTipText(tr("All values joined as ''{0}'' are going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey()));71 cbDecisionRenderer.setSelectedIndex(0);72 break;65 case UNDECIDED: 66 model.addElement(tr("Choose a value")); 67 setFont(getFont().deriveFont(Font.ITALIC)); 68 setToolTipText(tr("Please decide which values to keep")); 69 cbDecisionRenderer.setSelectedIndex(0); 70 break; 71 case KEEP_ONE: 72 model.addElement(decision.getChosenValue()); 73 setToolTipText(tr("Value ''{0}'' is going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey())); 74 cbDecisionRenderer.setSelectedIndex(0); 75 break; 76 case KEEP_NONE: 77 model.addElement(tr("deleted")); 78 setFont(getFont().deriveFont(Font.ITALIC)); 79 setToolTipText(tr("The key ''{0}'' and all its values are going to be removed", decision.getKey())); 80 cbDecisionRenderer.setSelectedIndex(0); 81 break; 82 case KEEP_ALL: 83 model.addElement(decision.getChosenValue()); 84 setToolTipText(tr("All values joined as ''{0}'' are going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey())); 85 cbDecisionRenderer.setSelectedIndex(0); 86 break; 73 87 } 74 88 } … … 84 98 85 99 reset(); 86 renderColors(isSelected);87 100 MultiValueResolutionDecision decision = (MultiValueResolutionDecision)value; 101 renderColors(decision,isSelected); 88 102 switch(column) { 89 case 0:90 if (decision.isDecided()) {91 setIcon(iconDecided);92 } else {93 setIcon(iconUndecided);94 }95 return this;103 case 0: 104 if (decision.isDecided()) { 105 setIcon(iconDecided); 106 } else { 107 setIcon(iconUndecided); 108 } 109 return this; 96 110 97 case 1:98 setText(decision.getKey());99 return this;111 case 1: 112 setText(decision.getKey()); 113 return this; 100 114 101 case 2:102 renderValue(decision);103 return cbDecisionRenderer;115 case 2: 116 renderValue(decision); 117 return cbDecisionRenderer; 104 118 } 105 119 return this; -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/PasteTagsConflictResolverDialog.java
r2115 r2220 107 107 } 108 108 109 110 109 protected JPanel buildButtonPanel() { 111 110 JPanel pnl = new JPanel(); … … 135 134 } 136 135 136 /** 137 * Initializes the conflict resolver for a specific type of primitives 138 * 139 * @param type the type of primitives 140 * @param tc the tags belonging to this type of primitives 141 * @param targetStatistics histogram of paste targets, number of primitives of each type in the paste target 142 */ 137 143 protected void initResolver(OsmPrimitiveType type, TagCollection tc, Map<OsmPrimitiveType,Integer> targetStatistics) { 138 resolvers.get(type).getModel().populate(tc); 144 resolvers.get(type).getModel().populate(tc,tc.getKeysWithMultipleValues()); 145 resolvers.get(type).getModel().prepareDefaultTagDecisions(); 139 146 if (!tc.isEmpty() && targetStatistics.get(type) != null && targetStatistics.get(type) > 0) { 140 147 tpResolvers.add(PANE_TITLES.get(type), resolvers.get(type)); … … 142 149 } 143 150 144 protected String formatStatisticsMessage(OsmPrimitiveType type, int count) { 145 String msg = ""; 146 switch(type) { 147 case NODE: msg= trn("{0} node", "{0} nodes", count, count); break; 148 case WAY: msg= trn("{0} way", "{0} ways", count, count); break; 149 case RELATION: msg= trn("{0} relation", "{0} relations", count, count); break; 150 } 151 return msg; 152 } 153 151 /** 152 * Populates the conflict resolver with one tag collection 153 * 154 * @param tagsForAllPrimitives the tag collection 155 * @param sourceStatistics histogram of tag source, number of primitives of each type in the source 156 * @param targetStatistics histogram of paste targets, number of primitives of each type in the paste target 157 */ 154 158 public void populate(TagCollection tagsForAllPrimitives, Map<OsmPrimitiveType, Integer> sourceStatistics, Map<OsmPrimitiveType,Integer> targetStatistics) { 155 159 mode = Mode.RESOLVING_ONE_TAGCOLLECTION_ONLY; … … 157 161 sourceStatistics = sourceStatistics == null ? new HashMap<OsmPrimitiveType, Integer>() :sourceStatistics; 158 162 targetStatistics = targetStatistics == null ? new HashMap<OsmPrimitiveType, Integer>() : targetStatistics; 159 allPrimitivesResolver.getModel().populate(tagsForAllPrimitives); 163 164 // init the resolver 165 // 166 allPrimitivesResolver.getModel().populate(tagsForAllPrimitives,tagsForAllPrimitives.getKeysWithMultipleValues()); 167 allPrimitivesResolver.getModel().prepareDefaultTagDecisions(); 168 169 // prepare the dialog with one tag resolver 160 170 pnlTagResolver.setLayout(new BorderLayout()); 161 171 pnlTagResolver.removeAll(); … … 183 193 } 184 194 195 /** 196 * Populate the tag conflict resolver with tags for each type of primitives 197 * 198 * @param tagsForNodes the tags belonging to nodes in the paste source 199 * @param tagsForWays the tags belonging to way in the paste source 200 * @param tagsForRelations the tags belonging to relations in the paste source 201 * @param sourceStatistics histogram of tag source, number of primitives of each type in the source 202 * @param targetStatistics histogram of paste targets, number of primitives of each type in the paste target 203 */ 185 204 public void populate(TagCollection tagsForNodes, TagCollection tagsForWays, TagCollection tagsForRelations, Map<OsmPrimitiveType,Integer> sourceStatistics, Map<OsmPrimitiveType, Integer> targetStatistics) { 186 205 tagsForNodes = (tagsForNodes == null) ? new TagCollection() : tagsForNodes; … … 426 445 } 427 446 428 protected void renderFrom(StatisticsInfo info) { 429 if (info == null) return; 430 if (info.sourceInfo == null) return; 431 if (info.sourceInfo.isEmpty()) return; 432 if (info.sourceInfo.size() == 1) { 433 setIcon(ImageProvider.get(info.sourceInfo.keySet().iterator().next())); 447 protected void renderStatistics(Map<OsmPrimitiveType, Integer> stat) { 448 if (stat == null) return; 449 if (stat.isEmpty()) return; 450 if (stat.size() == 1) { 451 setIcon(ImageProvider.get(stat.keySet().iterator().next())); 434 452 } else { 435 453 setIcon(ImageProvider.get("data", "object")); 436 454 } 437 455 String text = ""; 438 for (OsmPrimitiveType type: info.sourceInfo.keySet()) {439 int numPrimitives = info.sourceInfo.get(type) == null ? 0 : info.sourceInfo.get(type);456 for (OsmPrimitiveType type: stat.keySet()) { 457 int numPrimitives = stat.get(type) == null ? 0 : stat.get(type); 440 458 if (numPrimitives == 0) { 441 459 continue; … … 452 470 } 453 471 472 protected void renderFrom(StatisticsInfo info) { 473 renderStatistics(info.sourceInfo); 474 } 475 454 476 protected void renderTo(StatisticsInfo info) { 455 if (info == null) return; 456 if (info.targetInfo == null) return; 457 if (info.targetInfo.isEmpty()) return; 458 if (info.targetInfo.size() == 1) { 459 setIcon(ImageProvider.get(info.targetInfo.keySet().iterator().next())); 460 } else { 461 setIcon(ImageProvider.get("data", "object")); 462 } 463 String text = ""; 464 for (OsmPrimitiveType type: info.targetInfo.keySet()) { 465 int numPrimitives = info.targetInfo.get(type) == null ? 0 : info.targetInfo.get(type); 466 if (numPrimitives == 0) { 467 continue; 468 } 469 String msg = ""; 470 switch(type) { 471 case NODE: msg = trn("{0} node", "{0} nodes", numPrimitives,numPrimitives); break; 472 case WAY: msg = trn("{0} way", "{0} ways", numPrimitives, numPrimitives); break; 473 case RELATION: msg = trn("{0} relation", "{0} relations", numPrimitives, numPrimitives); break; 474 } 475 text = text.equals("") ? msg : text + ", " + msg; 476 } 477 setText(text); 477 renderStatistics(info.targetInfo); 478 478 } 479 479 -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolver.java
r2008 r2220 2 2 package org.openstreetmap.josm.gui.conflict.tags; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 4 6 import java.awt.BorderLayout; 7 import java.awt.GridBagConstraints; 8 import java.awt.GridBagLayout; 5 9 10 import javax.swing.BorderFactory; 11 import javax.swing.JCheckBox; 12 import javax.swing.JLabel; 6 13 import javax.swing.JPanel; 7 14 import javax.swing.JScrollPane; 15 import javax.swing.event.ChangeEvent; 16 import javax.swing.event.ChangeListener; 8 17 18 import org.openstreetmap.josm.Main; 19 20 /** 21 * This is a UI widget for resolving tag conflicts, i.e. differences of the tag values 22 * of multiple {@see OsmPrimitive}s. 23 * 24 * 25 */ 9 26 public class TagConflictResolver extends JPanel { 10 27 28 /** the model for the tag conflict resolver */ 11 29 private TagConflictResolverModel model; 30 /** selects wheter only tags with conflicts are displayed */ 31 private JCheckBox cbShowTagsWithConflictsOnly; 32 33 protected JPanel buildInfoPanel() { 34 JPanel pnl = new JPanel(); 35 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 36 pnl.setLayout(new GridBagLayout()); 37 GridBagConstraints gc = new GridBagConstraints(); 38 gc.fill = GridBagConstraints.BOTH; 39 gc.weighty = 1.0; 40 gc.weightx = 1.0; 41 gc.anchor = GridBagConstraints.LINE_START; 42 pnl.add(new JLabel(tr("<html>Please select the values to keep for the following tags.</html>")), gc); 43 44 gc.gridy = 1; 45 gc.fill = GridBagConstraints.HORIZONTAL; 46 gc.weighty = 0.0; 47 pnl.add(cbShowTagsWithConflictsOnly = new JCheckBox(tr("Show tags with conflicts only")), gc); 48 cbShowTagsWithConflictsOnly.addChangeListener( 49 new ChangeListener() { 50 public void stateChanged(ChangeEvent e) { 51 model.setShowTagsWithConflictsOnly(cbShowTagsWithConflictsOnly.isSelected()); 52 } 53 } 54 ); 55 cbShowTagsWithConflictsOnly.setSelected( 56 Main.pref.getBoolean(getClass().getName() + ".showTagsWithConflictsOnly", false) 57 ); 58 return pnl; 59 } 60 61 /** 62 * Remembers the current settings in the global preferences 63 * 64 */ 65 public void rememberPreferences() { 66 Main.pref.put(getClass().getName() + ".showTagsWithConflictsOnly", cbShowTagsWithConflictsOnly.isSelected()); 67 } 12 68 13 69 protected void build() { 14 70 setLayout(new BorderLayout()); 71 add(buildInfoPanel(), BorderLayout.NORTH); 15 72 add(new JScrollPane(new TagConflictResolverTable(model)), BorderLayout.CENTER); 16 73 } 74 17 75 public TagConflictResolver() { 18 76 this.model = new TagConflictResolverModel(); … … 20 78 } 21 79 80 /** 81 * Replies the model used by this dialog 82 * 83 * @return the model 84 */ 22 85 public TagConflictResolverModel getModel() { 23 86 return model; -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java
r2181 r2220 10 10 import java.util.Comparator; 11 11 import java.util.HashMap; 12 import java.util.HashSet; 12 13 import java.util.List; 14 import java.util.Set; 13 15 14 16 import javax.swing.table.DefaultTableModel; … … 20 22 21 23 private TagCollection tags; 22 private List<String> keys; 24 private List<String> displayedKeys; 25 private Set<String> keysWithConflicts; 23 26 private HashMap<String, MultiValueResolutionDecision> decisions; 24 27 private int numConflicts; 25 28 private PropertyChangeSupport support; 29 private boolean showTagsWithConflictsOnly = false; 26 30 27 31 public TagConflictResolverModel() { … … 37 41 support.removePropertyChangeListener(listener); 38 42 } 39 40 43 41 44 protected void setNumConflicts(int numConflicts) { … … 59 62 protected void sort() { 60 63 Collections.sort( 61 keys,64 displayedKeys, 62 65 new Comparator<String>() { 63 public int compare(String o1, String o2) {64 if (decisions.get( o1).isDecided() && ! decisions.get(o2).isDecided())66 public int compare(String key1, String key2) { 67 if (decisions.get(key1).isDecided() && ! decisions.get(key2).isDecided()) 65 68 return 1; 66 else if (!decisions.get( o1).isDecided() && decisions.get(o2).isDecided())69 else if (!decisions.get(key1).isDecided() && decisions.get(key2).isDecided()) 67 70 return -1; 68 return o1.compareTo(o2);71 return key1.compareTo(key2); 69 72 } 70 73 } … … 72 75 } 73 76 74 protected void init() { 75 keys.clear(); 76 keys.addAll(tags.getKeys()); 77 /** 78 * initializes the model from the current tags 79 * 80 */ 81 protected void rebuild() { 82 if (tags == null) return; 77 83 for(String key: tags.getKeys()) { 78 84 MultiValueResolutionDecision decision = new MultiValueResolutionDecision(tags.getTagsFor(key)); 79 decisions.put(key,decision); 80 } 85 if (decisions.get(key) == null) { 86 decisions.put(key,decision); 87 } 88 } 89 displayedKeys.clear(); 90 Set<String> keys = tags.getKeys(); 91 if (showTagsWithConflictsOnly) { 92 keys.retainAll(keysWithConflicts); 93 for (String key: tags.getKeys()) { 94 if (!decisions.get(key).isDecided() && !keys.contains(key)) { 95 keys.add(key); 96 } 97 } 98 } 99 displayedKeys.addAll(keys); 81 100 refreshNumConflicts(); 82 } 83 84 public void populate(TagCollection tags) { 101 sort(); 102 fireTableDataChanged(); 103 } 104 105 /** 106 * Populates the model with the tags for which conflicts are to be resolved. 107 * 108 * @param tags the tag collection with the tags. Must not be null. 109 * @param keysWithConflicts the set of tag keys with conflicts 110 * @throws IllegalArgumentException thrown if tags is null 111 */ 112 public void populate(TagCollection tags, Set<String> keysWithConflicts) { 85 113 if (tags == null) 86 114 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "tags")); 87 115 this.tags = tags; 88 keys = new ArrayList<String>(); 116 displayedKeys = new ArrayList<String>(); 117 this.keysWithConflicts = keysWithConflicts == null ? new HashSet<String>() : keysWithConflicts; 89 118 decisions = new HashMap<String, MultiValueResolutionDecision>(); 90 init(); 91 sort(); 92 fireTableDataChanged(); 93 } 94 119 rebuild(); 120 } 95 121 96 122 @Override 97 123 public int getRowCount() { 98 if ( keys == null) return 0;99 return keys.size();124 if (displayedKeys == null) return 0; 125 return displayedKeys.size(); 100 126 } 101 127 102 128 @Override 103 129 public Object getValueAt(int row, int column) { 104 return decisions.get( keys.get(row));130 return decisions.get(displayedKeys.get(row)); 105 131 } 106 132 … … 112 138 @Override 113 139 public void setValueAt(Object value, int row, int column) { 114 MultiValueResolutionDecision decision = decisions.get( keys.get(row));140 MultiValueResolutionDecision decision = decisions.get(displayedKeys.get(row)); 115 141 if (value instanceof String) { 116 142 decision.keepOne((String)value); … … 150 176 public TagCollection getResolution() { 151 177 TagCollection tc = new TagCollection(); 152 for (String key: keys) {178 for (String key: displayedKeys) { 153 179 tc.add(decisions.get(key).getResolution()); 154 180 } … … 157 183 158 184 public MultiValueResolutionDecision getDecision(int row) { 159 return decisions.get(keys.get(row)); 160 } 161 162 public void refresh() { 163 fireTableDataChanged(); 164 refreshNumConflicts(); 165 } 185 return decisions.get(displayedKeys.get(row)); 186 } 187 188 /** 189 * Sets whether all tags or only tags with conflicts are displayed 190 * 191 * @param showTagsWithConflictsOnly if true, only tags with conflicts are displayed 192 */ 193 public void setShowTagsWithConflictsOnly(boolean showTagsWithConflictsOnly) { 194 this.showTagsWithConflictsOnly = showTagsWithConflictsOnly; 195 rebuild(); 196 } 197 198 /** 199 * Prepare the default decisions for the current model 200 * 201 */ 202 public void prepareDefaultTagDecisions() { 203 for (MultiValueResolutionDecision decision: decisions.values()) { 204 List<String> values = decision.getValues(); 205 values.remove(""); 206 if (values.size() == 1) { 207 decision.keepOne(values.get(0)); 208 } else { 209 decision.keepAll(); 210 } 211 } 212 rebuild(); 213 } 214 166 215 } -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverTable.java
r2008 r2220 6 6 7 7 import javax.swing.AbstractAction; 8 import javax.swing.JComboBox; 8 9 import javax.swing.JComponent; 9 10 import javax.swing.JTable; … … 39 40 40 41 ((MultiValueCellEditor)getColumnModel().getColumn(2).getCellEditor()).addNavigationListeners(this); 42 43 setRowHeight((int)new JComboBox().getPreferredSize().getHeight()); 41 44 } 42 45
Note:
See TracChangeset
for help on using the changeset viewer.