001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.conflict.pair.relation;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Map;
007
008import javax.swing.table.DefaultTableModel;
009
010import org.openstreetmap.josm.command.conflict.RelationMemberConflictResolverCommand;
011import org.openstreetmap.josm.data.conflict.Conflict;
012import org.openstreetmap.josm.data.osm.OsmPrimitive;
013import org.openstreetmap.josm.data.osm.PrimitiveId;
014import org.openstreetmap.josm.data.osm.Relation;
015import org.openstreetmap.josm.data.osm.RelationMember;
016import org.openstreetmap.josm.gui.conflict.pair.AbstractListMergeModel;
017import org.openstreetmap.josm.gui.conflict.pair.ListRole;
018import org.openstreetmap.josm.tools.CheckParameterUtil;
019
020/**
021 * The model for merging two lists of relation members
022 * @since 1631
023 */
024public class RelationMemberListMergeModel extends AbstractListMergeModel<RelationMember, RelationMemberConflictResolverCommand> {
025
026    @Override
027    public boolean isEqualEntry(RelationMember e1, RelationMember e2) {
028        return e1.equals(e2);
029    }
030
031    @Override
032    protected void buildMergedEntriesTableModel() {
033        // the table model for merged entries is different because it supports
034        // editing cells in the first column
035        //
036        mergedEntriesTableModel = this.new EntriesTableModel(ListRole.MERGED_ENTRIES) {
037            @Override
038            public boolean isCellEditable(int row, int column) {
039                switch(column) {
040                case 1: return true;
041                default: return false;
042                }
043            }
044        };
045    }
046
047    @Override
048    protected void setValueAt(DefaultTableModel model, Object value, int row, int col) {
049        if (model == getMergedTableModel() && col == 1) {
050            RelationMember memberOld = getMergedEntries().get(row);
051            RelationMember memberNew = new RelationMember((String) value, memberOld.getMember());
052            getMergedEntries().remove(row);
053            getMergedEntries().add(row, memberNew);
054            fireModelDataChanged();
055        }
056    }
057
058    /**
059     * populates the model with the relation members in relation my and their
060     *
061     * @param my my relation. Must not be null.
062     * @param their their relation. Must not be null.
063     * @param mergedMap The map of merged primitives if the conflict results from merging two layers
064     *
065     * @throws IllegalArgumentException if my is null
066     * @throws IllegalArgumentException if their is null
067     */
068    public void populate(Relation my, Relation their, Map<PrimitiveId, PrimitiveId> mergedMap) {
069        initPopulate(my, their, mergedMap);
070
071        for (RelationMember n : my.getMembers()) {
072            getMyEntries().add(n);
073        }
074        for (RelationMember n : their.getMembers()) {
075            getTheirEntries().add(n);
076        }
077        if (myAndTheirEntriesEqual()) {
078            for (RelationMember m : getMyEntries()) {
079                getMergedEntries().add(cloneEntryForMergedList(m));
080            }
081            setFrozen(true);
082        } else {
083            setFrozen(false);
084        }
085
086        fireModelDataChanged();
087    }
088
089    @Override
090    protected RelationMember cloneEntryForMergedList(RelationMember entry) {
091        return new RelationMember(entry.getRole(), getMyPrimitive(entry));
092    }
093
094    @Override
095    public OsmPrimitive getMyPrimitive(RelationMember entry) {
096        return getMyPrimitiveById(entry.getMember());
097    }
098
099    @Override
100    public RelationMemberConflictResolverCommand buildResolveCommand(Conflict<? extends OsmPrimitive> conflict) {
101        CheckParameterUtil.ensureParameterNotNull(conflict, "conflict");
102        if (!isFrozen())
103            throw new IllegalArgumentException(tr("Merged members not frozen yet. Cannot build resolution command"));
104        return new RelationMemberConflictResolverCommand(conflict, getMergedEntries());
105    }
106}