source: josm/trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java@ 5077

Last change on this file since 5077 was 5077, checked in by xeen, 13 years ago

Bring area icon to most (all?) places in core. Fixes #6318 (related: #7036)

  • Property svn:eol-style set to native
File size: 8.1 KB
RevLine 
[298]1// License: GPL. Copyright 2007 by Immanuel Scholz and others
[626]2package org.openstreetmap.josm.command;
3
[1990]4import static org.openstreetmap.josm.tools.I18n.marktr;
[626]5import static org.openstreetmap.josm.tools.I18n.tr;
6
[4773]7import java.util.AbstractMap;
[3262]8import java.util.ArrayList;
[4302]9import java.util.Arrays;
[626]10import java.util.Collection;
[3262]11import java.util.Collections;
[4773]12import java.util.HashMap;
[626]13import java.util.LinkedList;
14import java.util.List;
[4773]15import java.util.Map;
[5077]16
[4918]17import javax.swing.Icon;
[626]18
[3910]19import org.openstreetmap.josm.Main;
[626]20import org.openstreetmap.josm.data.osm.OsmPrimitive;
[1814]21import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
[1990]22import org.openstreetmap.josm.gui.DefaultNameFormatter;
[626]23import org.openstreetmap.josm.tools.ImageProvider;
24
25/**
26 * Command that manipulate the key/value structure of several objects. Manages deletion,
27 * adding and modify of values and keys.
[1169]28 *
[626]29 * @author imi
30 */
31public class ChangePropertyCommand extends Command {
[1169]32 /**
33 * All primitives that are affected with this command.
34 */
35 private final List<OsmPrimitive> objects;
36 /**
[4773]37 * Key and value pairs. If value is <code>null</code>, delete all key references with the given
[1169]38 * key. Otherwise, change the properties of all objects to the given value or create keys of
39 * those objects that do not have the key yet.
40 */
[4773]41 private final AbstractMap<String, String> tags;
[628]42
[4773]43 /**
44 * Creates a command to change multiple properties of multiple objects
45 *
46 * @param objects the objects to modify
47 * @param tags the properties to set
48 */
49 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, AbstractMap<String, String> tags) {
[1750]50 super();
[1169]51 this.objects = new LinkedList<OsmPrimitive>();
[4773]52 this.tags = tags;
53 init(objects);
[1169]54 }
[626]55
[4773]56 /**
57 * Creates a command to change one property of multiple objects
58 *
59 * @param objects the objects to modify
60 * @param key the key of the property to set
61 * @param value the value of the key to set
62 */
63 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
64 this.objects = new LinkedList<OsmPrimitive>();
65 this.tags = new HashMap<String, String>(1);
66 this.tags.put(key, value);
67 init(objects);
68 }
69
70 /**
71 * Creates a command to change on property of one object
72 *
73 * @param object the object to modify
74 * @param key the key of the property to set
75 * @param value the value of the key to set
76 */
[1169]77 public ChangePropertyCommand(OsmPrimitive object, String key, String value) {
[4302]78 this(Arrays.asList(object), key, value);
[1169]79 }
[626]80
[4773]81 /**
82 * Initialize the instance by finding what objects will be modified
83 *
84 * @param objects the objects to (possibly) modify
85 */
86 private void init(Collection<? extends OsmPrimitive> objects) {
87 // determine what objects will be modified
88 for (OsmPrimitive osm : objects) {
89 boolean modified = false;
90
91 // loop over all tags
92 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
93 String oldVal = osm.get(tag.getKey());
94 String newVal = tag.getValue();
95
96 if (newVal == null || newVal.isEmpty()) {
97 if (oldVal != null)
98 // new value is null and tag exists (will delete tag)
99 modified = true;
100 }
101 else if (oldVal == null || !newVal.equals(oldVal))
102 // new value is not null and is different from current value
103 modified = true;
104 }
105 if (modified)
106 this.objects.add(osm);
107 }
108 }
109
[1169]110 @Override public boolean executeCommand() {
[3910]111 Main.main.getCurrentDataSet().beginUpdate();
112 try {
113 super.executeCommand(); // save old
[4773]114
115 for (OsmPrimitive osm : objects) {
116 boolean modified = false;
117
118 // loop over all tags
119 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
120 String oldVal = osm.get(tag.getKey());
121 String newVal = tag.getValue();
122
123 if (newVal == null || newVal.isEmpty()) {
124 if (oldVal != null) {
125 osm.remove(tag.getKey());
126 modified = true;
127 }
128 }
129 else if (oldVal == null || !newVal.equals(oldVal))
130 osm.put(tag.getKey(), newVal);
131 modified = true;
[3910]132 }
[4773]133 if (modified)
[3910]134 osm.setModified(true);
[1169]135 }
[3910]136 return true;
[1169]137 }
[3910]138 finally {
139 Main.main.getCurrentDataSet().endUpdate();
140 }
[626]141 }
[1169]142
143 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
144 modified.addAll(objects);
145 }
146
[4918]147 @Override
148 public String getDescriptionText() {
[1182]149 String text;
[4773]150 if (objects.size() == 1 && tags.size() == 1) {
[1814]151 OsmPrimitive primitive = objects.iterator().next();
[1989]152 String msg = "";
[4773]153 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
154 if (entry.getValue() == null) {
[1989]155 switch(OsmPrimitiveType.from(primitive)) {
[2990]156 case NODE: msg = marktr("Remove \"{0}\" for node ''{1}''"); break;
157 case WAY: msg = marktr("Remove \"{0}\" for way ''{1}''"); break;
158 case RELATION: msg = marktr("Remove \"{0}\" for relation ''{1}''"); break;
[1989]159 }
[4773]160 text = tr(msg, entry.getKey(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
[1989]161 } else {
162 switch(OsmPrimitiveType.from(primitive)) {
[2990]163 case NODE: msg = marktr("Set {0}={1} for node ''{2}''"); break;
164 case WAY: msg = marktr("Set {0}={1} for way ''{2}''"); break;
165 case RELATION: msg = marktr("Set {0}={1} for relation ''{2}''"); break;
[1989]166 }
[4773]167 text = tr(msg, entry.getKey(), entry.getValue(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
[1989]168 }
[4773]169 } else if (objects.size() > 1 && tags.size() == 1) {
170 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
171 if (entry.getValue() == null)
172 text = tr("Remove \"{0}\" for {1} objects", entry.getKey(), objects.size());
173 else
174 text = tr("Set {0}={1} for {2} objects", entry.getKey(), entry.getValue(), objects.size());
[1182]175 }
[4773]176 else {
177 boolean allnull = true;
178 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
179 if (tag.getValue() != null) {
180 allnull = false;
181 break;
182 }
183 }
[5077]184
[4773]185 if (allnull) {
186 text = tr("Deleted {0} properties for {1} objects", tags.size(), objects.size());
187 } else
188 text = tr("Set {0} properties for {1} objects", tags.size(), objects.size());
189 }
[4918]190 return text;
[3262]191 }
192
[4918]193 @Override
194 public Icon getDescriptionIcon() {
195 return ImageProvider.get("data", "key");
196 }
197
[3262]198 @Override public Collection<PseudoCommand> getChildren() {
[1169]199 if (objects.size() == 1)
[3262]200 return null;
201 List<PseudoCommand> children = new ArrayList<PseudoCommand>();
202 for (final OsmPrimitive osm : objects) {
203 children.add(new PseudoCommand() {
[4918]204 @Override public String getDescriptionText() {
205 return osm.getDisplayName(DefaultNameFormatter.getInstance());
206 }
[3262]207
[4918]208 @Override public Icon getDescriptionIcon() {
[5077]209 return ImageProvider.get(osm.getDisplayType());
[3262]210 }
[4918]211
[3262]212 @Override public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
213 return Collections.singleton(osm);
214 }
215
216 });
[1169]217 }
[3262]218 return children;
[1169]219 }
[626]220}
Note: See TracBrowser for help on using the repository browser.