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

Last change on this file since 1677 was 1677, checked in by stoecker, 15 years ago

remove all these ugly tab stops introduced in the last half year

  • Property svn:eol-style set to native
File size: 9.8 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.Font;
7import java.awt.GridBagLayout;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.util.Collection;
11import java.util.LinkedList;
12
13import javax.swing.ButtonGroup;
14import javax.swing.JCheckBox;
15import javax.swing.JLabel;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18import javax.swing.JRadioButton;
19import javax.swing.JTextField;
20
21import org.openstreetmap.josm.Main;
22import org.openstreetmap.josm.actions.JosmAction;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.gui.ExtendedDialog;
25import org.openstreetmap.josm.tools.GBC;
26import org.openstreetmap.josm.tools.Shortcut;
27
28public class SearchAction extends JosmAction {
29
30 public static final int SEARCH_HISTORY_SIZE = 10;
31
32 public static enum SearchMode {
33 replace, add, remove
34 }
35
36 public static final LinkedList<SearchSetting> searchHistory = new LinkedList<SearchSetting>();
37
38 private static SearchSetting lastSearch = null;
39
40 public SearchAction() {
41 super(tr("Search..."), "dialogs/search", tr("Search for objects."),
42 Shortcut.registerShortcut("system:find", tr("Search..."), KeyEvent.VK_F, Shortcut.GROUP_HOTKEY), true);
43 }
44
45 public void actionPerformed(ActionEvent e) {
46 if (Main.map == null) {
47 JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
48 return;
49 }
50 SearchSetting s = lastSearch;
51 if (s == null)
52 s = new SearchSetting("", false, false, SearchMode.replace);
53 showSearchDialog(s);
54 }
55
56 public void showSearchDialog(SearchSetting initialValues) {
57 JLabel label = new JLabel(tr("Please enter a search string."));
58 final JTextField input = new JTextField(initialValues.text);
59 input.selectAll();
60 input.requestFocusInWindow();
61 JRadioButton replace = new JRadioButton(tr("replace selection"), initialValues.mode == SearchMode.replace);
62 JRadioButton add = new JRadioButton(tr("add to selection"), initialValues.mode == SearchMode.add);
63 JRadioButton remove = new JRadioButton(tr("remove from selection"), initialValues.mode == SearchMode.remove);
64 ButtonGroup bg = new ButtonGroup();
65 bg.add(replace);
66 bg.add(add);
67 bg.add(remove);
68
69 JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
70 JCheckBox regexSearch = new JCheckBox(tr("regular expression"), initialValues.regexSearch);
71
72 JPanel left = new JPanel(new GridBagLayout());
73 left.add(label, GBC.eop());
74 left.add(input, GBC.eop().fill(GBC.HORIZONTAL));
75 left.add(replace, GBC.eol());
76 left.add(add, GBC.eol());
77 left.add(remove, GBC.eop());
78 left.add(caseSensitive, GBC.eol());
79 left.add(regexSearch, GBC.eol());
80
81 JPanel right = new JPanel();
82 JLabel description =
83 new JLabel("<html><ul>"
84 + "<li>"+tr("<b>Baker Street</b> - 'Baker' and 'Street' in any key or name.")+"</li>"
85 + "<li>"+tr("<b>\"Baker Street\"</b> - 'Baker Street' in any key or name.")+"</li>"
86 + "<li>"+tr("<b>name:Bak</b> - 'Bak' anywhere in the name.")+"</li>"
87 + "<li>"+tr("<b>type=route</b> - key 'type' with value exactly 'route'.") + "</li>"
88 + "<li>"+tr("<b>type=*</b> - key 'type' with any value. Try also <b>*=value</b>, <b>type=</b>, <b>*=*</b>, <b>*=</b>") + "</li>"
89 + "<li>"+tr("<b>-name:Bak</b> - not 'Bak' in the name.")+"</li>"
90 + "<li>"+tr("<b>foot:</b> - key=foot set to any value.")+"</li>"
91 + "<li>"+tr("<u>Special targets:</u>")+"</li>"
92 + "<li>"+tr("<b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)")+"</li>"
93 + "<li>"+tr("<b>user:</b>... - all objects changed by user")+"</li>"
94 + "<li>"+tr("<b>id:</b>... - object with given ID")+"</li>"
95 + "<li>"+tr("<b>nodes:</b>... - object with given number of nodes")+"</li>"
96 + "<li>"+tr("<b>modified</b> - all changed objects")+"</li>"
97 + "<li>"+tr("<b>selected</b> - all selected objects")+"</li>"
98 + "<li>"+tr("<b>incomplete</b> - all incomplete objects")+"</li>"
99 + "<li>"+tr("<b>untagged</b> - all untagged objects")+"</li>"
100 + "<li>"+tr("<b>child <i>expr</i></b> - all children of objects matching the expression")+"</li>"
101 + "<li>"+tr("<b>parent <i>expr</i></b> - all parents of objects matching the expression")+"</li>"
102 + "<li>"+tr("Use <b>|</b> or <b>OR</b> to combine with logical or")+"</li>"
103 + "<li>"+tr("Use <b>\"</b> to quote operators (e.g. if key contains :)")+"</li>"
104 + "<li>"+tr("Use <b>(</b> and <b>)</b> to group expressions")+"</li>"
105 + "</ul></html>");
106 description.setFont(description.getFont().deriveFont(Font.PLAIN));
107 right.add(description);
108
109 final JPanel p = new JPanel();
110 p.add(left);
111 p.add(right);
112
113 int result = new ExtendedDialog(Main.parent,
114 tr("Search"),
115 p,
116 new String[] {tr("Start Search"), tr("Cancel")},
117 new String[] {"dialogs/search.png", "cancel.png"}).getValue();
118 if(result != 1) return;
119
120 // User pressed OK - let's perform the search
121 SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace
122 : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
123 SearchSetting setting = new SearchSetting(input.getText(), caseSensitive.isSelected(), regexSearch.isSelected(), mode);
124 searchWithHistory(setting);
125 }
126
127 /**
128 * Adds the search specified by the settings in <code>s</code> to the
129 * search history and performs the search.
130 *
131 * @param s
132 */
133 public static void searchWithHistory(SearchSetting s) {
134 if(searchHistory.isEmpty() || !s.equals(searchHistory.getFirst()))
135 searchHistory.addFirst(s);
136 while (searchHistory.size() > SEARCH_HISTORY_SIZE)
137 searchHistory.removeLast();
138 lastSearch = s;
139 search(s.text, s.mode, s.caseSensitive, s.regexSearch);
140 }
141
142 public static void searchWithoutHistory(SearchSetting s) {
143 lastSearch = s;
144 search(s.text, s.mode, s.caseSensitive, s.regexSearch);
145 }
146
147 public static void search(String search, SearchMode mode, boolean caseSensitive, boolean regexSearch) {
148 if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://")
149 || search.startsWith("file:/")) {
150 SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
151 if (loader.url != null) {
152 Main.worker.execute(loader);
153 return;
154 }
155 }
156 try {
157 Collection<OsmPrimitive> sel = Main.ds.getSelected();
158 SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive, regexSearch);
159 int foundMatches = 0;
160 for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
161 if (mode == SearchMode.replace) {
162 if (matcher.match(osm)) {
163 sel.add(osm);
164 ++foundMatches;
165 } else
166 sel.remove(osm);
167 } else if (mode == SearchMode.add && !osm.selected && matcher.match(osm)) {
168 sel.add(osm);
169 ++foundMatches;
170 } else if (mode == SearchMode.remove && osm.selected && matcher.match(osm)) {
171 sel.remove(osm);
172 ++foundMatches;
173 }
174 }
175 Main.ds.setSelected(sel);
176 if (foundMatches == 0) {
177 String msg = null;
178 if (mode == SearchMode.replace)
179 msg = tr("No match found for ''{0}''", search);
180 else if (mode == SearchMode.add)
181 msg = tr("Nothing added to selection by searching for ''{0}''", search);
182 else if (mode == SearchMode.remove)
183 msg = tr("Nothing removed from selection by searching for ''{0}''", search);
184 Main.map.statusLine.setHelpText(msg);
185 JOptionPane.showMessageDialog(Main.parent, msg);
186 } else
187 Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
188 } catch (SearchCompiler.ParseError e) {
189 JOptionPane.showMessageDialog(Main.parent, e.getMessage());
190 }
191 }
192
193 public static class SearchSetting {
194 String text;
195 SearchMode mode;
196 boolean caseSensitive;
197 boolean regexSearch;
198
199 public SearchSetting(String text, boolean caseSensitive, boolean regexSearch, SearchMode mode) {
200 super();
201 this.caseSensitive = caseSensitive;
202 this.regexSearch = regexSearch;
203 this.mode = mode;
204 this.text = text;
205 }
206
207 @Override
208 public String toString() {
209 String cs = caseSensitive ? tr("CS") : tr("CI");
210 String rx = regexSearch ? (", " + tr("RX")) : "";
211 return "\"" + text + "\" (" + cs + rx + ", " + mode + ")";
212 }
213
214 public boolean equals(Object other) {
215 if(!(other instanceof SearchSetting))
216 return false;
217 SearchSetting o = (SearchSetting) other;
218 return (o.caseSensitive == this.caseSensitive
219 && o.regexSearch == this.regexSearch
220 && o.mode.equals(this.mode)
221 && o.text.equals(this.text));
222 }
223 }
224}
Note: See TracBrowser for help on using the repository browser.