Project

General

Profile

Download (10.7 KB) Statistics
| Branch: | Tag: | Revision:
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.common.CdmBase;
36
import eu.etaxonomy.cdm.model.molecular.Sequence;
37
import eu.etaxonomy.cdm.model.molecular.SingleRead;
38
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
39
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
40
import eu.etaxonomy.taxeditor.editor.Messages;
41
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
42
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
43
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
44
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
45
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
46
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
47
import eu.etaxonomy.taxeditor.store.CdmStore;
48
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
49
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
50

    
51
/**
52
 * Displays the derivate hierarchy of the specimen specified in the editor input.
53
 *
54
 */
55
public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkable,
56
        IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
57
        ISelectionChangedListener, IPostOperationEnabled{
58

    
59
    public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
60

    
61
    public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION = Messages.DerivateView_YOU_NEED_TO_SAVE;
62
    public static final String VIEW_HAS_UNSAVED_CHANGES = Messages.DerivateView_UNSAVED_CHANGES;
63

    
64
	private ConversationHolder conversation;
65

    
66
	private TreeViewer viewer;
67

    
68
    private boolean isDirty;
69

    
70
    private final int dndOperations = DND.DROP_MOVE;
71

    
72
    private DerivateLabelProvider labelProvider;
73

    
74
    private Set<SingleRead> multiLinkSingleReads;
75

    
76
    private ISelection selection = null;
77

    
78

    
79
    private DerivateContentProvider contentProvider;
80

    
81
    /**
82
     * Default constructor
83
     */
84
    public DerivateView() {
85
    }
86

    
87
    @Override
88
    public void createPartControl(Composite parent) {
89
        viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
90
        contentProvider = new DerivateContentProvider();
91
        viewer.setContentProvider(contentProvider);
92
        labelProvider = new DerivateLabelProvider();
93
        labelProvider.setConversation(conversation);
94
        viewer.setLabelProvider(labelProvider);
95
        viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
96
        // Propagate selection from viewer
97
        getSite().setSelectionProvider(viewer);
98
        //listen to selection changes
99
        viewer.addSelectionChangedListener(this);
100

    
101
        //create context menu
102
        MenuManager menuManager = new MenuManager();
103
        getSite().registerContextMenu(menuManager, viewer);
104
        Control control = viewer.getControl();
105
        Menu menu = menuManager.createContextMenu(control);
106
        control.setMenu(menu);
107

    
108
        //generate single read multi links
109
        generateMultiLinkSingleReads();
110
        labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
111

    
112
        //set initial selection
113
        IEditorInput editorInput = getEditorInput();
114
        viewer.setInput(((DerivateViewEditorInput) editorInput).getRootEntities());
115
        //set selection to selected derivate if only one was selected
116
        if(editorInput instanceof DerivateViewEditorInput){
117
            Set<SpecimenOrObservationBase<?>> derivateEntities = ((DerivateViewEditorInput) editorInput).getDerivateEntities();
118
            if(derivateEntities.size()==1){
119
                SpecimenOrObservationBase<?> specimen = derivateEntities.iterator().next();
120
                if(specimen != null){
121
                    viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
122
                }
123
            }
124
        }
125

    
126
        //add drag'n'drop support
127
        Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
128
        viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
129
        viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
130
    }
131

    
132
    @Override
133
    public void doSave(IProgressMonitor monitor) {
134
        String taskName = Messages.DerivateView_SAVING_HIERARCHY;
135
        if(getEditorInput() instanceof DerivateViewEditorInput){
136
            DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
137
            taskName += " "+derivateViewEditorInput.getName(); //$NON-NLS-1$
138
        }
139
        monitor.beginTask(taskName, 3);
140
        if (!conversation.isBound()) {
141
            conversation.bind();
142
        }
143
        monitor.worked(1);
144

    
145
        // commit the conversation and start a new transaction immediately
146
        conversation.commit(true);
147
        ((DerivateViewEditorInput) getEditorInput()).merge();
148
        monitor.worked(1);
149

    
150
        this.setDirty(false);
151
        monitor.worked(1);
152
        monitor.done();
153
        firePropertyChange(PROP_DIRTY);
154
        refreshTree();
155
    }
156

    
157
    @Override
158
    public void doSaveAs() {
159
    }
160

    
161
    @Override
162
    public String getTitleToolTip() {
163
        if(getEditorInput() instanceof DerivateViewEditorInput){
164
            DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
165
            return derivateViewEditorInput.getName();
166
        }
167
        return Messages.DerivateView_DERIVATIVE_EDITOR;
168
    }
169

    
170
    @Override
171
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
172
        setSite(site);
173
        setInput(input);
174
        if(input instanceof DerivateViewEditorInput){
175
            DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) input;
176
            conversation = derivateViewEditorInput.getConversationHolder();
177
            setPartName(derivateViewEditorInput.getName());
178
        }
179
    }
180

    
181
    @Override
182
    public boolean isDirty() {
183
        return isDirty;
184
    }
185

    
186
    /**
187
     * @param isDirty the isDirty to set
188
     */
189
    public void setDirty(boolean isDirty) {
190
        this.isDirty = isDirty;
191
    }
192

    
193
    @Override
194
    public boolean isSaveAsAllowed() {
195
        return false;
196
    }
197

    
198
    @Override
199
    public void setFocus() {
200
        viewer.getControl().setFocus();
201
        //make sure to bind again if maybe in another view the conversation was unbound
202
        if(!conversation.isBound()){
203
            conversation.bind();
204
        }
205
        ((DerivateViewEditorInput) getEditorInput()).bind();
206
    }
207

    
208
    @Override
209
    public void update(CdmDataChangeMap changeEvents) {
210
    }
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
    @Override
225
    public void changed(Object element) {
226
        setDirty(true);
227
        firePropertyChange(IEditorPart.PROP_DIRTY);
228
        viewer.refresh();
229
    }
230

    
231
    @Override
232
    public void forceDirty() {
233
        changed(null);
234
    }
235

    
236
    /**
237
     * Refreshes the derivate hierarchy tree and expands the tree
238
     * to show and select the given object.
239
     *
240
     * @param expandTo the object to which the tree should be expanded
241
     */
242
    public void refreshTree(Object expandTo){
243
        refreshTree();
244
        TreeSelection selection = (TreeSelection) viewer.getSelection();
245
        viewer.expandToLevel(selection.getFirstElement(), 1);
246
        viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
247
    }
248

    
249
    /**
250
     * Refreshes the derivate hierarchy tree
251
     */
252
    public void refreshTree(){
253
        generateMultiLinkSingleReads();
254
        labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
255
        viewer.refresh();
256
    }
257

    
258
    //FIXME:Remoting hack to make this work for remoting
259
    //This should actually be resolved using remoting post operations
260
    public void remove(Object obj) {
261
        Set<SpecimenOrObservationBase<?>> rootEntities = ((DerivateViewEditorInput) getEditorInput()).getRootEntities();
262
        rootEntities.remove(obj);
263
        viewer.setInput(rootEntities);
264
    }
265

    
266
    private void generateMultiLinkSingleReads() {
267
        Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
268
        for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
269
            if(entry.getValue().size()>1){
270
                multiLinkSingleReads.add(entry.getKey());
271
            }
272
        }
273
        this.multiLinkSingleReads = multiLinkSingleReads;
274
    }
275

    
276
    /**
277
     * @return a set of {@link SingleRead}s that have multiple parents
278
     */
279
    public Set<SingleRead> getMultiLinkSingleReads() {
280
        return this.multiLinkSingleReads;
281
    }
282

    
283
    @Override
284
    public void selectionChanged(SelectionChangedEvent event) {
285
        this.selection  = event.getSelection();
286
    }
287

    
288
    public ISelection getSelection() {
289
        return selection;
290
    }
291

    
292
    public DerivateLabelProvider getLabelProvider() {
293
        return labelProvider;
294
    }
295

    
296
    @Override
297
    public boolean postOperation(CdmBase objectAffectedByOperation) {
298
        refreshTree();
299
        if(objectAffectedByOperation!=null){
300
            changed(objectAffectedByOperation);
301
        }
302
        return true;
303
    }
304

    
305
    @Override
306
    public boolean onComplete() {
307
        return true;
308
    }
309

    
310
    @Override
311
    public void dispose() {
312
        ((DerivateViewEditorInput) getEditorInput()).dispose();
313
        super.dispose();
314
    }
315

    
316

    
317
    @Override
318
    public boolean canAttachMedia() {
319
        return true;
320
    }
321
}
(3-3/5)