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