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