Ignore:
Timestamp:
2010-07-03T22:08:57+02:00 (14 years ago)
Author:
stoecker
Message:

fix #5182 - Conflict system simplification - patch by Upliner

Location:
trunk/src/org/openstreetmap/josm/gui/conflict/pair
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/ConflictResolver.java

    r3083 r3362  
    2626import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListMergeModel;
    2727import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListMerger;
    28 import org.openstreetmap.josm.gui.conflict.pair.properties.OperationCancelledException;
    2928import org.openstreetmap.josm.gui.conflict.pair.properties.PropertiesMergeModel;
    3029import org.openstreetmap.josm.gui.conflict.pair.properties.PropertiesMerger;
     
    235234        this.conflict = conflict;
    236235        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
    243237        tabbedPane.setEnabledAt(0, true);
    244238        tagMerger.populate(conflict);
     
    270264     * @return the resolution command
    271265     */
    272     public Command buildResolveCommand() throws OperationCancelledException {
     266    public Command buildResolveCommand() {
    273267        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));
    294283        }
    295284        return new SequenceCommand(tr("Conflict Resolution"), commands);
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMergeModel.java

    r3083 r3362  
    33
    44import 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;
    75
    86import java.beans.PropertyChangeListener;
     
    108import java.util.ArrayList;
    119import java.util.Collections;
    12 import java.util.HashMap;
    1310import java.util.List;
    1411import java.util.Observable;
    1512
    16 import javax.swing.JOptionPane;
    17 
    18 import org.openstreetmap.josm.Main;
    1913import org.openstreetmap.josm.command.Command;
    2014import org.openstreetmap.josm.command.CoordinateConflictResolveCommand;
    2115import org.openstreetmap.josm.command.DeletedStateConflictResolveCommand;
    22 import org.openstreetmap.josm.command.PurgePrimitivesCommand;
    23 import org.openstreetmap.josm.command.UndeletePrimitivesCommand;
    2416import org.openstreetmap.josm.data.conflict.Conflict;
    2517import org.openstreetmap.josm.data.coor.LatLon;
    26 import org.openstreetmap.josm.data.osm.DataSet;
    2718import org.openstreetmap.josm.data.osm.Node;
    2819import 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;
    3220import 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;
    3621import org.openstreetmap.josm.tools.CheckParameterUtil;
    3722
     
    6550    private boolean myDeletedState;
    6651    private boolean theirDeletedState;
    67     private boolean myVisibleState;
    68     private boolean theirVisibleState;
    6952    private List<OsmPrimitive> myReferrers;
    7053    private List<OsmPrimitive> theirReferrers;
    7154    private MergeDecisionType deletedMergeDecision;
    72     private MergeDecisionType visibleMergeDecision;
    7355    private final PropertyChangeSupport support;
    7456    private boolean resolvedCompletely;
     
    118100
    119101    /**
    120      * replies true if there is a  conflict in the visible state and if this conflict is
    121      * resolved
    122      *
    123      * @return true if there is a conflict in the visible state and if this conflict is
    124      * resolved; false, otherwise
    125      */
    126     public boolean isDecidedVisibleState() {
    127         return ! visibleMergeDecision.equals(UNDECIDED);
    128     }
    129 
    130     /**
    131102     * replies true if the current decision for the coordinate conflict is <code>decision</code>
    132103     *
     
    148119    }
    149120
    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, otherwise
    155      */
    156     public boolean isVisibleStateDecision(MergeDecisionType decision) {
    157         return visibleMergeDecision.equals(decision);
    158     }
    159121    /**
    160122     * populates the model with the differences between my and their version
     
    177139        theirDeletedState = their.isDeleted();
    178140
    179         myVisibleState = my.isVisible();
    180         theirVisibleState = their.isVisible();
    181 
    182141        myReferrers = my.getDataSet() == null?Collections.<OsmPrimitive>emptyList():my.getReferrers();
    183142        theirReferrers = their.getDataSet() == null?Collections.<OsmPrimitive>emptyList():their.getReferrers();
     
    185144        coordMergeDecision = UNDECIDED;
    186145        deletedMergeDecision = UNDECIDED;
    187         visibleMergeDecision = UNDECIDED;
    188146        setChanged();
    189147        notifyObservers();
     
    265223
    266224    /**
    267      * replies my visible state,
    268      * @return my visible state
    269      */
    270     public Boolean getMyVisibleState() {
    271         return myVisibleState;
    272     }
    273 
    274     /**
    275      * replies their visible state,
    276      * @return their visible state
    277      */
    278     public  Boolean getTheirVisibleState() {
    279         return theirVisibleState;
    280     }
    281 
    282     /**
    283225     * returns my referrers,
    284226     * @return my referrers
     
    294236    public List<OsmPrimitive> getTheirReferrers() {
    295237        return theirReferrers;
    296     }
    297 
    298     /**
    299      * replies the merged visible state; null, if the merge decision is
    300      * {@see MergeDecisionType#UNDECIDED}.
    301      *
    302      * @return the merged visible state
    303      */
    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 happen
    311         return null;
    312238    }
    313239
     
    346272
    347273    /**
    348      * decides the conflict between two visible states
    349      * @param decision the decision (must not be null)
    350      *
    351      * @throws IllegalArgumentException thrown, if decision is null
    352      */
    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     /**
    362274     * replies true if my and their primitive have a conflict between
    363275     * their coordinate values
     
    385297
    386298    /**
    387      * replies true if my and their primitive have a conflict between
    388      * their visible states
    389      *
    390      * @return true if my and their primitive have a conflict between
    391      * their visible states
    392      */
    393     public boolean hasVisibleStateConflict() {
    394         return myVisibleState != theirVisibleState;
    395     }
    396 
    397     /**
    398299     * replies true if all conflict in this model are resolved
    399300     *
     
    408309            ret = ret && ! deletedMergeDecision.equals(UNDECIDED);
    409310        }
    410         if (hasVisibleStateConflict()) {
    411             ret = ret && ! visibleMergeDecision.equals(UNDECIDED);
    412         }
    413311        return ret;
    414312    }
     
    421319     * @return the list of commands
    422320     */
    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) {
    425322        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         }
    441323        if (hasCoordConflict() && isDecidedCoord()) {
    442324            cmds.add(new CoordinateConflictResolveCommand(conflict, coordMergeDecision));
     
    452334    }
    453335
    454     /**
    455      *
    456      * @param id
    457      */
    458     protected void handleExceptionWhileBuildingCommand(Exception e) {
    459         e.printStackTrace();
    460         String msg = e.getMessage() != null ? e.getMessage() : e.toString();
    461         msg = msg.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
    462         JOptionPane.showMessageDialog(
    463                 Main.parent,
    464                 tr("<html>An error occurred while communicating with the server<br>"
    465                         + "Details: {0}</html>",
    466                         msg
    467                 ),
    468                 tr("Communication with server failed"),
    469                 JOptionPane.ERROR_MESSAGE
    470         );
    471     }
    472 
    473     /**
    474      * User has decided to keep his local version of a primitive which had been deleted
    475      * on the server
    476      *
    477      * @param id the primitive id
    478      */
    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 API
    490      * doesn't offer a call for "undeleting" a node. We therefore create
    491      * a clone of the node which we flag as new. On the next upload the
    492      * server will assign the node a new id.
    493      *
    494      * @param node the node to undelete
    495      */
    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 dependent
    502      * nodes should be undeleted too.
    503      *
    504      * @param way  the way
    505      * @param dependent a list of dependent nodes which have to be undelete too
    506      * @return true, if the user confirms; false, otherwise
    507      */
    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 by
    580      * this way which are deleted on the server too.
    581      *
    582      * @param way the way to undelete
    583      * @return the undelete command
    584      * @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 by
    617      * this relation which are already deleted on the server.
    618      *
    619      * @param r the relation
    620      * @return the undelete command
    621      * @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 
    651336}
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMerger.java

    r3218 r3362  
    1919import javax.swing.JButton;
    2020import javax.swing.JLabel;
    21 import javax.swing.JOptionPane;
    2221import javax.swing.JPanel;
    2322
     
    5453    private JLabel lblTheirDeletedState;
    5554
    56     private JLabel lblMyVisibleState;
    57     private JLabel lblMergedVisibleState;
    58     private JLabel lblTheirVisibleState;
    59 
    6055    private JLabel lblMyReferrers;
    6156    private JLabel lblTheirReferrers;
     
    251246    }
    252247
    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 
    329248    protected void buildReferrersRow() {
    330249        GridBagConstraints gc = new GridBagConstraints();
     
    363282        buildCoordinateConflictRows();
    364283        buildDeletedStateConflictRows();
    365         buildVisibleStateRows();
    366284        buildReferrersRow();
    367285    }
     
    392310        else
    393311            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         else
    402             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         else
    411             return tr("Physically delete from local dataset");
    412312    }
    413313
     
    478378    }
    479379
    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_CONFLICT
    498                 );
    499                 lblMergedVisibleState.setBackground(BGCOLOR_DECIDED);
    500                 lblTheirVisibleState.setBackground(
    501                         model.isVisibleStateDecision(MergeDecisionType.KEEP_THEIR)
    502                         ? BGCOLOR_DECIDED : BGCOLOR_NO_CONFLICT
    503                 );
    504             }
    505         }
    506     }
    507 
    508380    protected void updateReferrers() {
    509381        lblMyReferrers.setText(referrersToString(model.getMyReferrers()));
     
    516388        updateCoordinates();
    517389        updateDeletedState();
    518         updateVisibleState();
    519390        updateReferrers();
    520391    }
     
    611482        public void update(Observable o, Object arg) {
    612483            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());
    708484        }
    709485    }
Note: See TracChangeset for help on using the changeset viewer.