2e086fa0d11bc89e65f5a2fd670f16847b318806
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / derivate / DerivateView.java
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.Collections;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.UUID;
13
14 import javax.annotation.PostConstruct;
15 import javax.annotation.PreDestroy;
16 import javax.inject.Inject;
17 import javax.inject.Named;
18
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.e4.core.contexts.ContextInjectionFactory;
21 import org.eclipse.e4.core.contexts.IEclipseContext;
22 import org.eclipse.e4.core.di.annotations.Optional;
23 import org.eclipse.e4.ui.di.Focus;
24 import org.eclipse.e4.ui.di.Persist;
25 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
26 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
27 import org.eclipse.e4.ui.services.EMenuService;
28 import org.eclipse.e4.ui.services.IServiceConstants;
29 import org.eclipse.e4.ui.workbench.modeling.EPartService;
30 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
31 import org.eclipse.jface.util.LocalSelectionTransfer;
32 import org.eclipse.jface.viewers.ISelectionChangedListener;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.StructuredSelection;
35 import org.eclipse.jface.viewers.TreeNode;
36 import org.eclipse.jface.viewers.TreeSelection;
37 import org.eclipse.jface.viewers.TreeViewer;
38 import org.eclipse.jface.viewers.Viewer;
39 import org.eclipse.jface.viewers.ViewerComparator;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.dnd.DND;
42 import org.eclipse.swt.dnd.Transfer;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Tree;
47 import org.eclipse.ui.IMemento;
48
49 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
51 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
52 import eu.etaxonomy.cdm.api.service.ITaxonService;
53 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
54 import eu.etaxonomy.cdm.model.molecular.Sequence;
55 import eu.etaxonomy.cdm.model.molecular.SingleRead;
56 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
57 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
58 import eu.etaxonomy.cdm.model.taxon.Taxon;
59 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
62 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
63 import eu.etaxonomy.taxeditor.editor.EditorUtil;
64 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
65 import eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4;
66 import eu.etaxonomy.taxeditor.editor.view.derivate.searchFilter.DerivateSearchCompositeController;
67 import eu.etaxonomy.taxeditor.model.IContextListener;
68 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
69 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
70 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
71 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
72 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
73 import eu.etaxonomy.taxeditor.model.MessagingUtils;
74 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
75 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
76 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
77 import eu.etaxonomy.taxeditor.store.CdmStore;
78 import eu.etaxonomy.taxeditor.view.search.derivative.DerivateContentProvider;
79 import eu.etaxonomy.taxeditor.view.search.derivative.DerivateLabelProvider;
80 import eu.etaxonomy.taxeditor.workbench.part.ICollapsableExpandable;
81 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
82
83 /**
84 * Displays the derivate hierarchy of the specimen specified in the editor input.
85 *
86 */
87 public class DerivateView implements IPartContentHasFactualData, IConversationEnabled,
88 ICdmEntitySessionEnabled, IDirtyMarkable, IPostOperationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
89 IContextListener, IE4SavablePart, ICollapsableExpandable {
90
91 private static final String SPECIMEN_EDITOR = Messages.DerivateView_SPECIMEN_EDITOR;
92
93 public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
94 public static final String INPUT_ID = ID+".editorInput"; //$NON-NLS-1$
95
96 public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION = Messages.DerivateView_YOU_NEED_TO_SAVE;
97 public static final String VIEW_HAS_UNSAVED_CHANGES = Messages.DerivateView_UNSAVED_CHANGES;
98
99 private static final List<String> SPECIMEN_INIT_STRATEGY = Arrays.asList(new String[] {
100 "descriptions", //$NON-NLS-1$
101 "annotations", //$NON-NLS-1$
102 "markers", //$NON-NLS-1$
103 "credits", //$NON-NLS-1$
104 "extensions", //$NON-NLS-1$
105 "rights", //$NON-NLS-1$
106 "sources", //$NON-NLS-1$
107 "derivationEvents.derivatives.annotations", //$NON-NLS-1$
108 "derivationEvents.derivatives.markers", //$NON-NLS-1$
109 "derivationEvents.derivatives.credits", //$NON-NLS-1$
110 "derivationEvents.derivatives.extensions", //$NON-NLS-1$
111 "derivationEvents.derivatives.rights", //$NON-NLS-1$
112 "derivationEvents.derivatives.sources" //$NON-NLS-1$
113 });
114
115 private static final int WARN_THRESHOLD = 200;
116
117
118 private ConversationHolder conversation;
119
120 private TreeViewer viewer;
121
122 private final int dndOperations = DND.DROP_MOVE;
123
124 private DerivateLabelProvider labelProvider;
125
126 private DerivateContentProvider contentProvider;
127
128 private DerivateSearchCompositeController derivateSearchCompositeController;
129
130 /**
131 * A map with keys being the derivative entities belonging to the {@link UUID}s passed to the constructor
132 * and values being the root elements of the hierarchy (may be the same objects as the derivative entities)
133 */
134 private Map<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>> derivateToRootEntityMap;
135
136 /**
137 * The set of root elements
138 */
139 private Set<SpecimenOrObservationBase<?>> rootElements;
140
141 private ICdmEntitySession cdmEntitySession;
142
143 /**
144 * <code>true</code> if this view is listening to selection changes
145 */
146 private boolean listenToSelectionChange;
147
148 private Taxon selectedTaxon;
149
150 @Inject
151 private ESelectionService selService;
152
153 @Inject
154 private MDirtyable dirty;
155
156 private ISelectionChangedListener selectionChangedListener;
157
158 @Inject
159 private MPart thisPart;
160
161 /**
162 * Default constructor
163 */
164 @Inject
165 public DerivateView() {
166 }
167
168 /**
169 * {@inheritDoc}
170 */
171 public void init(DerivateViewEditorInput editorInput){
172 this.derivateToRootEntityMap = new HashMap<>();
173 this.rootElements = new HashSet<>();
174
175 //init tree
176 Collection<UUID> derivativeUuids = editorInput.getDerivativeUuids();
177 checkWarnThreshold(derivativeUuids);
178 updateRootEntities(derivativeUuids);
179 //set taxon filter
180 derivateSearchCompositeController.setTaxonFilter(editorInput.getTaxonUuid());
181 //reset status bar
182 //TODO e4
183 // getEditorSite().getActionBars().getStatusLineManager().setMessage(""); //$NON-NLS-1$
184 }
185
186 @PostConstruct
187 public void createPartControl(Composite parent, EMenuService menuService,
188 IEclipseContext context) {
189 if (CdmStore.isActive()){
190 if(conversation == null){
191 conversation = CdmStore.createConversation();
192 }
193 if(cdmEntitySession == null){
194 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
195 }
196 }
197 else{
198 return;
199 }
200 //listen to context changes
201 CdmStore.getContextManager().addContextListener(this);
202
203 parent.setLayout(new GridLayout());
204
205 //---search and filter---
206 derivateSearchCompositeController = new DerivateSearchCompositeController(parent, this);
207 GridData gridDataSearchBar = new GridData();
208 gridDataSearchBar.horizontalAlignment = GridData.FILL;
209 gridDataSearchBar.grabExcessHorizontalSpace = true;
210 derivateSearchCompositeController.setLayoutData(gridDataSearchBar);
211 derivateSearchCompositeController.setEnabled(CdmStore.isActive());
212
213 //---tree viewer---
214 viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
215 GridData gridDataTree = new GridData();
216 gridDataTree.horizontalAlignment = GridData.FILL;
217 gridDataTree.verticalAlignment = GridData.FILL;
218 gridDataTree.grabExcessVerticalSpace = true;
219 gridDataTree.grabExcessHorizontalSpace = true;
220 viewer.getTree().setLayoutData(gridDataTree);
221 contentProvider = new DerivateContentProvider();
222 viewer.setContentProvider(contentProvider);
223 labelProvider = new DerivateLabelProvider();
224 labelProvider.setConversation(conversation);
225 viewer.setLabelProvider(labelProvider);
226 viewer.getTree().setEnabled(CdmStore.isActive());
227
228 //propagate selection
229 selectionChangedListener = (event -> selService.setSelection(event.getSelection()));
230 viewer.addSelectionChangedListener(selectionChangedListener);
231
232 //create context menu
233 menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.editor.popupmenu.specimeneditor");
234
235 //add drag'n'drop support
236 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
237 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
238 DerivateDropListener dropListener = new DerivateDropListener(this);
239 ContextInjectionFactory.inject(dropListener, context);
240 viewer.addDropSupport(dndOperations, transfers, dropListener);
241 }
242
243 public void updateRootEntities() {
244 updateRootEntities((Collection)null);
245 }
246
247 public void updateRootEntities(Collection<UUID> derivativeUuids) {
248 if(conversation!=null){
249 if (!conversation.isBound()) {
250 conversation.bind();
251 }
252 /*
253 * If the active session is not the session of the Derivative Editor
254 * then we will save the active session for later, bind temporarily
255 * to our session and rebind to the original session when we are
256 * done. This happens e.g. if a selection change happens in the
257 * taxon editor and "Link with editor" is enabled. The selection
258 * change event and thus the loading in updateRootEntities() happens
259 * in the session of the taxon editor.
260 */
261 ICdmEntitySession previousCdmEntitySession = CdmStore.getCurrentSessionManager().getActiveSession();
262 if(cdmEntitySession != null) {
263 cdmEntitySession.bind();
264 }
265
266 List<SpecimenOrObservationBase> derivates = null;
267 if(derivativeUuids!=null){
268 this.derivateToRootEntityMap = new HashMap<>();
269 this.rootElements = new HashSet<>();
270 derivates = CdmStore.getService(IOccurrenceService.class).load(new ArrayList(derivativeUuids), SPECIMEN_INIT_STRATEGY);
271 }
272 updateRootEntities(derivates);
273 if(previousCdmEntitySession!=null){
274 previousCdmEntitySession.bind();
275 }
276 }
277 }
278
279
280 public void updateRootEntities(List<SpecimenOrObservationBase> derivates) {
281 if(derivates!=null){
282 this.derivateToRootEntityMap = new HashMap<>();
283 this.rootElements = new HashSet<>();
284 for (SpecimenOrObservationBase derivate : derivates) {
285
286 if(derivate instanceof FieldUnit){
287 derivateToRootEntityMap.put(derivate, derivate);
288 }
289 else {
290 SpecimenOrObservationBase<?> topMostDerivate = EditorUtil.getTopMostDerivate(derivate);
291 if(topMostDerivate!=null){
292 derivateToRootEntityMap.put(derivate, topMostDerivate);
293 }
294 else{
295 derivateToRootEntityMap.put(derivate, derivate);
296 }
297 }
298 }
299 for (SpecimenOrObservationBase<?> specimen : derivateToRootEntityMap.values()) {
300 rootElements.add(specimen);
301 }
302 }
303 labelProvider.updateLabelCache(rootElements);
304 viewer.setInput(rootElements);
305 viewer.setComparator(new ViewerComparator() {
306 @Override
307 @SuppressWarnings("unchecked")
308 public int compare(Viewer testViewer, Object e1, Object e2) {
309 if (((TreeNode)e1).getValue() instanceof SpecimenOrObservationBase){
310 return ((SpecimenOrObservationBase)((TreeNode)e1).getValue()).getTitleCache().compareTo(((SpecimenOrObservationBase)((TreeNode)e2).getValue()).getTitleCache());
311 }else{
312 return e1.toString().compareTo(e2.toString());
313 }
314 //return (((SpecimenOrObservationBase) e1).getTitleCache()).compareTo(((SpecimenOrObservationBase) e2).getTitleCache());
315 }
316 });
317
318 //TODO e4
319 // getEditorSite().getActionBars().getStatusLineManager().setMessage(String.format(Messages.DerivateView_CNT_DERIVATIVES_FOUND, rootElements.size()));
320
321 //set selection to derivatives if the filter criteria
322 //taxon assignment or derivative type are set
323 if(derivates!=null && !derivateSearchCompositeController.isDefaultSearch()){
324 List<TreeNode> nodesToSelect = new ArrayList<>();
325 for (SpecimenOrObservationBase specimenOrObservationBase : derivates) {
326 nodesToSelect.add(new TreeNode(specimenOrObservationBase));
327 }
328 setSelection(new StructuredSelection(nodesToSelect));
329 }
330 else{
331 setSelection(null);
332 }
333 }
334
335 private void setSelection(StructuredSelection selection){
336 viewer.removeSelectionChangedListener(selectionChangedListener);
337 viewer.setSelection(selection);
338 viewer.addSelectionChangedListener(selectionChangedListener);
339 }
340
341 public void updateLabelCache(){
342 labelProvider.updateLabelCache(rootElements);
343 }
344
345 @Persist
346 @Override
347 public void save(IProgressMonitor monitor) {
348 String taskName = Messages.DerivateView_SAVING_HIERARCHY;
349 monitor.beginTask(taskName, 3);
350 if (!conversation.isBound()) {
351 conversation.bind();
352 if (!cdmEntitySession.isActive()){
353 cdmEntitySession.bind();
354 }
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<>(rootElements), true);
362
363 monitor.worked(1);
364
365 this.setDirty(false);
366 monitor.worked(1);
367 monitor.done();
368 dirty.setDirty(false);
369 refreshTree();
370 }
371
372 /**
373 * @param isDirty the isDirty to set
374 */
375 public void setDirty(boolean isDirty) {
376 dirty.setDirty(isDirty);
377 }
378
379 @Focus
380 public void setFocus() {
381 //make sure to bind again if maybe in another view the conversation was unbound
382 if(conversation!=null && !conversation.isBound()){
383 conversation.bind();
384 }
385 if(cdmEntitySession != null) {
386 cdmEntitySession.bind();
387 }
388 if(viewer!=null && !viewer.getControl().isDisposed()) {
389 viewer.getControl().setFocus();
390 selService.setSelection(viewer.getSelection());
391 }
392 }
393
394 @Override
395 public void update(CdmDataChangeMap changeEvents) {
396 }
397
398 @Override
399 public ConversationHolder getConversationHolder() {
400 return conversation;
401 }
402
403 @Override
404 public void changed(Object element) {
405 setDirty(true);
406 //firePropertyChange(IEditorPart.PROP_DIRTY);
407 viewer.update(new TreeNode(element), null);
408 viewer.refresh();
409 }
410
411 @Override
412 public void forceDirty() {
413 changed(null);
414 }
415
416 @Override
417 public Map<Object, List<String>> getPropertyPathsMap() {
418 List<String> specimenPropertyPaths = Arrays.asList(new String[] {
419 "descriptions", //$NON-NLS-1$
420 "derivationEvents.derivates", //$NON-NLS-1$
421 "annotations", //$NON-NLS-1$
422 "markers", //$NON-NLS-1$
423 "credits", //$NON-NLS-1$
424 "extensions", //$NON-NLS-1$
425 "rights", //$NON-NLS-1$
426 "sources" //$NON-NLS-1$
427 });
428 Map<Object, List<String>> specimenPropertyPathMap =
429 new HashMap<>();
430 specimenPropertyPathMap.put(SpecimenOrObservationBase.class,specimenPropertyPaths);
431 return specimenPropertyPathMap;
432 }
433
434 /**
435 * Refreshes the derivate hierarchy tree and expands the tree
436 * to show and select the given object.
437 *
438 * @param expandTo the object to which the tree should be expanded
439 */
440 public void refreshTree(Object expandTo){
441 refreshTree();
442 TreeSelection selection = (TreeSelection) viewer.getSelection();
443 viewer.expandToLevel(selection.getFirstElement(), 1);
444 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
445 }
446
447 /**
448 * Refreshes the derivate hierarchy tree
449 */
450 public void refreshTree(){
451 if(!viewer.getTree().isDisposed()){
452 viewer.refresh();
453 }
454 }
455
456 //FIXME:Remoting hack to make this work for remoting
457 //This should actually be resolved using remoting post operations
458 public void remove(Object obj) {
459 if (obj instanceof TreeNode){
460 obj = ((TreeNode)obj).getValue();
461 }
462 rootElements.remove(obj);
463 Object o = this.derivateToRootEntityMap.remove(obj);
464 viewer.setInput(rootElements);
465 }
466
467 /**
468 * @return a set of {@link SingleRead}s that have multiple parents
469 */
470 public Set<SingleRead> getMultiLinkSingleReads() {
471 return DerivateLabelProvider.getMultiLinkSingleReads();
472 }
473
474 public Object getSelectionInput() {
475 return selectedTaxon;
476 }
477
478 public DerivateLabelProvider getLabelProvider() {
479 return labelProvider;
480 }
481
482 @Override
483 public boolean postOperation(Object objectAffectedByOperation) {
484 refreshTree();
485 if(objectAffectedByOperation!=null){
486 changed(objectAffectedByOperation);
487 }
488 return true;
489 }
490
491 @Override
492 public boolean onComplete() {
493 return true;
494 }
495
496
497 @Override
498 public boolean canAttachMedia() {
499 return true;
500 }
501
502 public void addFieldUnit(FieldUnit fieldUnit) {
503 rootElements.add(fieldUnit);
504 derivateToRootEntityMap.put(fieldUnit, fieldUnit);
505 }
506
507 @Override
508 public ICdmEntitySession getCdmEntitySession() {
509 return cdmEntitySession;
510 }
511
512 @PreDestroy
513 public void dispose() {
514 if(conversation!=null){
515 conversation.close();
516 conversation = null;
517 }
518 if(cdmEntitySession != null) {
519 cdmEntitySession.dispose();
520 cdmEntitySession = null;
521 }
522 dirty.setDirty(false);
523 }
524
525
526 @Inject
527 @Optional
528 public void selectionChanged(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection,
529 @Named(IServiceConstants.ACTIVE_PART) MPart activePart, MPart thisPart){
530 if(activePart == thisPart || viewer==null){
531 return;
532 }
533 if(viewer.getTree().isDisposed()){
534 return;
535 }
536 if(listenToSelectionChange){
537 selectedTaxon = null;
538 if(activePart.getObject() instanceof TaxonNameEditorE4){
539 selectedTaxon = ((TaxonNameEditorE4) activePart.getObject()).getTaxon();
540 }
541 else if(selection != null){
542 Object selectedElement = selection.getFirstElement();
543 if(selectedElement instanceof TaxonNodeDto){
544 TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).load(((TaxonNodeDto)selectedElement).getTaxonUuid());
545 if(HibernateProxyHelper.isInstanceOf(taxonBase, Taxon.class)){
546 selectedTaxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
547 }
548 else if(selectedElement instanceof TaxonNode){
549 selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, TaxonNode.class).getTaxon();
550 }
551 else if(selectedElement instanceof Taxon){
552 selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, Taxon.class);
553 }
554 }
555 }
556 if(selectedTaxon!=null){
557 Collection<SpecimenOrObservationBase> fieldUnits = CdmStore.getService(IOccurrenceService.class).listFieldUnitsByAssociatedTaxon(selectedTaxon, null, null);
558 Collection<UUID> uuids = new HashSet<>();
559 for (SpecimenOrObservationBase specimenOrObservationBase : fieldUnits) {
560 uuids.add(specimenOrObservationBase.getUuid());
561 }
562 checkWarnThreshold(uuids);
563 updateRootEntities(uuids);
564
565 thisPart.setLabel(SPECIMEN_EDITOR+": " + selectedTaxon.getName()); //$NON-NLS-1$
566 }
567 else{
568 updateRootEntities((Collection<UUID>)Collections.EMPTY_LIST);
569 }
570 }
571 }
572
573 private void checkWarnThreshold(Collection<UUID> uuids) {
574 if(uuids!=null && uuids.size()>WARN_THRESHOLD){
575 MessagingUtils.warningDialog(Messages.DerivateView_PERF_WARNING, this.getClass(), String.format(Messages.DerivateView_PERF_WARNING_MESSAGE, uuids.size()));
576 uuids.clear();
577 }
578 }
579
580 public TreeViewer getViewer() {
581 return viewer;
582 }
583
584 /**
585 * {@inheritDoc}
586 */
587 @Override
588 public List<SpecimenOrObservationBase<?>> getRootEntities() {
589 return new ArrayList<>(rootElements);
590 }
591
592 public void toggleListenToSelectionChange(MPart part) {
593 listenToSelectionChange = !listenToSelectionChange;
594 derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
595 if(!listenToSelectionChange){
596 selectedTaxon = null;
597 part.setLabel(SPECIMEN_EDITOR);
598 }
599 else if(selectedTaxon==null){
600 part.setLabel(SPECIMEN_EDITOR+Messages.DerivateView_NO_TAXON_SELECTED);
601 }
602 }
603
604 public boolean isListenToSelectionChange(){
605 return listenToSelectionChange;
606 }
607
608 /**
609 * {@inheritDoc}
610 */
611 @Override
612 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
613 }
614
615 /**
616 * {@inheritDoc}
617 */
618 @Override
619 public void contextStop(IMemento memento, IProgressMonitor monitor) {
620 //close view when workbench closes
621 try{
622 thisPart.getContext().get(EPartService.class).hidePart(thisPart);
623 }
624 catch(Exception e){
625 //nothing
626 }
627 }
628
629 /**
630 * {@inheritDoc}
631 */
632 @Override
633 public void contextStart(IMemento memento, IProgressMonitor monitor) {
634 }
635
636 /**
637 * {@inheritDoc}
638 */
639 @Override
640 public void contextRefresh(IProgressMonitor monitor) {
641 }
642
643 /**
644 * {@inheritDoc}
645 */
646 @Override
647 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
648 }
649
650
651 public boolean isDirty() {
652 return dirty.isDirty();
653 }
654
655 @Override
656 public void collapse() {
657 viewer.collapseAll();
658 }
659
660 @Override
661 public void expand() {
662 viewer.expandAll();
663 }
664
665 }