1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.gui.download;
|
---|
3 |
|
---|
4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
5 |
|
---|
6 | import java.awt.event.ActionEvent;
|
---|
7 | import java.util.ArrayList;
|
---|
8 | import java.util.Collections;
|
---|
9 | import java.util.Optional;
|
---|
10 |
|
---|
11 | import javax.swing.JOptionPane;
|
---|
12 |
|
---|
13 | import org.openstreetmap.josm.data.osm.search.SearchSetting;
|
---|
14 | import org.openstreetmap.josm.data.preferences.ListProperty;
|
---|
15 | import org.openstreetmap.josm.gui.dialogs.SearchDialog;
|
---|
16 | import org.openstreetmap.josm.gui.download.overpass.OverpassWizardRegistration.OverpassWizardCallbacks;
|
---|
17 | import org.openstreetmap.josm.gui.tagging.ac.AutoCompComboBoxModel;
|
---|
18 | import org.openstreetmap.josm.gui.widgets.JosmComboBoxModel;
|
---|
19 | import org.openstreetmap.josm.tools.Logging;
|
---|
20 | import org.openstreetmap.josm.tools.SearchCompilerQueryWizard;
|
---|
21 | import org.openstreetmap.josm.tools.UncheckedParseException;
|
---|
22 | import org.openstreetmap.josm.tools.Utils;
|
---|
23 |
|
---|
24 | /**
|
---|
25 | * This dialog provides an easy and fast way to create an overpass query.
|
---|
26 | * @since 12576
|
---|
27 | * @since 12652: Moved here
|
---|
28 | */
|
---|
29 | public final class OverpassQueryWizardDialog extends SearchDialog {
|
---|
30 |
|
---|
31 | private static final ListProperty OVERPASS_WIZARD_HISTORY =
|
---|
32 | new ListProperty("download.overpass.wizard", new ArrayList<>());
|
---|
33 | private final OverpassWizardCallbacks callbacks;
|
---|
34 |
|
---|
35 | // dialog buttons
|
---|
36 | private static final int BUILD_QUERY = 0;
|
---|
37 | private static final int BUILD_AN_EXECUTE_QUERY = 1;
|
---|
38 | private static final int CANCEL = 2;
|
---|
39 |
|
---|
40 | private final AutoCompComboBoxModel<SearchSetting> model;
|
---|
41 |
|
---|
42 | /** preferences reader/writer with automatic transmogrification to and from String */
|
---|
43 | private final JosmComboBoxModel<SearchSetting>.Preferences prefs;
|
---|
44 |
|
---|
45 | /**
|
---|
46 | * Create a new {@link OverpassQueryWizardDialog}
|
---|
47 | * @param callbacks The Overpass download source panel.
|
---|
48 | */
|
---|
49 | public OverpassQueryWizardDialog(OverpassWizardCallbacks callbacks) {
|
---|
50 | super(new SearchSetting(), new AutoCompComboBoxModel<>(), new PanelOptions(false, true), callbacks.getParent(),
|
---|
51 | tr("Overpass Query Wizard"),
|
---|
52 | tr("Build query"), tr("Build query and execute"), tr("Cancel"));
|
---|
53 | this.callbacks = callbacks;
|
---|
54 | model = hcbSearchString.getModel();
|
---|
55 | setButtonIcons("dialogs/magic-wand", "download-overpass", "cancel");
|
---|
56 | setCancelButton(CANCEL + 1);
|
---|
57 | setDefaultButton(BUILD_AN_EXECUTE_QUERY + 1);
|
---|
58 | prefs = model.prefs(SearchSetting::fromString, SearchSetting::toString);
|
---|
59 | prefs.load(OVERPASS_WIZARD_HISTORY);
|
---|
60 | }
|
---|
61 |
|
---|
62 | @Override
|
---|
63 | public void buttonAction(int buttonIndex, ActionEvent evt) {
|
---|
64 | switch (buttonIndex) {
|
---|
65 | case BUILD_QUERY:
|
---|
66 | if (this.buildQueryAction()) {
|
---|
67 | this.saveHistory();
|
---|
68 | super.buttonAction(BUILD_QUERY, evt);
|
---|
69 | }
|
---|
70 | break;
|
---|
71 | case BUILD_AN_EXECUTE_QUERY:
|
---|
72 | if (this.buildQueryAction()) {
|
---|
73 | this.saveHistory();
|
---|
74 | super.buttonAction(BUILD_AN_EXECUTE_QUERY, evt);
|
---|
75 |
|
---|
76 | DownloadDialog.getInstance().startDownload();
|
---|
77 | }
|
---|
78 | break;
|
---|
79 | default:
|
---|
80 | super.buttonAction(buttonIndex, evt);
|
---|
81 | }
|
---|
82 | }
|
---|
83 |
|
---|
84 | /**
|
---|
85 | * Saves the latest, successfully parsed search term.
|
---|
86 | */
|
---|
87 | private void saveHistory() {
|
---|
88 | Optional.ofNullable(SearchSetting.fromString(hcbSearchString.getText()))
|
---|
89 | .ifPresent(model::addTopElement);
|
---|
90 | prefs.save(OVERPASS_WIZARD_HISTORY);
|
---|
91 | }
|
---|
92 |
|
---|
93 | /**
|
---|
94 | * Tries to process a search term using {@link SearchCompilerQueryWizard}. If the term cannot
|
---|
95 | * be parsed, the the corresponding dialog is shown.
|
---|
96 | * @param searchTerm The search term to parse.
|
---|
97 | * @return {@link Optional#empty()} if an exception was thrown when parsing, meaning
|
---|
98 | * that the term cannot be processed, or non-empty {@link Optional} containing the result
|
---|
99 | * of parsing.
|
---|
100 | */
|
---|
101 | private Optional<String> tryParseSearchTerm(String searchTerm) {
|
---|
102 | try {
|
---|
103 | return Optional.of(SearchCompilerQueryWizard.constructQuery(searchTerm));
|
---|
104 | } catch (UncheckedParseException | IllegalStateException ex) {
|
---|
105 | Logging.error(ex);
|
---|
106 | JOptionPane.showMessageDialog(
|
---|
107 | callbacks.getParent(),
|
---|
108 | "<html>" +
|
---|
109 | tr("The Overpass wizard could not parse the following query:") +
|
---|
110 | Utils.joinAsHtmlUnorderedList(Collections.singleton(Utils.escapeReservedCharactersHTML(searchTerm))) +
|
---|
111 | "</html>",
|
---|
112 | tr("Parse error"),
|
---|
113 | JOptionPane.ERROR_MESSAGE
|
---|
114 | );
|
---|
115 | return Optional.empty();
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * Builds an Overpass query out from {@link SearchSetting} contents.
|
---|
121 | * @return {@code true} if the query successfully built, {@code false} otherwise.
|
---|
122 | */
|
---|
123 | private boolean buildQueryAction() {
|
---|
124 | Optional<String> q = tryParseSearchTerm(getSearchSettings().text);
|
---|
125 | q.ifPresent(callbacks::submitWizardResult);
|
---|
126 | return q.isPresent();
|
---|
127 | }
|
---|
128 | }
|
---|