001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.command; 003 004import static org.openstreetmap.josm.tools.I18n.marktr; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.util.Collection; 008import java.util.Collections; 009import java.util.Objects; 010 011import javax.swing.Icon; 012 013import org.openstreetmap.josm.data.osm.DataSet; 014import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 015import org.openstreetmap.josm.data.osm.OsmPrimitive; 016import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 017import org.openstreetmap.josm.data.osm.Way; 018import org.openstreetmap.josm.tools.ImageProvider; 019 020/** 021 * A command that adds an osm primitive to a dataset. Keys cannot be added this way. 022 * 023 * See {@link ChangeCommand} for comments on relation back references. 024 * 025 * @author imi 026 */ 027public class AddCommand extends Command { 028 029 /** 030 * The primitive to add to the dataset. 031 */ 032 private final OsmPrimitive osm; 033 034 /** 035 * Creates the command and specify the element to add in the context of the given data set. 036 * @param data The data set. Must not be {@code null} 037 * @param osm The primitive to add 038 * @since 11240 039 */ 040 public AddCommand(DataSet data, OsmPrimitive osm) { 041 super(data); 042 this.osm = Objects.requireNonNull(osm, "osm"); 043 } 044 045 protected static final void checkNodeStyles(OsmPrimitive osm) { 046 if (osm instanceof Way) { 047 // Fix #10557 - node icon not updated after undoing/redoing addition of a way 048 ((Way) osm).clearCachedNodeStyles(); 049 } 050 } 051 052 @Override 053 public boolean executeCommand() { 054 getAffectedDataSet().addPrimitive(osm); 055 osm.setModified(true); 056 checkNodeStyles(osm); 057 return true; 058 } 059 060 @Override 061 public void undoCommand() { 062 getAffectedDataSet().removePrimitive(osm); 063 checkNodeStyles(osm); 064 } 065 066 @Override 067 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 068 added.add(osm); 069 } 070 071 @Override 072 public String getDescriptionText() { 073 String msg; 074 switch(OsmPrimitiveType.from(osm)) { 075 case NODE: msg = marktr("Add node {0}"); break; 076 case WAY: msg = marktr("Add way {0}"); break; 077 case RELATION: msg = marktr("Add relation {0}"); break; 078 default: /* should not happen */msg = ""; break; 079 } 080 return tr(msg, osm.getDisplayName(DefaultNameFormatter.getInstance())); 081 } 082 083 @Override 084 public Icon getDescriptionIcon() { 085 return ImageProvider.get(osm.getDisplayType()); 086 } 087 088 @Override 089 public Collection<OsmPrimitive> getParticipatingPrimitives() { 090 return Collections.singleton(osm); 091 } 092 093 @Override 094 public int hashCode() { 095 return Objects.hash(super.hashCode(), osm); 096 } 097 098 @Override 099 public boolean equals(Object obj) { 100 if (this == obj) return true; 101 if (obj == null || getClass() != obj.getClass()) return false; 102 if (!super.equals(obj)) return false; 103 AddCommand that = (AddCommand) obj; 104 return Objects.equals(osm, that.osm); 105 } 106}