source: josm/trunk/src/org/openstreetmap/josm/command/AddPrimitivesCommand.java@ 11348

Last change on this file since 11348 was 11240, checked in by Don-vip, 7 years ago

see #10387 - refactor various actions and commands so they can be used without data layer

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Objects;
11
12import javax.swing.Icon;
13
14import org.openstreetmap.josm.data.osm.DataSet;
15import org.openstreetmap.josm.data.osm.Node;
16import org.openstreetmap.josm.data.osm.NodeData;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.PrimitiveData;
19import org.openstreetmap.josm.gui.layer.OsmDataLayer;
20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
22/**
23 * Add primitives to a data layer.
24 * @since 2305
25 */
26public class AddPrimitivesCommand extends Command {
27
28 private List<PrimitiveData> data = new ArrayList<>();
29 private Collection<PrimitiveData> toSelect = new ArrayList<>();
30
31 // only filled on undo
32 private List<OsmPrimitive> createdPrimitives;
33 private Collection<OsmPrimitive> createdPrimitivesToSelect;
34
35 /**
36 * Constructs a new {@code AddPrimitivesCommand} to add data to the current edit layer.
37 * @param data The OSM primitives data to add. Must not be {@code null}
38 */
39 public AddPrimitivesCommand(List<PrimitiveData> data) {
40 this(data, data);
41 }
42
43 /**
44 * Constructs a new {@code AddPrimitivesCommand} to add data to the current edit layer.
45 * @param data The OSM primitives to add. Must not be {@code null}
46 * @param toSelect The OSM primitives to select at the end. Can be {@code null}
47 * @since 5953
48 */
49 public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect) {
50 init(data, toSelect);
51 }
52
53 /**
54 * Constructs a new {@code AddPrimitivesCommand} to add data to the given layer.
55 * @param data The OSM primitives data to add. Must not be {@code null}
56 * @param toSelect The OSM primitives to select at the end. Can be {@code null}
57 * @param layer The target data layer. Must not be {@code null}
58 */
59 public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, OsmDataLayer layer) {
60 super(layer);
61 init(data, toSelect);
62 }
63
64 private void init(List<PrimitiveData> data, List<PrimitiveData> toSelect) {
65 CheckParameterUtil.ensureParameterNotNull(data, "data");
66 this.data.addAll(data);
67 if (toSelect != null) {
68 this.toSelect.addAll(toSelect);
69 }
70 }
71
72 @Override
73 public boolean executeCommand() {
74 Collection<OsmPrimitive> primitivesToSelect;
75 if (createdPrimitives == null) { // first time execution
76 List<OsmPrimitive> newPrimitives = new ArrayList<>(data.size());
77 primitivesToSelect = new ArrayList<>(toSelect.size());
78
79 for (PrimitiveData pd : data) {
80 OsmPrimitive primitive = getAffectedDataSet().getPrimitiveById(pd);
81 boolean created = primitive == null;
82 if (created) {
83 primitive = pd.getType().newInstance(pd.getUniqueId(), true);
84 }
85 if (pd instanceof NodeData) { // Load nodes immediately because they can't be added to dataset without coordinates
86 primitive.load(pd);
87 }
88 if (created) {
89 getAffectedDataSet().addPrimitive(primitive);
90 }
91 newPrimitives.add(primitive);
92 if (toSelect.contains(pd)) {
93 primitivesToSelect.add(primitive);
94 }
95 }
96
97 // Then load ways and relations
98 for (int i = 0; i < newPrimitives.size(); i++) {
99 if (!(newPrimitives.get(i) instanceof Node)) {
100 newPrimitives.get(i).load(data.get(i));
101 }
102 }
103 newPrimitives.stream().forEach(p -> p.setModified(true));
104 } else { // redo
105 // When redoing this command, we have to add the same objects, otherwise
106 // a subsequent command (e.g. MoveCommand) cannot be redone.
107 for (OsmPrimitive osm : createdPrimitives) {
108 getAffectedDataSet().addPrimitive(osm);
109 }
110 primitivesToSelect = createdPrimitivesToSelect;
111 }
112
113 getAffectedDataSet().setSelected(primitivesToSelect);
114 return true;
115 }
116
117 @Override public void undoCommand() {
118 DataSet ds = getAffectedDataSet();
119
120 if (createdPrimitives == null) {
121 createdPrimitives = new ArrayList<>(data.size());
122 createdPrimitivesToSelect = new ArrayList<>(toSelect.size());
123
124 for (PrimitiveData pd : data) {
125 OsmPrimitive p = ds.getPrimitiveById(pd);
126 createdPrimitives.add(p);
127 if (toSelect.contains(pd)) {
128 createdPrimitivesToSelect.add(p);
129 }
130 }
131 createdPrimitives = PurgeCommand.topoSort(createdPrimitives);
132
133 for (PrimitiveData p : data) {
134 ds.removePrimitive(p);
135 }
136 data = null;
137 toSelect = null;
138
139 } else {
140 for (OsmPrimitive osm : createdPrimitives) {
141 ds.removePrimitive(osm);
142 }
143 }
144 }
145
146 @Override
147 public String getDescriptionText() {
148 int size = data != null ? data.size() : createdPrimitives.size();
149 return trn("Added {0} object", "Added {0} objects", size, size);
150 }
151
152 @Override
153 public Icon getDescriptionIcon() {
154 return null;
155 }
156
157 @Override
158 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
159 Collection<OsmPrimitive> added) {
160 // Does nothing because we don't want to create OsmPrimitives.
161 }
162
163 @Override
164 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
165 if (createdPrimitives != null)
166 return createdPrimitives;
167
168 Collection<OsmPrimitive> prims = new HashSet<>();
169 for (PrimitiveData d : data) {
170 OsmPrimitive osm = getAffectedDataSet().getPrimitiveById(d);
171 if (osm == null)
172 throw new RuntimeException();
173 prims.add(osm);
174 }
175 return prims;
176 }
177
178 @Override
179 public int hashCode() {
180 return Objects.hash(super.hashCode(), data, toSelect, createdPrimitives, createdPrimitivesToSelect);
181 }
182
183 @Override
184 public boolean equals(Object obj) {
185 if (this == obj) return true;
186 if (obj == null || getClass() != obj.getClass()) return false;
187 if (!super.equals(obj)) return false;
188 AddPrimitivesCommand that = (AddPrimitivesCommand) obj;
189 return Objects.equals(data, that.data) &&
190 Objects.equals(toSelect, that.toSelect) &&
191 Objects.equals(createdPrimitives, that.createdPrimitives) &&
192 Objects.equals(createdPrimitivesToSelect, that.createdPrimitivesToSelect);
193 }
194}
Note: See TracBrowser for help on using the repository browser.