Changeset 30778 in osm for applications/editors
- Timestamp:
- 2014-10-29T20:52:03+01:00 (10 years ago)
- Location:
- applications/editors/josm/plugins/merge-overlap
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/merge-overlap/build.xml
r30766 r30778 4 4 <property name="commit.message" value="MergeOverlap: help shortcut parser, rebuild"/> 5 5 <!-- enter the *lowest* JOSM version this plugin is currently compatible with --> 6 <property name="plugin.main.version" value="76 61"/>6 <property name="plugin.main.version" value="7674"/> 7 7 8 8 <!-- Configure these properties (replace "..." accordingly). -
applications/editors/josm/plugins/merge-overlap/src/mergeoverlap/hack/MyCombinePrimitiveResolverDialog.java
r30766 r30778 2 2 package mergeoverlap.hack; 3 3 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;5 import static org.openstreetmap.josm.tools.I18n.tr;6 7 import java.awt.BorderLayout;8 4 import java.awt.Component; 9 import java.awt.Dimension;10 import java.awt.FlowLayout;11 import java.awt.event.ActionEvent;12 import java.awt.event.HierarchyBoundsListener;13 import java.awt.event.HierarchyEvent;14 import java.awt.event.WindowAdapter;15 import java.awt.event.WindowEvent;16 5 import java.beans.PropertyChangeEvent; 17 import java.beans.PropertyChangeListener;18 import java.util.HashSet;19 6 import java.util.LinkedList; 20 7 import java.util.List; 21 8 import java.util.Map; 22 import java.util.Set;23 9 24 import javax.swing.AbstractAction;25 import javax.swing.Action;26 import javax.swing.JDialog;27 import javax.swing.JLabel;28 import javax.swing.JOptionPane;29 10 import javax.swing.JPanel; 30 import javax.swing.JSplitPane;31 11 32 12 import org.openstreetmap.josm.Main; 33 13 import org.openstreetmap.josm.command.ChangePropertyCommand; 34 14 import org.openstreetmap.josm.command.Command; 35 import org.openstreetmap.josm.data.osm.Node;36 15 import org.openstreetmap.josm.data.osm.OsmPrimitive; 37 16 import org.openstreetmap.josm.data.osm.Relation; 38 17 import org.openstreetmap.josm.data.osm.TagCollection; 39 18 import org.openstreetmap.josm.data.osm.Way; 40 import org.openstreetmap.josm.gui.DefaultNameFormatter; 41 import org.openstreetmap.josm.gui.SideButton; 42 import org.openstreetmap.josm.gui.conflict.tags.MultiValueResolutionDecision; 43 import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictDecision; 44 import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictDecisionType; 19 import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog; 45 20 import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictResolver; 46 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolver;47 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolverModel;48 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;49 import org.openstreetmap.josm.gui.help.HelpUtil;50 21 import org.openstreetmap.josm.gui.util.GuiHelper; 51 import org.openstreetmap.josm.tools.ImageProvider;52 import org.openstreetmap.josm.tools.WindowGeometry;53 22 54 23 /** … … 79 48 * see {@link #buildResolutionCommands()} 80 49 */ 81 public class MyCombinePrimitiveResolverDialog extends JDialog {50 public class MyCombinePrimitiveResolverDialog extends CombinePrimitiveResolverDialog { 82 51 83 52 /** the unique instance of the dialog */ … … 100 69 } 101 70 102 private AutoAdjustingSplitPane spTagConflictTypes; 103 private TagConflictResolver pnlTagConflictResolver; 104 private RelationMemberConflictResolver pnlRelationMemberConflictResolver; 105 private boolean canceled; 106 private JPanel pnlButtons; 107 private OsmPrimitive targetPrimitive; 108 109 /** the private help action */ 110 private ContextSensitiveHelpAction helpAction; 111 /** the apply button */ 112 private SideButton btnApply; 113 114 /** 115 * Replies the target primitive the collection of primitives is merged 116 * or combined to. 117 * 118 * @return the target primitive 119 */ 120 public OsmPrimitive getTargetPrimitmive() { 121 return targetPrimitive; 122 } 123 124 /** 125 * Sets the primitive the collection of primitives is merged or combined to. 126 * 127 * @param primitive the target primitive 128 */ 129 public void setTargetPrimitive(final OsmPrimitive primitive) { 130 this.targetPrimitive = primitive; 131 GuiHelper.runInEDTAndWait(new Runnable() { 132 @Override public void run() { 133 updateTitle(); 134 if (primitive instanceof Way) { 135 pnlRelationMemberConflictResolver.initForWayCombining(); 136 } else if (primitive instanceof Node) { 137 pnlRelationMemberConflictResolver.initForNodeMerging(); 138 } 139 } 140 }); 141 } 142 143 protected void updateTitle() { 144 if (targetPrimitive == null) { 145 setTitle(tr("Conflicts when combining primitives")); 146 return; 147 } 148 if (targetPrimitive instanceof Way) { 149 setTitle(tr("Conflicts when combining ways - combined way is ''{0}''", targetPrimitive 150 .getDisplayName(DefaultNameFormatter.getInstance()))); 151 helpAction.setHelpTopic(ht("/Action/CombineWay#ResolvingConflicts")); 152 getRootPane().putClientProperty("help", ht("/Action/CombineWay#ResolvingConflicts")); 153 } else if (targetPrimitive instanceof Node) { 154 setTitle(tr("Conflicts when merging nodes - target node is ''{0}''", targetPrimitive 155 .getDisplayName(DefaultNameFormatter.getInstance()))); 156 helpAction.setHelpTopic(ht("/Action/MergeNodes#ResolvingConflicts")); 157 getRootPane().putClientProperty("help", ht("/Action/MergeNodes#ResolvingConflicts")); 158 } 159 } 160 161 protected final void build() { 162 getContentPane().setLayout(new BorderLayout()); 163 updateTitle(); 164 spTagConflictTypes = new AutoAdjustingSplitPane(JSplitPane.VERTICAL_SPLIT); 165 spTagConflictTypes.setTopComponent(buildTagConflictResolverPanel()); 166 spTagConflictTypes.setBottomComponent(buildRelationMemberConflictResolverPanel()); 167 getContentPane().add(pnlButtons = buildButtonPanel(), BorderLayout.SOUTH); 168 addWindowListener(new AdjustDividerLocationAction()); 169 HelpUtil.setHelpContext(getRootPane(), ht("/")); 170 } 171 172 protected JPanel buildTagConflictResolverPanel() { 173 pnlTagConflictResolver = new TagConflictResolver(); 174 return pnlTagConflictResolver; 175 } 176 71 @Override 177 72 protected JPanel buildRelationMemberConflictResolverPanel() { 178 73 pnlRelationMemberConflictResolver = new RelationMemberConflictResolver(new MyRelationMemberConflictResolverModel()); … … 180 75 } 181 76 182 protected JPanel buildButtonPanel() { 183 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER)); 184 185 // -- apply button 186 ApplyAction applyAction = new ApplyAction(); 187 pnlTagConflictResolver.getModel().addPropertyChangeListener(applyAction); 188 pnlRelationMemberConflictResolver.getModel().addPropertyChangeListener(applyAction); 189 btnApply = new SideButton(applyAction); 190 btnApply.setFocusable(true); 191 pnl.add(btnApply); 192 193 // -- cancel button 194 CancelAction cancelAction = new CancelAction(); 195 pnl.add(new SideButton(cancelAction)); 196 197 // -- help button 198 helpAction = new ContextSensitiveHelpAction(); 199 pnl.add(new SideButton(helpAction)); 200 201 return pnl; 77 @Override 78 protected ApplyAction buildApplyAction() { 79 return new ApplyAction() { 80 @Override 81 public void propertyChange(PropertyChangeEvent evt) { 82 super.propertyChange(evt); 83 if (evt.getPropertyName().equals(MyRelationMemberConflictResolverModel.NUM_CONFLICTS_PROP)) { 84 updateEnabledState(); 85 } 86 } 87 }; 202 88 } 203 89 … … 207 93 */ 208 94 public MyCombinePrimitiveResolverDialog(Component parent) { 209 super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL); 210 build(); 211 } 212 213 /** 214 * Replies the tag conflict resolver model. 215 * @return The tag conflict resolver model. 216 */ 217 public TagConflictResolverModel getTagConflictResolverModel() { 218 return pnlTagConflictResolver.getModel(); 95 super(parent); 219 96 } 220 97 … … 223 100 * @return The relation membership conflict resolver model. 224 101 */ 102 @Override 225 103 public MyRelationMemberConflictResolverModel getRelationMemberConflictResolverModel() { 226 104 return (MyRelationMemberConflictResolverModel) pnlRelationMemberConflictResolver.getModel(); 227 105 } 228 106 229 protected List<Command> buildTagChangeCommand(OsmPrimitive primitive, TagCollection tc) { 230 LinkedList<Command> cmds = new LinkedList<>(); 231 for (String key : tc.getKeys()) { 232 if (tc.hasUniqueEmptyValue(key)) { 233 if (primitive.get(key) != null) { 234 cmds.add(new ChangePropertyCommand(primitive, key, null)); 235 } 236 } else { 237 String value = tc.getJoinedValues(key); 238 if (!value.equals(primitive.get(key))) { 239 cmds.add(new ChangePropertyCommand(primitive, key, value)); 240 } 241 } 242 } 243 return cmds; 244 } 245 107 /** 108 * Replies the list of {@link Command commands} needed to apply resolution choices. 109 * @return The list of {@link Command commands} needed to apply resolution choices. 110 */ 246 111 public List<Command> buildWayResolutionCommands() { 247 112 List<Command> cmds = new LinkedList<>(); … … 266 131 getRelationMemberConflictResolverModel().buildRelationCorrespondance(targetPrimitive, newRelations, oldWays); 267 132 } 268 269 protected void prepareDefaultTagDecisions() {270 TagConflictResolverModel model = getTagConflictResolverModel();271 for (int i = 0; i < model.getRowCount(); i++) {272 MultiValueResolutionDecision decision = model.getDecision(i);273 List<String> values = decision.getValues();274 values.remove("");275 if (values.size() == 1) {276 decision.keepOne(values.get(0));277 } else {278 decision.keepAll();279 }280 }281 model.rebuild();282 }283 284 protected void prepareDefaultRelationDecisions() {285 MyRelationMemberConflictResolverModel model = getRelationMemberConflictResolverModel();286 Set<Relation> relations = new HashSet<>();287 for (int i = 0; i < model.getNumDecisions(); i++) {288 RelationMemberConflictDecision decision = model.getDecision(i);289 if (!relations.contains(decision.getRelation())) {290 decision.decide(RelationMemberConflictDecisionType.KEEP);291 relations.add(decision.getRelation());292 } else {293 decision.decide(RelationMemberConflictDecisionType.REMOVE);294 }295 }296 model.refresh();297 }298 299 /**300 * Prepares the default decisions for populated tag and relation membership conflicts.301 */302 public void prepareDefaultDecisions() {303 prepareDefaultTagDecisions();304 prepareDefaultRelationDecisions();305 }306 307 protected JPanel buildEmptyConflictsPanel() {308 JPanel pnl = new JPanel(new BorderLayout());309 pnl.add(new JLabel(tr("No conflicts to resolve")));310 return pnl;311 }312 313 protected void prepareGUIBeforeConflictResolutionStarts() {314 MyRelationMemberConflictResolverModel relModel = getRelationMemberConflictResolverModel();315 TagConflictResolverModel tagModel = getTagConflictResolverModel();316 getContentPane().removeAll();317 318 if (relModel.getNumDecisions() > 0 && tagModel.getNumDecisions() > 0) {319 // display both, the dialog for resolving relation conflicts and for resolving tag conflicts320 spTagConflictTypes.setTopComponent(pnlTagConflictResolver);321 spTagConflictTypes.setBottomComponent(pnlRelationMemberConflictResolver);322 getContentPane().add(spTagConflictTypes, BorderLayout.CENTER);323 } else if (relModel.getNumDecisions() > 0) {324 // relation conflicts only325 getContentPane().add(pnlRelationMemberConflictResolver, BorderLayout.CENTER);326 } else if (tagModel.getNumDecisions() > 0) {327 // tag conflicts only328 getContentPane().add(pnlTagConflictResolver, BorderLayout.CENTER);329 } else {330 getContentPane().add(buildEmptyConflictsPanel(), BorderLayout.CENTER);331 }332 333 getContentPane().add(pnlButtons, BorderLayout.SOUTH);334 validate();335 int numTagDecisions = getTagConflictResolverModel().getNumDecisions();336 int numRelationDecisions = getRelationMemberConflictResolverModel().getNumDecisions();337 if (numTagDecisions > 0 && numRelationDecisions > 0) {338 spTagConflictTypes.setDividerLocation(0.5);339 }340 pnlRelationMemberConflictResolver.prepareForEditing();341 }342 343 protected void setCanceled(boolean canceled) {344 this.canceled = canceled;345 }346 347 /**348 * Determines if this dialog has been cancelled.349 * @return true if this dialog has been cancelled, false otherwise.350 */351 public boolean isCanceled() {352 return canceled;353 }354 355 @Override356 public void setVisible(boolean visible) {357 if (visible) {358 prepareGUIBeforeConflictResolutionStarts();359 new WindowGeometry(getClass().getName() + ".geometry", WindowGeometry.centerInWindow(Main.parent,360 new Dimension(600, 400))).applySafe(this);361 setCanceled(false);362 btnApply.requestFocusInWindow();363 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775364 new WindowGeometry(this).remember(getClass().getName() + ".geometry");365 }366 super.setVisible(visible);367 }368 369 class CancelAction extends AbstractAction {370 371 public CancelAction() {372 putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution"));373 putValue(Action.NAME, tr("Cancel"));374 putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel"));375 setEnabled(true);376 }377 378 @Override379 public void actionPerformed(ActionEvent arg0) {380 setCanceled(true);381 setVisible(false);382 }383 }384 385 class ApplyAction extends AbstractAction implements PropertyChangeListener {386 387 public ApplyAction() {388 putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts"));389 putValue(Action.NAME, tr("Apply"));390 putValue(Action.SMALL_ICON, ImageProvider.get("ok"));391 updateEnabledState();392 }393 394 @Override395 public void actionPerformed(ActionEvent arg0) {396 setVisible(false);397 pnlTagConflictResolver.rememberPreferences();398 }399 400 protected final void updateEnabledState() {401 setEnabled(pnlTagConflictResolver.getModel().getNumConflicts() == 0402 && pnlRelationMemberConflictResolver.getModel().getNumConflicts() == 0);403 }404 405 @Override406 public void propertyChange(PropertyChangeEvent evt) {407 if (evt.getPropertyName().equals(TagConflictResolverModel.NUM_CONFLICTS_PROP)) {408 updateEnabledState();409 }410 if (evt.getPropertyName().equals(MyRelationMemberConflictResolverModel.NUM_CONFLICTS_PROP)) {411 updateEnabledState();412 }413 }414 }415 416 class AdjustDividerLocationAction extends WindowAdapter {417 @Override418 public void windowOpened(WindowEvent e) {419 int numTagDecisions = getTagConflictResolverModel().getNumDecisions();420 int numRelationDecisions = getRelationMemberConflictResolverModel().getNumDecisions();421 if (numTagDecisions > 0 && numRelationDecisions > 0) {422 spTagConflictTypes.setDividerLocation(0.5);423 }424 }425 }426 427 static class AutoAdjustingSplitPane extends JSplitPane implements PropertyChangeListener, HierarchyBoundsListener {428 private double dividerLocation;429 430 public AutoAdjustingSplitPane(int newOrientation) {431 super(newOrientation);432 addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, this);433 addHierarchyBoundsListener(this);434 }435 436 @Override437 public void ancestorResized(HierarchyEvent e) {438 setDividerLocation((int) (dividerLocation * getHeight()));439 }440 441 @Override442 public void ancestorMoved(HierarchyEvent e) {443 // do nothing444 }445 446 @Override447 public void propertyChange(PropertyChangeEvent evt) {448 if (evt.getPropertyName().equals(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {449 int newVal = (Integer) evt.getNewValue();450 if (getHeight() != 0) {451 dividerLocation = (double) newVal / (double) getHeight();452 }453 }454 }455 }456 133 }
Note:
See TracChangeset
for help on using the changeset viewer.