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

Last change on this file since 12649 was 12649, checked in by Don-vip, 8 weeks ago

see #15182 - code refactoring to avoid dependence on GUI packages from Preferences

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