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