Moved all logging and dialog functionality to the new class MessagingUtils.
[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 public void focusGained(FocusEvent e) {
128 text_search.setForeground(NavigationUtil.getColor(Resources.SEARCH_VIEW_FOCUS));
129 if (defaultText.equals(text_search.getText())) {
130 text_search.setText("");
131 }
132 }
133
134 public void focusLost(FocusEvent e) {
135 if (text_search.getText() == "") {
136 text_search.setForeground(NavigationUtil.getColor(Resources.SEARCH_VIEW_FOREGROUND));
137 text_search.setText(defaultText);
138 }
139 }
140 });
141
142 text_search.addKeyListener(new KeyAdapter() {
143 /*
144 * (non-Javadoc)
145 * @see org.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt.events.KeyEvent)
146 */
147 @Override
148 public void keyPressed(KeyEvent e) {
149 if (e.keyCode == SWT.CR) {
150 search();
151 }
152 }
153 });
154 }
155
156 /**
157 * Creates the search layout.
158 * @param composite
159 */
160 private void createLayout(Composite composite) {
161 final RowLayout layout = new RowLayout();
162 layout.wrap = false;
163 layout.pack = true;
164 layout.justify = true;
165 layout.type = SWT.HORIZONTAL;
166 layout.marginLeft = 0;
167 layout.marginTop = 0;
168 layout.marginRight = 0;
169 layout.marginBottom = 0;
170 layout.spacing = 0;
171 composite.setLayout(layout);
172 }
173
174 private void search(){
175 final String searchString = getSearchString();
176 if(searchString == null){
177 return;
178 }
179
180 if("*".equals(searchString.trim())){
181 MessagingUtils.warningDialog(Messages.SearchBar_2, this, Messages.SearchBar_3);
182 return;
183 }
184
185
186 IFindTaxaAndNamesConfigurator configurator = configurationListener.getConfigurator();
187 configurator.setTitleSearchString(searchString);
188 openSearchResultsView(configurator);
189
190 }
191
192 private String getSearchString(){
193 String searchString = text_search.getText().trim();
194 if (searchString.equals(defaultText) || searchString.length() == 0)
195 return null;
196 return searchString;
197 }
198
199 /**
200 * Opens a new instance of the search result view to display the result to the user.
201 *
202 * @param searchResult
203 */
204 private void openSearchResultsView(IFindTaxaAndNamesConfigurator configurator) {
205 boolean openResultInSeparateWindows = PreferencesUtil.getPreferenceStore().getBoolean((IPreferenceKeys.SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS));
206 if(openResultInSeparateWindows){
207 //increment change secondary id so it is unique
208 secondaryId += "1";
209 }
210
211 try {
212 IViewPart resultsView = TaxeditorNavigationPlugin.getDefault()
213 .getWorkbench().getActiveWorkbenchWindow()
214 .getActivePage().showView(SearchResultView.ID, secondaryId,
215 IWorkbenchPage.VIEW_ACTIVATE);
216 ((SearchResultView) resultsView).performSearch(configurator);
217 } catch (PartInitException e) {
218 MessagingUtils.error(this.getClass(), Messages.SearchBar_4, e);
219 }
220 }
221
222 /**
223 * Handles drop down menu selection. Available items are defined in the enumeration SearchOption.
224 *
225 * @author n.hoffmann
226 * @created Feb 2, 2010
227 * @version 1.0
228 */
229 class DropdownSelectionListener extends SelectionAdapter {
230
231 private final Menu menu;
232
233 public DropdownSelectionListener(ToolItem dropdown) {
234 menu = new Menu(dropdown.getParent().getShell());
235 }
236
237 public void add(SearchOption option) {
238 MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
239 menuItem.setData(option);
240 menuItem.setText(option.getLabel());
241 menuItem.setSelection(option.getPreference());
242 menuItem.addSelectionListener(configurationListener);
243 }
244
245 @Override
246 public void widgetSelected(SelectionEvent event) {
247 if (event.detail == SWT.ARROW) {
248 ToolItem item = (ToolItem) event.widget;
249 Rectangle rect = item.getBounds();
250 Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
251 menu.setLocation(pt.x, pt.y + rect.height);
252 menu.setVisible(true);
253 } else {
254 search();
255 }
256 }
257 }
258
259 /**
260 * Handles search configuration selection.
261 *
262 * @author n.hoffmann
263 * @created Feb 2, 2010
264 * @version 1.0
265 */
266 class ConfigurationSelectionListener extends SelectionAdapter {
267
268 private IFindTaxaAndNamesConfigurator configurator = PreferencesUtil.getSearchConfigurator();
269
270 /*
271 * (non-Javadoc)
272 *
273 * @see
274 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
275 * .swt.events.SelectionEvent)
276 */
277 @Override
278 public void widgetSelected(SelectionEvent e) {
279 MessagingUtils.info(Messages.SearchBar_5);
280 SearchOption option = (SearchOption) e.widget.getData();
281
282 switch (option){
283 case TAXON:
284 configurator.setDoTaxa(configurator.isDoTaxa() ? false : true);
285 break;
286 case SYNONYM:
287 configurator.setDoSynonyms(configurator.isDoSynonyms() ? false : true);
288 break;
289 case NAME:
290 configurator.setDoNamesWithoutTaxa(configurator.isDoNamesWithoutTaxa() ? false : true);
291 break;
292 case COMMON_NAME:
293 configurator.setDoTaxaByCommonNames(getConfigurator().isDoTaxaByCommonNames() ? false : true);
294 break;
295 }
296
297 saveConfigurator();
298 }
299
300 public IFindTaxaAndNamesConfigurator getConfigurator() {
301 return configurator;
302 }
303
304 private void saveConfigurator() {
305 PreferencesUtil.setSearchConfigurator(getConfigurator());
306 this.configurator = PreferencesUtil.getSearchConfigurator();
307 }
308 }
309
310 /**
311 * Available search options.
312 *
313 * @author n.hoffmann
314 * @created Feb 2, 2010
315 * @version 1.0
316 */
317 enum SearchOption {
318 TAXON(Messages.SearchBar_6),
319 SYNONYM(Messages.SearchBar_7),
320 NAME(Messages.SearchBar_8),
321 COMMON_NAME(Messages.SearchBar_9);
322
323 private final String label;
324
325 private SearchOption(String label) {
326 this.label = label;
327 }
328
329 public String getLabel() {
330 return label;
331 }
332
333 public boolean getPreference() {
334 if (!PreferencesUtil.getPreferenceStore().contains(
335 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_TAXA)) {
336 // initializes the search configurator
337 PreferencesUtil.initializeSearchConfigurator();
338 }
339
340 switch (this) {
341 case TAXON:
342 boolean result = PreferencesUtil.getPreferenceStore().getBoolean(
343 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_TAXA);
344 return result;
345 case SYNONYM:
346 return PreferencesUtil.getPreferenceStore().getBoolean(
347 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_SYNONYMS);
348 case NAME:
349 return PreferencesUtil.getPreferenceStore().getBoolean(
350 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_NAMES);
351 case COMMON_NAME:
352 return PreferencesUtil.getPreferenceStore().getBoolean(
353 PreferencesUtil.TAXON_SERVICE_CONFIGURATOR_COMMON_NAMES);
354 }
355
356 return true;
357 }
358
359 }
360 }