Project

General

Profile

Download (10.9 KB) Statistics
| Branch: | Tag: | Revision:
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
        if(!text_search.isDisposed()){
377
            text_search.setEnabled(true);
378
        }
379
        if(!toolBar.isDisposed()){
380
            toolBar.setEnabled(true);
381
        }
382
    }
383

    
384
    @Override
385
    public void contextRefresh(IProgressMonitor monitor) {
386
    }
387

    
388
    @Override
389
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
390
    }
391
}
(1-1/3)