adapting to chages in CdmUtils
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / search / SearchBar.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.navigation.search;
11
12 import javax.annotation.PostConstruct;
13
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.events.FocusEvent;
17 import org.eclipse.swt.events.FocusListener;
18 import org.eclipse.swt.events.KeyAdapter;
19 import org.eclipse.swt.events.KeyEvent;
20 import org.eclipse.swt.events.SelectionAdapter;
21 import org.eclipse.swt.events.SelectionEvent;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.Rectangle;
24 import org.eclipse.swt.layout.RowLayout;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Menu;
28 import org.eclipse.swt.widgets.MenuItem;
29 import org.eclipse.swt.widgets.Text;
30 import org.eclipse.swt.widgets.ToolBar;
31 import org.eclipse.swt.widgets.ToolItem;
32 import org.eclipse.ui.IMemento;
33 import org.eclipse.ui.IViewPart;
34 import org.eclipse.ui.IWorkbenchPage;
35 import org.eclipse.ui.PartInitException;
36 import org.eclipse.ui.PlatformUI;
37 import org.eclipse.ui.swt.IFocusService;
38
39 import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
40 import eu.etaxonomy.taxeditor.model.AbstractUtility;
41 import eu.etaxonomy.taxeditor.model.IContextListener;
42 import eu.etaxonomy.taxeditor.model.MessagingUtils;
43 import eu.etaxonomy.taxeditor.navigation.internal.TaxeditorNavigationPlugin;
44 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
45 import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
46 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
47 import eu.etaxonomy.taxeditor.preference.Resources;
48 import eu.etaxonomy.taxeditor.store.CdmStore;
49
50 /**
51 * @author n.hoffmann
52 * @author e.-m.lee
53 * @created 15.04.2009
54 * @version 1.0
55 */
56 public class SearchBar implements IContextListener{
57 private Text text_search;
58 private String secondaryId;
59 private ToolBar toolBar;
60
61 private final String defaultText = Messages.SearchBar_0;
62
63 final private ConfigurationSelectionListener configurationListener = new ConfigurationSelectionListener();
64
65 /** {@inheritDoc} */
66 @PostConstruct
67 protected Control createControl(Composite parent) {
68 Composite composite = new Composite(parent, SWT.NONE);
69
70 createLayout(composite);
71 createSearchTextField(composite);
72 createToolBar(composite);
73 registerAtFocusService();
74 //register for context refreshes
75 CdmStore.getContextManager().addContextListener(this);
76
77 return composite;
78 }
79
80 /**
81 * Handles focus changes for the search textfield.
82 */
83 private void registerAtFocusService() {
84 IFocusService focusService =
85 PlatformUI.getWorkbench().getService(IFocusService.class);
86 if (focusService != null) {
87 focusService.addFocusTracker(text_search, "navigation.textControlId");
88 }
89 }
90
91 /**
92 * Creates the search toolbar.
93 * @param composite
94 */
95 private void createToolBar(Composite composite) {
96 toolBar = new ToolBar(composite, SWT.NULL);
97
98 ToolItem toolItem = new ToolItem(toolBar, SWT.DROP_DOWN | SWT.BORDER);
99 toolItem.setText(Messages.SearchBar_1);
100 toolBar.setEnabled(false);
101
102 DropdownSelectionListener dropdownListener = new DropdownSelectionListener(
103 toolItem);
104
105 for(SearchOption searchOption : SearchOption.values()){
106 dropdownListener.add(searchOption);
107 }
108
109 toolItem.addSelectionListener(dropdownListener);
110 }
111
112 /**
113 * Creates the search textfield.
114 * @param composite
115 */
116 private void createSearchTextField(Composite composite) {
117 // TODO for some reason the text_search composite has a margin when
118 // either SWT.BORDER or SWT.SEARCH
119 // is applied. I am not sure how to get rid of this.
120 text_search = new Text(composite, SWT.BORDER | SWT.SINGLE
121 | SWT.FULL_SELECTION);
122 text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOREGROUND));
123 text_search.setText(defaultText);
124 text_search.setEnabled(false);
125
126 addTextListeners();
127 }
128
129 /**
130 * Adds listeners to the search textfield.
131 */
132 private void addTextListeners() {
133 text_search.addFocusListener(new FocusListener() {
134
135 @Override
136 public void focusGained(FocusEvent e) {
137 text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOCUS));
138 if (defaultText.equals(text_search.getText())) {
139 text_search.setText("");
140 }
141 }
142
143 @Override
144 public void focusLost(FocusEvent e) {
145 if (text_search.getText() == "") {
146 text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOREGROUND));
147 text_search.setText(defaultText);
148 }
149 }
150 });
151
152 text_search.addKeyListener(new KeyAdapter() {
153 @Override
154 public void keyPressed(KeyEvent e) {
155 if (e.keyCode == SWT.CR) {
156 search();
157 }
158 }
159 });
160 }
161
162 /**
163 * Creates the search layout.
164 * @param composite
165 */
166 private void createLayout(Composite composite) {
167 final RowLayout layout = new RowLayout();
168 layout.wrap = false;
169 layout.pack = true;
170 layout.justify = true;
171 layout.type = SWT.HORIZONTAL;
172 layout.marginLeft = 0;
173 layout.marginTop = 0;
174 layout.marginRight = 0;
175 layout.marginBottom = 0;
176 layout.spacing = 0;
177 composite.setLayout(layout);
178 }
179
180 private void search(){
181 final String searchString = getSearchString();
182 if(searchString == null){
183 return;
184 }
185
186 if(!searchString.trim().matches(".*\\p{L}+.*")){
187 MessagingUtils.warningDialog(Messages.SearchBar_2, this, Messages.SearchBar_3);
188 return;
189 }
190
191
192 IFindTaxaAndNamesConfigurator configurator = configurationListener.getConfigurator();
193 configurator.setTitleSearchString(searchString);
194 openSearchResultsView(configurator);
195
196 }
197
198 private String getSearchString(){
199 String searchString = text_search.getText().trim();
200 if (searchString.equals(defaultText) || searchString.length() == 0) {
201 return null;
202 }
203 return searchString;
204 }
205
206 /**
207 * Opens a new instance of the search result view to display the result to the user.
208 *
209 * @param searchResult
210 */
211 private void openSearchResultsView(IFindTaxaAndNamesConfigurator configurator) {
212 boolean openResultInSeparateWindows = PreferencesUtil.getPreferenceStore().getBoolean((IPreferenceKeys.SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS));
213 if(openResultInSeparateWindows){
214 //increment change secondary id so it is unique
215 secondaryId += "1";
216 }
217
218 try {
219 IViewPart resultsView = TaxeditorNavigationPlugin.getDefault()
220 .getWorkbench().getActiveWorkbenchWindow()
221 .getActivePage().showView(SearchResultView.ID, secondaryId,
222 IWorkbenchPage.VIEW_ACTIVATE);
223 ((SearchResultView) resultsView).performSearch(configurator);
224 } catch (PartInitException e) {
225 MessagingUtils.error(this.getClass(), Messages.SearchBar_4, e);
226 }
227 }
228
229 /**
230 * Handles drop down menu selection. Available items are defined in the enumeration SearchOption.
231 *
232 * @author n.hoffmann
233 * @created Feb 2, 2010
234 * @version 1.0
235 */
236 class DropdownSelectionListener extends SelectionAdapter {
237
238 private final Menu menu;
239
240 public DropdownSelectionListener(ToolItem dropdown) {
241 menu = new Menu(dropdown.getParent().getShell());
242 }
243
244 public void add(SearchOption option) {
245 MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
246 menuItem.setData(option);
247 menuItem.setText(option.getLabel());
248 menuItem.setSelection(option.getPreference());
249 menuItem.addSelectionListener(configurationListener);
250 }
251
252 @Override
253 public void widgetSelected(SelectionEvent event) {
254 if (event.detail == SWT.ARROW) {
255 ToolItem item = (ToolItem) event.widget;
256 Rectangle rect = item.getBounds();
257 Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
258 menu.setLocation(pt.x, pt.y + rect.height);
259 menu.setVisible(true);
260 } else {
261 search();
262 }
263 }
264 }
265
266 /**
267 * Handles search configuration selection.
268 *
269 * @author n.hoffmann
270 * @created Feb 2, 2010
271 * @version 1.0
272 */
273 class ConfigurationSelectionListener extends SelectionAdapter {
274
275 private IFindTaxaAndNamesConfigurator configurator = PreferencesUtil.getSearchConfigurator();
276
277 @Override
278 public void widgetSelected(SelectionEvent e) {
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 IFindTaxaAndNamesConfigurator 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(Messages.SearchBar_6),
318 SYNONYM(Messages.SearchBar_7),
319 NAME(Messages.SearchBar_8),
320 COMMON_NAME(Messages.SearchBar_9);
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 IPreferenceKeys.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 IPreferenceKeys.TAXON_SERVICE_CONFIGURATOR_TAXA);
343 return result;
344 case SYNONYM:
345 return PreferencesUtil.getPreferenceStore().getBoolean(
346 IPreferenceKeys.TAXON_SERVICE_CONFIGURATOR_SYNONYMS);
347 case NAME:
348 return PreferencesUtil.getPreferenceStore().getBoolean(
349 IPreferenceKeys.TAXON_SERVICE_CONFIGURATOR_NAMES);
350 case COMMON_NAME:
351 return PreferencesUtil.getPreferenceStore().getBoolean(
352 IPreferenceKeys.TAXON_SERVICE_CONFIGURATOR_COMMON_NAMES);
353 }
354
355 return true;
356 }
357
358 }
359
360 @Override
361 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
362 }
363
364 @Override
365 public void contextStop(IMemento memento, IProgressMonitor monitor) {
366 if(!text_search.isDisposed()){
367 text_search.setEnabled(false);
368 }
369 if(!toolBar.isDisposed()){
370 toolBar.setEnabled(false);
371 }
372 }
373
374 @Override
375 public void contextStart(IMemento memento, IProgressMonitor monitor) {
376 text_search.setEnabled(true);
377 toolBar.setEnabled(true);
378 }
379
380 @Override
381 public void contextRefresh(IProgressMonitor monitor) {
382 }
383
384 @Override
385 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
386 }
387 }