source: josm/src/org/openstreetmap/josm/gui/annotation/AnnotationPreset.java@ 129

Last change on this file since 129 was 129, checked in by imi, 18 years ago
  • fixed combo box display in annotation preset tester
  • fixed NPE in GeoImageLayer
File size: 8.6 KB
Line 
1package org.openstreetmap.josm.gui.annotation;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.awt.GridBagLayout;
7import java.io.BufferedReader;
8import java.io.IOException;
9import java.io.InputStream;
10import java.io.InputStreamReader;
11import java.io.UnsupportedEncodingException;
12import java.util.Collection;
13import java.util.LinkedList;
14import java.util.List;
15
16import javax.swing.JCheckBox;
17import javax.swing.JComboBox;
18import javax.swing.JLabel;
19import javax.swing.JPanel;
20import javax.swing.JTextField;
21
22import org.openstreetmap.josm.command.ChangePropertyCommand;
23import org.openstreetmap.josm.command.Command;
24import org.openstreetmap.josm.command.SequenceCommand;
25import org.openstreetmap.josm.data.osm.OsmPrimitive;
26import org.openstreetmap.josm.tools.GBC;
27import org.xml.sax.Attributes;
28import org.xml.sax.SAXException;
29
30import uk.co.wilson.xml.MinML2;
31
32
33/**
34 * This class read encapsulate one annotation preset. A class method can
35 * read in all predefined presets, either shipped with JOSM or that are
36 * in the config directory.
37 *
38 * It is also able to construct dialogs out of preset definitions.
39 */
40public class AnnotationPreset {
41
42 private static interface Item {
43 void addToPanel(JPanel p);
44 void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds);
45 }
46
47 public static class Text implements Item {
48 String key;
49 String label;
50 JTextField value = new JTextField();
51
52 public void addToPanel(JPanel p) {
53 p.add(new JLabel(label), GBC.std().insets(0,0,10,0));
54 p.add(value, GBC.eol().fill(GBC.HORIZONTAL));
55 }
56 public Text(String key, String label, String value) {
57 this.key = key;
58 this.label = label;
59 this.value.setText(value == null ? "" : value);
60 }
61 public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
62 cmds.add(new ChangePropertyCommand(sel, key, value.getText()));
63 }
64 }
65
66 public static class Check implements Item {
67 String key;
68 JCheckBox check = new JCheckBox();
69
70 public void addToPanel(JPanel p) {
71 p.add(check, GBC.eol().fill(GBC.HORIZONTAL));
72 }
73 public Check(String key, String label, boolean check) {
74 this.key = key;
75 this.check.setText(label);
76 this.check.setSelected(check);
77 }
78 public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
79 cmds.add(new ChangePropertyCommand(sel, key, check.isSelected() ? "true" : null));
80 }
81 }
82
83 public static class Combo implements Item {
84 String key;
85 String label;
86 JComboBox combo;
87 private final String[] values;
88
89 public void addToPanel(JPanel p) {
90 p.add(new JLabel(label), GBC.std().insets(0,0,10,0));
91 p.add(combo, GBC.eol().fill(GBC.HORIZONTAL));
92 }
93 public Combo(String key, String label, String def, String[] values, String[] displayedValues, boolean editable) {
94 this.key = key;
95 this.label = label;
96 this.values = values;
97 combo = new JComboBox(displayedValues);
98 combo.setEditable(editable);
99 combo.setSelectedItem(def);
100 }
101 public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
102 String v = combo.getSelectedIndex() == -1 ? null : values[combo.getSelectedIndex()];
103 String str = combo.isEditable()?combo.getEditor().getItem().toString() : v;
104 cmds.add(new ChangePropertyCommand(sel, key, str));
105 }
106 }
107
108 public static class Label implements Item {
109 String text;
110
111 public void addToPanel(JPanel p) {
112 p.add(new JLabel(text), GBC.eol());
113 }
114 public Label(String text) {
115 this.text = text;
116 }
117 public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
118 }
119
120 public static class Key implements Item {
121 String key;
122 String value;
123
124 public void addToPanel(JPanel p) {}
125 public Key(String key, String value) {
126 this.key = key;
127 this.value = value;
128 }
129 public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
130 cmds.add(new ChangePropertyCommand(sel, key, value != null && !value.equals("") ? value : null));
131 }
132 }
133
134 private static class Parser extends MinML2 {
135 List<AnnotationPreset> data = new LinkedList<AnnotationPreset>();
136 List<Item> current;
137 String currentName;
138 Collection<Class<?>> currentTypes;
139 private static int unknownCounter = 1;
140
141 @Override public void startElement(String ns, String lname, String qname, Attributes a) throws SAXException {
142 if (qname.equals("annotations"))
143 return;
144 if (qname.equals("item")) {
145 current = new LinkedList<Item>();
146 currentName = a.getValue("name");
147 if (currentName == null)
148 currentName = "Unnamed Preset #"+(unknownCounter++);
149 if (a.getValue("type") != null) {
150 String s = a.getValue("type");
151 try {
152 for (String type : s.split(",")) {
153 type = Character.toUpperCase(type.charAt(0))+type.substring(1);
154 if (currentTypes == null)
155 currentTypes = new LinkedList<Class<?>>();
156 currentTypes.add(Class.forName("org.openstreetmap.josm.data.osm."+type));
157 }
158 } catch (ClassNotFoundException e) {
159 e.printStackTrace();
160 throw new SAXException(tr("Unknown type at line {0}", getLineNumber()));
161 }
162 }
163 } else if (qname.equals("text"))
164 current.add(new Text(a.getValue("key"), a.getValue("text"), a.getValue("default")));
165 else if (qname.equals("check")) {
166 String s = a.getValue("default");
167 boolean clear = s == null || s.equals("0") || s.startsWith("off") || s.startsWith("false") || s.startsWith("no");
168 current.add(new Check(a.getValue("key"), a.getValue("text"), !clear));
169 } else if (qname.equals("label"))
170 current.add(new Label(a.getValue("text")));
171 else if (qname.equals("combo")) {
172 String[] values = a.getValue("values").split(",");
173 String s = a.getValue("readonly");
174 String dvstr = a.getValue("display_values");
175 boolean editable = s == null || s.equals("0") || s.startsWith("off") || s.startsWith("false") || s.startsWith("no");
176 if (dvstr != null) {
177 if (editable && s != null)
178 throw new SAXException(tr("Cannot have a writable combobox with default values (line {0})", getLineNumber()));
179 editable = false; // for combos with display_value readonly default to false
180 }
181 String[] displayValues = dvstr == null ? values : dvstr.split(",");
182 if (displayValues.length != values.length)
183 throw new SAXException(tr("display_values ({0}) and values ({1}) must be of same number of elements.",
184 displayValues.length+" "+trn("element", "elements", displayValues.length),
185 values.length+" "+trn("element", "elements", values.length)));
186 current.add(new Combo(a.getValue("key"), a.getValue("text"), a.getValue("default"), values, displayValues, editable));
187 } else if (qname.equals("key"))
188 current.add(new Key(a.getValue("key"), a.getValue("value")));
189 else
190 throw new SAXException(tr("Unknown annotation object {0} at line {1} column {2}", qname, getLineNumber(), getColumnNumber()));
191 }
192
193 @Override public void endElement(String ns, String lname, String qname) {
194 if (qname.equals("item")) {
195 data.add(new AnnotationPreset(current, currentName, currentTypes));
196 current = null;
197 currentName = null;
198 currentTypes = null;
199 }
200 }
201 }
202
203 private List<Item> data;
204 public String name;
205 public Collection<Class<?>> types;
206
207 public AnnotationPreset(List<Item> data, String name, Collection<Class<?>> currentTypes) {
208 this.data = data;
209 this.name = name;
210 this.types = currentTypes;
211 }
212
213 /**
214 * Create an empty annotation preset. This will not have any items and
215 * will be an empty string as text. createPanel will return null.
216 * Use this as default item for "do not select anything".
217 */
218 public AnnotationPreset() {}
219
220 public static List<AnnotationPreset> readAll(InputStream inStream) throws IOException, SAXException {
221 BufferedReader in = null;
222 try {
223 in = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
224 } catch (UnsupportedEncodingException e) {
225 e.printStackTrace();
226 in = new BufferedReader(new InputStreamReader(inStream));
227 }
228 Parser p = new Parser();
229 p.parse(in);
230 return p.data;
231 }
232
233 public JPanel createPanel() {
234 if (data == null)
235 return null;
236 JPanel p = new JPanel(new GridBagLayout());
237 for (Item i : data)
238 i.addToPanel(p);
239 return p;
240 }
241
242 public Command createCommand(Collection<OsmPrimitive> participants) {
243 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
244 for (OsmPrimitive osm : participants)
245 if (types == null || types.contains(osm.getClass()))
246 sel.add(osm);
247 if (sel.isEmpty())
248 return null;
249
250 List<Command> cmds = new LinkedList<Command>();
251 for (Item i : data)
252 i.addCommands(sel, cmds);
253 if (cmds.size() == 0)
254 return null;
255 else if (cmds.size() == 1)
256 return cmds.get(0);
257 else
258 return new SequenceCommand(tr("Change Properties"), cmds);
259 }
260}
Note: See TracBrowser for help on using the repository browser.