Project

General

Profile

Download (10.8 KB) Statistics
| Branch: | Tag: | Revision:
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.core.runtime.IProgressMonitor;
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.events.FocusEvent;
16
import org.eclipse.swt.events.FocusListener;
17
import org.eclipse.swt.events.KeyAdapter;
18
import org.eclipse.swt.events.KeyEvent;
19
import org.eclipse.swt.events.SelectionAdapter;
20
import org.eclipse.swt.events.SelectionEvent;
21
import org.eclipse.swt.graphics.Point;
22
import org.eclipse.swt.graphics.Rectangle;
23
import org.eclipse.swt.layout.RowLayout;
24
import org.eclipse.swt.widgets.Composite;
25
import org.eclipse.swt.widgets.Control;
26
import org.eclipse.swt.widgets.Menu;
27
import org.eclipse.swt.widgets.MenuItem;
28
import org.eclipse.swt.widgets.Text;
29
import org.eclipse.swt.widgets.ToolBar;
30
import org.eclipse.swt.widgets.ToolItem;
31
import org.eclipse.ui.IMemento;
32
import org.eclipse.ui.IViewPart;
33
import org.eclipse.ui.IWorkbenchPage;
34
import org.eclipse.ui.PartInitException;
35
import org.eclipse.ui.PlatformUI;
36
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
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.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
}
(2-2/4)