source: josm/trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMerger.java@ 2070

Last change on this file since 2070 was 2070, checked in by Gubaer, 15 years ago

new: rewrite of CombineWay action
new: conflict resolution dialog for CombineWay, including conflicts for different relation memberships
cleanup: cleanup in OsmReader, reduces memory footprint and reduces parsing time
cleanup: made most of the public fields in OsmPrimitive @deprecated, added accessors and changed the code
cleanup: replaced usages of @deprecated constructors for ExtendedDialog
fixed #3208: Combine ways brokes relation order

WARNING: this changeset touches a lot of code all over the code base. "latest" might become slightly unstable in the next days. Also experience incompatibility issues with plugins in the next few days.

File size: 25.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.conflict.pair.properties;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Color;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.event.ActionEvent;
11import java.text.DecimalFormat;
12import java.util.Observable;
13import java.util.Observer;
14
15import javax.swing.AbstractAction;
16import javax.swing.Action;
17import javax.swing.BorderFactory;
18import javax.swing.JButton;
19import javax.swing.JLabel;
20import javax.swing.JOptionPane;
21import javax.swing.JPanel;
22
23import org.openstreetmap.josm.data.coor.LatLon;
24import org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType;
25import org.openstreetmap.josm.tools.ImageProvider;
26
27/**
28 * This class represents a UI component for resolving conflicts in some properties
29 * of {@see OsmPrimitive}.
30 *
31 */
32public class PropertiesMerger extends JPanel implements Observer {
33 private static DecimalFormat COORD_FORMATTER = new DecimalFormat("###0.0000");
34
35 public final static Color BGCOLOR_NO_CONFLICT = new Color(234,234,234);
36 public final static Color BGCOLOR_UNDECIDED = new Color(255,197,197);
37 public final static Color BGCOLOR_DECIDED = new Color(217,255,217);
38
39 private JLabel lblMyVersion;
40 private JLabel lblMergedVersion;
41 private JLabel lblTheirVersion;
42
43 private JLabel lblMyCoordinates;
44 private JLabel lblMergedCoordinates;
45 private JLabel lblTheirCoordinates;
46
47 private JLabel lblMyDeletedState;
48 private JLabel lblMergedDeletedState;
49 private JLabel lblTheirDeletedState;
50
51 private JLabel lblMyVisibleState;
52 private JLabel lblMergedVisibleState;
53 private JLabel lblTheirVisibleState;
54
55 private final PropertiesMergeModel model;
56
57 protected JLabel buildValueLabel(String name) {
58 JLabel lbl = new JLabel();
59 lbl.setName(name);
60 lbl.setHorizontalAlignment(JLabel.CENTER);
61 lbl.setOpaque(true);
62 lbl.setBorder(BorderFactory.createLoweredBevelBorder());
63 return lbl;
64 }
65
66 protected void buildHeaderRow() {
67 GridBagConstraints gc = new GridBagConstraints();
68
69 gc.gridx = 1;
70 gc.gridy = 0;
71 gc.gridwidth = 1;
72 gc.gridheight = 1;
73 gc.fill = GridBagConstraints.NONE;
74 gc.anchor = GridBagConstraints.CENTER;
75 gc.weightx = 0.0;
76 gc.weighty = 0.0;
77 gc.insets = new Insets(10,0,10,0);
78 lblMyVersion = new JLabel(tr("My version"));
79 lblMyVersion.setToolTipText(tr("Properties in my dataset, i.e. the local dataset"));
80 add(lblMyVersion, gc);
81
82 gc.gridx = 3;
83 gc.gridy = 0;
84 lblMergedVersion = new JLabel(tr("Merged version"));
85 lblMergedVersion.setToolTipText(tr("Properties in the merged element. They will replace properties in my elements when merge decisions are applied."));
86 add(lblMergedVersion, gc);
87
88 gc.gridx = 5;
89 gc.gridy = 0;
90 lblTheirVersion = new JLabel(tr("Their version"));
91 lblTheirVersion.setToolTipText(tr("Properties in their dataset, i.e. the server dataset"));
92 add(lblTheirVersion, gc);
93 }
94
95 protected void buildCoordinateConflictRows() {
96 GridBagConstraints gc = new GridBagConstraints();
97
98 gc.gridx = 0;
99 gc.gridy = 1;
100 gc.gridwidth = 1;
101 gc.gridheight = 1;
102 gc.fill = GridBagConstraints.HORIZONTAL;
103 gc.anchor = GridBagConstraints.LINE_START;
104 gc.weightx = 0.0;
105 gc.weighty = 0.0;
106 gc.insets = new Insets(0,5,0,5);
107 add(new JLabel(tr("Coordinates:")), gc);
108
109 gc.gridx = 1;
110 gc.gridy = 1;
111 gc.fill = GridBagConstraints.BOTH;
112 gc.anchor = GridBagConstraints.CENTER;
113 gc.weightx = 0.33;
114 gc.weighty = 0.0;
115 add(lblMyCoordinates = buildValueLabel("label.mycoordinates"), gc);
116
117 gc.gridx = 2;
118 gc.gridy = 1;
119 gc.fill = GridBagConstraints.NONE;
120 gc.anchor = GridBagConstraints.CENTER;
121 gc.weightx = 0.0;
122 gc.weighty = 0.0;
123 KeepMyCoordinatesAction actKeepMyCoordinates = new KeepMyCoordinatesAction();
124 model.addObserver(actKeepMyCoordinates);
125 JButton btnKeepMyCoordinates = new JButton(actKeepMyCoordinates);
126 btnKeepMyCoordinates.setName("button.keepmycoordinates");
127 add(btnKeepMyCoordinates, gc);
128
129
130 gc.gridx = 3;
131 gc.gridy = 1;
132 gc.fill = GridBagConstraints.BOTH;
133 gc.anchor = GridBagConstraints.CENTER;
134 gc.weightx = 0.33;
135 gc.weighty = 0.0;
136 add(lblMergedCoordinates = buildValueLabel("label.mergedcoordinates"), gc);
137
138 gc.gridx = 4;
139 gc.gridy = 1;
140 gc.fill = GridBagConstraints.NONE;
141 gc.anchor = GridBagConstraints.CENTER;
142 gc.weightx = 0.0;
143 gc.weighty = 0.0;
144 KeepTheirCoordinatesAction actKeepTheirCoordinates = new KeepTheirCoordinatesAction();
145 model.addObserver(actKeepTheirCoordinates);
146 JButton btnKeepTheirCoordinates = new JButton(actKeepTheirCoordinates);
147 add(btnKeepTheirCoordinates, gc);
148
149 gc.gridx = 5;
150 gc.gridy = 1;
151 gc.fill = GridBagConstraints.BOTH;
152 gc.anchor = GridBagConstraints.CENTER;
153 gc.weightx = 0.33;
154 gc.weighty = 0.0;
155 add(lblTheirCoordinates = buildValueLabel("label.theircoordinates"), gc);
156
157 // ---------------------------------------------------
158 gc.gridx = 3;
159 gc.gridy = 2;
160 gc.fill = GridBagConstraints.NONE;
161 gc.anchor = GridBagConstraints.CENTER;
162 gc.weightx = 0.0;
163 gc.weighty = 0.0;
164 gc.insets = new Insets(0,5,20,5);
165 UndecideCoordinateConflictAction actUndecideCoordinates = new UndecideCoordinateConflictAction();
166 model.addObserver(actUndecideCoordinates);
167 JButton btnUndecideCoordinates = new JButton(actUndecideCoordinates);
168 add(btnUndecideCoordinates, gc);
169 }
170
171 protected void buildDeletedStateConflictRows() {
172 GridBagConstraints gc = new GridBagConstraints();
173
174 gc.gridx = 0;
175 gc.gridy = 3;
176 gc.gridwidth = 1;
177 gc.gridheight = 1;
178 gc.fill = GridBagConstraints.BOTH;
179 gc.anchor = GridBagConstraints.LINE_START;
180 gc.weightx = 0.0;
181 gc.weighty = 0.0;
182 gc.insets = new Insets(0,5,0,5);
183 add(new JLabel(tr("Deleted State:")), gc);
184
185 gc.gridx = 1;
186 gc.gridy = 3;
187 gc.fill = GridBagConstraints.BOTH;
188 gc.anchor = GridBagConstraints.CENTER;
189 gc.weightx = 0.33;
190 gc.weighty = 0.0;
191 add(lblMyDeletedState = buildValueLabel("label.mydeletedstate"), gc);
192
193 gc.gridx = 2;
194 gc.gridy = 3;
195 gc.fill = GridBagConstraints.NONE;
196 gc.anchor = GridBagConstraints.CENTER;
197 gc.weightx = 0.0;
198 gc.weighty = 0.0;
199 KeepMyDeletedStateAction actKeepMyDeletedState = new KeepMyDeletedStateAction();
200 model.addObserver(actKeepMyDeletedState);
201 JButton btnKeepMyDeletedState = new JButton(actKeepMyDeletedState);
202 btnKeepMyDeletedState.setName("button.keepmydeletedstate");
203 add(btnKeepMyDeletedState, gc);
204
205
206 gc.gridx = 3;
207 gc.gridy = 3;
208 gc.fill = GridBagConstraints.BOTH;
209 gc.anchor = GridBagConstraints.CENTER;
210 gc.weightx = 0.33;
211 gc.weighty = 0.0;
212 add(lblMergedDeletedState = buildValueLabel("label.mergeddeletedstate"), gc);
213
214 gc.gridx = 4;
215 gc.gridy = 3;
216 gc.fill = GridBagConstraints.NONE;
217 gc.anchor = GridBagConstraints.CENTER;
218 gc.weightx = 0.0;
219 gc.weighty = 0.0;
220 KeepTheirDeletedStateAction actKeepTheirDeletedState = new KeepTheirDeletedStateAction();
221 model.addObserver(actKeepTheirDeletedState);
222 JButton btnKeepTheirDeletedState = new JButton(actKeepTheirDeletedState);
223 btnKeepTheirDeletedState.setName("button.keeptheirdeletedstate");
224 add(btnKeepTheirDeletedState, gc);
225
226 gc.gridx = 5;
227 gc.gridy = 3;
228 gc.fill = GridBagConstraints.BOTH;
229 gc.anchor = GridBagConstraints.CENTER;
230 gc.weightx = 0.33;
231 gc.weighty = 0.0;
232 add(lblTheirDeletedState = buildValueLabel("label.theirdeletedstate"), gc);
233
234 // ---------------------------------------------------
235 gc.gridx = 3;
236 gc.gridy = 4;
237 gc.fill = GridBagConstraints.NONE;
238 gc.anchor = GridBagConstraints.CENTER;
239 gc.weightx = 0.0;
240 gc.weighty = 0.0;
241 UndecideDeletedStateConflictAction actUndecideDeletedState = new UndecideDeletedStateConflictAction();
242 model.addObserver(actUndecideDeletedState);
243 JButton btnUndecideDeletedState = new JButton(actUndecideDeletedState);
244 btnUndecideDeletedState.setName("button.undecidedeletedstate");
245 add(btnUndecideDeletedState, gc);
246 }
247
248 protected void buildVisibleStateRows() {
249 GridBagConstraints gc = new GridBagConstraints();
250
251 gc.gridx = 0;
252 gc.gridy = 5;
253 gc.gridwidth = 1;
254 gc.gridheight = 1;
255 gc.fill = GridBagConstraints.BOTH;
256 gc.anchor = GridBagConstraints.LINE_START;
257 gc.weightx = 0.0;
258 gc.weighty = 0.0;
259 gc.insets = new Insets(0,5,0,5);
260 add(new JLabel(tr("Visible State:")), gc);
261
262 gc.gridx = 1;
263 gc.gridy = 5;
264 gc.fill = GridBagConstraints.BOTH;
265 gc.anchor = GridBagConstraints.CENTER;
266 gc.weightx = 0.33;
267 gc.weighty = 0.0;
268 add(lblMyVisibleState = buildValueLabel("label.myvisiblestate"), gc);
269
270 gc.gridx = 2;
271 gc.gridy = 5;
272 gc.fill = GridBagConstraints.NONE;
273 gc.anchor = GridBagConstraints.CENTER;
274 gc.weightx = 0.0;
275 gc.weighty = 0.0;
276 KeepMyVisibleStateAction actKeepMyVisibleState = new KeepMyVisibleStateAction();
277 model.addObserver(actKeepMyVisibleState);
278 JButton btnKeepMyVisibleState = new JButton(actKeepMyVisibleState);
279 btnKeepMyVisibleState.setName("button.keepmyvisiblestate");
280 add(btnKeepMyVisibleState, gc);
281
282 gc.gridx = 3;
283 gc.gridy = 5;
284 gc.fill = GridBagConstraints.BOTH;
285 gc.anchor = GridBagConstraints.CENTER;
286 gc.weightx = 0.33;
287 gc.weighty = 0.0;
288 add(lblMergedVisibleState = buildValueLabel("label.mergedvisiblestate"), gc);
289
290 gc.gridx = 4;
291 gc.gridy = 5;
292 gc.fill = GridBagConstraints.NONE;
293 gc.anchor = GridBagConstraints.CENTER;
294 gc.weightx = 0.0;
295 gc.weighty = 0.0;
296 KeepTheirVisibleStateAction actKeepTheirVisibleState = new KeepTheirVisibleStateAction();
297 model.addObserver(actKeepTheirVisibleState);
298 JButton btnKeepTheirVisibleState = new JButton(actKeepTheirVisibleState);
299 btnKeepTheirVisibleState.setName("button.keeptheirvisiblestate");
300 add(btnKeepTheirVisibleState, gc);
301
302 gc.gridx = 5;
303 gc.gridy = 5;
304 gc.fill = GridBagConstraints.BOTH;
305 gc.anchor = GridBagConstraints.CENTER;
306 gc.weightx = 0.33;
307 gc.weighty = 0.0;
308 add(lblTheirVisibleState = buildValueLabel("label.theirvisiblestate"), gc);
309
310 // ---------------------------------------------------
311 gc.gridx = 3;
312 gc.gridy = 6;
313 gc.fill = GridBagConstraints.NONE;
314 gc.anchor = GridBagConstraints.CENTER;
315 gc.weightx = 0.0;
316 gc.weighty = 0.0;
317 UndecideVisibleStateConflictAction actUndecideVisibleState = new UndecideVisibleStateConflictAction();
318 model.addObserver(actUndecideVisibleState);
319 JButton btnUndecideVisibleState = new JButton(actUndecideVisibleState);
320 btnUndecideVisibleState.setName("button.undecidevisiblestate");
321 add(btnUndecideVisibleState, gc);
322 }
323
324 protected void build() {
325 setLayout(new GridBagLayout());
326 buildHeaderRow();
327 buildCoordinateConflictRows();
328 buildDeletedStateConflictRows();
329 buildVisibleStateRows();
330 }
331
332 public PropertiesMerger() {
333 model = new PropertiesMergeModel();
334 model.addObserver(this);
335 build();
336 }
337
338 public String coordToString(LatLon coord) {
339 if (coord == null)
340 return tr("(none)");
341 StringBuilder sb = new StringBuilder();
342 sb.append("(")
343 .append(COORD_FORMATTER.format(coord.lat()))
344 .append(",")
345 .append(COORD_FORMATTER.format(coord.lon()))
346 .append(")");
347 return sb.toString();
348 }
349
350 public String deletedStateToString(Boolean deleted) {
351 if (deleted == null)
352 return tr("(none)");
353 if (deleted)
354 return tr("deleted");
355 else
356 return tr("not deleted");
357 }
358
359 public String visibleStateToString(Boolean visible) {
360 if (visible == null)
361 return tr("(none)");
362 if (visible)
363 return tr("visible (on the server)");
364 else
365 return tr("not visible (on the server)");
366 }
367
368 public String visibleStateToStringMerged(Boolean visible) {
369 if (visible == null)
370 return tr("(none)");
371 if (visible)
372 return tr("Keep a clone of the local version");
373 else
374 return tr("Physically delete from local dataset");
375 }
376
377 protected void updateCoordinates() {
378 lblMyCoordinates.setText(coordToString(model.getMyCoords()));
379 lblMergedCoordinates.setText(coordToString(model.getMergedCoords()));
380 lblTheirCoordinates.setText(coordToString(model.getTheirCoords()));
381 if (! model.hasCoordConflict()) {
382 lblMyCoordinates.setBackground(BGCOLOR_NO_CONFLICT);
383 lblMergedCoordinates.setBackground(BGCOLOR_NO_CONFLICT);
384 lblTheirCoordinates.setBackground(BGCOLOR_NO_CONFLICT);
385 } else {
386 if (!model.isDecidedCoord()) {
387 lblMyCoordinates.setBackground(BGCOLOR_UNDECIDED);
388 lblMergedCoordinates.setBackground(BGCOLOR_NO_CONFLICT);
389 lblTheirCoordinates.setBackground(BGCOLOR_UNDECIDED);
390 } else {
391 lblMyCoordinates.setBackground(
392 model.isCoordMergeDecision(MergeDecisionType.KEEP_MINE)
393 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
394 );
395 lblMergedCoordinates.setBackground(BGCOLOR_DECIDED);
396 lblTheirCoordinates.setBackground(
397 model.isCoordMergeDecision(MergeDecisionType.KEEP_THEIR)
398 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
399 );
400 }
401 }
402 }
403
404 protected void updateDeletedState() {
405 lblMyDeletedState.setText(deletedStateToString(model.getMyDeletedState()));
406 lblMergedDeletedState.setText(deletedStateToString(model.getMergedDeletedState()));
407 lblTheirDeletedState.setText(deletedStateToString(model.getTheirDeletedState()));
408
409 if (! model.hasDeletedStateConflict()) {
410 lblMyDeletedState.setBackground(BGCOLOR_NO_CONFLICT);
411 lblMergedDeletedState.setBackground(BGCOLOR_NO_CONFLICT);
412 lblTheirDeletedState.setBackground(BGCOLOR_NO_CONFLICT);
413 } else {
414 if (!model.isDecidedDeletedState()) {
415 lblMyDeletedState.setBackground(BGCOLOR_UNDECIDED);
416 lblMergedDeletedState.setBackground(BGCOLOR_NO_CONFLICT);
417 lblTheirDeletedState.setBackground(BGCOLOR_UNDECIDED);
418 } else {
419 lblMyDeletedState.setBackground(
420 model.isDeletedStateDecision(MergeDecisionType.KEEP_MINE)
421 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
422 );
423 lblMergedDeletedState.setBackground(BGCOLOR_DECIDED);
424 lblTheirDeletedState.setBackground(
425 model.isDeletedStateDecision(MergeDecisionType.KEEP_THEIR)
426 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
427 );
428 }
429 }
430 }
431
432 protected void updateVisibleState() {
433 lblMyVisibleState.setText(visibleStateToString(model.getMyVisibleState()));
434 lblMergedVisibleState.setText(visibleStateToStringMerged(model.getMergedVisibleState()));
435 lblTheirVisibleState.setText(visibleStateToString(model.getTheirVisibleState()));
436
437 if (! model.hasVisibleStateConflict()) {
438 lblMyVisibleState.setBackground(BGCOLOR_NO_CONFLICT);
439 lblMergedVisibleState.setBackground(BGCOLOR_NO_CONFLICT);
440 lblTheirVisibleState.setBackground(BGCOLOR_NO_CONFLICT);
441 } else {
442 if (!model.isDecidedVisibleState()) {
443 lblMyVisibleState.setBackground(BGCOLOR_UNDECIDED);
444 lblMergedVisibleState.setBackground(BGCOLOR_NO_CONFLICT);
445 lblTheirVisibleState.setBackground(BGCOLOR_UNDECIDED);
446 } else {
447 lblMyVisibleState.setBackground(
448 model.isVisibleStateDecision(MergeDecisionType.KEEP_MINE)
449 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
450 );
451 lblMergedVisibleState.setBackground(BGCOLOR_DECIDED);
452 lblTheirVisibleState.setBackground(
453 model.isVisibleStateDecision(MergeDecisionType.KEEP_THEIR)
454 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
455 );
456 }
457 }
458 }
459
460 public void update(Observable o, Object arg) {
461 updateCoordinates();
462 updateDeletedState();
463 updateVisibleState();
464 }
465
466 public PropertiesMergeModel getModel() {
467 return model;
468 }
469
470 class KeepMyCoordinatesAction extends AbstractAction implements Observer {
471 public KeepMyCoordinatesAction() {
472 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeepmine"));
473 putValue(Action.SHORT_DESCRIPTION, tr("Keep my coordiates"));
474 }
475
476 public void actionPerformed(ActionEvent e) {
477 model.decideCoordsConflict(MergeDecisionType.KEEP_MINE);
478 }
479
480 public void update(Observable o, Object arg) {
481 setEnabled(model.hasCoordConflict() && ! model.isDecidedCoord());
482 }
483 }
484
485 class KeepTheirCoordinatesAction extends AbstractAction implements Observer {
486 public KeepTheirCoordinatesAction() {
487 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeeptheir"));
488 putValue(Action.SHORT_DESCRIPTION, tr("Keep their coordiates"));
489 }
490
491 public void actionPerformed(ActionEvent e) {
492 model.decideCoordsConflict(MergeDecisionType.KEEP_THEIR);
493 }
494
495 public void update(Observable o, Object arg) {
496 setEnabled(model.hasCoordConflict() && ! model.isDecidedCoord());
497 }
498 }
499
500 class UndecideCoordinateConflictAction extends AbstractAction implements Observer {
501 public UndecideCoordinateConflictAction() {
502 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagundecide"));
503 putValue(Action.SHORT_DESCRIPTION, tr("Undecide conflict between different coordinates"));
504 }
505
506 public void actionPerformed(ActionEvent e) {
507 model.decideCoordsConflict(MergeDecisionType.UNDECIDED);
508 }
509
510 public void update(Observable o, Object arg) {
511 setEnabled(model.hasCoordConflict() && model.isDecidedCoord());
512 }
513 }
514
515 class KeepMyDeletedStateAction extends AbstractAction implements Observer {
516 public KeepMyDeletedStateAction() {
517 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeepmine"));
518 putValue(Action.SHORT_DESCRIPTION, tr("Keep my deleted state"));
519 }
520
521 public void actionPerformed(ActionEvent e) {
522 model.decideDeletedStateConflict(MergeDecisionType.KEEP_MINE);
523 }
524
525 public void update(Observable o, Object arg) {
526 setEnabled(model.hasDeletedStateConflict() && ! model.isDecidedDeletedState());
527 }
528 }
529
530 class KeepTheirDeletedStateAction extends AbstractAction implements Observer {
531 public KeepTheirDeletedStateAction() {
532 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeeptheir"));
533 putValue(Action.SHORT_DESCRIPTION, tr("Keep their deleted state"));
534 }
535
536 public void actionPerformed(ActionEvent e) {
537 model.decideDeletedStateConflict(MergeDecisionType.KEEP_THEIR);
538 }
539
540 public void update(Observable o, Object arg) {
541 setEnabled(model.hasDeletedStateConflict() && ! model.isDecidedDeletedState());
542 }
543 }
544
545 class UndecideDeletedStateConflictAction extends AbstractAction implements Observer {
546 public UndecideDeletedStateConflictAction() {
547 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagundecide"));
548 putValue(Action.SHORT_DESCRIPTION, tr("Undecide conflict between deleted state"));
549 }
550
551 public void actionPerformed(ActionEvent e) {
552 model.decideDeletedStateConflict(MergeDecisionType.UNDECIDED);
553 }
554
555 public void update(Observable o, Object arg) {
556 setEnabled(model.hasDeletedStateConflict() && model.isDecidedDeletedState());
557 }
558 }
559
560 class KeepMyVisibleStateAction extends AbstractAction implements Observer {
561 public KeepMyVisibleStateAction() {
562 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeepmine"));
563 putValue(Action.SHORT_DESCRIPTION, tr("Keep my visible state"));
564 }
565
566 public void actionPerformed(ActionEvent e) {
567 if (confirmKeepMine()) {
568 model.decideVisibleStateConflict(MergeDecisionType.KEEP_MINE);
569 }
570 }
571
572 public void update(Observable o, Object arg) {
573 setEnabled(model.hasVisibleStateConflict() && ! model.isDecidedVisibleState());
574 }
575
576 protected boolean confirmKeepMine() {
577 String [] options = {
578 tr("Yes, reset the id"),
579 tr("No, abort")
580 };
581 int ret = JOptionPane.showOptionDialog(
582 null,
583 tr("<html>To keep your local version, JOSM<br>"
584 + "has to reset the id of primitive {0} to 0.<br>"
585 + "On the next upload the server will assign<br>"
586 + "it a new id.<br>"
587 + "Do yo agree?</html>",
588 model.getMyPrimitive().getId()
589 ),
590 tr("Reset id to 0"),
591 JOptionPane.YES_NO_OPTION,
592 JOptionPane.QUESTION_MESSAGE,
593 null,
594 options,
595 options[1]
596 );
597 return ret == JOptionPane.YES_OPTION;
598 }
599 }
600
601 class KeepTheirVisibleStateAction extends AbstractAction implements Observer {
602 public KeepTheirVisibleStateAction() {
603 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeeptheir"));
604 putValue(Action.SHORT_DESCRIPTION, tr("Keep their visible state"));
605 }
606
607 public void actionPerformed(ActionEvent e) {
608 if (confirmKeepTheir()){
609 model.decideVisibleStateConflict(MergeDecisionType.KEEP_THEIR);
610 }
611 }
612
613 public void update(Observable o, Object arg) {
614 setEnabled(model.hasVisibleStateConflict() && ! model.isDecidedVisibleState());
615 }
616
617 protected boolean confirmKeepTheir() {
618 String [] options = {
619 tr("Yes, purge it"),
620 tr("No, abort")
621 };
622 int ret = JOptionPane.showOptionDialog(
623 null,
624 tr("<html>JOSM will have to remove your local primitive with id {0}<br>"
625 + "from the dataset.<br>"
626 + "Do you agree?</html>",
627 model.getMyPrimitive().getId()
628 ),
629 tr("Remove from dataset"),
630 JOptionPane.YES_NO_OPTION,
631 JOptionPane.QUESTION_MESSAGE,
632 null,
633 options,
634 options[1]
635 );
636 return ret == JOptionPane.YES_OPTION;
637 }
638 }
639
640 class UndecideVisibleStateConflictAction extends AbstractAction implements Observer {
641 public UndecideVisibleStateConflictAction() {
642 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagundecide"));
643 putValue(Action.SHORT_DESCRIPTION, tr("Undecide conflict between visible state"));
644 }
645
646 public void actionPerformed(ActionEvent e) {
647 model.decideVisibleStateConflict(MergeDecisionType.UNDECIDED);
648 }
649
650 public void update(Observable o, Object arg) {
651 setEnabled(model.hasVisibleStateConflict() && model.isDecidedVisibleState());
652 }
653 }
654}
Note: See TracBrowser for help on using the repository browser.