source: josm/trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java@ 1084

Last change on this file since 1084 was 1084, checked in by framm, 15 years ago
  • cosmetics: rename ShortCut to Shortcut, and shortCut to shortcut
  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions.search;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.Collection;
10import java.util.LinkedList;
11
12import javax.swing.ButtonGroup;
13import javax.swing.JCheckBox;
14import javax.swing.JLabel;
15import javax.swing.JOptionPane;
16import javax.swing.JPanel;
17import javax.swing.JRadioButton;
18import javax.swing.JTextField;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.actions.JosmAction;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.tools.GBC;
24import org.openstreetmap.josm.tools.Shortcut;
25
26public class SearchAction extends JosmAction {
27
28 public static final int SEARCH_HISTORY_SIZE = 10;
29
30 public static enum SearchMode {
31 replace, add, remove
32 }
33
34 public static final LinkedList<SearchSetting> searchHistory = new LinkedList<SearchSetting>();
35
36 private static SearchSetting lastSearch = null;
37
38 public SearchAction() {
39 super(tr("Search ..."), "dialogs/search", tr("Search for objects."),
40 Shortcut.registerShortcut("system:find", tr("Search..."), KeyEvent.VK_F, Shortcut.GROUP_HOTKEY), true);
41 }
42
43 public void actionPerformed(ActionEvent e) {
44 if (Main.map == null) {
45 JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
46 return;
47 }
48 SearchSetting s = lastSearch;
49 if (s == null)
50 s = new SearchSetting("", false, SearchMode.replace);
51 showSearchDialog(s);
52 }
53
54 public void showSearchDialog(SearchSetting initialValues) {
55 JLabel label = new JLabel(tr("Please enter a search string."));
56 final JTextField input = new JTextField(initialValues.text);
57 input.setToolTipText(tr("<html>Fulltext search:<ul>"
58 + "<li><b>Baker Street</b> - 'Baker' and 'Street' in any key or name.</li>"
59 + "<li><b>\"Baker Street\"</b> - 'Baker Street' in any key or name.</li>"
60 + "<li><b>name:Bak</b> - 'Bak' anywhere in the name.</li>"
61 + "<li><b>-name:Bak</b> - not 'Bak' in the name.</li>"
62 + "<li><b>foot:</b> - key=foot set to any value.</li>" + "<li>Special targets:</li>"
63 + "<li><b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)</li>"
64 + "<li><b>user:</b>... - all objects changed by user</li>"
65 + "<li><b>id:</b>... - object with given ID</li>"
66 + "<li><b>nodes:</b>... - object with given number of nodes</li>"
67 + "<li><b>modified</b> - all changed objects</li>"
68 + "<li><b>selected</b> - all selected objects</li>"
69 + "<li><b>incomplete</b> - all incomplete objects</li>"
70 + "<li>Use <b>|</b> or <b>OR</b> to combine with logical or</li>"
71 + "<li>Use <b>\"</b> to quote operators (e.g. if key contains :)</li>"
72 + "<li>Use <b>(</b> and <b>)</b> to group expressions</li>" + "</ul></html>"));
73
74 JRadioButton replace = new JRadioButton(tr("replace selection"), initialValues.mode == SearchMode.replace);
75 JRadioButton add = new JRadioButton(tr("add to selection"), initialValues.mode == SearchMode.add);
76 JRadioButton remove = new JRadioButton(tr("remove from selection"), initialValues.mode == SearchMode.remove);
77 ButtonGroup bg = new ButtonGroup();
78 bg.add(replace);
79 bg.add(add);
80 bg.add(remove);
81
82 JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
83
84 JPanel p = new JPanel(new GridBagLayout());
85 p.add(label, GBC.eop());
86 p.add(input, GBC.eop().fill(GBC.HORIZONTAL));
87 p.add(replace, GBC.eol());
88 p.add(add, GBC.eol());
89 p.add(remove, GBC.eop());
90 p.add(caseSensitive, GBC.eol());
91 JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null) {
92 @Override
93 public void selectInitialValue() {
94 input.requestFocusInWindow();
95 input.selectAll();
96 }
97 };
98 pane.createDialog(Main.parent, tr("Search")).setVisible(true);
99 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
100 return;
101 // User pressed OK - let's perform the search
102 SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace
103 : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
104 SearchSetting setting = new SearchSetting(input.getText(), caseSensitive.isSelected(), mode);
105 searchWithHistory(setting);
106 }
107
108 /**
109 * Adds the search specified by the settings in <code>s</code> to the
110 * search history and performs the search.
111 *
112 * @param s
113 */
114 public static void searchWithHistory(SearchSetting s) {
115 searchHistory.addFirst(s);
116 while (searchHistory.size() > SEARCH_HISTORY_SIZE)
117 searchHistory.removeLast();
118 lastSearch = s;
119 search(s.text, s.mode, s.caseSensitive);
120 }
121
122 public static void searchWithoutHistory(SearchSetting s) {
123 lastSearch = s;
124 search(s.text, s.mode, s.caseSensitive);
125 }
126
127 public static void search(String search, SearchMode mode, boolean caseSensitive) {
128 if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://")
129 || search.startsWith("file:/")) {
130 SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
131 if (loader.url != null) {
132 Main.worker.execute(loader);
133 return;
134 }
135 }
136 try {
137 Collection<OsmPrimitive> sel = Main.ds.getSelected();
138 SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
139 int foundMatches = 0;
140 for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
141 if (mode == SearchMode.replace) {
142 if (matcher.match(osm)) {
143 sel.add(osm);
144 ++foundMatches;
145 } else
146 sel.remove(osm);
147 } else if (mode == SearchMode.add && !osm.selected && matcher.match(osm)) {
148 sel.add(osm);
149 ++foundMatches;
150 } else if (mode == SearchMode.remove && osm.selected && matcher.match(osm)) {
151 sel.remove(osm);
152 ++foundMatches;
153 }
154 }
155 Main.ds.setSelected(sel);
156 if (foundMatches == 0) {
157 String msg = null;
158 if (mode == SearchMode.replace)
159 msg = tr("No match found for ''{0}''", search);
160 else if (mode == SearchMode.add)
161 msg = tr("Nothing added to selection by searching for ''{0}''", search);
162 else if (mode == SearchMode.remove)
163 msg = tr("Nothing removed from selection by searching for ''{0}''", search);
164 Main.map.statusLine.setHelpText(msg);
165 JOptionPane.showMessageDialog(Main.parent, msg);
166 } else
167 Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
168 } catch (SearchCompiler.ParseError e) {
169 JOptionPane.showMessageDialog(Main.parent, e.getMessage());
170 }
171 }
172
173 public static class SearchSetting {
174 String text;
175 SearchMode mode;
176 boolean caseSensitive;
177
178 public SearchSetting(String text, boolean caseSensitive, SearchMode mode) {
179 super();
180 this.caseSensitive = caseSensitive;
181 this.mode = mode;
182 this.text = text;
183 }
184
185 @Override
186 public String toString() {
187 String cs = caseSensitive ? tr("CI") : tr("CS");
188 return "\"" + text + "\" (" + cs + ", " + mode + ")";
189 }
190
191 }
192}
Note: See TracBrowser for help on using the repository browser.