merge-update from trunk
[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.StructuredSelection;
13 import org.eclipse.jface.viewers.TreeNode;
14 import org.eclipse.jface.viewers.TreeSelection;
15 import org.eclipse.jface.viewers.TreeViewer;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.dnd.DND;
18 import org.eclipse.swt.dnd.Transfer;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Menu;
22 import org.eclipse.swt.widgets.Tree;
23 import org.eclipse.ui.IEditorInput;
24 import org.eclipse.ui.IEditorPart;
25 import org.eclipse.ui.IEditorSite;
26 import org.eclipse.ui.PartInitException;
27 import org.eclipse.ui.part.EditorPart;
28
29 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
30 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
31 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
32 import eu.etaxonomy.cdm.model.molecular.Sequence;
33 import eu.etaxonomy.cdm.model.molecular.SingleRead;
34 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
35 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
36 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
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 {
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 }
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 viewer.setLabelProvider(labelProvider);
90 viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
91 // Propagate selection from viewer
92 getSite().setSelectionProvider(viewer);
93
94 //create context menu
95 MenuManager menuManager = new MenuManager();
96 getSite().registerContextMenu(menuManager, viewer);
97 Control control = viewer.getControl();
98 Menu menu = menuManager.createContextMenu(control);
99 control.setMenu(menu);
100
101 generateMultiLinkSingleReads();
102 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
103 IEditorInput editorInput = getEditorInput();
104 viewer.setInput(editorInput);
105 if(editorInput instanceof DerivateViewEditorInput){
106 SpecimenOrObservationBase<?> specimen = ((DerivateViewEditorInput) editorInput).getDerivate();
107 SpecimenOrObservationBase<?> rootElement = ((DerivateViewEditorInput) editorInput).getRootElement();
108 setPartName(DerivateLabelProvider.getDerivateText(rootElement));
109 viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
110 }
111
112 //add drag'n'drop support
113 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
114 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
115 viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
116 }
117
118 /* (non-Javadoc)
119 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
120 */
121 @Override
122 public void doSave(IProgressMonitor monitor) {
123 monitor.beginTask("Saving Derivates", 3);
124 if (!conversation.isBound()) {
125 conversation.bind();
126 }
127 monitor.worked(1);
128
129 // commit the conversation and start a new transaction immediately
130 conversation.commit(true);
131 monitor.worked(1);
132
133 this.setDirty(false);
134 monitor.worked(1);
135 monitor.done();
136 firePropertyChange(PROP_DIRTY);
137 refreshTree();
138 }
139
140 /* (non-Javadoc)
141 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
142 */
143 @Override
144 public void doSaveAs() {
145 }
146
147 /* (non-Javadoc)
148 * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
149 */
150 @Override
151 public String getTitleToolTip() {
152 return "Derivate View";
153 }
154
155 /* (non-Javadoc)
156 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
157 */
158 @Override
159 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
160 setSite(site);
161 setInput(input);
162 if(input instanceof DerivateViewEditorInput){
163 conversation = ((DerivateViewEditorInput) input).getConversationHolder();
164 }
165 }
166
167 /* (non-Javadoc)
168 * @see org.eclipse.ui.part.EditorPart#isDirty()
169 */
170 @Override
171 public boolean isDirty() {
172 return isDirty;
173 }
174
175 /**
176 * @param isDirty the isDirty to set
177 */
178 public void setDirty(boolean isDirty) {
179 this.isDirty = isDirty;
180 }
181
182 /* (non-Javadoc)
183 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
184 */
185 @Override
186 public boolean isSaveAsAllowed() {
187 return false;
188 }
189
190
191 /* (non-Javadoc)
192 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
193 */
194 @Override
195 public void setFocus() {
196 //make sure to bind again if maybe in another view the conversation was unbound
197 if(!conversation.isBound()){
198 conversation.bind();
199 }
200 }
201
202 /* (non-Javadoc)
203 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
204 */
205 @Override
206 public void update(CdmDataChangeMap changeEvents) {
207 }
208
209 /* (non-Javadoc)
210 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
211 */
212 @Override
213 public ConversationHolder getConversationHolder() {
214 return conversation;
215 }
216
217 /**
218 * @return the viewer
219 */
220 public TreeViewer getViewer() {
221 return viewer;
222 }
223
224 /* (non-Javadoc)
225 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(java.lang.Object)
226 */
227 @Override
228 public void changed(Object element) {
229 setDirty(true);
230 firePropertyChange(IEditorPart.PROP_DIRTY);
231 viewer.refresh();
232 }
233
234 /**
235 * Refreshes the derivate hierarchy tree and expands the tree
236 * to show and select the given object.
237 *
238 * @param expandTo the object to which the tree should be expanded
239 */
240 public void refreshTree(Object expandTo){
241 refreshTree();
242 TreeSelection selection = (TreeSelection) viewer.getSelection();
243 viewer.expandToLevel(selection.getFirstElement(), 1);
244 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
245 }
246
247 /**
248 * Refreshes the derivate hierarchy tree
249 */
250 public void refreshTree(){
251 generateMultiLinkSingleReads();
252 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
253 viewer.refresh();
254 }
255
256
257 private void generateMultiLinkSingleReads() {
258 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
259 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
260 if(entry.getValue().size()>1){
261 multiLinkSingleReads.add(entry.getKey());
262 }
263 }
264 this.multiLinkSingleReads = multiLinkSingleReads;
265 }
266
267 /**
268 * @return a set of {@link SingleRead}s that have multiple parents
269 */
270 public Set<SingleRead> getMultiLinkSingleReads() {
271 return this.multiLinkSingleReads;
272 }
273
274 }