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; 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.Way; 014import org.openstreetmap.josm.gui.DefaultNameFormatter; 015import org.openstreetmap.josm.gui.layer.OsmDataLayer; 016import org.openstreetmap.josm.tools.CheckParameterUtil; 017import org.openstreetmap.josm.tools.ImageProvider; 018 019/** 020 * Command that basically replaces one OSM primitive by another of the same type. 021 * 022 * @since 93 023 */ 024public class ChangeCommand extends Command { 025 026 private final OsmPrimitive osm; 027 private final OsmPrimitive newOsm; 028 029 /** 030 * Constructs a new {@code ChangeCommand} in the context of the current edit layer, if any. 031 * @param osm The existing primitive to modify 032 * @param newOsm The new primitive 033 */ 034 public ChangeCommand(OsmPrimitive osm, OsmPrimitive newOsm) { 035 this.osm = osm; 036 this.newOsm = newOsm; 037 sanityChecks(); 038 } 039 040 /** 041 * Constructs a new {@code ChangeCommand} in the context of a given data layer. 042 * @param layer The data layer 043 * @param osm The existing primitive to modify 044 * @param newOsm The new primitive 045 */ 046 public ChangeCommand(OsmDataLayer layer, OsmPrimitive osm, OsmPrimitive newOsm) { 047 super(layer); 048 this.osm = osm; 049 this.newOsm = newOsm; 050 sanityChecks(); 051 } 052 053 private void sanityChecks() { 054 CheckParameterUtil.ensureParameterNotNull(osm, "osm"); 055 CheckParameterUtil.ensureParameterNotNull(newOsm, "newOsm"); 056 if (newOsm instanceof Way && ((Way)newOsm).getNodesCount() == 0) { 057 // Do not allow to create empty ways (see #7465) 058 throw new IllegalArgumentException(tr("New way {0} has 0 nodes", newOsm)); 059 } 060 } 061 062 @Override 063 public boolean executeCommand() { 064 super.executeCommand(); 065 osm.cloneFrom(newOsm); 066 osm.setModified(true); 067 return true; 068 } 069 070 @Override 071 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 072 modified.add(osm); 073 } 074 075 @Override 076 public String getDescriptionText() { 077 String msg = ""; 078 switch(OsmPrimitiveType.from(osm)) { 079 case NODE: msg = marktr("Change node {0}"); break; 080 case WAY: msg = marktr("Change way {0}"); break; 081 case RELATION: msg = marktr("Change relation {0}"); break; 082 } 083 return tr(msg, osm.getDisplayName(DefaultNameFormatter.getInstance())); 084 } 085 086 @Override 087 public Icon getDescriptionIcon() { 088 return ImageProvider.get(osm.getDisplayType()); 089 } 090}