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