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