001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command.conflict;
003
004import static org.openstreetmap.josm.tools.I18n.trn;
005
006import java.util.Collection;
007import java.util.List;
008import java.util.Objects;
009
010import javax.swing.Icon;
011
012import org.openstreetmap.josm.data.conflict.Conflict;
013import org.openstreetmap.josm.data.osm.OsmPrimitive;
014import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
015import org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType;
016import org.openstreetmap.josm.gui.conflict.pair.tags.TagMergeItem;
017import org.openstreetmap.josm.tools.ImageProvider;
018
019/**
020 * Represents the resolution of a tag conflict in an {@link OsmPrimitive}.
021 *
022 */
023public class TagConflictResolveCommand extends ConflictResolveCommand {
024    /** the conflict to resolve */
025    private final Conflict<? extends OsmPrimitive> conflict;
026
027    /** the list of merge decisions, represented as {@link TagMergeItem}s */
028    private final List<TagMergeItem> mergeItems;
029
030    /**
031     * replies the number of decided conflicts
032     *
033     * @return the number of decided conflicts
034     */
035    public int getNumDecidedConflicts() {
036        int n = 0;
037        for (TagMergeItem item: mergeItems) {
038            if (!item.getMergeDecision().equals(MergeDecisionType.UNDECIDED)) {
039                n++;
040            }
041        }
042        return n;
043    }
044
045    /**
046     * constructor
047     *
048     * @param conflict the conflict data set
049     * @param mergeItems the list of merge decisions, represented as {@link TagMergeItem}s
050     */
051    public TagConflictResolveCommand(Conflict<? extends OsmPrimitive> conflict, List<TagMergeItem> mergeItems) {
052        this.conflict = conflict;
053        this.mergeItems = mergeItems;
054    }
055
056    @Override
057    public String getDescriptionText() {
058        switch (OsmPrimitiveType.from(conflict.getMy())) {
059            case NODE:
060                /* for correct i18n of plural forms - see #9110 */
061                return trn("Resolve {0} tag conflict in node {1}", "Resolve {0} tag conflicts in node {1}",
062                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
063            case WAY:
064                /* for correct i18n of plural forms - see #9110 */
065                return trn("Resolve {0} tag conflict in way {1}", "Resolve {0} tag conflicts in way {1}",
066                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
067            case RELATION:
068                /* for correct i18n of plural forms - see #9110 */
069                return trn("Resolve {0} tag conflict in relation {1}", "Resolve {0} tag conflicts in relation {1}",
070                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
071        }
072        return "";
073    }
074
075    @Override
076    public Icon getDescriptionIcon() {
077        return ImageProvider.get("data", "object");
078    }
079
080    @Override
081    public boolean executeCommand() {
082        // remember the current state of modified primitives, i.e. of
083        // OSM primitive 'my'
084        //
085        super.executeCommand();
086
087        // apply the merge decisions to OSM primitive 'my'
088        //
089        for (TagMergeItem item: mergeItems) {
090            if (!item.getMergeDecision().equals(MergeDecisionType.UNDECIDED)) {
091                item.applyToMyPrimitive(conflict.getMy());
092            }
093        }
094        rememberConflict(conflict);
095        return true;
096    }
097
098    @Override
099    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
100            Collection<OsmPrimitive> added) {
101        modified.add(conflict.getMy());
102    }
103
104    @Override
105    public int hashCode() {
106        return Objects.hash(super.hashCode(), conflict, mergeItems);
107    }
108
109    @Override
110    public boolean equals(Object obj) {
111        if (this == obj) return true;
112        if (obj == null || getClass() != obj.getClass()) return false;
113        if (!super.equals(obj)) return false;
114        TagConflictResolveCommand that = (TagConflictResolveCommand) obj;
115        return Objects.equals(conflict, that.conflict) &&
116                Objects.equals(mergeItems, that.mergeItems);
117    }
118}