521905660fe13ad50263c85fcc54d5326c79778d
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / search / SearchBar.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.navigation.search;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.events.FocusEvent;
15 import org.eclipse.swt.events.FocusListener;
16 import org.eclipse.swt.events.KeyAdapter;
17 import org.eclipse.swt.events.KeyEvent;
18 import org.eclipse.swt.events.SelectionAdapter;
19 import org.eclipse.swt.events.SelectionEvent;
20 import org.eclipse.swt.graphics.Point;
21 import org.eclipse.swt.graphics.Rectangle;
22 import org.eclipse.swt.layout.RowLayout;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.swt.widgets.Control;
25 import org.eclipse.swt.widgets.Menu;
26 import org.eclipse.swt.widgets.MenuItem;
27 import org.eclipse.swt.widgets.Text;
28 import org.eclipse.swt.widgets.ToolBar;
29 import org.eclipse.swt.widgets.ToolItem;
30 import org.eclipse.ui.IViewPart;
31 import org.eclipse.ui.IWorkbenchPage;
32 import org.eclipse.ui.PartInitException;
33 import org.eclipse.ui.PlatformUI;
34 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
35 import org.eclipse.ui.swt.IFocusService;
36
37 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
38 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
39 import eu.etaxonomy.taxeditor.navigation.internal.TaxeditorNavigationPlugin;
40 import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
41 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
42 import eu.etaxonomy.taxeditor.preference.Resources;
43
44 /**
45 * <p>SearchBar class.</p>
46 *
47 * @author n.hoffmann
48 * @author e.-m.lee
49 * @created 15.04.2009
50 * @version 1.0
51 */
52 public class SearchBar extends WorkbenchWindowControlContribution{
53 private Text text_search;
54 private String secondaryId;
55
56 private final String defaultText = "Use \"*\" for wildcard searching";
57
58 final private ConfigurationSelectionListener configurationListener = new ConfigurationSelectionListener();
59
60 /** {@inheritDoc} */
61 @Override
62 protected Control createControl(Composite parent) {
63 Composite composite = new Composite(parent, SWT.NONE);
64
65 createLayout(composite);
66 createSearchTextField(composite);
67 createToolBar(composite);
68 registerAtFocusService();
69
70 return composite;
71 }
72
73 /**
74 * Handles focus changes for the search textfield.
75 */
76 private void registerAtFocusService() {
77 IFocusService focusService =
78 (IFocusService) PlatformUI.getWorkbench().getService(IFocusService.class);
79 if (focusService != null) {
80 focusService.addFocusTracker(text_search, "navigation.textControlId");
81 }
82 }
83
84 /**
85 * Creates the search toolbar.
86 * @param composite
87 */
88 private void createToolBar(Composite composite) {
89 final ToolBar toolBar = new ToolBar(composite, SWT.NULL);
90
91 ToolItem toolItem = new ToolItem(toolBar, SWT.DROP_DOWN | SWT.BORDER);
92 toolItem.setText("Search");
93
94 DropdownSelectionListener dropdownListener = new DropdownSelectionListener(
95 toolItem);
96
97 for(SearchOption searchOption : SearchOption.values()){
98 dropdownListener.add(searchOption);
99 }
100
101 toolItem.addSelectionListener(dropdownListener);
102 }
103
104 /**
105 * Creates the search textfield.
106 * @param composite
107 */
108 private void createSearchTextField(Composite composite) {
109 // TODO for some reason the text_search composite has a margin when
110 // either SWT.BORDER or SWT.SEARCH
111 // is applied. I am not sure how to get rid of this.
112 text_search = new Text(composite, SWT.BORDER | SWT.SINGLE
113 | SWT.FULL_SELECTION);
114 text_search.setForeground(NavigationUtil.getColor(Resources.SEARCH_VIEW_FOREGROUND));
115 text_search.setText(defaultText);
116
117 addTextListeners();
118 }
119
120 /**
121 * Adds listeners to the search textfield.
122 */
123 private void addTextListeners() {
124 text_search.addFocusListener(new FocusListener() {
125
126 public void focusGained(FocusEvent e) {
127 text_search.setForeground(NavigationUtil.getColor(Resources.SEARCH_VIEW_FOCUS));
128 if (defaultText.equals(text_search.getText())) {
129 text_search.setText("");
130 }
131 }
132
133 public void focusLost(FocusEvent e) {
134 if (text_search.getText() == "") {
135 text_search.setForeground(NavigationUtil.getColor(Resources.SEARCH_VIEW_FOREGROUND));
136 text_search.setText(defaultText);
137 }
138 }
139 });
140
141 text_search.addKeyListener(new KeyAdapter() {
142 /*
143 * (non-Javadoc)
144 * @see org.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt.events.KeyEvent)
145 */
146 @Override
147 public void keyPressed(KeyEvent e) {
148 if (e.keyCode == SWT.CR) {
149 search();
150 }
151 }
152 });
153 }
154
155 /**
156 * Creates the search layout.
157 * @param composite
158 */
159 private void createLayout(Composite composite) {
160 final RowLayout layout = new RowLayout();
161 layout.wrap = false;
162 layout.pack = true;
163 layout.justify = true;
164 layout.type = SWT.HORIZONTAL;
165 layout.marginLeft = 0;
166 layout.marginTop = 0;
167 layout.marginRight = 0;
168 layout.marginBottom = 0;
169 layout.spacing = 0;
170 composite.setLayout(layout);
171 }
172
173 private void search(){
174 final String searchString = getSearchString();
175 if(searchString == null){
176 return;
177 }
178
179 if("*".equals(searchString.trim())){
180 NavigationUtil.warningDialog("Could not execute search", this, "Please type at least one character when using the \"*\" wildcard.");
181 return;
182 }
183
184
185 ITaxonServiceConfigurator configurator = configurationListener.getConfigurator();
186 configurator.setTitleSearchString(searchString);
187 openSearchResultsView(configurator);
188
189 }
190
191 private String getSearchString(){
192 String searchString = text_search.getText().trim();
193 if (searchString.equals(defaultText) || searchString.length() == 0)
194 return null;
195 return searchString;
196 }
197
198 /**
199 * Opens a new instance of the search result view to display the result to the user.
200 *
201 * @param searchResult
202 */
203 private void openSearchResultsView(ITaxonServiceConfigurator configurator) {
204 boolean openResultInSeparateWindows = PreferencesUtil.getPreferenceStore().getBoolean((IPreferenceKeys.SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS));
205 if(openResultInSeparateWindows){
206 //increment change secondary id so it is unique
207 secondaryId += "1";
208 }
209
210 try {
211 IViewPart resultsView = TaxeditorNavigationPlugin.getDefault()
212 .getWorkbench().getActiveWorkbenchWindow()
213 .getActivePage().showView(SearchResultView.ID, secondaryId,
214 IWorkbenchPage.VIEW_ACTIVATE);
215 ((SearchResultView) resultsView).performSearch(configurator);
216 } catch (PartInitException e) {
217 NavigationUtil.error(this.getClass(), "Error opening search result.", e);
218 }
219 }
220
221 /**
222 * Handles drop down menu selection. Available items are defined in the enumeration SearchOption.
223 *
224 * @author n.hoffmann
225 * @created Feb 2, 2010
226 * @version 1.0
227 */
228 class DropdownSelectionListener extends SelectionAdapter {
229
230 private final Menu menu;
231
232 public DropdownSelectionListener(ToolItem dropdown) {
233 menu = new Menu(dropdown.getParent().getShell());
234 }
235
236 public void add(SearchOption option) {
237 MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
238 menuItem.setData(option);
239 menuItem.setText(option.getLabel());
240 menuItem.setSelection(option.getPreference());
241 menuItem.addSelectionListener(configurationListener);
242 }
243
244 @Override
245 public void widgetSelected(SelectionEvent event) {
246 if (event.detail == SWT.ARROW) {
247 ToolItem item = (ToolItem) event.widget;
248 Rectangle rect = item.getBounds();
249 Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
250 menu.setLocation(pt.x, pt.y + rect.height);
251 menu.setVisible(true);
252 } else {
253 search();
254 }
255 }
256 }
257
258 /**
259 * Handles search configuration selection.
260 *
261 * @author n.hoffmann
262 * @created Feb 2, 2010
263 * @version 1.0
264 */
265 class ConfigurationSelectionListener extends SelectionAdapter {
266
267 private ITaxonServiceConfigurator configurator = PreferencesUtil.getSearchConfigurator();
268
269 /*
270 * (non-Javadoc)
271 *
272 * @see
273 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
274 * .swt.events.SelectionEvent)
275 */
276 @Override
277 public void widgetSelected(SelectionEvent e) {
278 NavigationUtil.info("configuration menu clicked");
279 SearchOption option = (SearchOption) e.widget.getData();
280
281 switch (option){
282 case TAXON:
283 configurator.setDoTaxa(configurator.isDoTaxa() ? false : true);
284 break;
285 case SYNONYM:
286 configurator.setDoSynonyms(configurator.isDoSynonyms() ? false : true);
287 break;
288 case NAME:
289 configurator.setDoNamesWithoutTaxa(configurator.isDoNamesWithoutTaxa() ? false : true);
290 break;
291 case COMMON_NAME:
292 configurator.setDoTaxaByCommonNames(getConfigurator().isDoTaxaByCommonNames() ? false : true);
293 break;
294 }
295
296 saveConfigurator();
297 }
298
299 public ITaxonServiceConfigurator getConfigurator() {
300 return configurator;
301 }
302
303 private void saveConfigurator() {
304 PreferencesUtil.setSearchConfigurator(getConfigurator());
305 this.configurator = PreferencesUtil.getSearchConfigurator();
306 }
307 }
308
309 /**
310 * Available search options.
311 *
312 * @author n.hoffmann
313 * @created Feb 2, 2010
314 * @version 1.0
315 */
316 enum SearchOption {
317 TAXON("Taxa"),
318 SYNONYM("Synonyms"),
319 NAME("Names (without taxa)"),
320 COMMON_NAME("Common Names");
321
322 private final String label;
323
324 private SearchOption(String label) {
325 this.label = label;
326 }
327
328 public String getLabel() {
329 return label;
330 }
331
332 public boolean getPreference() {
333 if (!PreferencesUtil.getPreferenceStore().contains(
334 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_TAXA)) {
335 // initializes the search configurator
336 PreferencesUtil.initializeSearchConfigurator();
337 }
338
339 switch (this) {
340 case TAXON:
341 boolean result = PreferencesUtil.getPreferenceStore().getBoolean(
342 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_TAXA);
343 return result;
344 case SYNONYM:
345 return PreferencesUtil.getPreferenceStore().getBoolean(
346 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_SYNONYMS);
347 case NAME:
348 return PreferencesUtil.getPreferenceStore().getBoolean(
349 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_NAMES);
350 case COMMON_NAME:
351 return PreferencesUtil.getPreferenceStore().getBoolean(
352 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_COMMON_NAMES);
353 }
354
355 return true;
356 }
357
358 }
359 }