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