Merge branch 'develop' into remoting-4.0
[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.Collection;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Map.Entry;
7 import java.util.Set;
8 import java.util.UUID;
9
10 import org.eclipse.core.runtime.IProgressMonitor;
11 import org.eclipse.jface.action.MenuManager;
12 import org.eclipse.jface.util.LocalSelectionTransfer;
13 import org.eclipse.jface.viewers.AbstractTreeViewer;
14 import org.eclipse.jface.viewers.ISelection;
15 import org.eclipse.jface.viewers.ISelectionChangedListener;
16 import org.eclipse.jface.viewers.SelectionChangedEvent;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.jface.viewers.TreeNode;
19 import org.eclipse.jface.viewers.TreeSelection;
20 import org.eclipse.jface.viewers.TreeViewer;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.dnd.DND;
23 import org.eclipse.swt.dnd.Transfer;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.swt.widgets.Control;
26 import org.eclipse.swt.widgets.Menu;
27 import org.eclipse.swt.widgets.Tree;
28 import org.eclipse.ui.IEditorInput;
29 import org.eclipse.ui.IEditorPart;
30 import org.eclipse.ui.IEditorSite;
31 import org.eclipse.ui.PartInitException;
32 import org.eclipse.ui.part.EditorPart;
33
34 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
35 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
36 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
37 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
38 import eu.etaxonomy.cdm.model.common.CdmBase;
39 import eu.etaxonomy.cdm.model.molecular.Sequence;
40 import eu.etaxonomy.cdm.model.molecular.SingleRead;
41 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
42 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
43 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
44 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
45 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
46 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
47 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
48 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
49 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
50 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
51 import eu.etaxonomy.taxeditor.store.CdmStore;
52 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
53 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
54
55 /**
56 * Displays the derivate hierarchy of the specimen specified in the editor input.
57 *
58 */
59 public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkable,
60 IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
61 ISelectionChangedListener, IPostOperationEnabled , ICdmEntitySessionEnabled {
62
63 public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView";
64
65 private ConversationHolder conversation;
66
67 private TreeViewer viewer;
68
69 private boolean isDirty;
70
71 private final int dndOperations = DND.DROP_MOVE;
72
73 private DerivateLabelProvider labelProvider;
74
75 private Set<SingleRead> multiLinkSingleReads;
76
77 private ISelection selection = null;
78
79 private final ICdmEntitySession cdmEntitySession;
80
81 private DerivateContentProvider contentProvider;
82
83 /**
84 * Default constructor
85 */
86 public DerivateView() {
87 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
88 }
89
90 /* (non-Javadoc)
91 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
92 */
93 @Override
94 public void createPartControl(Composite parent) {
95 viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
96 contentProvider = new DerivateContentProvider();
97 viewer.setContentProvider(contentProvider);
98 labelProvider = new DerivateLabelProvider();
99 labelProvider.setConversation(conversation);
100 viewer.setLabelProvider(labelProvider);
101 viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
102 // Propagate selection from viewer
103 getSite().setSelectionProvider(viewer);
104 //listen to selection changes
105 viewer.addSelectionChangedListener(this);
106
107 //create context menu
108 MenuManager menuManager = new MenuManager();
109 getSite().registerContextMenu(menuManager, viewer);
110 Control control = viewer.getControl();
111 Menu menu = menuManager.createContextMenu(control);
112 control.setMenu(menu);
113
114 generateMultiLinkSingleReads();
115 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
116 IEditorInput editorInput = getEditorInput();
117 viewer.setInput(((DerivateViewEditorInput) editorInput).getRootUUIDs());
118 //set selection to selected derivate if only one was selected
119 if(editorInput instanceof DerivateViewEditorInput){
120 Set<UUID> derivateUUIDs = ((DerivateViewEditorInput) editorInput).getDerivateUUIDs();
121 if(derivateUUIDs.size()==1){
122 SpecimenOrObservationBase<?> specimen = CdmStore.getService(IOccurrenceService.class).load(derivateUUIDs.iterator().next());
123 if(specimen!=null){
124 viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
125 }
126 }
127 }
128
129 //add drag'n'drop support
130 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
131 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
132 viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
133 }
134
135 /* (non-Javadoc)
136 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
137 */
138 @Override
139 public void doSave(IProgressMonitor monitor) {
140 String taskName = "Saving hierarchy";
141 if(getEditorInput() instanceof DerivateViewEditorInput){
142 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
143 taskName += " "+derivateViewEditorInput.getName();
144 }
145 monitor.beginTask(taskName, 3);
146 if (!conversation.isBound()) {
147 conversation.bind();
148 }
149 monitor.worked(1);
150
151 // commit the conversation and start a new transaction immediately
152 conversation.commit(true);
153 CdmStore.getService(IOccurrenceService.class).merge(getRootEntities());
154 monitor.worked(1);
155
156 this.setDirty(false);
157 monitor.worked(1);
158 monitor.done();
159 firePropertyChange(PROP_DIRTY);
160 refreshTree();
161 }
162
163 /* (non-Javadoc)
164 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
165 */
166 @Override
167 public void doSaveAs() {
168 }
169
170 /* (non-Javadoc)
171 * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
172 */
173 @Override
174 public String getTitleToolTip() {
175 if(getEditorInput() instanceof DerivateViewEditorInput){
176 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
177 return derivateViewEditorInput.getName();
178 }
179 return "Derivative View";
180 }
181
182 /* (non-Javadoc)
183 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
184 */
185 @Override
186 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
187 setSite(site);
188 setInput(input);
189 if(input instanceof DerivateViewEditorInput){
190 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) input;
191 conversation = derivateViewEditorInput.getConversationHolder();
192 setPartName(derivateViewEditorInput.getName());
193 }
194 }
195
196 /* (non-Javadoc)
197 * @see org.eclipse.ui.part.EditorPart#isDirty()
198 */
199 @Override
200 public boolean isDirty() {
201 return isDirty;
202 }
203
204 /**
205 * @param isDirty the isDirty to set
206 */
207 public void setDirty(boolean isDirty) {
208 this.isDirty = isDirty;
209 }
210
211 /* (non-Javadoc)
212 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
213 */
214 @Override
215 public boolean isSaveAsAllowed() {
216 return false;
217 }
218
219
220 /* (non-Javadoc)
221 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
222 */
223 @Override
224 public void setFocus() {
225 viewer.getControl().setFocus();
226 //make sure to bind again if maybe in another view the conversation was unbound
227 if(!conversation.isBound()){
228 conversation.bind();
229 }
230 cdmEntitySession.bind();
231 }
232
233 /* (non-Javadoc)
234 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
235 */
236 @Override
237 public void update(CdmDataChangeMap changeEvents) {
238 }
239
240 /* (non-Javadoc)
241 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
242 */
243 @Override
244 public ConversationHolder getConversationHolder() {
245 return conversation;
246 }
247
248 /**
249 * @return the viewer
250 */
251 public TreeViewer getViewer() {
252 return viewer;
253 }
254
255 /* (non-Javadoc)
256 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(java.lang.Object)
257 */
258 @Override
259 public void changed(Object element) {
260 setDirty(true);
261 firePropertyChange(IEditorPart.PROP_DIRTY);
262 viewer.refresh();
263 }
264
265 /* (non-Javadoc)
266 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#forceDirty()
267 */
268 @Override
269 public void forceDirty() {
270 changed(null);
271 }
272
273 /**
274 * Refreshes the derivate hierarchy tree and expands the tree
275 * to show and select the given object.
276 *
277 * @param expandTo the object to which the tree should be expanded
278 */
279 public void refreshTree(Object expandTo){
280 refreshTree();
281 TreeSelection selection = (TreeSelection) viewer.getSelection();
282 viewer.expandToLevel(selection.getFirstElement(), 1);
283 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
284 }
285
286 /**
287 * Refreshes the derivate hierarchy tree
288 */
289 public void refreshTree(){
290 generateMultiLinkSingleReads();
291 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
292 viewer.refresh();
293 }
294
295
296 private void generateMultiLinkSingleReads() {
297 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
298 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
299 if(entry.getValue().size()>1){
300 multiLinkSingleReads.add(entry.getKey());
301 }
302 }
303 this.multiLinkSingleReads = multiLinkSingleReads;
304 }
305
306 /**
307 * @return a set of {@link SingleRead}s that have multiple parents
308 */
309 public Set<SingleRead> getMultiLinkSingleReads() {
310 return this.multiLinkSingleReads;
311 }
312
313 /* (non-Javadoc)
314 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
315 */
316 @Override
317 public void selectionChanged(SelectionChangedEvent event) {
318 this.selection = event.getSelection();
319 }
320
321 public ISelection getSelection() {
322 return selection;
323 }
324
325 public DerivateLabelProvider getLabelProvider() {
326 return labelProvider;
327 }
328
329 /* (non-Javadoc)
330 * @see eu.etaxonomy.taxeditor.operation.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
331 */
332 @Override
333 public boolean postOperation(CdmBase objectAffectedByOperation) {
334 refreshTree();
335 if(objectAffectedByOperation!=null){
336 changed(objectAffectedByOperation);
337 }
338 return true;
339 }
340
341 /* (non-Javadoc)
342 * @see eu.etaxonomy.taxeditor.operation.IPostOperationEnabled#onComplete()
343 */
344 @Override
345 public boolean onComplete() {
346 return true;
347 }
348
349 @Override
350 public void dispose() {
351 cdmEntitySession.dispose();
352 super.dispose();
353 }
354
355 /* (non-Javadoc)
356 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getCdmEntitySession()
357 */
358 @Override
359 public ICdmEntitySession getCdmEntitySession() {
360 return cdmEntitySession;
361 }
362
363 /* (non-Javadoc)
364 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getRootEntities()
365 */
366 @Override
367 public List<SpecimenOrObservationBase> getRootEntities() {
368 return contentProvider.getRootElements();
369 }
370
371 }