1 package eu
.etaxonomy
.taxeditor
.editor
.view
.derivate
;
3 import java
.util
.Collection
;
4 import java
.util
.HashSet
;
5 import java
.util
.Map
.Entry
;
8 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
9 import org
.eclipse
.jface
.action
.MenuManager
;
10 import org
.eclipse
.jface
.util
.LocalSelectionTransfer
;
11 import org
.eclipse
.jface
.viewers
.AbstractTreeViewer
;
12 import org
.eclipse
.jface
.viewers
.ISelection
;
13 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
14 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
15 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
16 import org
.eclipse
.jface
.viewers
.TreeNode
;
17 import org
.eclipse
.jface
.viewers
.TreeSelection
;
18 import org
.eclipse
.jface
.viewers
.TreeViewer
;
19 import org
.eclipse
.swt
.SWT
;
20 import org
.eclipse
.swt
.dnd
.DND
;
21 import org
.eclipse
.swt
.dnd
.Transfer
;
22 import org
.eclipse
.swt
.widgets
.Composite
;
23 import org
.eclipse
.swt
.widgets
.Control
;
24 import org
.eclipse
.swt
.widgets
.Menu
;
25 import org
.eclipse
.swt
.widgets
.Tree
;
26 import org
.eclipse
.ui
.IEditorInput
;
27 import org
.eclipse
.ui
.IEditorPart
;
28 import org
.eclipse
.ui
.IEditorSite
;
29 import org
.eclipse
.ui
.PartInitException
;
30 import org
.eclipse
.ui
.part
.EditorPart
;
32 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
33 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
34 import eu
.etaxonomy
.cdm
.api
.service
.molecular
.ISequenceService
;
35 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
36 import eu
.etaxonomy
.cdm
.model
.molecular
.Sequence
;
37 import eu
.etaxonomy
.cdm
.model
.molecular
.SingleRead
;
38 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
39 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
40 import eu
.etaxonomy
.taxeditor
.editor
.Messages
;
41 import eu
.etaxonomy
.taxeditor
.editor
.view
.derivate
.searchFilter
.DerivateSearchCompositeController
;
42 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkable
;
43 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
44 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasFactualData
;
45 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasMedia
;
46 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasSupplementalData
;
47 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
48 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
49 import eu
.etaxonomy
.taxeditor
.ui
.element
.LayoutConstants
;
50 import eu
.etaxonomy
.taxeditor
.view
.derivateSearch
.DerivateContentProvider
;
51 import eu
.etaxonomy
.taxeditor
.view
.derivateSearch
.DerivateLabelProvider
;
54 * Displays the derivate hierarchy of the specimen specified in the editor input.
57 public class DerivateView
extends EditorPart
implements IPartContentHasFactualData
, IDirtyMarkable
,
58 IConversationEnabled
, IPartContentHasDetails
, IPartContentHasSupplementalData
, IPartContentHasMedia
,
59 ISelectionChangedListener
, IPostOperationEnabled
{
61 public static final String ID
= "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
63 public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION
= Messages
.DerivateView_YOU_NEED_TO_SAVE
;
64 public static final String VIEW_HAS_UNSAVED_CHANGES
= Messages
.DerivateView_UNSAVED_CHANGES
;
66 private ConversationHolder conversation
;
68 private TreeViewer viewer
;
70 private boolean isDirty
;
72 private final int dndOperations
= DND
.DROP_MOVE
;
74 private DerivateLabelProvider labelProvider
;
76 private Set
<SingleRead
> multiLinkSingleReads
;
78 private ISelection selection
= null;
81 private DerivateContentProvider contentProvider
;
83 private DerivateSearchCompositeController derivateSearchCompositeController
;
88 public DerivateView() {
92 public void createPartControl(Composite parent
) {
94 parent
.setLayout(LayoutConstants
.LAYOUT());
95 parent
.setLayoutData(LayoutConstants
.FILL());
97 //---search and filter---
98 derivateSearchCompositeController
= new DerivateSearchCompositeController(parent
, this);
99 derivateSearchCompositeController
.setEnabled(CdmStore
.isActive());
100 derivateSearchCompositeController
.setLayoutData(LayoutConstants
.FILL_HORIZONTALLY());
103 viewer
= new TreeViewer(new Tree(parent
, SWT
.MULTI
| SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.FULL_SELECTION
));
104 viewer
.getTree().setLayoutData(LayoutConstants
.FILL());
105 contentProvider
= new DerivateContentProvider();
106 viewer
.setContentProvider(contentProvider
);
107 labelProvider
= new DerivateLabelProvider();
108 labelProvider
.setConversation(conversation
);
109 viewer
.setLabelProvider(labelProvider
);
110 viewer
.setAutoExpandLevel(AbstractTreeViewer
.ALL_LEVELS
);
111 // Propagate selection from viewer
112 getSite().setSelectionProvider(viewer
);
113 //listen to selection changes
114 viewer
.addSelectionChangedListener(this);
116 //create context menu
117 MenuManager menuManager
= new MenuManager();
118 getSite().registerContextMenu(menuManager
, viewer
);
119 Control control
= viewer
.getControl();
120 Menu menu
= menuManager
.createContextMenu(control
);
121 control
.setMenu(menu
);
123 generateMultiLinkSingleReads();
124 labelProvider
.setMultiLinkSingleReads(multiLinkSingleReads
);
125 IEditorInput editorInput
= getEditorInput();
126 viewer
.setInput(((DerivateViewEditorInput
) editorInput
).getRootEntities());
127 //set selection to selected derivate if only one was selected
128 if(editorInput
instanceof DerivateViewEditorInput
){
129 Set
<SpecimenOrObservationBase
<?
>> derivateEntities
= ((DerivateViewEditorInput
) editorInput
).getDerivateEntities();
130 if(derivateEntities
.size()==1){
131 SpecimenOrObservationBase
<?
> specimen
= derivateEntities
.iterator().next();
132 if(specimen
!= null){
133 viewer
.setSelection(new StructuredSelection(new TreeNode(specimen
)));
138 //add drag'n'drop support
139 Transfer
[] transfers
= new Transfer
[] {LocalSelectionTransfer
.getTransfer(),};
140 viewer
.addDragSupport(dndOperations
, transfers
, new DerivateDragListener(this));
141 viewer
.addDropSupport(dndOperations
, transfers
, new DerivateDropListener(this));
145 public void doSave(IProgressMonitor monitor
) {
146 String taskName
= Messages
.DerivateView_SAVING_HIERARCHY
;
147 if(getEditorInput() instanceof DerivateViewEditorInput
){
148 DerivateViewEditorInput derivateViewEditorInput
= (DerivateViewEditorInput
) getEditorInput();
149 taskName
+= " "+derivateViewEditorInput
.getName(); //$NON-NLS-1$
151 monitor
.beginTask(taskName
, 3);
152 if (!conversation
.isBound()) {
157 // commit the conversation and start a new transaction immediately
158 conversation
.commit(true);
159 ((DerivateViewEditorInput
) getEditorInput()).merge();
162 this.setDirty(false);
165 firePropertyChange(PROP_DIRTY
);
170 public void doSaveAs() {
174 public String
getTitleToolTip() {
175 if(getEditorInput() instanceof DerivateViewEditorInput
){
176 DerivateViewEditorInput derivateViewEditorInput
= (DerivateViewEditorInput
) getEditorInput();
177 return derivateViewEditorInput
.getName();
179 return Messages
.DerivateView_DERIVATIVE_EDITOR
;
183 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
186 if(input
instanceof DerivateViewEditorInput
){
187 DerivateViewEditorInput derivateViewEditorInput
= (DerivateViewEditorInput
) input
;
188 conversation
= derivateViewEditorInput
.getConversationHolder();
189 setPartName(derivateViewEditorInput
.getName());
194 public boolean isDirty() {
199 * @param isDirty the isDirty to set
201 public void setDirty(boolean isDirty
) {
202 this.isDirty
= isDirty
;
206 public boolean isSaveAsAllowed() {
211 public void setFocus() {
212 viewer
.getControl().setFocus();
213 //make sure to bind again if maybe in another view the conversation was unbound
214 if(!conversation
.isBound()){
217 ((DerivateViewEditorInput
) getEditorInput()).bind();
221 public void update(CdmDataChangeMap changeEvents
) {
225 public ConversationHolder
getConversationHolder() {
232 public TreeViewer
getViewer() {
237 public void changed(Object element
) {
239 firePropertyChange(IEditorPart
.PROP_DIRTY
);
244 public void forceDirty() {
249 * Refreshes the derivate hierarchy tree and expands the tree
250 * to show and select the given object.
252 * @param expandTo the object to which the tree should be expanded
254 public void refreshTree(Object expandTo
){
256 TreeSelection selection
= (TreeSelection
) viewer
.getSelection();
257 viewer
.expandToLevel(selection
.getFirstElement(), 1);
258 viewer
.setSelection(new StructuredSelection(new TreeNode(expandTo
)));
262 * Refreshes the derivate hierarchy tree
264 public void refreshTree(){
265 generateMultiLinkSingleReads();
266 labelProvider
.setMultiLinkSingleReads(multiLinkSingleReads
);
270 //FIXME:Remoting hack to make this work for remoting
271 //This should actually be resolved using remoting post operations
272 public void remove(Object obj
) {
273 Set
<SpecimenOrObservationBase
<?
>> rootEntities
= ((DerivateViewEditorInput
) getEditorInput()).getRootEntities();
274 rootEntities
.remove(obj
);
275 viewer
.setInput(rootEntities
);
278 private void generateMultiLinkSingleReads() {
279 Set
<SingleRead
> multiLinkSingleReads
= new HashSet
<SingleRead
>();
280 for(Entry
<SingleRead
, Collection
<Sequence
>> entry
:CdmStore
.getService(ISequenceService
.class).getSingleReadSequencesMap().entrySet()){
281 if(entry
.getValue().size()>1){
282 multiLinkSingleReads
.add(entry
.getKey());
285 this.multiLinkSingleReads
= multiLinkSingleReads
;
289 * @return a set of {@link SingleRead}s that have multiple parents
291 public Set
<SingleRead
> getMultiLinkSingleReads() {
292 return this.multiLinkSingleReads
;
296 public void selectionChanged(SelectionChangedEvent event
) {
297 this.selection
= event
.getSelection();
300 public ISelection
getSelection() {
304 public DerivateLabelProvider
getLabelProvider() {
305 return labelProvider
;
309 public boolean postOperation(CdmBase objectAffectedByOperation
) {
311 if(objectAffectedByOperation
!=null){
312 changed(objectAffectedByOperation
);
318 public boolean onComplete() {
323 public void dispose() {
324 ((DerivateViewEditorInput
) getEditorInput()).dispose();
330 public boolean canAttachMedia() {