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 false;
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        relation.setMember(position, new RelationMember(oldRole, relation.getMember(position).getMember()));
065        relation.setModified(oldModified);
066    }
067
068    @Override
069    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
070        modified.add(relation);
071    }
072
073    @Override
074    public String getDescriptionText() {
075        return tr("Change relation member role for {0} {1}",
076                OsmPrimitiveType.from(relation),
077                relation.getDisplayName(DefaultNameFormatter.getInstance()));
078    }
079
080    @Override
081    public Icon getDescriptionIcon() {
082        return ImageProvider.get(relation.getDisplayType());
083    }
084
085    @Override
086    public int hashCode() {
087        return Objects.hash(super.hashCode(), relation, position, newRole, oldRole, oldModified);
088    }
089
090    @Override
091    public boolean equals(Object obj) {
092        if (this == obj) return true;
093        if (obj == null || getClass() != obj.getClass()) return false;
094        if (!super.equals(obj)) return false;
095        ChangeRelationMemberRoleCommand that = (ChangeRelationMemberRoleCommand) obj;
096        return position == that.position &&
097                Objects.equals(relation, that.relation) &&
098                Objects.equals(newRole, that.newRole) &&
099                Objects.equals(oldRole, that.oldRole) &&
100                Objects.equals(oldModified, that.oldModified);
101    }
102}