Project

General

Profile

Download (23.2 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.taxeditor.editor.view.derivate;
2

    
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.Collection;
6
import java.util.HashMap;
7
import java.util.HashSet;
8
import java.util.List;
9
import java.util.Map;
10
import java.util.Set;
11
import java.util.UUID;
12

    
13
import org.eclipse.core.runtime.IProgressMonitor;
14
import org.eclipse.jface.action.MenuManager;
15
import org.eclipse.jface.util.LocalSelectionTransfer;
16
import org.eclipse.jface.viewers.AbstractTreeViewer;
17
import org.eclipse.jface.viewers.ISelection;
18
import org.eclipse.jface.viewers.IStructuredSelection;
19
import org.eclipse.jface.viewers.StructuredSelection;
20
import org.eclipse.jface.viewers.TreeNode;
21
import org.eclipse.jface.viewers.TreeSelection;
22
import org.eclipse.jface.viewers.TreeViewer;
23
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.dnd.DND;
25
import org.eclipse.swt.dnd.Transfer;
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.Menu;
32
import org.eclipse.swt.widgets.Tree;
33
import org.eclipse.ui.IEditorInput;
34
import org.eclipse.ui.IEditorPart;
35
import org.eclipse.ui.IEditorSite;
36
import org.eclipse.ui.IMemento;
37
import org.eclipse.ui.ISelectionListener;
38
import org.eclipse.ui.ISelectionService;
39
import org.eclipse.ui.IWorkbenchPart;
40
import org.eclipse.ui.PartInitException;
41
import org.eclipse.ui.part.EditorPart;
42

    
43
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
44
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
45
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
46
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
47
import eu.etaxonomy.cdm.model.common.CdmBase;
48
import eu.etaxonomy.cdm.model.molecular.SingleRead;
49
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
50
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
51
import eu.etaxonomy.cdm.model.taxon.Taxon;
52
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
53
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
54
import eu.etaxonomy.taxeditor.editor.EditorUtil;
55
import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
56
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
57
import eu.etaxonomy.taxeditor.editor.view.derivate.searchFilter.DerivateSearchCompositeController;
58
import eu.etaxonomy.taxeditor.model.IContextListener;
59
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
60
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
61
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
62
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
63
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
64
import eu.etaxonomy.taxeditor.model.MessagingUtils;
65
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
66
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
67
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
68
import eu.etaxonomy.taxeditor.store.CdmStore;
69
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
70
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
71

    
72
/**
73
 * Displays the derivate hierarchy of the specimen specified in the editor input.
74
 *
75
 */
76
public class DerivateView extends EditorPart implements IPartContentHasFactualData, IConversationEnabled,
77
        ICdmEntitySessionEnabled, IDirtyMarkable, IPostOperationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
78
        IContextListener, ISelectionListener {
79
    private static final String SPECIMEN_EDITOR = Messages.DerivateView_SPECIMEN_EDITOR;
80

    
81
    public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
82

    
83
    public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION = Messages.DerivateView_YOU_NEED_TO_SAVE;
84
    public static final String VIEW_HAS_UNSAVED_CHANGES = Messages.DerivateView_UNSAVED_CHANGES;
85

    
86
    private static final List<String> SPECIMEN_INIT_STRATEGY = Arrays.asList(new String[] {
87
            "descriptions", //$NON-NLS-1$
88
            "annotations", //$NON-NLS-1$
89
            "markers", //$NON-NLS-1$
90
            "credits", //$NON-NLS-1$
91
            "extensions", //$NON-NLS-1$
92
            "rights", //$NON-NLS-1$
93
            "sources", //$NON-NLS-1$
94
            "derivationEvents.derivatives.annotations", //$NON-NLS-1$
95
            "derivationEvents.derivatives.markers", //$NON-NLS-1$
96
            "derivationEvents.derivatives.credits", //$NON-NLS-1$
97
            "derivationEvents.derivatives.extensions", //$NON-NLS-1$
98
            "derivationEvents.derivatives.rights", //$NON-NLS-1$
99
            "derivationEvents.derivatives.sources" //$NON-NLS-1$
100
    });
101

    
102
	private static final int WARN_THRESHOLD = 200;
103

    
104
    private DelaySelection delaySelection = null;
105
    /**
106
     * This is the monitor for the DelaySelection runnable.
107
     * If it is <code>true</code> then it is currently delaying a selection.
108
     */
109
    private boolean isInDelay;
110

    
111

    
112
    /**
113
     * This class invokes internal_selectionChanged() in a separate thread.
114
     * This allows an asynchronous and/or delayed handling of selection changes
115
     */
116
    private class DelaySelection implements Runnable{
117
        private IWorkbenchPart part;
118
        private ISelection selection;
119

    
120
        public DelaySelection(IWorkbenchPart part, ISelection selection) {
121
            super();
122
            this.part = part;
123
            this.selection = selection;
124
        }
125

    
126
        @Override
127
        public void run() {
128
            try{
129
                selectionChanged_internal(part, selection);
130
            }
131
            finally{
132
                isInDelay = false;
133
            }
134
        }
135

    
136
        public synchronized void setSelection(ISelection selection) {
137
            this.selection = selection;
138
        }
139

    
140
        public synchronized void setPart(IWorkbenchPart part) {
141
            this.part = part;
142
        }
143

    
144
    }
145

    
146
	private ConversationHolder conversation;
147

    
148
	private TreeViewer viewer;
149

    
150
    private boolean isDirty;
151

    
152
    private final int dndOperations = DND.DROP_MOVE;
153

    
154
    private DerivateLabelProvider labelProvider;
155

    
156
    private DerivateContentProvider contentProvider;
157

    
158
    private DerivateSearchCompositeController derivateSearchCompositeController;
159

    
160
    /**
161
     * A map with keys being the derivative entities belonging to the {@link UUID}s passed to the constructor
162
     * and values being the root elements of the hierarchy (may be the same objects as the derivative entities)
163
     */
164
    private Map<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>> derivateToRootEntityMap;
165

    
166
    /**
167
     * The set of root elements
168
     */
169
    private Set<SpecimenOrObservationBase<?>> rootElements;
170

    
171
    private ICdmEntitySession cdmEntitySession;
172

    
173
    /**
174
     * <code>true</code> if this view is listening to selection  changes
175
     */
176
    private boolean listenToSelectionChange;
177

    
178
    private Taxon selectedTaxon;
179

    
180
    private ISelectionService selectionService;
181

    
182
    /**
183
     * Default constructor
184
     */
185
    public DerivateView() {
186
    }
187

    
188

    
189
    /**
190
     * {@inheritDoc}
191
     */
192
    @Override
193
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
194
        this.setSite(site);
195
        this.setInput(input);
196
        this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
197
        this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
198

    
199
        if (CdmStore.isActive() && conversation == null) {
200
            conversation = CdmStore.createConversation();
201
        }
202
        if (CdmStore.isActive()) {
203
            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
204
        }
205
        //listen to context changes
206
        CdmStore.getContextManager().addContextListener(this);
207
    }
208

    
209
    @Override
210
    public void createPartControl(Composite parent) {
211

    
212
        parent.setLayout(new GridLayout());
213

    
214
        //---search and filter---
215
        derivateSearchCompositeController = new DerivateSearchCompositeController(parent, this);
216
        GridData gridDataSearchBar = new GridData();
217
        gridDataSearchBar.horizontalAlignment = GridData.FILL;
218
        gridDataSearchBar.grabExcessHorizontalSpace = true;
219
        derivateSearchCompositeController.setLayoutData(gridDataSearchBar);
220
        derivateSearchCompositeController.setEnabled(CdmStore.isActive());
221

    
222
        //---tree viewer---
223
        viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
224
        GridData gridDataTree = new GridData();
225
        gridDataTree.horizontalAlignment = GridData.FILL;
226
        gridDataTree.verticalAlignment = GridData.FILL;
227
        gridDataTree.grabExcessVerticalSpace = true;
228
        gridDataTree.grabExcessHorizontalSpace = true;
229
        viewer.getTree().setLayoutData(gridDataTree);
230
        contentProvider = new DerivateContentProvider();
231
        viewer.setContentProvider(contentProvider);
232
        labelProvider = new DerivateLabelProvider();
233
        labelProvider.setConversation(conversation);
234
        viewer.setLabelProvider(labelProvider);
235
        viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
236
        viewer.getTree().setEnabled(CdmStore.isActive());
237
        // Propagate selection from viewer
238
        getSite().setSelectionProvider(viewer);
239

    
240
        //listen to selection changes
241
        selectionService = getSite().getWorkbenchWindow().getSelectionService();
242
        selectionService.addSelectionListener(this);
243

    
244
        //create context menu
245
        MenuManager menuManager = new MenuManager();
246
        menuManager.setRemoveAllWhenShown(true);
247
        getSite().registerContextMenu(menuManager, viewer);
248
        Control control = viewer.getControl();
249
        Menu menu = menuManager.createContextMenu(control);
250
        control.setMenu(menu);
251

    
252
        //init tree
253
        Collection<UUID> derivativeUuids = ((DerivateViewEditorInput)getEditorInput()).getDerivativeUuids();
254
        checkWarnThreshold(derivativeUuids);
255
		updateRootEntities(derivativeUuids);
256
        //set taxon filter
257
        derivateSearchCompositeController.setTaxonFilter(((DerivateViewEditorInput) getEditorInput()).getTaxonUuid());
258
        //reset status bar
259
        getEditorSite().getActionBars().getStatusLineManager().setMessage(""); //$NON-NLS-1$
260

    
261
        //add drag'n'drop support
262
        Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
263
        viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
264
        viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
265
    }
266

    
267
    public void updateRootEntities() {
268
        updateRootEntities((Collection)null);
269
    }
270

    
271
    public void updateRootEntities(Collection<UUID> derivativeUuids) {
272
        if(conversation!=null){
273
            if (!conversation.isBound()) {
274
                conversation.bind();
275
            }
276
            /*
277
             * If the active session is not the session of the Derivative Editor
278
             * then we will save the active session for later, bind temporarily
279
             * to our session and rebind to the original session when we are
280
             * done. This happens e.g. if a selection change happens in the
281
             * taxon editor and "Link with editor" is enabled. The selection
282
             * change event and thus the loading in updateRootEntities() happens
283
             * in the session of the taxon editor.
284
             */
285
            ICdmEntitySession previousCdmEntitySession = CdmStore.getCurrentSessionManager().getActiveSession();
286
            if(cdmEntitySession != null) {
287
                cdmEntitySession.bind();
288
            }
289

    
290
            List<SpecimenOrObservationBase> derivates = null;
291
            if(derivativeUuids!=null){
292
                this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
293
                this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
294
                derivates = CdmStore.getService(IOccurrenceService.class).load(new ArrayList(derivativeUuids), SPECIMEN_INIT_STRATEGY);
295
            }
296
            updateRootEntities(derivates);
297
            previousCdmEntitySession.bind();
298
        }
299
    }
300

    
301

    
302
    public void updateRootEntities(List<SpecimenOrObservationBase> derivates) {
303
            if(derivates!=null){
304
                this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
305
                this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
306
                for (SpecimenOrObservationBase derivate : derivates) {
307

    
308
                    if(derivate instanceof FieldUnit){
309
                        derivateToRootEntityMap.put(derivate, derivate);
310
                    }
311
                    else {
312
                        SpecimenOrObservationBase<?> topMostDerivate = EditorUtil.getTopMostDerivate(derivate);
313
                        if(topMostDerivate!=null){
314
                            derivateToRootEntityMap.put(derivate, topMostDerivate);
315
                        }
316
                        else{
317
                            derivateToRootEntityMap.put(derivate, derivate);
318
                        }
319
                    }
320
                }
321
                for (SpecimenOrObservationBase<?> specimen : derivateToRootEntityMap.values()) {
322
                    rootElements.add(specimen);
323
                }
324
            }
325
            labelProvider.updateLabelCache(rootElements);
326
            viewer.setInput(rootElements);
327

    
328
            getEditorSite().getActionBars().getStatusLineManager().setMessage(String.format(Messages.DerivateView_CNT_DERIVATIVES_FOUND, rootElements.size()));
329

    
330
            //set selection to derivatives if the filter criteria
331
            //taxon assignment or derivative type are set
332
            if(derivates!=null && !derivateSearchCompositeController.isDefaultSearch()){
333
                List<TreeNode> nodesToSelect = new ArrayList<TreeNode>();
334
                for (SpecimenOrObservationBase specimenOrObservationBase : derivates) {
335
                    nodesToSelect.add(new TreeNode(specimenOrObservationBase));
336
                }
337
                viewer.setSelection(new StructuredSelection(nodesToSelect));
338
            }
339
            else{
340
                viewer.setSelection(null);
341
            }
342

    
343
    }
344

    
345
    public void updateLabelCache(){
346
        labelProvider.updateLabelCache(rootElements);
347
    }
348

    
349
    @Override
350
    public void doSave(IProgressMonitor monitor) {
351
        String taskName = Messages.DerivateView_SAVING_HIERARCHY;
352
        monitor.beginTask(taskName, 3);
353
        if (!conversation.isBound()) {
354
            conversation.bind();
355
        }
356
        monitor.worked(1);
357

    
358
        // commit the conversation and start a new transaction immediately
359
        conversation.commit(true);
360

    
361
        CdmStore.getService(IOccurrenceService.class).merge(new ArrayList<SpecimenOrObservationBase>(rootElements), true);
362

    
363
        monitor.worked(1);
364

    
365
        this.setDirty(false);
366
        monitor.worked(1);
367
        monitor.done();
368
        firePropertyChange(PROP_DIRTY);
369
        refreshTree();
370
    }
371

    
372
    @Override
373
    public void doSaveAs() {
374
    }
375

    
376
    @Override
377
    public String getTitleToolTip() {
378
        return Messages.DerivateView_DERIVATIVE_EDITOR;
379
    }
380

    
381
    @Override
382
    public boolean isDirty() {
383
        return isDirty;
384
    }
385

    
386
    /**
387
     * @param isDirty the isDirty to set
388
     */
389
    public void setDirty(boolean isDirty) {
390
        this.isDirty = isDirty;
391
    }
392

    
393
    @Override
394
    public boolean isSaveAsAllowed() {
395
        return false;
396
    }
397

    
398
    @Override
399
    public void setFocus() {
400
        //make sure to bind again if maybe in another view the conversation was unbound
401
        if(conversation!=null && !conversation.isBound()){
402
            conversation.bind();
403
        }
404
        if(cdmEntitySession != null) {
405
            cdmEntitySession.bind();
406
        }
407
        derivateSearchCompositeController.setFocusOnSearchField();
408
    }
409

    
410
    @Override
411
    public void update(CdmDataChangeMap changeEvents) {
412
    }
413

    
414
    @Override
415
    public ConversationHolder getConversationHolder() {
416
        return conversation;
417
    }
418

    
419
    @Override
420
    public void changed(Object element) {
421
        setDirty(true);
422
        firePropertyChange(IEditorPart.PROP_DIRTY);
423
        viewer.update(new TreeNode(element), null);
424
    }
425

    
426
    @Override
427
    public void forceDirty() {
428
        changed(null);
429
    }
430

    
431
    @Override
432
    public Map<Object, List<String>> getPropertyPathsMap() {
433
        List<String> specimenPropertyPaths = Arrays.asList(new String[] {
434
                "descriptions", //$NON-NLS-1$
435
                "derivationEvents.derivates", //$NON-NLS-1$
436
                "annotations", //$NON-NLS-1$
437
                "markers", //$NON-NLS-1$
438
                "credits", //$NON-NLS-1$
439
                "extensions", //$NON-NLS-1$
440
                "rights", //$NON-NLS-1$
441
                "sources" //$NON-NLS-1$
442
        });
443
        Map<Object, List<String>> specimenPropertyPathMap =
444
                new HashMap<Object, List<String>>();
445
        specimenPropertyPathMap.put(SpecimenOrObservationBase.class,specimenPropertyPaths);
446
        return specimenPropertyPathMap;
447
    }
448

    
449
    /**
450
     * Refreshes the derivate hierarchy tree and expands the tree
451
     * to show and select the given object.
452
     *
453
     * @param expandTo the object to which the tree should be expanded
454
     */
455
    public void refreshTree(Object expandTo){
456
        refreshTree();
457
        TreeSelection selection = (TreeSelection) viewer.getSelection();
458
        viewer.expandToLevel(selection.getFirstElement(), 1);
459
        viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
460
    }
461

    
462
    /**
463
     * Refreshes the derivate hierarchy tree
464
     */
465
    public void refreshTree(){
466
    	if(!viewer.getTree().isDisposed()){
467
    		viewer.refresh();
468
    	}
469
    }
470

    
471
    //FIXME:Remoting hack to make this work for remoting
472
    //This should actually be resolved using remoting post operations
473
    public void remove(Object obj) {
474
        rootElements.remove(obj);
475
        viewer.setInput(rootElements);
476
    }
477

    
478
    /**
479
     * @return a set of {@link SingleRead}s that have multiple parents
480
     */
481
    public Set<SingleRead> getMultiLinkSingleReads() {
482
        return DerivateLabelProvider.getMultiLinkSingleReads();
483
    }
484

    
485
    public Object getSelectionInput() {
486
        return selectedTaxon;
487
    }
488

    
489
    public DerivateLabelProvider getLabelProvider() {
490
        return labelProvider;
491
    }
492

    
493
    @Override
494
    public boolean postOperation(CdmBase objectAffectedByOperation) {
495
        refreshTree();
496
        if(objectAffectedByOperation!=null){
497
            changed(objectAffectedByOperation);
498
        }
499
        return true;
500
    }
501

    
502
    @Override
503
    public boolean onComplete() {
504
        return true;
505
    }
506

    
507

    
508
    @Override
509
    public boolean canAttachMedia() {
510
        return true;
511
    }
512

    
513
    public void addFieldUnit(FieldUnit fieldUnit) {
514
        rootElements.add(fieldUnit);
515
        derivateToRootEntityMap.put(fieldUnit, fieldUnit);
516
    }
517

    
518
    @Override
519
    public ICdmEntitySession getCdmEntitySession() {
520
        return cdmEntitySession;
521
    }
522

    
523
    @Override
524
    public void dispose() {
525
        super.dispose();
526
        if(conversation!=null){
527
            conversation.close();
528
        }
529
        if(cdmEntitySession != null) {
530
            cdmEntitySession.dispose();
531
        }
532
    }
533
    public void selectionChanged_internal(IWorkbenchPart part, ISelection selection) {
534
    	if(part == this){
535
            return;
536
        }
537
        if(viewer.getTree().isDisposed()){
538
            return;
539
        }
540
        if(listenToSelectionChange){
541
            if(part instanceof MultiPageTaxonEditor){
542
                selectedTaxon = ((MultiPageTaxonEditor) part).getTaxon();
543
            }
544
            else if(selection instanceof IStructuredSelection){
545
                Object selectedElement = ((IStructuredSelection) selection).getFirstElement();
546
                if(selectedElement instanceof CdmBase){
547
                    if(((CdmBase) selectedElement).isInstanceOf(TaxonNode.class)){
548
                        selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, TaxonNode.class).getTaxon();
549
                    }
550
                    else if(((CdmBase) selectedElement).isInstanceOf(Taxon.class)){
551
                        selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, Taxon.class);
552
                    }
553
                }
554
            }
555
            if(selectedTaxon!=null){
556
                Collection<SpecimenOrObservationBase> fieldUnits = CdmStore.getService(IOccurrenceService.class).listFieldUnitsByAssociatedTaxon(selectedTaxon, null, null);
557
                Collection<UUID> uuids = new HashSet<UUID>();
558
                for (SpecimenOrObservationBase specimenOrObservationBase : fieldUnits) {
559
                    uuids.add(specimenOrObservationBase.getUuid());
560
                }
561
                checkWarnThreshold(uuids);
562
                updateRootEntities(uuids);
563
                setPartName(SPECIMEN_EDITOR+": " + selectedTaxon.getName()); //$NON-NLS-1$
564
            }
565
        }
566
    }
567

    
568
    @Override
569
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
570
    	if(delaySelection==null){
571
            delaySelection = new DelaySelection(part, selection);
572
        }
573
        delaySelection.setPart(part);
574
        delaySelection.setSelection(selection);
575
        if(!isInDelay){
576
            isInDelay = true;
577
            Display.getCurrent().asyncExec(delaySelection);
578
        }
579
    }
580

    
581

    
582
	private void checkWarnThreshold(Collection<UUID> uuids) {
583
		if(uuids!=null && uuids.size()>WARN_THRESHOLD){
584
			MessagingUtils.warningDialog(Messages.DerivateView_PERF_WARNING, this.getClass(), String.format(Messages.DerivateView_PERF_WARNING_MESSAGE, uuids.size()));
585
			uuids.clear();
586
		}
587
	}
588

    
589
    public TreeViewer getViewer() {
590
        return viewer;
591
    }
592

    
593
    /**
594
     * {@inheritDoc}
595
     */
596
    @Override
597
    public List<SpecimenOrObservationBase<?>> getRootEntities() {
598
        return new ArrayList<SpecimenOrObservationBase<?>>(rootElements);
599
    }
600

    
601
    public void toggleListenToSelectionChange() {
602
        listenToSelectionChange = !listenToSelectionChange;
603
        derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
604
        if(!listenToSelectionChange){
605
            selectedTaxon = null;
606
            setPartName(SPECIMEN_EDITOR);
607
        }
608
        else if(selectedTaxon==null){
609
            setPartName(SPECIMEN_EDITOR+Messages.DerivateView_NO_TAXON_SELECTED);
610
        }
611
    }
612

    
613
    public boolean isListenToSelectionChange(){
614
        return listenToSelectionChange;
615
    }
616

    
617
    /**
618
     * {@inheritDoc}
619
     */
620
    @Override
621
    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
622
    }
623

    
624
    /**
625
     * {@inheritDoc}
626
     */
627
    @Override
628
    public void contextStop(IMemento memento, IProgressMonitor monitor) {
629
        derivateSearchCompositeController.setEnabled(false);
630
        if(!viewer.getTree().isDisposed()) {
631
            viewer.getTree().setEnabled(false);
632
            viewer.setInput(null);
633
        }
634
    }
635

    
636
    /**
637
     * {@inheritDoc}
638
     */
639
    @Override
640
    public void contextStart(IMemento memento, IProgressMonitor monitor) {
641
        derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
642
        if(!viewer.getTree().isDisposed()){
643
            viewer.getTree().setEnabled(true);
644
        }
645
        refreshTree();
646
    }
647

    
648
    /**
649
     * {@inheritDoc}
650
     */
651
    @Override
652
    public void contextRefresh(IProgressMonitor monitor) {
653
    }
654

    
655
    /**
656
     * {@inheritDoc}
657
     */
658
    @Override
659
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
660
    }
661

    
662
}
(3-3/6)