Project

General

Profile

Download (12.8 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.editor.view.media.MediaViewPart;
61
import eu.etaxonomy.taxeditor.model.AbstractUtility;
62
import eu.etaxonomy.taxeditor.model.FeatureNodeContainer;
63
import eu.etaxonomy.taxeditor.model.FeatureNodeContainerTree;
64
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
66
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
67
import eu.etaxonomy.taxeditor.model.ImageResources;
68
import eu.etaxonomy.taxeditor.model.MessagingUtils;
69
import eu.etaxonomy.taxeditor.view.AbstractCdmEditorViewPart;
70
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
71
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
72

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

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

    
85
	protected TreeViewer viewer;
86

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

    
93
	protected ToggleDescriptionAction showAllElementsAction;
94

    
95
	protected ToggleDescriptionAction hideAllElementsAction;
96

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

    
99
    private DescriptiveContentProvider provider;
100

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

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

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

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

    
126
		createToolbar();
127

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

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

    
157

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

    
173
            }
174
        });
175
	}
176

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

    
187
		return super.getInitialSelection();
188
	}
189

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

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

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

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

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

    
212
		control.setMenu(menu);
213
	}
214

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

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

    
260
	protected String getViewName(){
261
	    return "Factual Data";
262
	}
263

    
264
	private String createPartTitle(Object selectedObject){
265
	    if(selectedObject!=null){
266
	        return getViewName()+": "+selectedObject;
267
	    }
268
        return getViewName();
269
	}
270

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

    
280
		public ToggleDescriptionAction(boolean expand){
281
			super(null, IAction.AS_PUSH_BUTTON);
282
			expanded = expand;
283
			setImageAndTooltip();
284
		}
285

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

    
296
			String toolTipText = expanded ? "Collapse all" : "Show all factual data";
297
			setToolTipText(toolTipText);
298
		}
299

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

    
311
	/** {@inheritDoc} */
312
	@Override
313
	public boolean postOperation(CdmBase objectAffectedByOperation) {
314
		return super.postOperation(objectAffectedByOperation);
315
	}
316

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

    
326
		if(object instanceof DescriptionElementBase){
327
			DescriptionElementBase descriptionElement = (DescriptionElementBase) object;
328
			DescriptionBase description = descriptionElement.getInDescription();
329
			FeatureNodeContainerTree containerTree = featureNodeContainerCache.get(description);
330

    
331
			FeatureNodeContainer featureNodeContainer = containerTree.getFeatureNodeContainerForDescriptionElement(descriptionElement);
332
			viewer.expandToLevel(featureNodeContainer, 1);
333

    
334
		}
335

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

    
344
		super.changed(object);
345
	}
346

    
347
	/** {@inheritDoc} */
348
	@Override
349
	public Viewer getViewer() {
350
		return viewer;
351
	}
352

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

    
363
	public void toggleShowOnlyIndividualAssociations(){
364
	    provider.toggleShowOnlyIndividualAssociations();
365
	    viewer.refresh();
366
	}
367
}
(6-6/7)