Changeset 3362 in josm for trunk/src/org
- Timestamp:
- 2010-07-03T22:08:57+02:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/command/PurgePrimitivesCommand.java
r3335 r3362 40 40 * 41 41 */ 42 @Deprecated 42 43 public class PurgePrimitivesCommand extends ConflictResolveCommand{ 43 44 -
trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java
r3262 r3362 26 26 * 27 27 */ 28 @Deprecated 28 29 public class UndeletePrimitivesCommand extends ConflictResolveCommand { 29 30 //static private final Logger logger = Logger.getLogger(UndeletePrimitivesCommand.class.getName()); -
trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java
r3262 r3362 51 51 super.executeCommand(); 52 52 if (!conflict.getMy().isNew()) { 53 long myVersion = conflict.getMy().getVersion(); 54 long theirVersion = conflict.getTheir().getVersion(); 53 55 conflict.getMy().setOsmId( 54 56 conflict.getMy().getId(), 55 (int)Math.max( conflict.getMy().getVersion(), conflict.getTheir().getVersion())57 (int)Math.max(myVersion, theirVersion) 56 58 ); 59 // update visiblity state 60 if (theirVersion >= myVersion) { 61 conflict.getMy().setVisible(conflict.getTheir().isVisible()); 62 } 57 63 } 58 64 getLayer().getConflicts().remove(conflict); -
trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
r3348 r3362 997 997 } 998 998 } 999 1000 /** 1001 * Marks all "invisible" objects as deleted. These objects should be always marked as 1002 * deleted when downloaded from the server. They can be undeleted later if necessary. 1003 * 1004 */ 1005 public void deleteInvisible() { 1006 for (OsmPrimitive primitive:allPrimitives) { 1007 if (!primitive.isVisible()) { 1008 primitive.setDeleted(true); 1009 } 1010 } 1011 } 999 1012 } -
trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java
r3336 r3362 11 11 import java.util.Map; 12 12 import java.util.Set; 13 import java.util.logging.Logger;14 13 15 14 import org.openstreetmap.josm.data.conflict.Conflict; … … 23 22 */ 24 23 public class DataSetMerger { 25 private static Logger logger = Logger.getLogger(DataSetMerger.class.getName());26 24 27 25 /** the collection of conflicts created during merging */ … … 244 242 // target.version > source.version => keep target version 245 243 return true; 246 if (! target.isVisible() && source.isVisible() && target.getVersion() == source.getVersion()) { 247 // should not happen 248 conflicts.add(target,source); 249 } else if (target.isVisible() && ! source.isVisible()) { 250 // this is always a conflict because the user has to decide whether 251 // he wants to create a clone of its target primitive or whether he 252 // wants to purge the target from the local dataset. He can't keep it unchanged 253 // because it was deleted on the server. 254 // 255 conflicts.add(target,source); 256 } else if (target.isIncomplete() && !source.isIncomplete()) { 244 245 if (target.isIncomplete() && !source.isIncomplete()) { 257 246 // target is incomplete, source completes it 258 247 // => merge source into target -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/ConflictResolver.java
r3083 r3362 26 26 import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListMergeModel; 27 27 import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListMerger; 28 import org.openstreetmap.josm.gui.conflict.pair.properties.OperationCancelledException;29 28 import org.openstreetmap.josm.gui.conflict.pair.properties.PropertiesMergeModel; 30 29 import org.openstreetmap.josm.gui.conflict.pair.properties.PropertiesMerger; … … 235 234 this.conflict = conflict; 236 235 propertiesMerger.populate(conflict); 237 if (propertiesMerger.getModel().hasVisibleStateConflict()) { 238 tabbedPane.setEnabledAt(1, false); 239 tabbedPane.setEnabledAt(2, false); 240 tabbedPane.setEnabledAt(3, false); 241 return; 242 } 236 243 237 tabbedPane.setEnabledAt(0, true); 244 238 tagMerger.populate(conflict); … … 270 264 * @return the resolution command 271 265 */ 272 public Command buildResolveCommand() throws OperationCancelledException{266 public Command buildResolveCommand() { 273 267 ArrayList<Command> commands = new ArrayList<Command>(); 274 if (propertiesMerger.getModel().hasVisibleStateConflict()) { 275 if (propertiesMerger.getModel().isDecidedVisibleState()) { 276 commands.addAll(propertiesMerger.getModel().buildResolveCommand(conflict)); 277 } 278 } else { 279 if (tagMerger.getModel().getNumResolvedConflicts() > 0) { 280 commands.add(tagMerger.getModel().buildResolveCommand(conflict)); 281 } 282 commands.addAll(propertiesMerger.getModel().buildResolveCommand(conflict)); 283 if (my instanceof Way && nodeListMerger.getModel().isFrozen()) { 284 NodeListMergeModel model =(NodeListMergeModel)nodeListMerger.getModel(); 285 commands.add(model.buildResolveCommand(conflict)); 286 } else if (my instanceof Relation && relationMemberMerger.getModel().isFrozen()) { 287 RelationMemberListMergeModel model =(RelationMemberListMergeModel)relationMemberMerger.getModel(); 288 commands.add(model.buildResolveCommand((Relation)my, (Relation)their)); 289 } 290 if (isResolvedCompletely()) { 291 commands.add(new VersionConflictResolveCommand(conflict)); 292 commands.add(new ModifiedConflictResolveCommand(conflict)); 293 } 268 269 if (tagMerger.getModel().getNumResolvedConflicts() > 0) { 270 commands.add(tagMerger.getModel().buildResolveCommand(conflict)); 271 } 272 commands.addAll(propertiesMerger.getModel().buildResolveCommand(conflict)); 273 if (my instanceof Way && nodeListMerger.getModel().isFrozen()) { 274 NodeListMergeModel model = (NodeListMergeModel) nodeListMerger.getModel(); 275 commands.add(model.buildResolveCommand(conflict)); 276 } else if (my instanceof Relation && relationMemberMerger.getModel().isFrozen()) { 277 RelationMemberListMergeModel model = (RelationMemberListMergeModel) relationMemberMerger.getModel(); 278 commands.add(model.buildResolveCommand((Relation) my, (Relation) their)); 279 } 280 if (isResolvedCompletely()) { 281 commands.add(new VersionConflictResolveCommand(conflict)); 282 commands.add(new ModifiedConflictResolveCommand(conflict)); 294 283 } 295 284 return new SequenceCommand(tr("Conflict Resolution"), commands); -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMergeModel.java
r3083 r3362 3 3 4 4 import static org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType.UNDECIDED; 5 import static org.openstreetmap.josm.tools.I18n.tr;6 import static org.openstreetmap.josm.tools.I18n.trn;7 5 8 6 import java.beans.PropertyChangeListener; … … 10 8 import java.util.ArrayList; 11 9 import java.util.Collections; 12 import java.util.HashMap;13 10 import java.util.List; 14 11 import java.util.Observable; 15 12 16 import javax.swing.JOptionPane;17 18 import org.openstreetmap.josm.Main;19 13 import org.openstreetmap.josm.command.Command; 20 14 import org.openstreetmap.josm.command.CoordinateConflictResolveCommand; 21 15 import org.openstreetmap.josm.command.DeletedStateConflictResolveCommand; 22 import org.openstreetmap.josm.command.PurgePrimitivesCommand;23 import org.openstreetmap.josm.command.UndeletePrimitivesCommand;24 16 import org.openstreetmap.josm.data.conflict.Conflict; 25 17 import org.openstreetmap.josm.data.coor.LatLon; 26 import org.openstreetmap.josm.data.osm.DataSet;27 18 import org.openstreetmap.josm.data.osm.Node; 28 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; 29 import org.openstreetmap.josm.data.osm.Relation;30 import org.openstreetmap.josm.data.osm.RelationMember;31 import org.openstreetmap.josm.data.osm.Way;32 20 import org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType; 33 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;34 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;35 import org.openstreetmap.josm.io.OsmTransferException;36 21 import org.openstreetmap.josm.tools.CheckParameterUtil; 37 22 … … 65 50 private boolean myDeletedState; 66 51 private boolean theirDeletedState; 67 private boolean myVisibleState;68 private boolean theirVisibleState;69 52 private List<OsmPrimitive> myReferrers; 70 53 private List<OsmPrimitive> theirReferrers; 71 54 private MergeDecisionType deletedMergeDecision; 72 private MergeDecisionType visibleMergeDecision;73 55 private final PropertyChangeSupport support; 74 56 private boolean resolvedCompletely; … … 118 100 119 101 /** 120 * replies true if there is a conflict in the visible state and if this conflict is121 * resolved122 *123 * @return true if there is a conflict in the visible state and if this conflict is124 * resolved; false, otherwise125 */126 public boolean isDecidedVisibleState() {127 return ! visibleMergeDecision.equals(UNDECIDED);128 }129 130 /**131 102 * replies true if the current decision for the coordinate conflict is <code>decision</code> 132 103 * … … 148 119 } 149 120 150 /**151 * replies true if the current decision for the visible state conflict is <code>decision</code>152 *153 * @return true if the current decision for the visible state conflict is <code>decision</code>;154 * false, otherwise155 */156 public boolean isVisibleStateDecision(MergeDecisionType decision) {157 return visibleMergeDecision.equals(decision);158 }159 121 /** 160 122 * populates the model with the differences between my and their version … … 177 139 theirDeletedState = their.isDeleted(); 178 140 179 myVisibleState = my.isVisible();180 theirVisibleState = their.isVisible();181 182 141 myReferrers = my.getDataSet() == null?Collections.<OsmPrimitive>emptyList():my.getReferrers(); 183 142 theirReferrers = their.getDataSet() == null?Collections.<OsmPrimitive>emptyList():their.getReferrers(); … … 185 144 coordMergeDecision = UNDECIDED; 186 145 deletedMergeDecision = UNDECIDED; 187 visibleMergeDecision = UNDECIDED;188 146 setChanged(); 189 147 notifyObservers(); … … 265 223 266 224 /** 267 * replies my visible state,268 * @return my visible state269 */270 public Boolean getMyVisibleState() {271 return myVisibleState;272 }273 274 /**275 * replies their visible state,276 * @return their visible state277 */278 public Boolean getTheirVisibleState() {279 return theirVisibleState;280 }281 282 /**283 225 * returns my referrers, 284 226 * @return my referrers … … 294 236 public List<OsmPrimitive> getTheirReferrers() { 295 237 return theirReferrers; 296 }297 298 /**299 * replies the merged visible state; null, if the merge decision is300 * {@see MergeDecisionType#UNDECIDED}.301 *302 * @return the merged visible state303 */304 public Boolean getMergedVisibleState() {305 switch(visibleMergeDecision) {306 case KEEP_MINE: return myVisibleState;307 case KEEP_THEIR: return theirVisibleState;308 case UNDECIDED: return null;309 }310 // should not happen311 return null;312 238 } 313 239 … … 346 272 347 273 /** 348 * decides the conflict between two visible states349 * @param decision the decision (must not be null)350 *351 * @throws IllegalArgumentException thrown, if decision is null352 */353 public void decideVisibleStateConflict(MergeDecisionType decision) throws IllegalArgumentException {354 CheckParameterUtil.ensureParameterNotNull(decision, "decision");355 this.visibleMergeDecision = decision;356 setChanged();357 notifyObservers();358 fireCompletelyResolved();359 }360 361 /**362 274 * replies true if my and their primitive have a conflict between 363 275 * their coordinate values … … 385 297 386 298 /** 387 * replies true if my and their primitive have a conflict between388 * their visible states389 *390 * @return true if my and their primitive have a conflict between391 * their visible states392 */393 public boolean hasVisibleStateConflict() {394 return myVisibleState != theirVisibleState;395 }396 397 /**398 299 * replies true if all conflict in this model are resolved 399 300 * … … 408 309 ret = ret && ! deletedMergeDecision.equals(UNDECIDED); 409 310 } 410 if (hasVisibleStateConflict()) {411 ret = ret && ! visibleMergeDecision.equals(UNDECIDED);412 }413 311 return ret; 414 312 } … … 421 319 * @return the list of commands 422 320 */ 423 public List<Command> buildResolveCommand(Conflict<? extends OsmPrimitive> conflict) throws OperationCancelledException{ 424 OsmPrimitive my = conflict.getMy(); 321 public List<Command> buildResolveCommand(Conflict<? extends OsmPrimitive> conflict) { 425 322 List<Command> cmds = new ArrayList<Command>(); 426 if (hasVisibleStateConflict() && isDecidedVisibleState()) {427 if (isVisibleStateDecision(MergeDecisionType.KEEP_MINE)) {428 try {429 UndeletePrimitivesCommand cmd = createUndeletePrimitiveCommand(my);430 if (cmd == null)431 throw new OperationCancelledException();432 cmds.add(cmd);433 } catch(OsmTransferException e) {434 handleExceptionWhileBuildingCommand(e);435 throw new OperationCancelledException(e);436 }437 } else if (isVisibleStateDecision(MergeDecisionType.KEEP_THEIR)) {438 cmds.add(new PurgePrimitivesCommand(my));439 }440 }441 323 if (hasCoordConflict() && isDecidedCoord()) { 442 324 cmds.add(new CoordinateConflictResolveCommand(conflict, coordMergeDecision)); … … 452 334 } 453 335 454 /**455 *456 * @param id457 */458 protected void handleExceptionWhileBuildingCommand(Exception e) {459 e.printStackTrace();460 String msg = e.getMessage() != null ? e.getMessage() : e.toString();461 msg = msg.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");462 JOptionPane.showMessageDialog(463 Main.parent,464 tr("<html>An error occurred while communicating with the server<br>"465 + "Details: {0}</html>",466 msg467 ),468 tr("Communication with server failed"),469 JOptionPane.ERROR_MESSAGE470 );471 }472 473 /**474 * User has decided to keep his local version of a primitive which had been deleted475 * on the server476 *477 * @param id the primitive id478 */479 protected UndeletePrimitivesCommand createUndeletePrimitiveCommand(OsmPrimitive my) throws OsmTransferException {480 if (my instanceof Node)481 return createUndeleteNodeCommand((Node)my);482 else if (my instanceof Way)483 return createUndeleteWayCommand((Way)my);484 else if (my instanceof Relation)485 return createUndeleteRelationCommand((Relation)my);486 return null;487 }488 /**489 * Undelete a node which is already deleted on the server. The API490 * doesn't offer a call for "undeleting" a node. We therefore create491 * a clone of the node which we flag as new. On the next upload the492 * server will assign the node a new id.493 *494 * @param node the node to undelete495 */496 protected UndeletePrimitivesCommand createUndeleteNodeCommand(Node node) {497 return new UndeletePrimitivesCommand(node);498 }499 500 /**501 * displays a confirmation message. The user has to confirm that additional dependent502 * nodes should be undeleted too.503 *504 * @param way the way505 * @param dependent a list of dependent nodes which have to be undelete too506 * @return true, if the user confirms; false, otherwise507 */508 protected boolean confirmUndeleteDependentPrimitives(Way way, ArrayList<OsmPrimitive> dependent) {509 String [] options = {510 tr("Yes, undelete them too"),511 tr("No, cancel operation")512 };513 int ret = JOptionPane.showOptionDialog(514 Main.parent,515 "<html>" + trn("There is {0} additional node used by way {1}<br>"516 + "which is deleted on the server."517 + "<br><br>"518 + "Do you want to undelete this node too?",519 "There are {0} additional nodes used by way {1}<br>"520 + "which are deleted on the server."521 + "<br><br>"522 + "Do you want to undelete these nodes too?",523 dependent.size(), dependent.size(), way.getId())524 + "</html>",525 tr("Undelete additional nodes?"),526 JOptionPane.YES_NO_OPTION,527 JOptionPane.QUESTION_MESSAGE,528 null,529 options,530 options[0]531 );532 533 switch(ret) {534 case JOptionPane.CLOSED_OPTION: return false;535 case JOptionPane.YES_OPTION: return true;536 case JOptionPane.NO_OPTION: return false;537 }538 return false;539 540 }541 542 protected boolean confirmUndeleteDependentPrimitives(Relation r, ArrayList<OsmPrimitive> dependent) {543 String [] options = {544 tr("Yes, undelete them too"),545 tr("No, cancel operation")546 };547 int ret = JOptionPane.showOptionDialog(548 Main.parent,549 "<html>" + trn("There is {0} additional primitive referred to by relation {1}<br>"550 + "which is deleted on the server."551 + "<br><br>"552 + "Do you want to undelete this too?",553 "There are {0} additional primitives referred to by relation {1}<br>"554 + "which are deleted on the server."555 + "<br><br>"556 + "Do you want to undelete these too?",557 dependent.size(), dependent.size(), r.getId())558 + "</html>",559 tr("Undelete dependent primitives?"),560 JOptionPane.YES_NO_OPTION,561 JOptionPane.QUESTION_MESSAGE,562 null,563 options,564 options[0]565 );566 567 switch(ret) {568 case JOptionPane.CLOSED_OPTION: return false;569 case JOptionPane.YES_OPTION: return true;570 case JOptionPane.NO_OPTION: return false;571 }572 return false;573 574 }575 576 /**577 * Creates the undelete command for a way which is already deleted on the server.578 *579 * This method also checks whether there are additional nodes referred to by580 * this way which are deleted on the server too.581 *582 * @param way the way to undelete583 * @return the undelete command584 * @see #createUndeleteNodeCommand(Node)585 */586 protected UndeletePrimitivesCommand createUndeleteWayCommand(final Way way) throws OsmTransferException {587 588 HashMap<Long,OsmPrimitive> candidates = new HashMap<Long,OsmPrimitive>();589 for (Node n : way.getNodes()) {590 if (!n.isNew() && !candidates.values().contains(n)) {591 candidates.put(n.getId(), n);592 }593 }594 MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();595 reader.append(candidates.values());596 DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);597 598 ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>();599 for (OsmPrimitive their : ds.allPrimitives()) {600 if (candidates.keySet().contains(their.getId()) && ! their.isVisible()) {601 toDelete.add(candidates.get(their.getId()));602 }603 }604 if (!toDelete.isEmpty()) {605 if (! confirmUndeleteDependentPrimitives(way, toDelete))606 // FIXME: throw exception ?607 return null;608 }609 toDelete.add(way);610 return new UndeletePrimitivesCommand(toDelete);611 }612 613 /**614 * Creates an undelete command for a relation which is already deleted on the server.615 *616 * This method checks whether there are additional primitives referred to by617 * this relation which are already deleted on the server.618 *619 * @param r the relation620 * @return the undelete command621 * @see #createUndeleteNodeCommand(Node)622 */623 protected UndeletePrimitivesCommand createUndeleteRelationCommand(final Relation r) throws OsmTransferException {624 625 HashMap<Long,OsmPrimitive> candidates = new HashMap<Long, OsmPrimitive>();626 for (RelationMember m : r.getMembers()) {627 if (!m.getMember().isNew() && !candidates.values().contains(m.getMember())) {628 candidates.put(m.getMember().getId(), m.getMember());629 }630 }631 632 MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();633 reader.append(candidates.values());634 DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);635 636 ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>();637 for (OsmPrimitive their : ds.allPrimitives()) {638 if (candidates.keySet().contains(their.getId()) && ! their.isVisible()) {639 toDelete.add(candidates.get(their.getId()));640 }641 }642 if (!toDelete.isEmpty()) {643 if (! confirmUndeleteDependentPrimitives(r, toDelete))644 // FIXME: throw exception ?645 return null;646 }647 toDelete.add(r);648 return new UndeletePrimitivesCommand(toDelete);649 }650 651 336 } -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMerger.java
r3218 r3362 19 19 import javax.swing.JButton; 20 20 import javax.swing.JLabel; 21 import javax.swing.JOptionPane;22 21 import javax.swing.JPanel; 23 22 … … 54 53 private JLabel lblTheirDeletedState; 55 54 56 private JLabel lblMyVisibleState;57 private JLabel lblMergedVisibleState;58 private JLabel lblTheirVisibleState;59 60 55 private JLabel lblMyReferrers; 61 56 private JLabel lblTheirReferrers; … … 251 246 } 252 247 253 protected void buildVisibleStateRows() {254 GridBagConstraints gc = new GridBagConstraints();255 256 gc.gridx = 0;257 gc.gridy = 5;258 gc.gridwidth = 1;259 gc.gridheight = 1;260 gc.fill = GridBagConstraints.BOTH;261 gc.anchor = GridBagConstraints.LINE_START;262 gc.weightx = 0.0;263 gc.weighty = 0.0;264 gc.insets = new Insets(0,5,0,5);265 add(new JLabel(tr("Visible State:")), gc);266 267 gc.gridx = 1;268 gc.gridy = 5;269 gc.fill = GridBagConstraints.BOTH;270 gc.anchor = GridBagConstraints.CENTER;271 gc.weightx = 0.33;272 gc.weighty = 0.0;273 add(lblMyVisibleState = buildValueLabel("label.myvisiblestate"), gc);274 275 gc.gridx = 2;276 gc.gridy = 5;277 gc.fill = GridBagConstraints.NONE;278 gc.anchor = GridBagConstraints.CENTER;279 gc.weightx = 0.0;280 gc.weighty = 0.0;281 KeepMyVisibleStateAction actKeepMyVisibleState = new KeepMyVisibleStateAction();282 model.addObserver(actKeepMyVisibleState);283 JButton btnKeepMyVisibleState = new JButton(actKeepMyVisibleState);284 btnKeepMyVisibleState.setName("button.keepmyvisiblestate");285 add(btnKeepMyVisibleState, gc);286 287 gc.gridx = 3;288 gc.gridy = 5;289 gc.fill = GridBagConstraints.BOTH;290 gc.anchor = GridBagConstraints.CENTER;291 gc.weightx = 0.33;292 gc.weighty = 0.0;293 add(lblMergedVisibleState = buildValueLabel("label.mergedvisiblestate"), gc);294 295 gc.gridx = 4;296 gc.gridy = 5;297 gc.fill = GridBagConstraints.NONE;298 gc.anchor = GridBagConstraints.CENTER;299 gc.weightx = 0.0;300 gc.weighty = 0.0;301 KeepTheirVisibleStateAction actKeepTheirVisibleState = new KeepTheirVisibleStateAction();302 model.addObserver(actKeepTheirVisibleState);303 JButton btnKeepTheirVisibleState = new JButton(actKeepTheirVisibleState);304 btnKeepTheirVisibleState.setName("button.keeptheirvisiblestate");305 add(btnKeepTheirVisibleState, gc);306 307 gc.gridx = 5;308 gc.gridy = 5;309 gc.fill = GridBagConstraints.BOTH;310 gc.anchor = GridBagConstraints.CENTER;311 gc.weightx = 0.33;312 gc.weighty = 0.0;313 add(lblTheirVisibleState = buildValueLabel("label.theirvisiblestate"), gc);314 315 // ---------------------------------------------------316 gc.gridx = 3;317 gc.gridy = 6;318 gc.fill = GridBagConstraints.NONE;319 gc.anchor = GridBagConstraints.CENTER;320 gc.weightx = 0.0;321 gc.weighty = 0.0;322 UndecideVisibleStateConflictAction actUndecideVisibleState = new UndecideVisibleStateConflictAction();323 model.addObserver(actUndecideVisibleState);324 JButton btnUndecideVisibleState = new JButton(actUndecideVisibleState);325 btnUndecideVisibleState.setName("button.undecidevisiblestate");326 add(btnUndecideVisibleState, gc);327 }328 329 248 protected void buildReferrersRow() { 330 249 GridBagConstraints gc = new GridBagConstraints(); … … 363 282 buildCoordinateConflictRows(); 364 283 buildDeletedStateConflictRows(); 365 buildVisibleStateRows();366 284 buildReferrersRow(); 367 285 } … … 392 310 else 393 311 return tr("not deleted"); 394 }395 396 public String visibleStateToString(Boolean visible) {397 if (visible == null)398 return tr("(none)");399 if (visible)400 return tr("visible (on the server)");401 else402 return tr("not visible (on the server)");403 }404 405 public String visibleStateToStringMerged(Boolean visible) {406 if (visible == null)407 return tr("(none)");408 if (visible)409 return tr("Keep a clone of the local version");410 else411 return tr("Physically delete from local dataset");412 312 } 413 313 … … 478 378 } 479 379 480 protected void updateVisibleState() {481 lblMyVisibleState.setText(visibleStateToString(model.getMyVisibleState()));482 lblMergedVisibleState.setText(visibleStateToStringMerged(model.getMergedVisibleState()));483 lblTheirVisibleState.setText(visibleStateToString(model.getTheirVisibleState()));484 485 if (! model.hasVisibleStateConflict()) {486 lblMyVisibleState.setBackground(BGCOLOR_NO_CONFLICT);487 lblMergedVisibleState.setBackground(BGCOLOR_NO_CONFLICT);488 lblTheirVisibleState.setBackground(BGCOLOR_NO_CONFLICT);489 } else {490 if (!model.isDecidedVisibleState()) {491 lblMyVisibleState.setBackground(BGCOLOR_UNDECIDED);492 lblMergedVisibleState.setBackground(BGCOLOR_NO_CONFLICT);493 lblTheirVisibleState.setBackground(BGCOLOR_UNDECIDED);494 } else {495 lblMyVisibleState.setBackground(496 model.isVisibleStateDecision(MergeDecisionType.KEEP_MINE)497 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT498 );499 lblMergedVisibleState.setBackground(BGCOLOR_DECIDED);500 lblTheirVisibleState.setBackground(501 model.isVisibleStateDecision(MergeDecisionType.KEEP_THEIR)502 ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT503 );504 }505 }506 }507 508 380 protected void updateReferrers() { 509 381 lblMyReferrers.setText(referrersToString(model.getMyReferrers())); … … 516 388 updateCoordinates(); 517 389 updateDeletedState(); 518 updateVisibleState();519 390 updateReferrers(); 520 391 } … … 611 482 public void update(Observable o, Object arg) { 612 483 setEnabled(model.hasDeletedStateConflict() && model.isDecidedDeletedState()); 613 }614 }615 616 class KeepMyVisibleStateAction extends AbstractAction implements Observer {617 public KeepMyVisibleStateAction() {618 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeepmine"));619 putValue(Action.SHORT_DESCRIPTION, tr("Keep my visible state"));620 }621 622 public void actionPerformed(ActionEvent e) {623 if (confirmKeepMine()) {624 model.decideVisibleStateConflict(MergeDecisionType.KEEP_MINE);625 }626 }627 628 public void update(Observable o, Object arg) {629 setEnabled(model.hasVisibleStateConflict() && ! model.isDecidedVisibleState());630 }631 632 protected boolean confirmKeepMine() {633 String [] options = {634 tr("Yes, reset the id"),635 tr("No, abort")636 };637 int ret = JOptionPane.showOptionDialog(638 null,639 tr("<html>To keep your local version, JOSM<br>"640 + "has to reset the id of primitive {0} to 0.<br>"641 + "On the next upload the server will assign<br>"642 + "it a new id.<br>"643 + "Do you agree?</html>",644 model.getMyPrimitive().getId()645 ),646 tr("Reset id to 0"),647 JOptionPane.YES_NO_OPTION,648 JOptionPane.QUESTION_MESSAGE,649 null,650 options,651 options[1]652 );653 return ret == JOptionPane.YES_OPTION;654 }655 }656 657 class KeepTheirVisibleStateAction extends AbstractAction implements Observer {658 public KeepTheirVisibleStateAction() {659 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagkeeptheir"));660 putValue(Action.SHORT_DESCRIPTION, tr("Keep their visible state"));661 }662 663 public void actionPerformed(ActionEvent e) {664 if (confirmKeepTheir()){665 model.decideVisibleStateConflict(MergeDecisionType.KEEP_THEIR);666 }667 }668 669 public void update(Observable o, Object arg) {670 setEnabled(model.hasVisibleStateConflict() && ! model.isDecidedVisibleState());671 }672 673 protected boolean confirmKeepTheir() {674 String [] options = {675 tr("Yes, purge it"),676 tr("No, abort")677 };678 int ret = JOptionPane.showOptionDialog(679 null,680 tr("<html>JOSM will have to remove your local primitive with id {0}<br>"681 + "from the dataset.<br>"682 + "Do you agree?</html>",683 model.getMyPrimitive().getId()684 ),685 tr("Remove from dataset"),686 JOptionPane.YES_NO_OPTION,687 JOptionPane.QUESTION_MESSAGE,688 null,689 options,690 options[1]691 );692 return ret == JOptionPane.YES_OPTION;693 }694 }695 696 class UndecideVisibleStateConflictAction extends AbstractAction implements Observer {697 public UndecideVisibleStateConflictAction() {698 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs/conflict", "tagundecide"));699 putValue(Action.SHORT_DESCRIPTION, tr("Undecide conflict between visible state"));700 }701 702 public void actionPerformed(ActionEvent e) {703 model.decideVisibleStateConflict(MergeDecisionType.UNDECIDED);704 }705 706 public void update(Observable o, Object arg) {707 setEnabled(model.hasVisibleStateConflict() && model.isDecidedVisibleState());708 484 } 709 485 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java
r3083 r3362 28 28 import org.openstreetmap.josm.gui.DefaultNameFormatter; 29 29 import org.openstreetmap.josm.gui.conflict.pair.ConflictResolver; 30 import org.openstreetmap.josm.gui.conflict.pair.properties.OperationCancelledException;31 30 import org.openstreetmap.josm.gui.help.HelpBrowser; 32 31 import org.openstreetmap.josm.gui.help.HelpUtil; … … 262 261 } 263 262 } 264 try { 265 Command cmd = resolver.buildResolveCommand(); 266 Main.main.undoRedo.add(cmd); 267 closeDialog(); 268 } catch(OperationCancelledException e) { 269 // do nothing. Exception already reported 270 } 263 Command cmd = resolver.buildResolveCommand(); 264 Main.main.undoRedo.add(cmd); 265 closeDialog(); 271 266 } 272 267 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java
r3102 r3362 121 121 if (dataSet == null) 122 122 return; 123 dataSet.deleteInvisible(); 123 124 synchronized (this) { 124 125 if (cancelled) return; -
trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
r3245 r3362 39 39 import org.openstreetmap.josm.Main; 40 40 import org.openstreetmap.josm.actions.RenameLayerAction; 41 import org.openstreetmap.josm.command.PurgePrimitivesCommand;42 41 import org.openstreetmap.josm.data.Bounds; 43 42 import org.openstreetmap.josm.data.SelectionChangedListener; … … 326 325 } 327 326 } 328 PurgePrimitivesCommand cmd = buildPurgeCommand();329 if (cmd != null) {330 Main.main.undoRedo.add(cmd);331 }332 327 // repaint to make sure new data is displayed properly. 333 328 Main.map.mapView.repaint(); 334 warnNumNewConflicts( 335 numNewConflicts, 336 cmd == null ? 0 : cmd.getPurgedPrimitives().size() 337 ); 329 warnNumNewConflicts(numNewConflicts); 338 330 } 339 331 … … 342 334 * 343 335 * @param numNewConflicts the number of detected conflicts 344 * @param numPurgedPrimitives the number of automatically purged objects 345 */ 346 protected void warnNumNewConflicts(int numNewConflicts, int numPurgedPrimitives) { 347 if (numNewConflicts == 0 && numPurgedPrimitives == 0) return; 336 */ 337 protected void warnNumNewConflicts(int numNewConflicts) { 338 if (numNewConflicts == 0) return; 348 339 349 340 String msg1 = trn( … … 353 344 numNewConflicts 354 345 ); 355 String msg2 = trn(356 "{0} conflict has been <strong>resolved automatically</strong> by purging {0} object<br>from the local dataset because it is deleted on the server.",357 "{0} conflicts have been <strong>resolved automatically</strong> by purging {0} objects<br> from the local dataset because they are deleted on the server.",358 numPurgedPrimitives,359 numPurgedPrimitives360 );361 int numRemainingConflicts = numNewConflicts - numPurgedPrimitives;362 String msg3 = "";363 if (numRemainingConflicts >0) {364 msg3 = trn(365 "{0} conflict remains to be resolved.<br><br>Please open the Conflict List Dialog and manually resolve it.",366 "{0} conflicts remain to be resolved.<br><br>Please open the Conflict List Dialog and manually resolve them.",367 numRemainingConflicts,368 numRemainingConflicts369 );370 }371 346 372 347 StringBuffer sb = new StringBuffer(); 373 sb.append("<html>").append(msg1); 374 if (numPurgedPrimitives > 0) { 375 sb.append("<br>").append(msg2); 376 } 377 if (numRemainingConflicts > 0) { 378 sb.append("<br>").append(msg3); 379 } 380 sb.append("</html>"); 348 sb.append("<html>").append(msg1).append("</html>"); 381 349 if (numNewConflicts > 0) { 382 350 ButtonSpec[] options = new ButtonSpec[] { … … 403 371 } 404 372 405 /**406 * Builds the purge command for primitives which can be purged automatically407 * from the local dataset because they've been deleted on the408 * server.409 *410 * @return the purge command. <code>null</code> if no primitives have to411 * be purged412 */413 protected PurgePrimitivesCommand buildPurgeCommand() {414 ArrayList<OsmPrimitive> toPurge = new ArrayList<OsmPrimitive>();415 conflictLoop:416 for (Conflict<?> c: conflicts) {417 if (c.getMy().isDeleted() && !c.getTheir().isVisible()) {418 // Local and server version of the primitive are deleted. We419 // can purge it from the local dataset.420 //421 toPurge.add(c.getMy());422 } else if (!c.getMy().isModified() && ! c.getTheir().isVisible()) {423 // We purge deleted *ways* and *relations* automatically if they are424 // deleted on the server and if they aren't modified in the local425 // dataset.426 //427 if (c.getMy() instanceof Way || c.getMy() instanceof Relation) {428 toPurge.add(c.getMy());429 continue conflictLoop;430 }431 // We only purge nodes if they aren't part of a modified way.432 // Otherwise the number of nodes of a modified way could drop433 // below 2 and we would lose the modified data when the way434 // gets purged.435 //436 for (OsmPrimitive parent: c.getMy().getReferrers()) {437 if (parent.isModified() && parent instanceof Way) {438 continue conflictLoop;439 }440 }441 toPurge.add(c.getMy());442 }443 }444 if (toPurge.isEmpty()) return null;445 PurgePrimitivesCommand cmd = new PurgePrimitivesCommand(this, toPurge);446 return cmd;447 }448 373 449 374 @Override public boolean isMergable(final Layer other) { -
trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
r3083 r3362 456 456 if (isCanceled())return null; 457 457 fetchPrimitives(relations,OsmPrimitiveType.RELATION, progressMonitor); 458 if (outputDataSet != null) { 459 outputDataSet.deleteInvisible(); 460 } 458 461 return outputDataSet; 459 462 } finally { -
trunk/src/org/openstreetmap/josm/io/OsmServerBackreferenceReader.java
r3083 r3362 274 274 ret = visitor.getTargetDataSet(); 275 275 readIncompletePrimitives(ret, progressMonitor.createSubTaskMonitor(1, false)); 276 if (ret != null) { 277 ret.deleteInvisible(); 278 } 276 279 return ret; 277 280 } finally {
Note:
See TracChangeset
for help on using the changeset viewer.