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 viewer.getControl().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 and expands the tree
237 * to show and select the given object.
238 *
239 * @param expandTo the object to which the tree should be expanded
240 */
241 public void refreshTree(Object expandTo){
242 refreshTree();
243 TreeSelection selection = (TreeSelection) viewer.getSelection();
244 viewer.expandToLevel(selection.getFirstElement(), 1);
245 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
246 }
247
248 /**
249 * Refreshes the derivate hierarchy tree
250 */
251 public void refreshTree(){
252 generateMultiLinkSingleReads();
253 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
254 viewer.refresh();
255 }
256
257
258 private void generateMultiLinkSingleReads() {
259 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
260 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
261 if(entry.getValue().size()>1){
262 multiLinkSingleReads.add(entry.getKey());
263 }
264 }
265 this.multiLinkSingleReads = multiLinkSingleReads;
266 }
267
268 /**
269 * @return a set of {@link SingleRead}s that have multiple parents
270 */
271 public Set<SingleRead> getMultiLinkSingleReads() {
272 return this.multiLinkSingleReads;
273 }
274
275 }