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