Add "Open in..." to taxon search #5616
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / search / SearchResultView.java
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 java.util.ArrayList;
13 import java.util.List;
14
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.Status;
18 import org.eclipse.core.runtime.jobs.Job;
19 import org.eclipse.jface.action.GroupMarker;
20 import org.eclipse.jface.action.MenuManager;
21 import org.eclipse.jface.viewers.ArrayContentProvider;
22 import org.eclipse.jface.viewers.DoubleClickEvent;
23 import org.eclipse.jface.viewers.IDoubleClickListener;
24 import org.eclipse.jface.viewers.IStructuredSelection;
25 import org.eclipse.jface.viewers.TableViewer;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.layout.GridData;
28 import org.eclipse.swt.layout.GridLayout;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Display;
32 import org.eclipse.swt.widgets.Label;
33 import org.eclipse.swt.widgets.Menu;
34 import org.eclipse.swt.widgets.Text;
35 import org.eclipse.ui.IMemento;
36 import org.eclipse.ui.IWorkbenchActionConstants;
37 import org.eclipse.ui.part.ViewPart;
38
39 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
40 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
41 import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
42 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
43 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
44 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
45 import eu.etaxonomy.cdm.persistence.query.MatchMode;
46 import eu.etaxonomy.taxeditor.model.AbstractUtility;
47 import eu.etaxonomy.taxeditor.model.ContextListenerAdapter;
48 import eu.etaxonomy.taxeditor.model.IContextListener;
49 import eu.etaxonomy.taxeditor.navigation.search.SearchBar.SearchOption;
50 import eu.etaxonomy.taxeditor.store.CdmStore;
51 import eu.etaxonomy.taxeditor.view.CdmViewerChooser;
52
53 /**
54 * <p>SearchResultView class.</p>
55 *
56 * @author p.ciardelli
57 * @author n.hoffmann
58 * @created 19.01.2009
59 * @version 1.0
60 */
61 public class SearchResultView extends ViewPart implements IConversationEnabled{
62
63 private static Object[] EMPTY = new Object[0];
64
65 private class ContextListener extends ContextListenerAdapter{
66 /* (non-Javadoc)
67 * @see eu.etaxonomy.taxeditor.model.IContextListener#contextStop(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
68 */
69 @Override
70 public void contextStop(IMemento memento, IProgressMonitor monitor) {
71 monitor.subTask("Getting rid of search results");
72 AbstractUtility.hideView(SearchResultView.this);
73 }
74 }
75
76 /** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.searc"{trunked}</code> */
77 public static final String ID =
78 "eu.etaxonomy.taxeditor.navigation.search.searchResultView"; //$NON-NLS-1$
79
80 private TableViewer resultViewer;
81
82 private ConversationHolder conversation;
83
84 private Text searchString;
85
86 private Text configurationLabel;
87
88 private Text status;
89
90 private SearchJob searchJob;
91
92 private IContextListener contextListener;
93
94 /* (non-Javadoc)
95 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
96 */
97 /** {@inheritDoc} */
98 @Override
99 public void createPartControl(Composite parent) {
100
101 conversation = CdmStore.createConversation();
102 contextListener = new ContextListener();
103 CdmStore.getContextManager().addContextListener(contextListener);
104
105 GridLayout layout = new GridLayout();
106 layout.marginWidth = 0;
107 layout.marginHeight = 0;
108
109 parent.setLayout(layout);
110
111 Composite infoComposite = createInfoComposite(parent);
112 infoComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
113
114 resultViewer = new TableViewer(parent, SWT.NONE);
115 resultViewer.setContentProvider(new ArrayContentProvider());
116 resultViewer.setLabelProvider(new SearchResultLabelProvider());
117 resultViewer.addDoubleClickListener(new IDoubleClickListener() {
118 @Override
119 public void doubleClick(DoubleClickEvent event) {
120 if(event.getSelection() instanceof IStructuredSelection){
121 Object selectedObject = ((IStructuredSelection) event.getSelection()).getFirstElement();
122 CdmViewerChooser chooser = new CdmViewerChooser(getSite().getShell());
123 chooser.chooseViewer(selectedObject);
124 }
125 }
126 });
127
128 resultViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
129
130 getSite().setSelectionProvider(resultViewer);
131
132 // register context menu
133 MenuManager menuMgr = new MenuManager();
134 menuMgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
135 getSite().registerContextMenu(menuMgr, resultViewer);
136
137 Control control = resultViewer.getControl();
138 Menu menu = menuMgr.createContextMenu(control);
139 control.setMenu(menu);
140 }
141
142 private Composite createInfoComposite(Composite parent){
143 Composite composite = new Composite(parent, SWT.NULL);
144
145 composite.setLayout(new GridLayout(2, false));
146
147 Label searchStringLabel = new Label(composite, SWT.NULL);
148 searchStringLabel.setText("Search String:");
149
150 searchString = new Text(composite, SWT.NULL);
151 searchString.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
152 searchString.setEditable(false);
153 // searchString.setText(" ");
154
155 Label configurationDescriptionLabel = new Label(composite, SWT.NULL);
156 configurationDescriptionLabel.setText("Search for:");
157
158 configurationLabel = new Text(composite, SWT.WRAP);
159 configurationLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
160 configurationLabel.setEditable(false);
161
162 Label statusLabel = new Label(composite, SWT.NULL);
163 statusLabel.setText("Status:");
164
165 status = new Text(composite, SWT.NULL);
166 status.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
167 status.setEditable(false);
168
169 return composite;
170 }
171
172 /**
173 * <p>performSearch</p>
174 *
175 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator} object.
176 */
177 public void performSearch(IFindTaxaAndNamesConfigurator configurator){
178 setPartName("Search: '" + configurator.getTitleSearchString() + "'");
179
180 searchString.setText(configurator.getTitleSearchString());
181
182 List<String> includedEntities = new ArrayList<String>();
183 if(configurator.isDoTaxa()) {
184 includedEntities.add(SearchOption.TAXON.getLabel());
185 }
186 if(configurator.isDoSynonyms()) {
187 includedEntities.add(SearchOption.SYNONYM.getLabel());
188 }
189 if(configurator.isDoNamesWithoutTaxa()) {
190 includedEntities.add(SearchOption.NAME.getLabel());
191 }
192 if(configurator.isDoTaxaByCommonNames()){
193 includedEntities.add(SearchOption.COMMON_NAME.getLabel());
194 }
195 configurator.setMatchMode(MatchMode.LIKE);
196
197 String includedEntitiesString = "";
198 for (int i = 0; i < includedEntities.size(); i++){
199 includedEntitiesString += includedEntities.get(i);
200 if(i < includedEntities.size() -1){
201 includedEntitiesString += ", ";
202 }
203 }
204
205 configurationLabel.setText(includedEntitiesString);
206
207 status.setText("Searching...");
208
209 searchJob = new SearchJob(Display.getCurrent(), configurator);
210 searchJob.schedule();
211
212 }
213
214 /**
215 * <p>displaySearchResult</p>
216 *
217 * @param result a {@link java.util.List} object.
218 */
219 protected void displaySearchResult(List<UuidAndTitleCache<IdentifiableEntity>> result) {
220 if(result.size() > 0){
221 resultViewer.setInput(result);
222 status.setText(result.size() + " entities found");
223 }else{
224 resultViewer.setInput(EMPTY);
225 status.setText("Search returned no results");
226 }
227 }
228
229 /* (non-Javadoc)
230 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
231 */
232 /** {@inheritDoc} */
233 @Override
234 public void setFocus() {
235 //logger.warn("Setting focus to search result viewer");
236 conversation.bind();
237 // pass focus to resultViewer
238 resultViewer.getControl().setFocus();
239 }
240
241 /* (non-Javadoc)
242 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
243 */
244 /**
245 * <p>getConversationHolder</p>
246 *
247 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
248 */
249 @Override
250 public ConversationHolder getConversationHolder() {
251 return this.conversation;
252 }
253
254 /* (non-Javadoc)
255 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
256 */
257 /** {@inheritDoc} */
258 @Override
259 public void update(CdmDataChangeMap changeEvents) {
260 // TODO Auto-generated method stub
261
262 }
263
264 /* (non-Javadoc)
265 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
266 */
267 /** {@inheritDoc} */
268 @Override
269 public void dispose() {
270 super.dispose();
271 conversation.close();
272 if(searchJob != null) {
273 searchJob.cancel();
274 }
275 CdmStore.getContextManager().removeContextListener(contextListener);
276 }
277
278 /**
279 *
280 * @author n.hoffmann
281 * @created Feb 2, 2010
282 * @version 1.0
283 */
284 class SearchJob extends Job{
285
286 private final IFindTaxaAndNamesConfigurator configurator;
287
288 private final Display display;
289
290 /**
291 * @param name
292 */
293 public SearchJob(Display display, IFindTaxaAndNamesConfigurator configurator) {
294 super("Performing Search");
295 this.display = display;
296 this.configurator = configurator;
297 }
298
299 /* (non-Javadoc)
300 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
301 */
302 @Override
303 protected IStatus run(IProgressMonitor monitor) {
304 monitor.beginTask("", 100);
305 monitor.worked(20);
306
307 final List<UuidAndTitleCache<IdentifiableEntity>> searchResult = CdmStore.getSearchManager().findTaxaAndNames(configurator);
308 monitor.worked(40);
309
310 if(! monitor.isCanceled()){
311 display.asyncExec(new Runnable() {
312 @Override
313 public void run() {
314 displaySearchResult(searchResult);
315 }
316 });
317 }else{
318 display.asyncExec(new Runnable() {
319 @Override
320 public void run() {
321 status.setText("Cancelled");
322 }
323 });
324 }
325 monitor.done();
326 return Status.OK_STATUS;
327 }
328
329 }
330 }