- fixed potential session exceptions during closing/saving
[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.StructuredSelection;
12 import org.eclipse.jface.viewers.TreeNode;
13 import org.eclipse.jface.viewers.TreeViewer;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.dnd.DND;
16 import org.eclipse.swt.dnd.Transfer;
17 import org.eclipse.swt.widgets.Composite;
18 import org.eclipse.swt.widgets.Control;
19 import org.eclipse.swt.widgets.Menu;
20 import org.eclipse.swt.widgets.Tree;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.IEditorPart;
23 import org.eclipse.ui.IEditorSite;
24 import org.eclipse.ui.IMemento;
25 import org.eclipse.ui.PartInitException;
26 import org.eclipse.ui.part.EditorPart;
27
28 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
29 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
30 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
31 import eu.etaxonomy.cdm.model.molecular.Sequence;
32 import eu.etaxonomy.cdm.model.molecular.SingleRead;
33 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
34 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
35 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
36 import eu.etaxonomy.taxeditor.model.IContextListener;
37 import eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider;
38 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
39 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
40 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
41 import eu.etaxonomy.taxeditor.store.CdmStore;
42 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
43
44 /**
45 * Displays the derivate hierarchy of all derivates having one single {@link FieldUnit} as root.
46 *
47 */
48 public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkableSelectionProvider,
49 IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IContextListener {
50
51 /**
52 * Key used for storing a single DerivateView in a memento
53 */
54 private static final String DERIVATE_VIEW_MEMENTO_KEY = "derivateView";
55
56 /**
57 * Key to to group mementos for every single DerivateView
58 */
59 private static final String DERIVATE_VIEWS_MEMENTO_KEY = "derivateViews";
60
61 public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView";
62
63 private ConversationHolder conversation;
64
65 private TreeViewer viewer;
66
67 private boolean isDirty;
68
69 private final int dndOperations = DND.DROP_MOVE;
70
71 private DerivateLabelProvider labelProvider;
72
73 private Set<SingleRead> multiLinkSingleReads;
74
75 /**
76 * Default constructor
77 */
78 public DerivateView() {
79 CdmStore.getContextManager().addContextListener(this);
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 viewer.setLabelProvider(labelProvider);
91 viewer.setAutoExpandLevel(2);
92 // Propagate selection from viewer
93 getSite().setSelectionProvider(viewer);
94
95 //create context menu
96 MenuManager menuManager = new MenuManager();
97 getSite().registerContextMenu(menuManager, viewer);
98 Control control = viewer.getControl();
99 Menu menu = menuManager.createContextMenu(control);
100 control.setMenu(menu);
101
102 generateMultiLinkSingleReads();
103 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
104 IEditorInput editorInput = getEditorInput();
105 viewer.setInput(editorInput);
106 if(editorInput instanceof DerivateViewEditorInput){
107 SpecimenOrObservationBase<?> specimen = ((DerivateViewEditorInput) editorInput).getDerivate();
108 SpecimenOrObservationBase<?> rootElement = ((DerivateViewEditorInput) editorInput).getRootElement();
109 setPartName(DerivateLabelProvider.getDerivateText(rootElement));
110 viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
111 }
112
113 //add drag'n'drop support
114 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
115 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
116 viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
117 }
118
119 /* (non-Javadoc)
120 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
121 */
122 @Override
123 public void doSave(IProgressMonitor monitor) {
124 monitor.beginTask("Saving Derivates", 3);
125 if (!conversation.isBound()) {
126 conversation.bind();
127 }
128 monitor.worked(1);
129
130 // commit the conversation and start a new transaction immediately
131 conversation.commit(true);
132 monitor.worked(1);
133
134 this.setDirty(false);
135 monitor.worked(1);
136 monitor.done();
137 firePropertyChange(PROP_DIRTY);
138 refreshTree();
139 }
140
141 /* (non-Javadoc)
142 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
143 */
144 @Override
145 public void doSaveAs() {
146 }
147
148 /* (non-Javadoc)
149 * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
150 */
151 @Override
152 public String getTitleToolTip() {
153 return "Derivate View";
154 }
155
156 /* (non-Javadoc)
157 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
158 */
159 @Override
160 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
161 setSite(site);
162 setInput(input);
163 if(input instanceof DerivateViewEditorInput){
164 conversation = ((DerivateViewEditorInput) input).getConversationHolder();
165 }
166 }
167
168 /* (non-Javadoc)
169 * @see org.eclipse.ui.part.EditorPart#isDirty()
170 */
171 @Override
172 public boolean isDirty() {
173 return isDirty;
174 }
175
176 /**
177 * @param isDirty the isDirty to set
178 */
179 public void setDirty(boolean isDirty) {
180 this.isDirty = isDirty;
181 }
182
183 /* (non-Javadoc)
184 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
185 */
186 @Override
187 public boolean isSaveAsAllowed() {
188 return false;
189 }
190
191
192 /* (non-Javadoc)
193 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
194 */
195 @Override
196 public void setFocus() {
197 //make sure to bind again if maybe in another view the conversation was unbound
198 if(!conversation.isBound()){
199 conversation.bind();
200 }
201 }
202
203 /* (non-Javadoc)
204 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
205 */
206 @Override
207 public void update(CdmDataChangeMap changeEvents) {
208 }
209
210 /* (non-Javadoc)
211 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
212 */
213 @Override
214 public ConversationHolder getConversationHolder() {
215 return conversation;
216 }
217
218 /**
219 * @return the viewer
220 */
221 public TreeViewer getViewer() {
222 return viewer;
223 }
224
225 /* (non-Javadoc)
226 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(java.lang.Object)
227 */
228 @Override
229 public void changed(Object element) {
230 setDirty(true);
231 firePropertyChange(IEditorPart.PROP_DIRTY);
232 viewer.refresh();
233 }
234
235 /**
236 * Refreshes the derivate hierarchy tree
237 */
238 public void refreshTree(){
239 generateMultiLinkSingleReads();
240 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
241 viewer.refresh();
242 }
243
244 private void generateMultiLinkSingleReads() {
245 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
246 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
247 if(entry.getValue().size()>1){
248 multiLinkSingleReads.add(entry.getKey());
249 }
250 }
251 this.multiLinkSingleReads = multiLinkSingleReads;
252 }
253
254 /**
255 * @return a set of {@link SingleRead}s that have multiple parents
256 */
257 public Set<SingleRead> getMultiLinkSingleReads() {
258 return this.multiLinkSingleReads;
259 }
260
261 /* (non-Javadoc)
262 * @see eu.etaxonomy.taxeditor.model.IContextListener#contextAboutToStop(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
263 */
264 @Override
265 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
266 }
267
268 /* (non-Javadoc)
269 * @see eu.etaxonomy.taxeditor.model.IContextListener#contextStop(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
270 */
271 @Override
272 public void contextStop(IMemento memento, IProgressMonitor monitor) {
273 }
274
275 /* (non-Javadoc)
276 * @see eu.etaxonomy.taxeditor.model.IContextListener#contextStart(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
277 */
278 @Override
279 public void contextStart(IMemento memento, IProgressMonitor monitor) {
280 // if(memento == null){
281 // return;
282 // }
283 // IMemento editorMementos = memento.getChild(DERIVATE_VIEW_MEMENTO_KEY);
284 // DerivateViewEditorInput input = new DerivateViewEditorInput(UUID.fromString(editorInput.getString(DerivateViewEditorInput.UUID_MEMENTO_KEY)));
285 // try {
286 // EditorUtil.open(input);
287 // } catch (PartInitException e) {
288 // AbstractUtility.error(getClass(), "Error opening an editor window", e);
289 // }
290 }
291
292 /* (non-Javadoc)
293 * @see eu.etaxonomy.taxeditor.model.IContextListener#contextRefresh(org.eclipse.core.runtime.IProgressMonitor)
294 */
295 @Override
296 public void contextRefresh(IProgressMonitor monitor) {
297 }
298
299 /* (non-Javadoc)
300 * @see eu.etaxonomy.taxeditor.model.IContextListener#workbenchShutdown(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
301 */
302 @Override
303 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
304 if (!conversation.isBound()) {
305 conversation.bind();
306 }
307 conversation.close();
308 // if(memento == null){
309 // return;
310 // }
311 //
312 // IEditorInput input = getEditorInput();
313 // if(input instanceof IPersistable){
314 // memento.createChild(DERIVATE_VIEW_MEMENTO_KEY);
315 // ((IPersistable) input).saveState(memento);
316 // }
317 }
318
319 }