Project

General

Profile

Download (10.4 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
import javax.inject.Inject;
14

    
15
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.e4.ui.model.application.MApplication;
17
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
18
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
19
import org.eclipse.e4.ui.workbench.modeling.EModelService;
20
import org.eclipse.e4.ui.workbench.modeling.EPartService;
21
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.events.FocusEvent;
24
import org.eclipse.swt.events.FocusListener;
25
import org.eclipse.swt.events.KeyAdapter;
26
import org.eclipse.swt.events.KeyEvent;
27
import org.eclipse.swt.events.SelectionAdapter;
28
import org.eclipse.swt.events.SelectionEvent;
29
import org.eclipse.swt.graphics.Point;
30
import org.eclipse.swt.graphics.Rectangle;
31
import org.eclipse.swt.layout.RowLayout;
32
import org.eclipse.swt.widgets.Composite;
33
import org.eclipse.swt.widgets.Control;
34
import org.eclipse.swt.widgets.Menu;
35
import org.eclipse.swt.widgets.MenuItem;
36
import org.eclipse.swt.widgets.Text;
37
import org.eclipse.swt.widgets.ToolBar;
38
import org.eclipse.swt.widgets.ToolItem;
39
import org.eclipse.ui.IMemento;
40
import org.eclipse.ui.PlatformUI;
41
import org.eclipse.ui.swt.IFocusService;
42

    
43
import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
44
import eu.etaxonomy.taxeditor.model.AbstractUtility;
45
import eu.etaxonomy.taxeditor.model.IContextListener;
46
import eu.etaxonomy.taxeditor.model.MessagingUtils;
47
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
48
import eu.etaxonomy.taxeditor.navigation.search.e4.SearchResultViewE4;
49
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
50
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
51
import eu.etaxonomy.taxeditor.preference.Resources;
52
import eu.etaxonomy.taxeditor.store.CdmStore;
53
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
54

    
55
/**
56
 * @author n.hoffmann
57
 * @author e.-m.lee
58
 * @created 15.04.2009
59
 * @version 1.0
60
 */
61
public class SearchBar implements IContextListener{
62

    
63
    public static final String NAVIGATION_STACK_ID = "navigation";
64

    
65
    private Text text_search;
66
	private ToolBar toolBar;
67

    
68
	private final String defaultText = Messages.SearchBar_0;
69

    
70
	@Inject
71
	private EPartService partService;
72

    
73
	@Inject
74
	private MApplication application;
75

    
76
	@Inject
77
	private EModelService modelService;
78

    
79
	final private ConfigurationSelectionListener configurationListener = new ConfigurationSelectionListener();
80

    
81
	/** {@inheritDoc} */
82
	@PostConstruct
83
	protected Control createControl(Composite parent) {
84
		Composite composite = new Composite(parent, SWT.NONE);
85

    
86
		createLayout(composite);
87
		createSearchTextField(composite);
88
		createToolBar(composite);
89
		registerAtFocusService();
90
		//register for context refreshes
91
		CdmStore.getContextManager().addContextListener(this);
92

    
93
		return composite;
94
	}
95

    
96
	/**
97
	 * Handles focus changes for the search textfield.
98
	 */
99
	private void registerAtFocusService() {
100
		IFocusService focusService =
101
			PlatformUI.getWorkbench().getService(IFocusService.class);
102
		if (focusService != null) {
103
			focusService.addFocusTracker(text_search, "navigation.textControlId");
104
		}
105
	}
106

    
107
	/**
108
	 * Creates the search toolbar.
109
	 * @param composite
110
	 */
111
	private void createToolBar(Composite composite) {
112
		toolBar = new ToolBar(composite, SWT.NULL);
113

    
114
		ToolItem toolItem = new ToolItem(toolBar, SWT.DROP_DOWN | SWT.BORDER);
115
		toolItem.setText(Messages.SearchBar_1);
116
		toolBar.setEnabled(false);
117

    
118
		DropdownSelectionListener dropdownListener = new DropdownSelectionListener(
119
				toolItem);
120

    
121
		for(SearchOption searchOption : SearchOption.values()){
122
			dropdownListener.add(searchOption);
123
		}
124

    
125
		toolItem.addSelectionListener(dropdownListener);
126
	}
127

    
128
	/**
129
	 * Creates the search textfield.
130
	 * @param composite
131
	 */
132
	private void createSearchTextField(Composite composite) {
133
		// TODO for some reason the text_search composite has a margin when
134
		// either SWT.BORDER or SWT.SEARCH
135
		// is applied. I am not sure how to get rid of this.
136
		text_search = new Text(composite, SWT.BORDER | SWT.SINGLE
137
				| SWT.FULL_SELECTION);
138
		text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOREGROUND));
139
		text_search.setText(defaultText);
140
        text_search.setEnabled(false);
141

    
142
		addTextListeners();
143
	}
144

    
145
	/**
146
	 * Adds listeners to the search textfield.
147
	 */
148
	private void addTextListeners() {
149
		text_search.addFocusListener(new FocusListener() {
150

    
151
			@Override
152
            public void focusGained(FocusEvent e) {
153
				text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOCUS));
154
				if (defaultText.equals(text_search.getText())) {
155
					text_search.setText("");
156
				}
157
			}
158

    
159
			@Override
160
            public void focusLost(FocusEvent e) {
161
				if (text_search.getText() == "") {
162
					text_search.setForeground(AbstractUtility.getColor(Resources.SEARCH_VIEW_FOREGROUND));
163
					text_search.setText(defaultText);
164
				}
165
			}
166
		});
167

    
168
		text_search.addKeyListener(new KeyAdapter() {
169
			@Override
170
			public void keyPressed(KeyEvent e) {
171
				if (e.keyCode == SWT.CR) {
172
					search();
173
				}
174
			}
175
		});
176
	}
177

    
178
	/**
179
	 * Creates the search layout.
180
	 * @param composite
181
	 */
182
	private void createLayout(Composite composite) {
183
		final RowLayout layout = new RowLayout();
184
		layout.wrap = false;
185
		layout.pack = true;
186
		layout.justify = true;
187
		layout.type = SWT.HORIZONTAL;
188
		layout.marginLeft = 0;
189
		layout.marginTop = 0;
190
		layout.marginRight = 0;
191
		layout.marginBottom = 0;
192
		layout.spacing = 0;
193
		composite.setLayout(layout);
194
	}
195

    
196
	private void search(){
197
		final String searchString = getSearchString();
198
		if(searchString == null){
199
			return;
200
		}
201

    
202
		if(!searchString.trim().matches(".*\\p{L}+.*")){
203
			MessagingUtils.warningDialog(Messages.SearchBar_2, this, Messages.SearchBar_3);
204
			return;
205
		}
206

    
207

    
208
		IFindTaxaAndNamesConfigurator configurator = configurationListener.getConfigurator();
209
		configurator.setTitleSearchString(searchString);
210
		openSearchResultsView(configurator);
211

    
212
	}
213

    
214
	private String getSearchString(){
215
		String searchString = text_search.getText().trim();
216
		if (searchString.equals(defaultText) || searchString.length() == 0) {
217
            return null;
218
        }
219
		return searchString;
220
	}
221

    
222
	/**
223
	 * Opens a new instance of the search result view to display the result to the user.
224
	 *
225
	 * @param searchResult
226
	 */
227
	private void openSearchResultsView(IFindTaxaAndNamesConfigurator configurator) {
228
		boolean openResultInSeparateWindows = PreferencesUtil.getPreferenceStore().getBoolean((IPreferenceKeys.SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS));
229
		String partId = "eu.etaxonomy.taxeditor.navigation.search.e4.SearchResultViewE4";
230

    
231
		MPart part = partService.findPart(partId);
232
		if(openResultInSeparateWindows && part.getObject()!=null){
233
		    part = partService.createPart(partId);
234
		    //FIXME E4 this part stack id has to re-used or a adapted after migration
235
		    MPartStack editorAreaPartStack = WorkbenchUtility.getPartStack(NAVIGATION_STACK_ID, application, modelService);
236
		    if(editorAreaPartStack!=null){
237
		        editorAreaPartStack.getChildren().add(part);
238
		    }
239
		}
240
        part = partService.showPart(part, PartState.ACTIVATE);
241
        SearchResultViewE4 resultView = (SearchResultViewE4)part.getObject();
242
        resultView.performSearch(configurator);
243

    
244
	}
245

    
246
	/**
247
	 * Handles drop down menu selection. Available items are defined in the enumeration SearchOption.
248
	 *
249
	 * @author n.hoffmann
250
	 * @created Feb 2, 2010
251
	 * @version 1.0
252
	 */
253
	class DropdownSelectionListener extends SelectionAdapter {
254

    
255
		private final Menu menu;
256

    
257
		public DropdownSelectionListener(ToolItem dropdown) {
258
			menu = new Menu(dropdown.getParent().getShell());
259
		}
260

    
261
		public void add(SearchOption option) {
262
			MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
263
			menuItem.setData(option);
264
			menuItem.setText(option.getLabel());
265
			menuItem.setSelection(option.getPreference());
266
			menuItem.addSelectionListener(configurationListener);
267
		}
268

    
269
		@Override
270
		public void widgetSelected(SelectionEvent event) {
271
			if (event.detail == SWT.ARROW) {
272
				ToolItem item = (ToolItem) event.widget;
273
				Rectangle rect = item.getBounds();
274
				Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
275
				menu.setLocation(pt.x, pt.y + rect.height);
276
				menu.setVisible(true);
277
			} else {
278
				search();
279
			}
280
		}
281
	}
282

    
283
	/**
284
	 * Handles search configuration selection.
285
	 *
286
	 * @author n.hoffmann
287
	 * @created Feb 2, 2010
288
	 * @version 1.0
289
	 */
290
	class ConfigurationSelectionListener extends SelectionAdapter {
291

    
292
		private IFindTaxaAndNamesConfigurator configurator = PreferencesUtil.getSearchConfigurator();
293

    
294
		@Override
295
		public void widgetSelected(SelectionEvent e) {
296
			SearchOption option = (SearchOption) e.widget.getData();
297

    
298
			switch (option){
299
			case TAXON:
300
				configurator.setDoTaxa(configurator.isDoTaxa() ? false : true);
301
				break;
302
			case SYNONYM:
303
				configurator.setDoSynonyms(configurator.isDoSynonyms() ? false : true);
304
				break;
305
			case NAME:
306
				configurator.setDoNamesWithoutTaxa(configurator.isDoNamesWithoutTaxa() ? false : true);
307
				break;
308
			case COMMON_NAME:
309
				configurator.setDoTaxaByCommonNames(getConfigurator().isDoTaxaByCommonNames() ? false : true);
310
				break;
311
			}
312

    
313
			saveConfigurator();
314
		}
315

    
316
		public IFindTaxaAndNamesConfigurator getConfigurator() {
317
			return configurator;
318
		}
319

    
320
		private void saveConfigurator() {
321
			PreferencesUtil.setSearchConfigurator(getConfigurator());
322
			this.configurator = PreferencesUtil.getSearchConfigurator();
323
		}
324
	}
325

    
326
    @Override
327
    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
328
    }
329

    
330
    @Override
331
    public void contextStop(IMemento memento, IProgressMonitor monitor) {
332
        if(!text_search.isDisposed()){
333
            text_search.setEnabled(false);
334
        }
335
        if(!toolBar.isDisposed()){
336
            toolBar.setEnabled(false);
337
        }
338
    }
339

    
340
    @Override
341
    public void contextStart(IMemento memento, IProgressMonitor monitor) {
342
        if(!text_search.isDisposed()){
343
            text_search.setEnabled(true);
344
        }
345
        if(!toolBar.isDisposed()){
346
            toolBar.setEnabled(true);
347
        }
348
    }
349

    
350
    @Override
351
    public void contextRefresh(IProgressMonitor monitor) {
352
    }
353

    
354
    @Override
355
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
356
    }
357
}
(1-1/4)