001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Collection;
007import java.util.Objects;
008
009import javax.swing.Icon;
010
011import org.openstreetmap.josm.data.osm.OsmPrimitive;
012import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
013import org.openstreetmap.josm.data.osm.Relation;
014import org.openstreetmap.josm.data.osm.RelationMember;
015import org.openstreetmap.josm.gui.DefaultNameFormatter;
016import org.openstreetmap.josm.tools.ImageProvider;
017
018/**
019 * Command that changes the role of a relation member
020 *
021 * @author Teemu Koskinen <teemu.koskinen@mbnet.fi>
022 */
023public class ChangeRelationMemberRoleCommand extends Command {
024
025    // The relation to be changed
026    private final Relation relation;
027    // Position of the member
028    private final int position;
029    // The new role
030    private final String newRole;
031    // The old role
032    private String oldRole;
033    // Old value of modified
034    private Boolean oldModified;
035
036    /**
037     * Constructs a new {@code ChangeRelationMemberRoleCommand}.
038     * @param relation The relation to be changed
039     * @param position Member position
040     * @param newRole New role
041     */
042    public ChangeRelationMemberRoleCommand(Relation relation, int position, String newRole) {
043        this.relation = relation;
044        this.position = position;
045        this.newRole = newRole;
046    }
047
048    @Override
049    public boolean executeCommand() {
050        if (position < 0 || position >= relation.getMembersCount())
051            return true;
052
053        oldRole = relation.getMember(position).getRole();
054        if (newRole.equals(oldRole)) return true;
055        relation.setMember(position, new RelationMember(newRole, relation.getMember(position).getMember()));
056
057        oldModified = relation.isModified();
058        relation.setModified(true);
059        return true;
060    }
061
062    @Override
063    public void undoCommand() {
064        if (position >= 0 && position < relation.getMembersCount()) {
065            relation.setMember(position, new RelationMember(oldRole, relation.getMember(position).getMember()));
066            if (oldModified != null) {
067                relation.setModified(oldModified);
068            }
069        }
070    }
071
072    @Override
073    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
074        modified.add(relation);
075    }
076
077    @Override
078    public String getDescriptionText() {
079        return tr("Change relation member role for {0} {1}",
080                OsmPrimitiveType.from(relation),
081                relation.getDisplayName(DefaultNameFormatter.getInstance()));
082    }
083
084    @Override
085    public Icon getDescriptionIcon() {
086        return ImageProvider.get(relation.getDisplayType());
087    }
088
089    @Override
090    public int hashCode() {
091        return Objects.hash(super.hashCode(), relation, position, newRole, oldRole, oldModified);
092    }
093
094    @Override
095    public boolean equals(Object obj) {
096        if (this == obj) return true;
097        if (obj == null || getClass() != obj.getClass()) return false;
098        if (!super.equals(obj)) return false;
099        ChangeRelationMemberRoleCommand that = (ChangeRelationMemberRoleCommand) obj;
100        return position == that.position &&
101                Objects.equals(relation, that.relation) &&
102                Objects.equals(newRole, that.newRole) &&
103                Objects.equals(oldRole, that.oldRole) &&
104                Objects.equals(oldModified, that.oldModified);
105    }
106}