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