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.e4;
11

    
12
import java.util.ArrayList;
13
import java.util.List;
14

    
15
import javax.annotation.PostConstruct;
16
import javax.annotation.PreDestroy;
17
import javax.inject.Inject;
18

    
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.core.runtime.jobs.Job;
23
import org.eclipse.e4.ui.di.Focus;
24
import org.eclipse.e4.ui.model.application.MApplication;
25
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
26
import org.eclipse.e4.ui.services.EMenuService;
27
import org.eclipse.e4.ui.workbench.modeling.EModelService;
28
import org.eclipse.e4.ui.workbench.modeling.EPartService;
29
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
30
import org.eclipse.jface.viewers.ArrayContentProvider;
31
import org.eclipse.jface.viewers.DoubleClickEvent;
32
import org.eclipse.jface.viewers.IDoubleClickListener;
33
import org.eclipse.jface.viewers.ISelection;
34
import org.eclipse.jface.viewers.ISelectionChangedListener;
35
import org.eclipse.jface.viewers.IStructuredSelection;
36
import org.eclipse.jface.viewers.TableViewer;
37
import org.eclipse.swt.SWT;
38
import org.eclipse.swt.layout.GridData;
39
import org.eclipse.swt.layout.GridLayout;
40
import org.eclipse.swt.widgets.Composite;
41
import org.eclipse.swt.widgets.Display;
42
import org.eclipse.swt.widgets.Label;
43
import org.eclipse.swt.widgets.Text;
44
import org.eclipse.ui.IMemento;
45

    
46
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
47
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
48
import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
49
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
50
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
51
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
52
import eu.etaxonomy.cdm.persistence.query.MatchMode;
53
import eu.etaxonomy.taxeditor.model.AbstractUtility;
54
import eu.etaxonomy.taxeditor.model.ContextListenerAdapter;
55
import eu.etaxonomy.taxeditor.model.IContextListener;
56
import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
57
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
58
import eu.etaxonomy.taxeditor.navigation.search.SearchOption;
59
import eu.etaxonomy.taxeditor.navigation.search.SearchResultLabelProvider;
60
import eu.etaxonomy.taxeditor.store.CdmStore;
61

    
62
/**
63
 *
64
 * @author pplitzner
65
 * @since Sep 27, 2017
66
 *
67
 */
68
public class SearchResultViewE4 implements IConversationEnabled{
69

    
70
	private static Object[] EMPTY = new Object[0];
71

    
72
	@Inject
73
	private MPart thisPart;
74

    
75
	private class ContextListener extends ContextListenerAdapter{
76
		@Override
77
		public void contextStop(IMemento memento, IProgressMonitor monitor) {
78
	        //close view when workbench closes
79
	        try{
80
	            thisPart.getContext().get(EPartService.class).hidePart(thisPart);
81
	        }
82
	        catch(Exception e){
83
	            //nothing
84
	        }
85
		}
86
	}
87

    
88
	/** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.searc"{trunked}</code> */
89
	public static final String ID =
90
			"eu.etaxonomy.taxeditor.navigation.search.searchResultView"; //$NON-NLS-1$
91

    
92
	private TableViewer resultViewer;
93

    
94
	private ConversationHolder conversation;
95

    
96
	private Text searchString;
97

    
98
	private Text configurationLabel;
99

    
100
	private Text status;
101

    
102
	private SearchJob searchJob;
103

    
104
	private IContextListener contextListener;
105

    
106
    @Inject
107
    private ESelectionService selService;
108

    
109
    @Inject
110
    private MApplication application;
111

    
112
    @Inject
113
    private EModelService modelService;
114

    
115
    @Inject
116
    private EPartService partService;
117

    
118
    private ISelectionChangedListener selectionChangedListener;
119

    
120
	/** {@inheritDoc} */
121
	@PostConstruct
122
	public void createPartControl(Composite parent, EMenuService menuService) {
123
        if (CdmStore.isActive()){
124
            if(conversation == null){
125
                conversation = getConversation_internal();
126
            }
127
        }
128
        else{
129
            return;
130
        }
131
		contextListener = new ContextListener();
132
		CdmStore.getContextManager().addContextListener(contextListener);
133

    
134
		GridLayout layout = new GridLayout();
135
		layout.marginWidth = 0;
136
		layout.marginHeight = 0;
137

    
138
		parent.setLayout(layout);
139

    
140
		Composite infoComposite = createInfoComposite(parent);
141
		infoComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
142

    
143
		resultViewer = new TableViewer(parent, SWT.NONE);
144
		resultViewer.setContentProvider(new ArrayContentProvider());
145
		resultViewer.setLabelProvider(new SearchResultLabelProvider());
146
		resultViewer.addDoubleClickListener(new IDoubleClickListener() {
147
			@Override
148
            public void doubleClick(DoubleClickEvent event) {
149
			    ISelection selection = event.getSelection();
150
			    if(selection instanceof IStructuredSelection){
151
			        Object firstElement = ((IStructuredSelection) selection).getFirstElement();
152
			        if(firstElement instanceof UuidAndTitleCache){
153
			            NavigationUtil.openEditor((UuidAndTitleCache) firstElement, resultViewer.getControl().getShell(), modelService, partService, application);
154
			        }
155
			    }
156
			}
157
		});
158

    
159
		resultViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
160

    
161
		 //propagate selection
162
        selectionChangedListener = (event -> selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event)));
163
        resultViewer.addSelectionChangedListener(selectionChangedListener);
164

    
165
        //create context menu
166
        menuService.registerContextMenu(resultViewer.getControl(), "eu.etaxonomy.taxeditor.navigation.popupmenu.searchresults");
167

    
168
	}
169

    
170
	private Composite createInfoComposite(Composite parent){
171
		Composite composite = new Composite(parent, SWT.NULL);
172

    
173
		composite.setLayout(new GridLayout(2, false));
174

    
175
		Label searchStringLabel = new Label(composite, SWT.NULL);
176
		searchStringLabel.setText(Messages.SearchResultView_SEARCH_STRING);
177

    
178
		searchString = new Text(composite, SWT.NULL);
179
		searchString.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
180
		searchString.setEditable(false);
181
//		searchString.setText("                                               ");
182

    
183
		Label configurationDescriptionLabel = new Label(composite, SWT.NULL);
184
		configurationDescriptionLabel.setText(Messages.SearchResultView_SEARCH_FOR);
185

    
186
		configurationLabel = new Text(composite, SWT.WRAP);
187
		configurationLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
188
		configurationLabel.setEditable(false);
189

    
190
		Label statusLabel = new Label(composite, SWT.NULL);
191
		statusLabel.setText(Messages.SearchResultView_STATUS);
192

    
193
		status = new Text(composite, SWT.NULL);
194
		status.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
195
		status.setEditable(false);
196

    
197
		return composite;
198
	}
199

    
200
	/**
201
	 * <p>performSearch</p>
202
	 *
203
	 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator} object.
204
	 */
205
	public void performSearch(IFindTaxaAndNamesConfigurator configurator){
206
		thisPart.setLabel(String.format(Messages.SearchResultView_SEARCH, configurator.getTitleSearchString()));
207

    
208
		searchString.setText(configurator.getTitleSearchString());
209

    
210
		List<String> includedEntities = new ArrayList<String>();
211
		if(configurator.isDoTaxa()) {
212
            includedEntities.add(SearchOption.TAXON.getLabel());
213
        }
214
		if(configurator.isDoSynonyms()) {
215
            includedEntities.add(SearchOption.SYNONYM.getLabel());
216
        }
217
		if(configurator.isDoNamesWithoutTaxa()) {
218
            includedEntities.add(SearchOption.NAME.getLabel());
219
        }
220
		if(configurator.isDoTaxaByCommonNames()){
221
			includedEntities.add(SearchOption.COMMON_NAME.getLabel());
222
		}
223
		configurator.setMatchMode(MatchMode.LIKE);
224

    
225
		String includedEntitiesString = ""; //$NON-NLS-1$
226
		for (int i = 0; i < includedEntities.size(); i++){
227
			includedEntitiesString += includedEntities.get(i);
228
			if(i < includedEntities.size() -1){
229
				includedEntitiesString += ", "; //$NON-NLS-1$
230
			}
231
		}
232

    
233
		configurationLabel.setText(includedEntitiesString);
234

    
235
		status.setText(Messages.SearchResultView_SEARCHING);
236

    
237
		searchJob = new SearchJob(Display.getCurrent(), configurator);
238
		searchJob.schedule();
239

    
240
	}
241

    
242
	/**
243
	 * <p>displaySearchResult</p>
244
	 *
245
	 * @param result a {@link java.util.List} object.
246
	 */
247
	protected void displaySearchResult(List<UuidAndTitleCache<IdentifiableEntity>> result) {
248
		if(result.size() > 0){
249
			resultViewer.setInput(result);
250
			status.setText(String.format(Messages.SearchResultView_CNT_ENTITIES_FOUND, result.size()));
251
		}else{
252
			resultViewer.setInput(EMPTY);
253
			status.setText(Messages.SearchResultView_NO_RESULTS);
254
		}
255
	}
256

    
257
	/** {@inheritDoc} */
258
	@Focus
259
	public void setFocus() {
260
		//logger.warn("Setting focus to search result viewer");
261
		ConversationHolder conversation_internal = getConversation_internal();
262
		if(conversation_internal!=null){
263
		    conversation_internal.bind();
264
		}
265
		// pass focus to resultViewer
266
		if(resultViewer!=null && resultViewer.getControl()!=null){
267
		    resultViewer.getControl().setFocus();
268
		}
269
	}
270

    
271
	/**
272
	 * <p>getConversationHolder</p>
273
	 *
274
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
275
	 */
276
	@Override
277
    public ConversationHolder getConversationHolder() {
278
		return this.conversation;
279
	}
280

    
281
	/** {@inheritDoc} */
282
	@Override
283
    public void update(CdmDataChangeMap changeEvents) {
284
		// TODO Auto-generated method stub
285

    
286
	}
287

    
288
	/** {@inheritDoc} */
289
	@PreDestroy
290
	public void dispose() {
291
		if(conversation!=null){
292
		    conversation.close();
293
		}
294
		if(searchJob != null) {
295
            searchJob.cancel();
296
        }
297
	}
298

    
299
	private ConversationHolder getConversation_internal(){
300
	    if(conversation==null && CdmStore.isActive()){
301
	        try {
302
	            conversation = CdmStore.createConversation();
303
            } catch (Exception e) {
304
                //nothing
305
            }
306
	    }
307
	    return conversation;
308
	}
309

    
310
	/**
311
	 *
312
	 * @author n.hoffmann
313
	 * @created Feb 2, 2010
314
	 * @version 1.0
315
	 */
316
	class SearchJob extends Job{
317

    
318
		private final IFindTaxaAndNamesConfigurator configurator;
319

    
320
		private final Display display;
321

    
322
		/**
323
		 * @param name
324
		 */
325
		public SearchJob(Display display, IFindTaxaAndNamesConfigurator configurator) {
326
			super(Messages.SearchResultView_PERFORMING_SEARCH);
327
			this.display = display;
328
			this.configurator = configurator;
329
		}
330

    
331
		@Override
332
		protected IStatus run(IProgressMonitor monitor) {
333
			monitor.beginTask("", 100); //$NON-NLS-1$
334
			monitor.worked(20);
335

    
336
			final List<UuidAndTitleCache<IdentifiableEntity>> searchResult = CdmStore.getSearchManager().findTaxaAndNames(configurator);
337
			monitor.worked(40);
338

    
339
			if(! monitor.isCanceled()){
340
				display.asyncExec(new Runnable() {
341
					@Override
342
                    public void run() {
343
						displaySearchResult(searchResult);
344
					}
345
				});
346
			}else{
347
				display.asyncExec(new Runnable() {
348
					@Override
349
                    public void run() {
350
						status.setText(Messages.SearchResultView_CANCELLED);
351
					}
352
				});
353
			}
354
			monitor.done();
355
			return Status.OK_STATUS;
356
		}
357

    
358
	}
359
}
    (1-1/1)