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

Last change on this file since 298 was 298, checked in by imi, 17 years ago
  • added license description to head of each source file
File size: 10.0 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.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.GridBagLayout;
8import java.awt.Image;
9import java.awt.event.ActionEvent;
10import java.io.BufferedReader;
11import java.io.FileInputStream;
12import java.io.IOException;
13import java.io.InputStream;
14import java.io.InputStreamReader;
15import java.io.UnsupportedEncodingException;
16import java.net.URL;
17import java.util.Collection;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.StringTokenizer;
21
22import javax.swing.AbstractAction;
23import javax.swing.Action;
24import javax.swing.ImageIcon;
25import javax.swing.JCheckBox;
26import javax.swing.JComboBox;
27import javax.swing.JLabel;
28import javax.swing.JOptionPane;
29import javax.swing.JPanel;
30import javax.swing.JTextField;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.command.ChangePropertyCommand;
34import org.openstreetmap.josm.command.Command;
35import org.openstreetmap.josm.command.SequenceCommand;
36import org.openstreetmap.josm.data.osm.OsmPrimitive;
37import org.openstreetmap.josm.tools.GBC;
38import org.openstreetmap.josm.tools.ImageProvider;
39import org.openstreetmap.josm.tools.XmlObjectParser;
40import org.xml.sax.SAXException;
41
42
43/**
44 * This class read encapsulate one tagging preset. A class method can
45 * read in all predefined presets, either shipped with JOSM or that are
46 * in the config directory.
47 *
48 * It is also able to construct dialogs out of preset definitions.
49 */
50public class TaggingPreset extends AbstractAction {
51
52 public static abstract class Item {
53 public boolean focus = false;
54 abstract void addToPanel(JPanel p);
55 abstract void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds);
56 boolean requestFocusInWindow() {return false;}
57 }
58
59 public static class Text extends Item {
60 public String key;
61 public String text;
62 public String default_;
63 public boolean delete_if_empty = false;
64
65 private JTextField value = new JTextField();
66
67 @Override public void addToPanel(JPanel p) {
68 value.setText(default_ == null ? "" : default_);
69 p.add(new JLabel(text), GBC.std().insets(0,0,10,0));
70 p.add(value, GBC.eol().fill(GBC.HORIZONTAL));
71 }
72 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
73 String v = value.getText();
74 if (delete_if_empty && v.length() == 0)
75 v = null;
76 cmds.add(new ChangePropertyCommand(sel, key, v));
77 }
78 @Override boolean requestFocusInWindow() {return value.requestFocusInWindow();}
79 }
80
81 public static class Check extends Item {
82 public String key;
83 public String text;
84 public boolean default_ = false;
85
86 private JCheckBox check = new JCheckBox();
87
88 @Override public void addToPanel(JPanel p) {
89 check.setSelected(default_);
90 check.setText(text);
91 p.add(check, GBC.eol().fill(GBC.HORIZONTAL));
92 }
93 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
94 cmds.add(new ChangePropertyCommand(sel, key, check.isSelected() ? "true" : null));
95 }
96 @Override boolean requestFocusInWindow() {return check.requestFocusInWindow();}
97 }
98
99 public static class Combo extends Item {
100 public String key;
101 public String text;
102 public String values;
103 public String display_values;
104 public String default_;
105 public boolean delete_if_empty = false;
106 public boolean editable = true;
107
108 private JComboBox combo;
109
110 @Override public void addToPanel(JPanel p) {
111 combo = new JComboBox((display_values != null ? display_values : values).split(","));
112 combo.setEditable(editable);
113 combo.setSelectedItem(default_);
114 p.add(new JLabel(text), GBC.std().insets(0,0,10,0));
115 p.add(combo, GBC.eol().fill(GBC.HORIZONTAL));
116 }
117 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
118 String v = combo.getSelectedIndex() == -1 ? null : values.split(",")[combo.getSelectedIndex()];
119 String str = combo.isEditable()?combo.getEditor().getItem().toString() : v;
120 if (delete_if_empty && str != null && str.length() == 0)
121 str = null;
122 cmds.add(new ChangePropertyCommand(sel, key, str));
123 }
124 @Override boolean requestFocusInWindow() {return combo.requestFocusInWindow();}
125 }
126
127 public static class Label extends Item {
128 public String text;
129
130 @Override public void addToPanel(JPanel p) {
131 p.add(new JLabel(text), GBC.eol());
132 }
133 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
134 }
135
136 public static class Key extends Item {
137 public String key;
138 public String value;
139
140 @Override public void addToPanel(JPanel p) {}
141 @Override public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
142 cmds.add(new ChangePropertyCommand(sel, key, value != null && !value.equals("") ? value : null));
143 }
144 }
145
146 /**
147 * The types as preparsed collection.
148 */
149 public Collection<Class<?>> types;
150 private List<Item> data = new LinkedList<Item>();
151
152 /**
153 * Create an empty tagging preset. This will not have any items and
154 * will be an empty string as text. createPanel will return null.
155 * Use this as default item for "do not select anything".
156 */
157 public TaggingPreset() {}
158
159 /**
160 * Called from the XML parser to set the name of the tagging preset
161 */
162 public void setName(String name) {
163 putValue(Action.NAME, name);
164 putValue("toolbar", "tagging_"+name);
165 }
166
167 /**
168 * Called from the XML parser to set the icon
169 */
170 public void setIcon(String iconName) {
171 ImageIcon icon = ImageProvider.getIfAvailable(null, iconName);
172 if (icon == null)
173 icon = new ImageIcon(iconName);
174 if (Math.max(icon.getIconHeight(), icon.getIconWidth()) != 24)
175 icon = new ImageIcon(icon.getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH));
176 putValue(Action.SMALL_ICON, icon);
177 }
178
179 /**
180 * Called from the XML parser to set the types, this preset affects
181 */
182 public void setType(String types) throws SAXException {
183 try {
184 for (String type : types.split(",")) {
185 type = Character.toUpperCase(type.charAt(0))+type.substring(1);
186 if (this.types == null)
187 this.types = new LinkedList<Class<?>>();
188 this.types.add(Class.forName("org.openstreetmap.josm.data.osm."+type));
189 }
190 } catch (ClassNotFoundException e) {
191 e.printStackTrace();
192 throw new SAXException(tr("Unknown type"));
193 }
194 }
195
196 public static List<TaggingPreset> readAll(InputStream inStream) throws SAXException {
197 BufferedReader in = null;
198 try {
199 in = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
200 } catch (UnsupportedEncodingException e) {
201 e.printStackTrace();
202 in = new BufferedReader(new InputStreamReader(inStream));
203 }
204 XmlObjectParser parser = new XmlObjectParser();
205 parser.mapOnStart("item", TaggingPreset.class);
206 parser.map("text", Text.class);
207 parser.map("check", Check.class);
208 parser.map("combo", Combo.class);
209 parser.map("label", Label.class);
210 parser.map("key", Key.class);
211 LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>();
212 parser.start(in);
213 while(parser.hasNext()) {
214 Object o = parser.next();
215 if (o instanceof TaggingPreset) {
216 all.add((TaggingPreset)o);
217 Main.toolbar.register((TaggingPreset)o);
218 } else
219 all.getLast().data.add((Item)o);
220 }
221 return all;
222 }
223
224 public static Collection<TaggingPreset> readFromPreferences() {
225 LinkedList<TaggingPreset> allPresets = new LinkedList<TaggingPreset>();
226 String allTaggingPresets = Main.pref.get("taggingpreset.sources");
227 StringTokenizer st = new StringTokenizer(allTaggingPresets, ";");
228 while (st.hasMoreTokens()) {
229 InputStream in = null;
230 String source = st.nextToken();
231 try {
232 if (source.startsWith("http") || source.startsWith("ftp") || source.startsWith("file"))
233 in = new URL(source).openStream();
234 else if (source.startsWith("resource://"))
235 in = Main.class.getResourceAsStream(source.substring("resource:/".length()));
236 else
237 in = new FileInputStream(source);
238 allPresets.addAll(TaggingPreset.readAll(in));
239 in.close();
240 } catch (IOException e) {
241 e.printStackTrace();
242 JOptionPane.showMessageDialog(Main.parent, tr("Could not read tagging preset source: {0}",source));
243 } catch (SAXException e) {
244 e.printStackTrace();
245 JOptionPane.showMessageDialog(Main.parent, tr("Error parsing {0}: ", source)+e.getMessage());
246 }
247 }
248 return allPresets;
249 }
250
251
252 public JPanel createPanel() {
253 if (data == null)
254 return null;
255 JPanel p = new JPanel(new GridBagLayout());
256 for (Item i : data)
257 i.addToPanel(p);
258 return p;
259 }
260
261 public void actionPerformed(ActionEvent e) {
262 Collection<OsmPrimitive> sel = Main.ds.getSelected();
263 JPanel p = createPanel();
264 if (p == null)
265 return;
266 int answer = JOptionPane.OK_OPTION;
267 if (p.getComponentCount() != 0) {
268 final JOptionPane optionPane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION){
269 @Override public void selectInitialValue() {
270 for (Item i : data) {
271 if (i.focus) {
272 System.out.println(i.requestFocusInWindow());
273 return;
274 }
275 }
276 }
277 };
278 optionPane.createDialog(Main.parent, trn("Change {0} object", "Change {0} objects", sel.size(), sel.size())).setVisible(true);
279 Object answerObj = optionPane.getValue();
280 if (answerObj == null || answerObj == JOptionPane.UNINITIALIZED_VALUE ||
281 (answerObj instanceof Integer && (Integer)answerObj != JOptionPane.OK_OPTION))
282 answer = JOptionPane.CANCEL_OPTION;
283 }
284 if (answer == JOptionPane.OK_OPTION) {
285 Command cmd = createCommand(Main.ds.getSelected());
286 if (cmd != null)
287 Main.main.editLayer().add(cmd);
288 }
289 Main.ds.setSelected(Main.ds.getSelected()); // force update
290 }
291
292 private Command createCommand(Collection<OsmPrimitive> participants) {
293 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
294 for (OsmPrimitive osm : participants)
295 if (types == null || types.contains(osm.getClass()))
296 sel.add(osm);
297 if (sel.isEmpty())
298 return null;
299
300 List<Command> cmds = new LinkedList<Command>();
301 for (Item i : data)
302 i.addCommands(sel, cmds);
303 if (cmds.size() == 0)
304 return null;
305 else if (cmds.size() == 1)
306 return cmds.get(0);
307 else
308 return new SequenceCommand(tr("Change Properties"), cmds);
309 }
310}
Note: See TracBrowser for help on using the repository browser.