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.DataSet; 012import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 013import org.openstreetmap.josm.data.osm.OsmPrimitive; 014import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 015import org.openstreetmap.josm.data.osm.Relation; 016import org.openstreetmap.josm.data.osm.RelationMember; 017import org.openstreetmap.josm.tools.ImageProvider; 018 019/** 020 * Command that changes the role of a relation member 021 * 022 * @author Teemu Koskinen <teemu.koskinen@mbnet.fi> 023 */ 024public class ChangeRelationMemberRoleCommand extends Command { 025 026 // The relation to be changed 027 private final Relation relation; 028 // Position of the member 029 private final int position; 030 // The new role 031 private final String newRole; 032 // The old role 033 private String oldRole; 034 // Old value of modified 035 private Boolean oldModified; 036 037 /** 038 * Constructs a new {@code ChangeRelationMemberRoleCommand}. 039 * @param relation The relation to be changed. Must not be null, and belong to a data set 040 * @param position Member position 041 * @param newRole New role 042 */ 043 public ChangeRelationMemberRoleCommand(Relation relation, int position, String newRole) { 044 this(relation.getDataSet(), relation, position, newRole); 045 } 046 047 /** 048 * Constructs a new {@code ChangeRelationMemberRoleCommand}. 049 * @param dataSet The data set the role is in. Must not be {@code null} 050 * @param relation The relation to be changed 051 * @param position Member position 052 * @param newRole New role 053 * @since 12355 054 */ 055 public ChangeRelationMemberRoleCommand(DataSet dataSet, Relation relation, int position, String newRole) { 056 super(dataSet); 057 this.relation = relation; 058 this.position = position; 059 this.newRole = newRole; 060 } 061 062 @Override 063 public boolean executeCommand() { 064 if (position >= 0 && position < relation.getMembersCount()) { 065 oldRole = relation.getMember(position).getRole(); 066 if (!newRole.equals(oldRole)) { 067 relation.setMember(position, new RelationMember(newRole, relation.getMember(position).getMember())); 068 oldModified = relation.isModified(); 069 relation.setModified(true); 070 } 071 } 072 return true; 073 } 074 075 @Override 076 public void undoCommand() { 077 if (position >= 0 && position < relation.getMembersCount()) { 078 relation.setMember(position, new RelationMember(oldRole, relation.getMember(position).getMember())); 079 if (oldModified != null) { 080 relation.setModified(oldModified); 081 } 082 } 083 } 084 085 @Override 086 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 087 modified.add(relation); 088 } 089 090 @Override 091 public String getDescriptionText() { 092 return tr("Change relation member role for {0} {1}", 093 OsmPrimitiveType.from(relation), 094 relation.getDisplayName(DefaultNameFormatter.getInstance())); 095 } 096 097 @Override 098 public Icon getDescriptionIcon() { 099 return ImageProvider.get(relation.getDisplayType()); 100 } 101 102 @Override 103 public int hashCode() { 104 return Objects.hash(super.hashCode(), relation, position, newRole, oldRole, oldModified); 105 } 106 107 @Override 108 public boolean equals(Object obj) { 109 if (this == obj) return true; 110 if (obj == null || getClass() != obj.getClass()) return false; 111 if (!super.equals(obj)) return false; 112 ChangeRelationMemberRoleCommand that = (ChangeRelationMemberRoleCommand) obj; 113 return position == that.position && 114 Objects.equals(relation, that.relation) && 115 Objects.equals(newRole, that.newRole) && 116 Objects.equals(oldRole, that.oldRole) && 117 Objects.equals(oldModified, that.oldModified); 118 } 119}