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        super(conflict.getMy().getDataSet());
053        this.conflict = conflict;
054        this.mergeItems = mergeItems;
055    }
056
057    @Override
058    public String getDescriptionText() {
059        switch (OsmPrimitiveType.from(conflict.getMy())) {
060            case NODE:
061                /* for correct i18n of plural forms - see #9110 */
062                return trn("Resolve {0} tag conflict in node {1}", "Resolve {0} tag conflicts in node {1}",
063                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
064            case WAY:
065                /* for correct i18n of plural forms - see #9110 */
066                return trn("Resolve {0} tag conflict in way {1}", "Resolve {0} tag conflicts in way {1}",
067                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
068            case RELATION:
069                /* for correct i18n of plural forms - see #9110 */
070                return trn("Resolve {0} tag conflict in relation {1}", "Resolve {0} tag conflicts in relation {1}",
071                        getNumDecidedConflicts(), getNumDecidedConflicts(), conflict.getMy().getId());
072            default:
073                return "";
074        }
075    }
076
077    @Override
078    public Icon getDescriptionIcon() {
079        return ImageProvider.get("data", "object");
080    }
081
082    @Override
083    public boolean executeCommand() {
084        // remember the current state of modified primitives, i.e. of
085        // OSM primitive 'my'
086        //
087        super.executeCommand();
088
089        // apply the merge decisions to OSM primitive 'my'
090        //
091        for (TagMergeItem item: mergeItems) {
092            if (!item.getMergeDecision().equals(MergeDecisionType.UNDECIDED)) {
093                item.applyToMyPrimitive(conflict.getMy());
094            }
095        }
096        rememberConflict(conflict);
097        return true;
098    }
099
100    @Override
101    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
102            Collection<OsmPrimitive> added) {
103        modified.add(conflict.getMy());
104    }
105
106    @Override
107    public int hashCode() {
108        return Objects.hash(super.hashCode(), conflict, mergeItems);
109    }
110
111    @Override
112    public boolean equals(Object obj) {
113        if (this == obj) return true;
114        if (obj == null || getClass() != obj.getClass()) return false;
115        if (!super.equals(obj)) return false;
116        TagConflictResolveCommand that = (TagConflictResolveCommand) obj;
117        return Objects.equals(conflict, that.conflict) &&
118                Objects.equals(mergeItems, that.mergeItems);
119    }
120}