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

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

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

  • Property svn:eol-style set to native
File size: 12.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.JOptionPane;
20import javax.swing.JPanel;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.gui.ExtendedDialog;
24import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
25import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
26import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
27import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane.ValidationListener;
28import org.openstreetmap.josm.gui.preferences.SourceEditor;
29import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
30import org.openstreetmap.josm.gui.preferences.SourceEntry;
31import org.openstreetmap.josm.gui.preferences.SourceProvider;
32import org.openstreetmap.josm.gui.preferences.SourceType;
33import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
34import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
35import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetReader;
36import org.openstreetmap.josm.tools.GBC;
37import org.openstreetmap.josm.tools.Logging;
38import org.openstreetmap.josm.tools.Utils;
39import org.xml.sax.SAXException;
40import org.xml.sax.SAXParseException;
41
42/**
43 * Preference settings for tagging presets.
44 */
45public final class TaggingPresetPreference implements SubPreferenceSetting {
46
47 private final class TaggingPresetValidationListener implements ValidationListener {
48 @Override
49 public boolean validatePreferences() {
50 if (sources.hasActiveSourcesChanged()) {
51 List<Integer> sourcesToRemove = new ArrayList<>();
52 int i = -1;
53 SOURCES:
54 for (SourceEntry source: sources.getActiveSources()) {
55 i++;
56 boolean canLoad = false;
57 try {
58 TaggingPresetReader.readAll(source.url, false);
59 canLoad = true;
60 } catch (IOException e) {
61 Logging.log(Logging.LEVEL_WARN, tr("Could not read tagging preset source: {0}", source), e);
62 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Error"),
63 tr("Yes"), tr("No"), tr("Cancel"));
64 ed.setContent(tr("Could not read tagging preset source: {0}\nDo you want to keep it?", source));
65 switch (ed.showDialog().getValue()) {
66 case 1:
67 continue SOURCES;
68 case 2:
69 sourcesToRemove.add(i);
70 continue SOURCES;
71 default:
72 return false;
73 }
74 } catch (SAXException e) {
75 // We will handle this in step with validation
76 Logging.trace(e);
77 }
78
79 String errorMessage = null;
80
81 try {
82 TaggingPresetReader.readAll(source.url, true);
83 } catch (IOException e) {
84 // Should not happen, but at least show message
85 String msg = tr("Could not read tagging preset source {0}", source);
86 Logging.log(Logging.LEVEL_ERROR, msg, e);
87 JOptionPane.showMessageDialog(Main.parent, msg);
88 return false;
89 } catch (SAXParseException e) {
90 if (canLoad) {
91 errorMessage = tr("<html>Tagging preset source {0} can be loaded but it contains errors. " +
92 "Do you really want to use it?<br><br><table width=600>Error is: [{1}:{2}] {3}</table></html>",
93 source, e.getLineNumber(), e.getColumnNumber(), Utils.escapeReservedCharactersHTML(e.getMessage()));
94 } else {
95 errorMessage = tr("<html>Unable to parse tagging preset source: {0}. " +
96 "Do you really want to use it?<br><br><table width=400>Error is: [{1}:{2}] {3}</table></html>",
97 source, e.getLineNumber(), e.getColumnNumber(), Utils.escapeReservedCharactersHTML(e.getMessage()));
98 }
99 Logging.log(Logging.LEVEL_WARN, errorMessage, e);
100 } catch (SAXException e) {
101 if (canLoad) {
102 errorMessage = tr("<html>Tagging preset source {0} can be loaded but it contains errors. " +
103 "Do you really want to use it?<br><br><table width=600>Error is: {1}</table></html>",
104 source, Utils.escapeReservedCharactersHTML(e.getMessage()));
105 } else {
106 errorMessage = tr("<html>Unable to parse tagging preset source: {0}. " +
107 "Do you really want to use it?<br><br><table width=600>Error is: {1}</table></html>",
108 source, Utils.escapeReservedCharactersHTML(e.getMessage()));
109 }
110 Logging.log(Logging.LEVEL_ERROR, errorMessage, e);
111 }
112
113 if (errorMessage != null) {
114 Logging.error(errorMessage);
115 int result = JOptionPane.showConfirmDialog(Main.parent, new JLabel(errorMessage), tr("Error"),
116 JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE);
117
118 switch (result) {
119 case JOptionPane.YES_OPTION:
120 continue SOURCES;
121 case JOptionPane.NO_OPTION:
122 sourcesToRemove.add(i);
123 continue SOURCES;
124 default:
125 return false;
126 }
127 }
128 }
129 sources.removeSources(sourcesToRemove);
130 return true;
131 } else {
132 return true;
133 }
134 }
135 }
136
137 /**
138 * Factory used to create a new {@code TaggingPresetPreference}.
139 */
140 public static class Factory implements PreferenceSettingFactory {
141 @Override
142 public PreferenceSetting createPreferenceSetting() {
143 return new TaggingPresetPreference();
144 }
145 }
146
147 private TaggingPresetPreference() {
148 super();
149 }
150
151 private static final List<SourceProvider> presetSourceProviders = new ArrayList<>();
152
153 private SourceEditor sources;
154 private JCheckBox sortMenu;
155
156 /**
157 * Registers a new additional preset source provider.
158 * @param provider The preset source provider
159 * @return {@code true}, if the provider has been added, {@code false} otherwise
160 */
161 public static boolean registerSourceProvider(SourceProvider provider) {
162 if (provider != null)
163 return presetSourceProviders.add(provider);
164 return false;
165 }
166
167 private final ValidationListener validationListener = new TaggingPresetValidationListener();
168
169 @Override
170 public void addGui(PreferenceTabbedPane gui) {
171 sortMenu = new JCheckBox(tr("Sort presets menu alphabetically"),
172 Main.pref.getBoolean("taggingpreset.sortmenu", false));
173
174 final JPanel panel = new JPanel(new GridBagLayout());
175 panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
176 panel.add(sortMenu, GBC.eol().insets(5, 5, 5, 0));
177 sources = new TaggingPresetSourceEditor();
178 panel.add(sources, GBC.eol().fill(GBC.BOTH));
179 final MapPreference mapPref = gui.getMapPreference();
180 mapPref.addSubTab(this, tr("Tagging Presets"), panel);
181 sources.deferLoading(mapPref, panel);
182 gui.addValidationListener(validationListener);
183 }
184
185 static class TaggingPresetSourceEditor extends SourceEditor {
186
187 private static final String ICONPREF = "taggingpreset.icon.sources";
188
189 TaggingPresetSourceEditor() {
190 super(SourceType.TAGGING_PRESET, Main.getJOSMWebsite()+"/presets", presetSourceProviders, true);
191 }
192
193 @Override
194 public Collection<? extends SourceEntry> getInitialSourcesList() {
195 return PresetPrefHelper.INSTANCE.get();
196 }
197
198 @Override
199 public boolean finish() {
200 return doFinish(PresetPrefHelper.INSTANCE, ICONPREF);
201 }
202
203 @Override
204 public Collection<ExtendedSourceEntry> getDefault() {
205 return PresetPrefHelper.INSTANCE.getDefault();
206 }
207
208 @Override
209 public Collection<String> getInitialIconPathsList() {
210 return Main.pref.getCollection(ICONPREF, null);
211 }
212
213 @Override
214 public String getStr(I18nString ident) {
215 switch (ident) {
216 case AVAILABLE_SOURCES:
217 return tr("Available presets:");
218 case ACTIVE_SOURCES:
219 return tr("Active presets:");
220 case NEW_SOURCE_ENTRY_TOOLTIP:
221 return tr("Add a new preset by entering filename or URL");
222 case NEW_SOURCE_ENTRY:
223 return tr("New preset entry:");
224 case REMOVE_SOURCE_TOOLTIP:
225 return tr("Remove the selected presets from the list of active presets");
226 case EDIT_SOURCE_TOOLTIP:
227 return tr("Edit the filename or URL for the selected active preset");
228 case ACTIVATE_TOOLTIP:
229 return tr("Add the selected available presets to the list of active presets");
230 case RELOAD_ALL_AVAILABLE:
231 return marktr("Reloads the list of available presets from ''{0}''");
232 case LOADING_SOURCES_FROM:
233 return marktr("Loading preset sources from ''{0}''");
234 case FAILED_TO_LOAD_SOURCES_FROM:
235 return marktr("<html>Failed to load the list of preset sources from<br>"
236 + "''{0}''.<br>"
237 + "<br>"
238 + "Details (untranslated):<br>{1}</html>");
239 case FAILED_TO_LOAD_SOURCES_FROM_HELP_TOPIC:
240 return "/Preferences/Presets#FailedToLoadPresetSources";
241 case ILLEGAL_FORMAT_OF_ENTRY:
242 return marktr("Warning: illegal format of entry in preset list ''{0}''. Got ''{1}''");
243 default: throw new AssertionError();
244 }
245 }
246 }
247
248 @Override
249 public boolean ok() {
250 boolean restart = Main.pref.put("taggingpreset.sortmenu", sortMenu.getSelectedObjects() != null);
251 restart |= sources.finish();
252
253 return restart;
254 }
255
256 /**
257 * Helper class for tagging presets preferences.
258 */
259 public static class PresetPrefHelper extends SourceEditor.SourcePrefHelper {
260
261 /**
262 * The unique instance.
263 */
264 public static final PresetPrefHelper INSTANCE = new PresetPrefHelper();
265
266 /**
267 * Constructs a new {@code PresetPrefHelper}.
268 */
269 public PresetPrefHelper() {
270 super("taggingpreset.entries");
271 }
272
273 @Override
274 public Collection<ExtendedSourceEntry> getDefault() {
275 ExtendedSourceEntry i = new ExtendedSourceEntry("defaultpresets.xml", "resource://data/defaultpresets.xml");
276 i.title = tr("Internal Preset");
277 i.description = tr("The default preset for JOSM");
278 return Collections.singletonList(i);
279 }
280
281 @Override
282 public Map<String, String> serialize(SourceEntry entry) {
283 Map<String, String> res = new HashMap<>();
284 res.put("url", entry.url);
285 res.put("title", entry.title == null ? "" : entry.title);
286 return res;
287 }
288
289 @Override
290 public SourceEntry deserialize(Map<String, String> s) {
291 return new SourceEntry(s.get("url"), null, s.get("title"), true);
292 }
293 }
294
295 @Override
296 public boolean isExpert() {
297 return false;
298 }
299
300 @Override
301 public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
302 return gui.getMapPreference();
303 }
304}
Note: See TracBrowser for help on using the repository browser.