source: josm/trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java@ 1814

Last change on this file since 1814 was 1814, checked in by Gubaer, 15 years ago

removed dependencies to Main.ds, removed Main.ds
removed AddVisitor, NameVisitor, DeleteVisitor - unnecessary double dispatching for these simple cases

  • Property svn:eol-style set to native
File size: 27.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.tagging;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.Component;
9import java.awt.GridBagLayout;
10import java.awt.Image;
11import java.awt.event.ActionEvent;
12import java.io.BufferedReader;
13import java.io.IOException;
14import java.io.InputStreamReader;
15import java.io.Reader;
16import java.io.UnsupportedEncodingException;
17import java.util.Arrays;
18import java.util.Collection;
19import java.util.HashMap;
20import java.util.HashSet;
21import java.util.LinkedHashMap;
22import java.util.LinkedList;
23import java.util.List;
24import java.util.Set;
25
26import javax.swing.AbstractAction;
27import javax.swing.Action;
28import javax.swing.ImageIcon;
29import javax.swing.JComboBox;
30import javax.swing.JComponent;
31import javax.swing.JLabel;
32import javax.swing.JOptionPane;
33import javax.swing.JPanel;
34import javax.swing.JTextField;
35
36import org.openstreetmap.josm.Main;
37import org.openstreetmap.josm.command.ChangePropertyCommand;
38import org.openstreetmap.josm.command.Command;
39import org.openstreetmap.josm.command.SequenceCommand;
40import org.openstreetmap.josm.data.osm.Node;
41import org.openstreetmap.josm.data.osm.OsmPrimitive;
42import org.openstreetmap.josm.data.osm.OsmUtils;
43import org.openstreetmap.josm.data.osm.Relation;
44import org.openstreetmap.josm.data.osm.Way;
45import org.openstreetmap.josm.gui.ExtendedDialog;
46import org.openstreetmap.josm.gui.QuadStateCheckBox;
47import org.openstreetmap.josm.io.MirroredInputStream;
48import org.openstreetmap.josm.tools.GBC;
49import org.openstreetmap.josm.tools.ImageProvider;
50import org.openstreetmap.josm.tools.UrlLabel;
51import org.openstreetmap.josm.tools.XmlObjectParser;
52import org.xml.sax.SAXException;
53
54/**
55 * This class read encapsulate one tagging preset. A class method can
56 * read in all predefined presets, either shipped with JOSM or that are
57 * in the config directory.
58 *
59 * It is also able to construct dialogs out of preset definitions.
60 */
61public class TaggingPreset extends AbstractAction {
62
63 public TaggingPresetMenu group = null;
64 public String name;
65 public String locale_name;
66
67 public static abstract class Item {
68 public boolean focus = false;
69 abstract boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel);
70 abstract void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds);
71 boolean requestFocusInWindow() {return false;}
72 }
73
74 public static class Usage {
75 Set<String> values;
76 Boolean hadKeys = false;
77 Boolean hadEmpty = false;
78 public Boolean allSimilar()
79 {
80 return values.size() == 1 && !hadEmpty;
81 }
82 public Boolean unused()
83 {
84 return values.size() == 0;
85 }
86 public String getFirst()
87 {
88 return (String)(values.toArray()[0]);
89 }
90 public Boolean hadKeys()
91 {
92 return hadKeys;
93 }
94 }
95
96 public static final String DIFFERENT = tr("<different>");
97
98 static Usage determineTextUsage(Collection<OsmPrimitive> sel, String key) {
99 Usage returnValue = new Usage();
100 returnValue.values = new HashSet<String>();
101 for (OsmPrimitive s : sel) {
102 String v = s.get(key);
103 if (v != null) {
104 returnValue.values.add(v);
105 } else {
106 returnValue.hadEmpty = true;
107 }
108 if(s.keys != null && s.keys.size() > 0) {
109 returnValue.hadKeys = true;
110 }
111 }
112 return returnValue;
113 }
114
115 static Usage determineBooleanUsage(Collection<OsmPrimitive> sel, String key) {
116
117 Usage returnValue = new Usage();
118 returnValue.values = new HashSet<String>();
119 for (OsmPrimitive s : sel) {
120 returnValue.values.add(OsmUtils.getNamedOsmBoolean(s.get(key)));
121 }
122 return returnValue;
123 }
124
125 public static class Text extends Item {
126
127 public String key;
128 public String text;
129 public String locale_text;
130 public String default_;
131 public String originalValue;
132 public boolean use_last_as_default = false;
133 public boolean delete_if_empty = false;
134
135 private JComponent value;
136
137 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
138
139 // find out if our key is already used in the selection.
140 Usage usage = determineTextUsage(sel, key);
141 if (usage.unused())
142 {
143 value = new JTextField();
144 if (use_last_as_default && lastValue.containsKey(key)) {
145 ((JTextField)value).setText(lastValue.get(key));
146 } else {
147 ((JTextField)value).setText(default_);
148 }
149 originalValue = null;
150 } else if (usage.allSimilar()) {
151 // all objects use the same value
152 value = new JTextField();
153 for (String s : usage.values) {
154 ((JTextField) value).setText(s);
155 }
156 originalValue = ((JTextField)value).getText();
157 } else {
158 // the objects have different values
159 value = new JComboBox(usage.values.toArray());
160 ((JComboBox)value).setEditable(true);
161 ((JComboBox)value).getEditor().setItem(DIFFERENT);
162 originalValue = DIFFERENT;
163 }
164 if(locale_text == null) {
165 locale_text = tr(text);
166 }
167 p.add(new JLabel(locale_text+":"), GBC.std().insets(0,0,10,0));
168 p.add(value, GBC.eol().fill(GBC.HORIZONTAL));
169 return true;
170 }
171
172 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
173
174 // return if unchanged
175 String v = (value instanceof JComboBox) ?
176 ((JComboBox)value).getEditor().getItem().toString() :
177 ((JTextField)value).getText();
178
179 if (use_last_as_default) {
180 lastValue.put(key, v);
181 }
182 if (v.equals(originalValue) || (originalValue == null && v.length() == 0)) return;
183
184 if (delete_if_empty && v.length() == 0) {
185 v = null;
186 }
187 cmds.add(new ChangePropertyCommand(sel, key, v));
188 }
189 @Override boolean requestFocusInWindow() {return value.requestFocusInWindow();}
190 }
191
192 public static class Check extends Item {
193
194 public String key;
195 public String text;
196 public String locale_text;
197 public boolean default_ = false; // only used for tagless objects
198 public boolean use_last_as_default = false;
199
200 private QuadStateCheckBox check;
201 private QuadStateCheckBox.State initialState;
202 private boolean def;
203
204 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
205
206 // find out if our key is already used in the selection.
207 Usage usage = determineBooleanUsage(sel, key);
208 def = default_;
209
210 if(locale_text == null) {
211 locale_text = tr(text);
212 }
213
214 String oneValue = null;
215 for (String s : usage.values) {
216 oneValue = s;
217 }
218 if (usage.values.size() < 2 && (oneValue == null || OsmUtils.trueval.equals(oneValue) || OsmUtils.falseval.equals(oneValue))) {
219 if(def)
220 {
221 for (OsmPrimitive s : sel)
222 if(s.keys != null && s.keys.size() > 0) {
223 def = false;
224 }
225 }
226
227 // all selected objects share the same value which is either true or false or unset,
228 // we can display a standard check box.
229 initialState = OsmUtils.trueval.equals(oneValue) ?
230 QuadStateCheckBox.State.SELECTED :
231 OsmUtils.falseval.equals(oneValue) ?
232 QuadStateCheckBox.State.NOT_SELECTED :
233 def ? QuadStateCheckBox.State.SELECTED
234 : QuadStateCheckBox.State.UNSET;
235 check = new QuadStateCheckBox(locale_text, initialState,
236 new QuadStateCheckBox.State[] {
237 QuadStateCheckBox.State.SELECTED,
238 QuadStateCheckBox.State.NOT_SELECTED,
239 QuadStateCheckBox.State.UNSET });
240 } else {
241 def = false;
242 // the objects have different values, or one or more objects have something
243 // else than true/false. we display a quad-state check box
244 // in "partial" state.
245 initialState = QuadStateCheckBox.State.PARTIAL;
246 check = new QuadStateCheckBox(locale_text, QuadStateCheckBox.State.PARTIAL,
247 new QuadStateCheckBox.State[] {
248 QuadStateCheckBox.State.PARTIAL,
249 QuadStateCheckBox.State.SELECTED,
250 QuadStateCheckBox.State.NOT_SELECTED,
251 QuadStateCheckBox.State.UNSET });
252 }
253 p.add(check, GBC.eol().fill(GBC.HORIZONTAL));
254 return true;
255 }
256
257 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
258 // if the user hasn't changed anything, don't create a command.
259 if (check.getState() == initialState && !def) return;
260
261 // otherwise change things according to the selected value.
262 cmds.add(new ChangePropertyCommand(sel, key,
263 check.getState() == QuadStateCheckBox.State.SELECTED ? OsmUtils.trueval :
264 check.getState() == QuadStateCheckBox.State.NOT_SELECTED ? OsmUtils.falseval :
265 null));
266 }
267 @Override boolean requestFocusInWindow() {return check.requestFocusInWindow();}
268 }
269
270 public static class Combo extends Item {
271
272 public String key;
273 public String text;
274 public String locale_text;
275 public String values;
276 public String display_values;
277 public String locale_display_values;
278 public String default_;
279 public boolean delete_if_empty = false;
280 public boolean editable = true;
281 public boolean use_last_as_default = false;
282
283 private JComboBox combo;
284 private LinkedHashMap<String,String> lhm;
285 private Usage usage;
286 private String originalValue;
287
288 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
289
290 // find out if our key is already used in the selection.
291 usage = determineTextUsage(sel, key);
292
293 String[] value_array = values.split(",");
294 String[] display_array;
295 if(locale_display_values != null) {
296 display_array = locale_display_values.split(",");
297 } else if(display_values != null) {
298 display_array = display_values.split(",");
299 } else {
300 display_array = value_array;
301 }
302
303 lhm = new LinkedHashMap<String,String>();
304 if (!usage.allSimilar() && !usage.unused())
305 {
306 lhm.put(DIFFERENT, DIFFERENT);
307 }
308 for (int i=0; i<value_array.length; i++) {
309 lhm.put(value_array[i],
310 (locale_display_values == null) ?
311 tr(display_array[i]) : display_array[i]);
312 }
313 if(!usage.unused())
314 {
315 for (String s : usage.values) {
316 if (!lhm.containsKey(s)) {
317 lhm.put(s, s);
318 }
319 }
320 }
321 if (default_ != null && !lhm.containsKey(default_)) {
322 lhm.put(default_, default_);
323 }
324 if(!lhm.containsKey("")) {
325 lhm.put("", "");
326 }
327
328 combo = new JComboBox(lhm.values().toArray());
329 combo.setEditable(editable);
330 if (usage.allSimilar() && !usage.unused())
331 {
332 originalValue=usage.getFirst();
333 combo.setSelectedItem(lhm.get(originalValue));
334 }
335 // use default only in case it is a totally new entry
336 else if(default_ != null && !usage.hadKeys())
337 {
338 combo.setSelectedItem(default_);
339 originalValue=DIFFERENT;
340 }
341 else if(usage.unused())
342 {
343 combo.setSelectedItem("");
344 originalValue="";
345 }
346 else
347 {
348 combo.setSelectedItem(DIFFERENT);
349 originalValue=DIFFERENT;
350 }
351
352 if(locale_text == null) {
353 locale_text = tr(text);
354 }
355 p.add(new JLabel(locale_text+":"), GBC.std().insets(0,0,10,0));
356 p.add(combo, GBC.eol().fill(GBC.HORIZONTAL));
357 return true;
358 }
359 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
360 Object obj = combo.getSelectedItem();
361 String display = (obj == null) ? null : obj.toString();
362 String value = null;
363 if(display == null && combo.isEditable()) {
364 display = combo.getEditor().getItem().toString();
365 }
366
367 if (display != null)
368 {
369 for (String key : lhm.keySet()) {
370 String k = lhm.get(key);
371 if (k != null && k.equals(display)) {
372 value=key;
373 }
374 }
375 if(value == null) {
376 value = display;
377 }
378 } else {
379 value = "";
380 }
381
382 // no change if same as before
383 if (value.equals(originalValue) || (originalValue == null && (value == null || value.length() == 0))) return;
384
385 if (delete_if_empty && value != null && value.length() == 0) {
386 value = null;
387 }
388 cmds.add(new ChangePropertyCommand(sel, key, value));
389 }
390 @Override boolean requestFocusInWindow() {return combo.requestFocusInWindow();}
391 }
392
393 public static class Label extends Item {
394 public String text;
395 public String locale_text;
396
397 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
398 if(locale_text == null) {
399 locale_text = tr(text);
400 }
401 p.add(new JLabel(locale_text), GBC.eol());
402 return false;
403 }
404 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
405 }
406
407 public static class Link extends Item {
408 public String href;
409 public String text;
410 public String locale_text;
411 public String locale_href;
412
413 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
414 if(locale_text == null) {
415 locale_text = text == null ? tr("More information about this feature") : tr(text);
416 }
417 String url = locale_href;
418 if (url == null) {
419 url = href;
420 }
421 if (url != null) {
422 p.add(new UrlLabel(url, locale_text), GBC.eol().anchor(GBC.WEST));
423 }
424 return false;
425 }
426 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
427 }
428
429 public static class Optional extends Item {
430 // TODO: Draw a box around optional stuff
431 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
432 p.add(new JLabel(" "), GBC.eol()); // space
433 p.add(new JLabel(tr("Optional Attributes:")), GBC.eol());
434 p.add(new JLabel(" "), GBC.eol()); // space
435 return false;
436 }
437 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
438 }
439
440 public static class Space extends Item {
441 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
442 p.add(new JLabel(" "), GBC.eol()); // space
443 return false;
444 }
445 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
446 }
447
448 public static class Key extends Item {
449 public String key;
450 public String value;
451
452 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) { return false; }
453 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
454 cmds.add(new ChangePropertyCommand(sel, key, value != null && !value.equals("") ? value : null));
455 }
456 }
457
458 /**
459 * The types as preparsed collection.
460 */
461 public List<String> types;
462 public List<Item> data = new LinkedList<Item>();
463 private static HashMap<String,String> lastValue = new HashMap<String,String>();
464
465 /**
466 * Create an empty tagging preset. This will not have any items and
467 * will be an empty string as text. createPanel will return null.
468 * Use this as default item for "do not select anything".
469 */
470 public TaggingPreset() {}
471
472 /**
473 * Change the display name without changing the toolbar value.
474 */
475 public void setDisplayName() {
476 putValue(Action.NAME, getName());
477 putValue("toolbar", "tagging_" + getRawName());
478 putValue(SHORT_DESCRIPTION, (group != null ?
479 tr("Use preset ''{0}'' of group ''{1}''", getLocaleName(), group.getName()) :
480 tr("Use preset ''{0}''", getLocaleName())));
481 }
482
483 public String getLocaleName() {
484 if(locale_name == null) {
485 locale_name = tr(name);
486 }
487 return locale_name;
488 }
489
490 public String getName() {
491 return group != null ? group.getName() + "/" + getLocaleName() : getLocaleName();
492 }
493 public String getRawName() {
494 return group != null ? group.getRawName() + "/" + name : name;
495 }
496 /**
497 * Called from the XML parser to set the icon
498 *
499 * FIXME for Java 1.6 - use 24x24 icons for LARGE_ICON_KEY (button bar)
500 * and the 16x16 icons for SMALL_ICON.
501 */
502 public void setIcon(String iconName) {
503 Collection<String> s = Main.pref.getCollection("taggingpreset.icon.sources", null);
504 ImageIcon icon = ImageProvider.getIfAvailable(s, "presets", null, iconName);
505 if (icon == null)
506 {
507 System.out.println("Could not get presets icon " + iconName);
508 icon = new ImageIcon(iconName);
509 }
510 if (Math.max(icon.getIconHeight(), icon.getIconWidth()) != 16) {
511 icon = new ImageIcon(icon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
512 }
513 putValue(Action.SMALL_ICON, icon);
514 }
515
516 /**
517 * Called from the XML parser to set the types this preset affects
518 */
519 private static Collection<String> allowedtypes = Arrays.asList(new String[]
520 {marktr("way"), marktr("node"), marktr("relation"), marktr("closedway")});
521 public void setType(String types) throws SAXException {
522 this.types = Arrays.asList(types.split(","));
523 for (String type : this.types) {
524 if(!allowedtypes.contains(type))
525 throw new SAXException(tr("Unknown type: {0}", type));
526 }
527 }
528
529 public static List<TaggingPreset> readAll(Reader in) throws SAXException {
530 XmlObjectParser parser = new XmlObjectParser();
531 parser.mapOnStart("item", TaggingPreset.class);
532 parser.mapOnStart("separator", TaggingPresetSeparator.class);
533 parser.mapBoth("group", TaggingPresetMenu.class);
534 parser.map("text", Text.class);
535 parser.map("link", Link.class);
536 parser.mapOnStart("optional", Optional.class);
537 parser.map("check", Check.class);
538 parser.map("combo", Combo.class);
539 parser.map("label", Label.class);
540 parser.map("space", Space.class);
541 parser.map("key", Key.class);
542 LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>();
543 TaggingPresetMenu lastmenu = null;
544 parser.start(in);
545 while(parser.hasNext()) {
546 Object o = parser.next();
547 if (o instanceof TaggingPresetMenu) {
548 TaggingPresetMenu tp = (TaggingPresetMenu) o;
549 if(tp == lastmenu) {
550 lastmenu = tp.group;
551 } else
552 {
553 tp.setDisplayName();
554 tp.group = lastmenu;
555 lastmenu = tp;
556 all.add(tp);
557 Main.toolbar.register(tp);
558
559 }
560 } else if (o instanceof TaggingPresetSeparator) {
561 TaggingPresetSeparator tp = (TaggingPresetSeparator) o;
562 tp.group = lastmenu;
563 all.add(tp);
564 } else if (o instanceof TaggingPreset) {
565 TaggingPreset tp = (TaggingPreset) o;
566 tp.group = lastmenu;
567 tp.setDisplayName();
568 all.add(tp);
569 Main.toolbar.register(tp);
570 } else {
571 all.getLast().data.add((Item)o);
572 }
573 }
574 return all;
575 }
576
577 public static Collection<TaggingPreset> readFromPreferences() {
578 LinkedList<TaggingPreset> allPresets = new LinkedList<TaggingPreset>();
579 LinkedList<String> sources = new LinkedList<String>();
580
581 if(Main.pref.getBoolean("taggingpreset.enable-defaults", true)) {
582 sources.add("resource://presets/presets.xml");
583 }
584 sources.addAll(Main.pref.getCollection("taggingpreset.sources", new LinkedList<String>()));
585
586 for(String source : sources)
587 {
588 try {
589 MirroredInputStream s = new MirroredInputStream(source);
590 InputStreamReader r;
591 try
592 {
593 r = new InputStreamReader(s, "UTF-8");
594 }
595 catch (UnsupportedEncodingException e)
596 {
597 r = new InputStreamReader(s);
598 }
599 allPresets.addAll(TaggingPreset.readAll(new BufferedReader(r)));
600 } catch (IOException e) {
601 e.printStackTrace();
602 JOptionPane.showMessageDialog(Main.parent, tr("Could not read tagging preset source: {0}",source));
603 } catch (SAXException e) {
604 e.printStackTrace();
605 JOptionPane.showMessageDialog(Main.parent, tr("Error parsing {0}: ", source)+e.getMessage());
606 }
607 }
608 return allPresets;
609 }
610
611 private class PresetPanel extends JPanel {
612 boolean hasElements = false;
613 PresetPanel()
614 {
615 super(new GridBagLayout());
616 }
617 }
618
619 public PresetPanel createPanel(Collection<OsmPrimitive> selected) {
620 if (data == null)
621 return null;
622 PresetPanel p = new PresetPanel();
623 LinkedList<Item> l = new LinkedList<Item>();
624 if(types != null)
625 {
626 JPanel pp = new JPanel();
627 for(String t : types)
628 {
629 JLabel la = new JLabel(ImageProvider.get("Mf_" + t));
630 la.setToolTipText(tr("Elements of type {0} are supported.", tr(t)));
631 pp.add(la);
632 }
633 p.add(pp, GBC.eol());
634 }
635
636 for (Item i : data)
637 {
638 if(i instanceof Link) {
639 l.add(i);
640 } else
641 {
642 if(i.addToPanel(p, selected)) {
643 p.hasElements = true;
644 }
645 }
646 }
647 for(Item link : l) {
648 link.addToPanel(p, selected);
649 }
650 return p;
651 }
652
653 public void actionPerformed(ActionEvent e) {
654 Collection<OsmPrimitive> sel = createSelection(Main.main.getCurrentDataSet().getSelected());
655 PresetPanel p = createPanel(sel);
656 if (p == null)
657 return;
658
659 int answer = 1;
660 if (p.getComponentCount() != 0 && (sel.size() == 0 || p.hasElements)) {
661 String title = trn("Change {0} object", "Change {0} objects", sel.size(), sel.size());
662 if(sel.size() == 0) {
663 if(originalSelectionEmpty) {
664 title = tr("Nothing selected!");
665 } else {
666 title = tr("Selection unsuitable!");
667 }
668 }
669
670 class PresetDialog extends ExtendedDialog {
671 public PresetDialog(Component content, String title, boolean disableApply) {
672 super(Main.parent,
673 title,
674 new String[] { tr("Apply Preset"), tr("Cancel") },
675 true);
676 contentConstraints = GBC.eol().fill().insets(5,10,5,0);
677 setupDialog(content, new String[] {"ok.png", "cancel.png" });
678 buttons.get(0).setEnabled(!disableApply);
679 buttons.get(0).setToolTipText(title);
680 setVisible(true);
681 }
682 }
683
684 answer = new PresetDialog(p, title, (sel.size() == 0)).getValue();
685 }
686 if (sel.size() != 0 && answer == 1) {
687 Command cmd = createCommand(sel);
688 if (cmd != null) {
689 Main.main.undoRedo.add(cmd);
690 }
691 }
692 Main.main.getCurrentDataSet().setSelected(Main.main.getCurrentDataSet().getSelected()); // force update
693 }
694
695 /**
696 * True whenever the original selection given into createSelection was empty
697 */
698 private boolean originalSelectionEmpty = false;
699
700 /**
701 * Removes all unsuitable OsmPrimitives from the given list
702 * @param participants List of possibile OsmPrimitives to tag
703 * @return Cleaned list with suitable OsmPrimitives only
704 */
705 private Collection<OsmPrimitive> createSelection(Collection<OsmPrimitive> participants) {
706 originalSelectionEmpty = participants.size() == 0;
707 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
708 for (OsmPrimitive osm : participants)
709 {
710 if (types != null)
711 {
712 if(osm instanceof Relation)
713 {
714 if(!types.contains("relation")) {
715 continue;
716 }
717 }
718 else if(osm instanceof Node)
719 {
720 if(!types.contains("node")) {
721 continue;
722 }
723 }
724 else if(osm instanceof Way)
725 {
726 if(!types.contains("way") &&
727 !(types.contains("closedway") && ((Way)osm).isClosed())) {
728 continue;
729 }
730 }
731 }
732 sel.add(osm);
733 }
734 return sel;
735 }
736
737 private Command createCommand(Collection<OsmPrimitive> sel) {
738 List<Command> cmds = new LinkedList<Command>();
739 for (Item i : data) {
740 i.addCommands(sel, cmds);
741 }
742 if (cmds.size() == 0)
743 return null;
744 else if (cmds.size() == 1)
745 return cmds.get(0);
746 else
747 return new SequenceCommand(tr("Change Properties"), cmds);
748 }
749}
Note: See TracBrowser for help on using the repository browser.