Project

General

Profile

Download (13.1 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.store.CdmStore;
70
import eu.etaxonomy.taxeditor.view.AbstractCdmEditorViewPart;
71
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
72
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
73

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

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

    
86
	protected TreeViewer viewer;
87

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

    
94
	protected ToggleDescriptionAction showAllElementsAction;
95

    
96
	protected ToggleDescriptionAction hideAllElementsAction;
97

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

    
100
    private DescriptiveContentProvider provider;
101

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

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

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

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

    
127
		createToolbar();
128

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

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

    
158

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

    
174
            }
175
        });
176
	}
177

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

    
188
		return super.getInitialSelection();
189
	}
190

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

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

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

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

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

    
213
		control.setMenu(menu);
214
	}
215

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

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

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

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

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

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

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

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

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

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

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

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

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

    
335
		}
336

    
337
		if(object != null){
338
			StructuredSelection selection = new StructuredSelection(object);
339
			viewer.setSelection(selection, true);
340
		}
341
		if(part instanceof BulkEditor && !(object instanceof SpecimenOrObservationBase<?>)){
342
		    ((BulkEditor) part).forceDirty();
343
		    if(CdmStore.getCurrentSessionManager().isRemoting()) {
344
		        IStructuredSelection selection = (IStructuredSelection) ((BulkEditor) part).getSelectionProvider().getSelection();
345
		        ((BulkEditor) part).changed(selection.getFirstElement());
346
		    }
347
		}
348

    
349

    
350
		super.changed(object);
351
	}
352

    
353
	/** {@inheritDoc} */
354
	@Override
355
	public Viewer getViewer() {
356
		return viewer;
357
	}
358

    
359
	/**
360
	 * <p>onComplete</p>
361
	 *
362
	 * @return a boolean.
363
	 */
364
	@Override
365
    public boolean onComplete() {
366
		return false;
367
	}
368

    
369
	public void toggleShowOnlyIndividualAssociations(){
370
	    provider.toggleShowOnlyIndividualAssociations();
371
	    viewer.refresh();
372
	}
373
}
(6-6/7)