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