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

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

replaced JOptionPane.show* by OptionPaneUtil.show*
ExtendeDialog now always on top, too

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