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