c805c6f165e7a4d70d2fd3c172b7b67a8a8e2606
[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 import java.util.UUID;
8
9 import org.eclipse.core.runtime.IProgressMonitor;
10 import org.eclipse.jface.action.MenuManager;
11 import org.eclipse.jface.util.LocalSelectionTransfer;
12 import org.eclipse.jface.viewers.AbstractTreeViewer;
13 import org.eclipse.jface.viewers.ISelection;
14 import org.eclipse.jface.viewers.ISelectionChangedListener;
15 import org.eclipse.jface.viewers.SelectionChangedEvent;
16 import org.eclipse.jface.viewers.StructuredSelection;
17 import org.eclipse.jface.viewers.TreeNode;
18 import org.eclipse.jface.viewers.TreeSelection;
19 import org.eclipse.jface.viewers.TreeViewer;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.dnd.DND;
22 import org.eclipse.swt.dnd.Transfer;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.swt.widgets.Control;
25 import org.eclipse.swt.widgets.Menu;
26 import org.eclipse.swt.widgets.Tree;
27 import org.eclipse.ui.IEditorInput;
28 import org.eclipse.ui.IEditorPart;
29 import org.eclipse.ui.IEditorSite;
30 import org.eclipse.ui.PartInitException;
31 import org.eclipse.ui.part.EditorPart;
32
33 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
34 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
35 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
36 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
37 import eu.etaxonomy.cdm.model.common.CdmBase;
38 import eu.etaxonomy.cdm.model.molecular.Sequence;
39 import eu.etaxonomy.cdm.model.molecular.SingleRead;
40 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
42 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
43 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
44 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
45 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
46 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
47 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
48 import eu.etaxonomy.taxeditor.store.CdmStore;
49 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
50 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
51
52 /**
53 * Displays the derivate hierarchy of the specimen specified in the editor input.
54 *
55 */
56 public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkable,
57 IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
58 ISelectionChangedListener, IPostOperationEnabled {
59
60 public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView";
61
62 private ConversationHolder conversation;
63
64 private TreeViewer viewer;
65
66 private boolean isDirty;
67
68 private final int dndOperations = DND.DROP_MOVE;
69
70 private DerivateLabelProvider labelProvider;
71
72 private Set<SingleRead> multiLinkSingleReads;
73
74 private ISelection selection = null;
75
76 /**
77 * Default constructor
78 */
79 public DerivateView() {
80 }
81
82 @Override
83 public void createPartControl(Composite parent) {
84 viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
85 viewer.setContentProvider(new DerivateContentProvider());
86 labelProvider = new DerivateLabelProvider();
87 labelProvider.setConversation(conversation);
88 viewer.setLabelProvider(labelProvider);
89 viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
90 // Propagate selection from viewer
91 getSite().setSelectionProvider(viewer);
92 //listen to selection changes
93 viewer.addSelectionChangedListener(this);
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(((DerivateViewEditorInput) editorInput).getRootUUIDs());
106 //set selection to selected derivate if only one was selected
107 if(editorInput instanceof DerivateViewEditorInput){
108 Set<UUID> derivateUUIDs = ((DerivateViewEditorInput) editorInput).getDerivateUUIDs();
109 if(derivateUUIDs.size()==1){
110 SpecimenOrObservationBase<?> specimen = CdmStore.getService(IOccurrenceService.class).load(derivateUUIDs.iterator().next());
111 if(specimen!=null){
112 viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
113 }
114 }
115 }
116
117 //add drag'n'drop support
118 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
119 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
120 viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
121 }
122
123 @Override
124 public void doSave(IProgressMonitor monitor) {
125 String taskName = "Saving hierarchy";
126 if(getEditorInput() instanceof DerivateViewEditorInput){
127 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
128 taskName += " "+derivateViewEditorInput.getName();
129 }
130 monitor.beginTask(taskName, 3);
131 if (!conversation.isBound()) {
132 conversation.bind();
133 }
134 monitor.worked(1);
135
136 // commit the conversation and start a new transaction immediately
137 conversation.commit(true);
138 monitor.worked(1);
139
140 this.setDirty(false);
141 monitor.worked(1);
142 monitor.done();
143 firePropertyChange(PROP_DIRTY);
144 refreshTree();
145 }
146
147 @Override
148 public void doSaveAs() {
149 }
150
151 @Override
152 public String getTitleToolTip() {
153 if(getEditorInput() instanceof DerivateViewEditorInput){
154 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
155 return derivateViewEditorInput.getName();
156 }
157 return "Derivative Editor";
158 }
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 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) input;
166 conversation = derivateViewEditorInput.getConversationHolder();
167 setPartName(derivateViewEditorInput.getName());
168 }
169 }
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 @Override
184 public boolean isSaveAsAllowed() {
185 return false;
186 }
187
188 @Override
189 public void setFocus() {
190 viewer.getControl().setFocus();
191 //make sure to bind again if maybe in another view the conversation was unbound
192 if(!conversation.isBound()){
193 conversation.bind();
194 }
195 }
196
197 @Override
198 public void update(CdmDataChangeMap changeEvents) {
199 }
200
201 @Override
202 public ConversationHolder getConversationHolder() {
203 return conversation;
204 }
205
206 /**
207 * @return the viewer
208 */
209 public TreeViewer getViewer() {
210 return viewer;
211 }
212
213 @Override
214 public void changed(Object element) {
215 setDirty(true);
216 firePropertyChange(IEditorPart.PROP_DIRTY);
217 viewer.refresh();
218 }
219
220 @Override
221 public void forceDirty() {
222 changed(null);
223 }
224
225 /**
226 * Refreshes the derivate hierarchy tree and expands the tree
227 * to show and select the given object.
228 *
229 * @param expandTo the object to which the tree should be expanded
230 */
231 public void refreshTree(Object expandTo){
232 refreshTree();
233 TreeSelection selection = (TreeSelection) viewer.getSelection();
234 viewer.expandToLevel(selection.getFirstElement(), 1);
235 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
236 }
237
238 /**
239 * Refreshes the derivate hierarchy tree
240 */
241 public void refreshTree(){
242 generateMultiLinkSingleReads();
243 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
244 viewer.refresh();
245 }
246
247 private void generateMultiLinkSingleReads() {
248 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
249 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
250 if(entry.getValue().size()>1){
251 multiLinkSingleReads.add(entry.getKey());
252 }
253 }
254 this.multiLinkSingleReads = multiLinkSingleReads;
255 }
256
257 /**
258 * @return a set of {@link SingleRead}s that have multiple parents
259 */
260 public Set<SingleRead> getMultiLinkSingleReads() {
261 return this.multiLinkSingleReads;
262 }
263
264 @Override
265 public void selectionChanged(SelectionChangedEvent event) {
266 this.selection = event.getSelection();
267 }
268
269 public ISelection getSelection() {
270 return selection;
271 }
272
273 public DerivateLabelProvider getLabelProvider() {
274 return labelProvider;
275 }
276
277 @Override
278 public boolean postOperation(CdmBase objectAffectedByOperation) {
279 refreshTree();
280 if(objectAffectedByOperation!=null){
281 changed(objectAffectedByOperation);
282 }
283 return true;
284 }
285
286 @Override
287 public boolean onComplete() {
288 return true;
289 }
290
291 @Override
292 public boolean canAttachMedia() {
293 return true;
294 }
295
296 }