Project

General

Profile

Download (12.7 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.taxeditor.editor.view.descriptive;
12

    
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.eclipse.jface.action.Action;
21
import org.eclipse.jface.action.GroupMarker;
22
import org.eclipse.jface.action.IAction;
23
import org.eclipse.jface.action.IToolBarManager;
24
import org.eclipse.jface.action.MenuManager;
25
import org.eclipse.jface.resource.ImageDescriptor;
26
import org.eclipse.jface.viewers.DoubleClickEvent;
27
import org.eclipse.jface.viewers.IDoubleClickListener;
28
import org.eclipse.jface.viewers.ISelection;
29
import org.eclipse.jface.viewers.IStructuredSelection;
30
import org.eclipse.jface.viewers.ITreeContentProvider;
31
import org.eclipse.jface.viewers.StructuredSelection;
32
import org.eclipse.jface.viewers.TreeNode;
33
import org.eclipse.jface.viewers.TreeSelection;
34
import org.eclipse.jface.viewers.TreeViewer;
35
import org.eclipse.jface.viewers.Viewer;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.dnd.DND;
38
import org.eclipse.swt.dnd.Transfer;
39
import org.eclipse.swt.graphics.ImageData;
40
import org.eclipse.swt.widgets.Composite;
41
import org.eclipse.swt.widgets.Control;
42
import org.eclipse.swt.widgets.Menu;
43
import org.eclipse.swt.widgets.Tree;
44
import org.eclipse.ui.IWorkbenchActionConstants;
45
import org.eclipse.ui.IWorkbenchPart;
46
import org.eclipse.ui.PartInitException;
47

    
48
import eu.etaxonomy.cdm.model.common.CdmBase;
49
import eu.etaxonomy.cdm.model.description.DescriptionBase;
50
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
51
import eu.etaxonomy.cdm.model.description.IDescribable;
52
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
53
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;
56
import eu.etaxonomy.taxeditor.editor.EditorUtil;
57
import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor;
58
import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView;
59
import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateViewEditorInput;
60
import eu.etaxonomy.taxeditor.model.AbstractUtility;
61
import eu.etaxonomy.taxeditor.model.FeatureNodeContainer;
62
import eu.etaxonomy.taxeditor.model.FeatureNodeContainerTree;
63
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
64
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
66
import eu.etaxonomy.taxeditor.model.ImageResources;
67
import eu.etaxonomy.taxeditor.model.MessagingUtils;
68
import eu.etaxonomy.taxeditor.view.AbstractCdmEditorViewPart;
69
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
70
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
71

    
72
/**
73
 * <p>DescriptiveViewPart class.</p>
74
 *
75
 * @author n.hoffmann
76
 * @created Jun 9, 2010
77
 * @version 1.0
78
 */
79
public class DescriptiveViewPart extends AbstractCdmEditorViewPart implements IPartContentHasDetails, IPartContentHasSupplementalData {
80

    
81
	/** Constant <code>ID="eu.etaxonomy.taxeditor.editor.view.desc"{trunked}</code> */
82
	public static final String ID = "eu.etaxonomy.taxeditor.editor.view.descriptive";
83

    
84
	protected TreeViewer viewer;
85

    
86
	/**
87
	 * Maps {@link FeatureNodeContainerTree} to their corresponding {@link TaxonDescritpion}.<br>
88
	 * This serves as input for the {@link ITreeContentProvider} of the {@link TreeViewer}
89
	 */
90
	protected Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache = new HashMap<DescriptionBase<?>, FeatureNodeContainerTree>();
91

    
92
	protected ToggleDescriptionAction showAllElementsAction;
93

    
94
	protected ToggleDescriptionAction hideAllElementsAction;
95

    
96
	protected int dndOperations = DND.DROP_COPY | DND.DROP_MOVE;
97

    
98
    private DescriptiveContentProvider provider;
99

    
100
	/** {@inheritDoc} */
101
	@Override
102
	public void createViewer(Composite parent) {
103
		viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL
104
				| SWT.V_SCROLL | SWT.FULL_SELECTION));
105
		provider = new DescriptiveContentProvider(featureNodeContainerCache);
106
        viewer.setContentProvider(provider);
107
		viewer.setLabelProvider(new DescriptiveLabelProvider());
108
		viewer.setSorter(new DescriptiveViewerSorter());
109
		viewer.setAutoExpandLevel(2);
110
		Transfer[] transfers = new Transfer[] { DescriptionElementTransfer.getInstance() };
111
		viewer.addDragSupport(dndOperations, transfers, new DescriptionElementDragListener(
112
				this));
113
		viewer.addDropSupport(dndOperations, transfers,
114
				new DescriptionElementDropAdapter(viewer));
115

    
116
		// Propagate selection from viewer
117
		getSite().setSelectionProvider(viewer);
118

    
119
		showAllElementsAction = new ToggleDescriptionAction(false);
120
		hideAllElementsAction = new ToggleDescriptionAction(true);
121

    
122
		// Add context menu to tree
123
		createMenu();
124

    
125
		createToolbar();
126

    
127
		// set initial input
128
//		if(getEditor() != null){
129
//			viewer.setInput(getEditor().getEditorInput());
130
//		}
131

    
132
		viewer.addDoubleClickListener(new IDoubleClickListener() {
133
            @Override
134
            public void doubleClick(DoubleClickEvent event) {
135
                //Open derivate editor when specimen description element is double clicked
136
                TreeSelection selection = (TreeSelection) viewer.getSelection();
137
                Iterator iterator = selection.iterator();
138
                Set<UUID> specimenUuids = new HashSet<UUID>();
139
                while(iterator.hasNext()){
140
                    Object next = iterator.next();
141
                    if(next instanceof IndividualsAssociation){
142
                        SpecimenOrObservationBase<?> specimen = ((IndividualsAssociation)next).getAssociatedSpecimenOrObservation();
143
                        if(specimen!=null){
144
                            specimenUuids.add(specimen.getUuid());
145
                        }
146
                    }
147
                }
148
                try {
149
                    if(!specimenUuids.isEmpty()){
150
                        EditorUtil.open(new DerivateViewEditorInput(specimenUuids));
151
                    }
152
                } catch (PartInitException e) {
153
                    MessagingUtils.error(DescriptiveViewPart.class, "Could not open Derivative Editor", e);
154
                }
155

    
156

    
157
                    //TODO: extend command to accept parameter to open editor
158
//                    String commandId = "eu.etaxonomy.taxeditor.editor.handler.openDerivateView";
159
//                    IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
160
//                    try {
161
//                        handlerService.executeCommand(commandId, null);
162
//                    } catch (ExecutionException e) {
163
//                        MessagingUtils.error(DerivateSearchCompositeController.class, e);
164
//                    } catch (NotDefinedException e) {
165
//                        MessagingUtils.error(DerivateSearchCompositeController.class, e);
166
//                    } catch (NotEnabledException e) {
167
//                        MessagingUtils.error(DerivateSearchCompositeController.class, e);
168
//                    } catch (NotHandledException e) {
169
//                        MessagingUtils.error(DerivateSearchCompositeController.class, e);
170
//                    }
171

    
172
            }
173
        });
174
	}
175

    
176
	/* (non-Javadoc)
177
	 * @see eu.etaxonomy.taxeditor.model.AbstractCdmViewPart#getInitialSelection()
178
	 */
179
	/** {@inheritDoc} */
180
	@Override
181
	protected ISelection getInitialSelection() {
182
		if(getEditor() != null){
183
			return new StructuredSelection(getEditor().getEditorInput());
184
		}
185

    
186
		return super.getInitialSelection();
187
	}
188

    
189
	protected void createToolbar() {
190
		IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
191
		toolBarManager.add(showAllElementsAction);
192
		toolBarManager.add(hideAllElementsAction);
193
	}
194

    
195
	/*
196
	 * TODO add to the views menu
197
	 */
198
	protected void createMenu(){
199
		MenuManager menuManager = new MenuManager();
200
		menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
201

    
202
		getSite().registerContextMenu(menuManager, viewer);
203

    
204
		// FIXME for some reason this is not working
205
		menuManager.add(showAllElementsAction);
206
		menuManager.add(hideAllElementsAction);
207

    
208
		Control control = viewer.getControl();
209
		Menu menu = menuManager.createContextMenu(control);
210

    
211
		control.setMenu(menu);
212
	}
213

    
214
	/** {@inheritDoc} */
215
	@Override
216
    protected void selectionChanged_internal(IWorkbenchPart part, ISelection selection) {
217
		if(AbstractUtility.getActiveEditor() == null){
218
		    setPartName(createPartTitle(null));
219
			showEmptyPage();
220
			return;
221
		}
222

    
223
		if(part == this){
224
		    return;
225
		}
226
		if(part instanceof DetailsViewPart || part instanceof SupplementalDataViewPart){
227
		    // do not show empty page as these views are also used to edit the description selected in this view
228
		    return;
229
		}
230
		// unpackage TreeNode of DerivateView
231
		else if(part instanceof DerivateView){
232
		    TreeNode treeNodeOfSelection = EditorUtil.getTreeNodeOfSelection(selection);
233
		    if(treeNodeOfSelection!=null){
234
		        selection = new StructuredSelection(treeNodeOfSelection.getValue());
235
		    }
236
		}
237
        else if(part instanceof ChecklistEditor){
238
            if(selection instanceof StructuredSelection  && ((IStructuredSelection) selection).getFirstElement() instanceof Taxon){
239
                Taxon taxon = (Taxon)((IStructuredSelection) selection).getFirstElement();
240
                selection = new StructuredSelection(taxon);
241
            }
242
        }
243
		if(selection instanceof IStructuredSelection
244
		        && ((IStructuredSelection) selection).getFirstElement() instanceof IDescribable<?>
245
		        && part instanceof IPartContentHasFactualData  && !(((IStructuredSelection) selection).getFirstElement() instanceof SpecimenOrObservationBase && part instanceof BulkEditor)){
246
		    featureNodeContainerCache.clear();
247
	        setPartName(createPartTitle(((IStructuredSelection) selection).getFirstElement()));
248
		    showViewer(part, (IStructuredSelection) selection);
249
		    return;
250
		}
251
		else{
252
            setPartName(createPartTitle(null));
253
		    showEmptyPage();
254
		}
255
	}
256

    
257
	protected String getViewName(){
258
	    return "Factual Data";
259
	}
260

    
261
	private String createPartTitle(Object selectedObject){
262
	    if(selectedObject!=null){
263
	        return getViewName()+": "+selectedObject;
264
	    }
265
        return getViewName();
266
	}
267

    
268
	/**
269
	 *
270
	 * @author n.hoffmann
271
	 * @created May 28, 2010
272
	 * @version 1.0
273
	 */
274
	protected class ToggleDescriptionAction extends Action{
275
		private final boolean expanded;
276

    
277
		public ToggleDescriptionAction(boolean expand){
278
			super(null, IAction.AS_PUSH_BUTTON);
279
			expanded = expand;
280
			setImageAndTooltip();
281
		}
282

    
283
		private void setImageAndTooltip(){
284
			setImageDescriptor(new ImageDescriptor() {
285
				@Override
286
				public ImageData getImageData() {
287
					setText(expanded ? "Collapse All" : "Expand All");
288
					String resource = expanded ? ImageResources.COLLAPSE_ALL : ImageResources.EXPAND_ALL;
289
					return ImageResources.getImage(resource).getImageData();
290
				}
291
			});
292

    
293
			String toolTipText = expanded ? "Collapse all" : "Show all factual data";
294
			setToolTipText(toolTipText);
295
		}
296

    
297
		@Override
298
		public void run() {
299
			if(expanded){
300
				viewer.collapseAll();
301
			}else{
302
				viewer.expandAll();
303
			}
304
			setImageAndTooltip();
305
		}
306
	}
307

    
308
	/** {@inheritDoc} */
309
	@Override
310
	public boolean postOperation(CdmBase objectAffectedByOperation) {
311
		return super.postOperation(objectAffectedByOperation);
312
	}
313

    
314
	/** {@inheritDoc} */
315
	@Override
316
	public void changed(Object object) {
317
		for(FeatureNodeContainerTree containerTree : featureNodeContainerCache.values()){
318
			containerTree.buildTree();
319
		}
320
		viewer.expandToLevel(2);
321
		viewer.refresh();
322

    
323
		if(object instanceof DescriptionElementBase){
324
			DescriptionElementBase descriptionElement = (DescriptionElementBase) object;
325
			DescriptionBase description = descriptionElement.getInDescription();
326
			FeatureNodeContainerTree containerTree = featureNodeContainerCache.get(description);
327

    
328
			FeatureNodeContainer featureNodeContainer = containerTree.getFeatureNodeContainerForDescriptionElement(descriptionElement);
329
			viewer.expandToLevel(featureNodeContainer, 1);
330

    
331
		}
332

    
333
		if(object != null){
334
			StructuredSelection selection = new StructuredSelection(object);
335
			viewer.setSelection(selection, true);
336
		}
337
		if(part instanceof BulkEditor && !(object instanceof SpecimenOrObservationBase<?>)){
338
		    ((BulkEditor) part).forceDirty();
339
		}
340

    
341
		super.changed(object);
342
	}
343

    
344
	/** {@inheritDoc} */
345
	@Override
346
	public Viewer getViewer() {
347
		return viewer;
348
	}
349

    
350
	/**
351
	 * <p>onComplete</p>
352
	 *
353
	 * @return a boolean.
354
	 */
355
	@Override
356
    public boolean onComplete() {
357
		return false;
358
	}
359

    
360
	public void toggleShowOnlyIndividualAssociations(){
361
	    provider.toggleShowOnlyIndividualAssociations();
362
	    viewer.refresh();
363
	}
364
}
(6-6/7)