source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/map/TaggingPresetPreference.java@ 6380

Last change on this file since 6380 was 6380, checked in by Don-vip, 10 years ago

update license/copyright information

  • Property svn:eol-style set to native
File size: 14.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.map;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.GridBagLayout;
8import java.io.IOException;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15
16import javax.swing.BorderFactory;
17import javax.swing.JCheckBox;
18import javax.swing.JLabel;
19import javax.swing.JMenu;
20import javax.swing.JMenuItem;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JSeparator;
24import javax.swing.event.ChangeEvent;
25import javax.swing.event.ChangeListener;
26
27import org.openstreetmap.josm.Main;
28import org.openstreetmap.josm.gui.ExtendedDialog;
29import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
30import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
31import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
32import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane.ValidationListener;
33import org.openstreetmap.josm.gui.preferences.SourceEditor;
34import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
35import org.openstreetmap.josm.gui.preferences.SourceEntry;
36import org.openstreetmap.josm.gui.preferences.SourceProvider;
37import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
38import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
39import org.openstreetmap.josm.gui.tagging.TaggingPreset;
40import org.openstreetmap.josm.gui.tagging.TaggingPresetMenu;
41import org.openstreetmap.josm.gui.tagging.TaggingPresetReader;
42import org.openstreetmap.josm.gui.tagging.TaggingPresetSeparator;
43import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
44import org.openstreetmap.josm.tools.GBC;
45import org.xml.sax.SAXException;
46import org.xml.sax.SAXParseException;
47
48public final class TaggingPresetPreference implements SubPreferenceSetting {
49
50 public static class Factory implements PreferenceSettingFactory {
51 @Override
52 public PreferenceSetting createPreferenceSetting() {
53 return new TaggingPresetPreference();
54 }
55 }
56
57 private TaggingPresetPreference() {
58 super();
59 }
60
61 private static final List<SourceProvider> presetSourceProviders = new ArrayList<SourceProvider>();
62 public static Collection<TaggingPreset> taggingPresets;
63 private SourceEditor sources;
64 private JCheckBox sortMenu;
65
66 public static final boolean registerSourceProvider(SourceProvider provider) {
67 if (provider != null)
68 return presetSourceProviders.add(provider);
69 return false;
70 }
71
72 private ValidationListener validationListener = new ValidationListener() {
73 @Override
74 public boolean validatePreferences() {
75 if (sources.hasActiveSourcesChanged()) {
76 List<Integer> sourcesToRemove = new ArrayList<Integer>();
77 int i = -1;
78 SOURCES:
79 for (SourceEntry source: sources.getActiveSources()) {
80 i++;
81 boolean canLoad = false;
82 try {
83 TaggingPresetReader.readAll(source.url, false);
84 canLoad = true;
85 } catch (IOException e) {
86 Main.warn(tr("Could not read tagging preset source: {0}", source));
87 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Error"),
88 new String[] {tr("Yes"), tr("No"), tr("Cancel")});
89 ed.setContent(tr("Could not read tagging preset source: {0}\nDo you want to keep it?", source));
90 switch (ed.showDialog().getValue()) {
91 case 1:
92 continue SOURCES;
93 case 2:
94 sourcesToRemove.add(i);
95 continue SOURCES;
96 default:
97 return false;
98 }
99 } catch (SAXException e) {
100 // We will handle this in step with validation
101 }
102
103 String errorMessage = null;
104
105 try {
106 TaggingPresetReader.readAll(source.url, true);
107 } catch (IOException e) {
108 // Should not happen, but at least show message
109 String msg = tr("Could not read tagging preset source {0}", source);
110 Main.error(msg);
111 JOptionPane.showMessageDialog(Main.parent, msg);
112 return false;
113 } catch (SAXParseException e) {
114 if (canLoad) {
115 errorMessage = tr("<html>Tagging preset source {0} can be loaded but it contains errors. " +
116 "Do you really want to use it?<br><br><table width=600>Error is: [{1}:{2}] {3}</table></html>",
117 source, e.getLineNumber(), e.getColumnNumber(), e.getMessage());
118 } else {
119 errorMessage = tr("<html>Unable to parse tagging preset source: {0}. " +
120 "Do you really want to use it?<br><br><table width=400>Error is: [{1}:{2}] {3}</table></html>",
121 source, e.getLineNumber(), e.getColumnNumber(), e.getMessage());
122 }
123 } catch (SAXException e) {
124 if (canLoad) {
125 errorMessage = tr("<html>Tagging preset source {0} can be loaded but it contains errors. " +
126 "Do you really want to use it?<br><br><table width=600>Error is: {1}</table></html>",
127 source, e.getMessage());
128 } else {
129 errorMessage = tr("<html>Unable to parse tagging preset source: {0}. " +
130 "Do you really want to use it?<br><br><table width=600>Error is: {1}</table></html>",
131 source, e.getMessage());
132 }
133
134 }
135
136 if (errorMessage != null) {
137 Main.error(errorMessage);
138 int result = JOptionPane.showConfirmDialog(Main.parent, new JLabel(errorMessage), tr("Error"),
139 JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE);
140
141 switch (result) {
142 case JOptionPane.YES_OPTION:
143 continue SOURCES;
144 case JOptionPane.NO_OPTION:
145 sourcesToRemove.add(i);
146 continue SOURCES;
147 default:
148 return false;
149 }
150 }
151 }
152 sources.removeSources(sourcesToRemove);
153 return true;
154 } else
155 return true;
156 }
157 };
158
159 @Override
160 public void addGui(final PreferenceTabbedPane gui) {
161 sortMenu = new JCheckBox(tr("Sort presets menu"),
162 Main.pref.getBoolean("taggingpreset.sortmenu", false));
163
164 final JPanel panel = new JPanel(new GridBagLayout());
165 panel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
166 panel.add(sortMenu, GBC.eol().insets(5,5,5,0));
167 sources = new TaggingPresetSourceEditor();
168 panel.add(sources, GBC.eol().fill(GBC.BOTH));
169 gui.getMapPreference().addSubTab(this, tr("Tagging Presets"), panel);
170
171 // this defers loading of tagging preset sources to the first time the tab
172 // with the tagging presets is selected by the user
173 //
174 gui.getMapPreference().getTabPane().addChangeListener(
175 new ChangeListener() {
176 @Override
177 public void stateChanged(ChangeEvent e) {
178 if (gui.getMapPreference().getTabPane().getSelectedComponent() == panel) {
179 sources.initiallyLoadAvailableSources();
180 }
181 }
182 }
183 );
184 gui.addValidationListener(validationListener);
185 }
186
187 static class TaggingPresetSourceEditor extends SourceEditor {
188
189 private static final String iconpref = "taggingpreset.icon.sources";
190
191 public TaggingPresetSourceEditor() {
192 super(false, Main.JOSM_WEBSITE+"/presets", presetSourceProviders);
193 }
194
195 @Override
196 public Collection<? extends SourceEntry> getInitialSourcesList() {
197 return PresetPrefHelper.INSTANCE.get();
198 }
199
200 @Override
201 public boolean finish() {
202 List<SourceEntry> activeStyles = activeSourcesModel.getSources();
203
204 boolean changed = PresetPrefHelper.INSTANCE.put(activeStyles);
205
206 if (tblIconPaths != null) {
207 List<String> iconPaths = iconPathsModel.getIconPaths();
208
209 if (!iconPaths.isEmpty()) {
210 if (Main.pref.putCollection(iconpref, iconPaths)) {
211 changed = true;
212 }
213 } else if (Main.pref.putCollection(iconpref, null)) {
214 changed = true;
215 }
216 }
217 return changed;
218 }
219
220 @Override
221 public Collection<ExtendedSourceEntry> getDefault() {
222 return PresetPrefHelper.INSTANCE.getDefault();
223 }
224
225 @Override
226 public Collection<String> getInitialIconPathsList() {
227 return Main.pref.getCollection(iconpref, null);
228 }
229
230 @Override
231 public String getStr(I18nString ident) {
232 switch (ident) {
233 case AVAILABLE_SOURCES:
234 return tr("Available presets:");
235 case ACTIVE_SOURCES:
236 return tr("Active presets:");
237 case NEW_SOURCE_ENTRY_TOOLTIP:
238 return tr("Add a new preset by entering filename or URL");
239 case NEW_SOURCE_ENTRY:
240 return tr("New preset entry:");
241 case REMOVE_SOURCE_TOOLTIP:
242 return tr("Remove the selected presets from the list of active presets");
243 case EDIT_SOURCE_TOOLTIP:
244 return tr("Edit the filename or URL for the selected active preset");
245 case ACTIVATE_TOOLTIP:
246 return tr("Add the selected available presets to the list of active presets");
247 case RELOAD_ALL_AVAILABLE:
248 return marktr("Reloads the list of available presets from ''{0}''");
249 case LOADING_SOURCES_FROM:
250 return marktr("Loading preset sources from ''{0}''");
251 case FAILED_TO_LOAD_SOURCES_FROM:
252 return marktr("<html>Failed to load the list of preset sources from<br>"
253 + "''{0}''.<br>"
254 + "<br>"
255 + "Details (untranslated):<br>{1}</html>");
256 case FAILED_TO_LOAD_SOURCES_FROM_HELP_TOPIC:
257 return "/Preferences/Presets#FailedToLoadPresetSources";
258 case ILLEGAL_FORMAT_OF_ENTRY:
259 return marktr("Warning: illegal format of entry in preset list ''{0}''. Got ''{1}''");
260 default: throw new AssertionError();
261 }
262 }
263 }
264
265 @Override
266 public boolean ok() {
267 boolean restart = Main.pref.put("taggingpreset.sortmenu", sortMenu.getSelectedObjects() != null);
268 restart |= sources.finish();
269
270 return restart;
271 }
272
273 /**
274 * Initialize the tagging presets (load and may display error)
275 */
276 public static void initialize() {
277 taggingPresets = TaggingPresetReader.readFromPreferences(false);
278 for (TaggingPreset tp: taggingPresets) {
279 if (!(tp instanceof TaggingPresetSeparator)) {
280 Main.toolbar.register(tp);
281 }
282 }
283 if (taggingPresets.isEmpty()) {
284 Main.main.menu.presetsMenu.setVisible(false);
285 } else {
286 AutoCompletionManager.cachePresets(taggingPresets);
287 HashMap<TaggingPresetMenu,JMenu> submenus = new HashMap<TaggingPresetMenu,JMenu>();
288 for (final TaggingPreset p : taggingPresets) {
289 JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
290 if (p instanceof TaggingPresetSeparator) {
291 m.add(new JSeparator());
292 } else if (p instanceof TaggingPresetMenu) {
293 JMenu submenu = new JMenu(p);
294 submenu.setText(p.getLocaleName());
295 ((TaggingPresetMenu)p).menu = submenu;
296 submenus.put((TaggingPresetMenu)p, submenu);
297 m.add(submenu);
298 } else {
299 JMenuItem mi = new JMenuItem(p);
300 mi.setText(p.getLocaleName());
301 m.add(mi);
302 }
303 }
304 }
305 if (Main.pref.getBoolean("taggingpreset.sortmenu")) {
306 TaggingPresetMenu.sortMenu(Main.main.menu.presetsMenu);
307 }
308 }
309
310 public static class PresetPrefHelper extends SourceEditor.SourcePrefHelper {
311
312 /**
313 * The unique instance.
314 */
315 public final static PresetPrefHelper INSTANCE = new PresetPrefHelper();
316
317 /**
318 * Constructs a new {@code PresetPrefHelper}.
319 */
320 public PresetPrefHelper() {
321 super("taggingpreset.entries");
322 }
323
324 @Override
325 public Collection<ExtendedSourceEntry> getDefault() {
326 ExtendedSourceEntry i = new ExtendedSourceEntry("defaultpresets.xml", "resource://data/defaultpresets.xml");
327 i.title = tr("Internal Preset");
328 i.description = tr("The default preset for JOSM");
329 return Collections.singletonList(i);
330 }
331
332 @Override
333 public Map<String, String> serialize(SourceEntry entry) {
334 Map<String, String> res = new HashMap<String, String>();
335 res.put("url", entry.url);
336 res.put("title", entry.title == null ? "" : entry.title);
337 return res;
338 }
339
340 @Override
341 public SourceEntry deserialize(Map<String, String> s) {
342 return new SourceEntry(s.get("url"), null, s.get("title"), true);
343 }
344 }
345
346 @Override
347 public boolean isExpert() {
348 return false;
349 }
350
351 @Override
352 public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
353 return gui.getMapPreference();
354 }
355}
Note: See TracBrowser for help on using the repository browser.