Project

General

Profile

Download (12 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2007 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9

    
10
package eu.etaxonomy.taxeditor.featuretree.e4;
11

    
12
import java.util.Arrays;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16

    
17
import javax.annotation.PostConstruct;
18
import javax.annotation.PreDestroy;
19
import javax.inject.Inject;
20

    
21
import org.eclipse.core.runtime.IProgressMonitor;
22
import org.eclipse.e4.ui.di.Focus;
23
import org.eclipse.e4.ui.di.Persist;
24
import org.eclipse.e4.ui.di.UISynchronize;
25
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
26
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
27
import org.eclipse.e4.ui.services.EMenuService;
28
import org.eclipse.e4.ui.workbench.modeling.EPartService;
29
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
30
import org.eclipse.jface.util.LocalSelectionTransfer;
31
import org.eclipse.jface.viewers.ISelection;
32
import org.eclipse.jface.viewers.ISelectionChangedListener;
33
import org.eclipse.jface.viewers.IStructuredSelection;
34
import org.eclipse.jface.viewers.SelectionChangedEvent;
35
import org.eclipse.jface.viewers.StructuredSelection;
36
import org.eclipse.jface.viewers.TreeViewer;
37
import org.eclipse.swt.SWT;
38
import org.eclipse.swt.dnd.DND;
39
import org.eclipse.swt.dnd.Transfer;
40
import org.eclipse.swt.events.KeyAdapter;
41
import org.eclipse.swt.events.KeyEvent;
42
import org.eclipse.swt.layout.FillLayout;
43
import org.eclipse.swt.widgets.Composite;
44
import org.eclipse.ui.IMemento;
45

    
46
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
47
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
48
import eu.etaxonomy.cdm.api.service.ITermService;
49
import eu.etaxonomy.cdm.api.service.ITermTreeService;
50
import eu.etaxonomy.cdm.model.description.Character;
51
import eu.etaxonomy.cdm.model.term.TermNode;
52
import eu.etaxonomy.cdm.model.term.TermTree;
53
import eu.etaxonomy.cdm.model.term.TermType;
54
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
55
import eu.etaxonomy.taxeditor.editor.definedterm.FeatureTreeViewerComparator;
56
import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
57
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
58
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
59
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
60
import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddFeatureOperation;
61
import eu.etaxonomy.taxeditor.model.AbstractUtility;
62
import eu.etaxonomy.taxeditor.model.IContextListener;
63
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
64
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
66
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
67
import eu.etaxonomy.taxeditor.store.AppModelId;
68
import eu.etaxonomy.taxeditor.store.CdmStore;
69
import eu.etaxonomy.taxeditor.store.StoreUtil;
70
import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
71

    
72
/**
73
 *
74
 * @author pplitzner
75
 * @date 06.06.2017
76
 *
77
 */
78
public class FeatureTreeEditor implements IFeatureTreeEditor, ISelectionChangedListener,
79
        IE4ViewerPart, IPartContentHasDetails, IPartContentHasSupplementalData,
80
        IContextListener, IConversationEnabled, IDirtyMarkable {
81

    
82
    private static final List<String> TREE_PROPERTY_PATH = Arrays.asList(new String[] {
83
            "root", //$NON-NLS-1$
84
            "root.children", //$NON-NLS-1$
85
            "root.children.inapplicableIf", //$NON-NLS-1$
86
            "root.children.inapplicableIf.feature", //$NON-NLS-1$
87
            "root.children.inapplicableIf.state", //$NON-NLS-1$
88
            "root.children.onlyApplicableIf", //$NON-NLS-1$
89
            "root.children.onlyApplicableIf.feature", //$NON-NLS-1$
90
            "root.children.onlyApplicableIf.state", //$NON-NLS-1$
91
    });
92

    
93
    private ConversationHolder conversation;
94

    
95
    private ICdmEntitySession cdmEntitySession;
96

    
97
    @Inject
98
    private ESelectionService selService;
99

    
100
    @Inject
101
    private MDirtyable dirty;
102

    
103
    @Inject
104
    private UISynchronize sync;
105

    
106
    @Inject
107
    private MPart thisPart;
108

    
109
    private TreeViewer viewer;
110

    
111
    @Inject
112
    public FeatureTreeEditor() {
113
        CdmStore.getContextManager().addContextListener(this);
114
    }
115

    
116
    @PostConstruct
117
    public void createControl(Composite parent, EMenuService menuService){
118
        if (CdmStore.isActive()){
119
            initSession();
120
        }
121
        else{
122
            return;
123
        }
124
        parent.setLayout(new FillLayout());
125
        viewer = new TreeViewer(parent);
126
        viewer.setContentProvider(new FeatureTreeContentProvider());
127
        viewer.setLabelProvider(new FeatureTreeLabelProvider());
128

    
129
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
130
        Transfer[] transfers = new Transfer[] {
131
                FeatureNodeTransfer.getInstance(),
132
                TermTransfer.getInstance(),
133
                LocalSelectionTransfer.getTransfer()};
134
        viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(viewer));
135
        viewer.addDropSupport(ops, transfers, new FeatureTreeDropAdapter(this, viewer, sync));
136
        viewer.addSelectionChangedListener(this);
137
        viewer.getTree().addKeyListener(new KeyAdapter() {
138
            @Override
139
            public void keyPressed(KeyEvent e) {
140
                if(e.stateMask == SWT.MOD1 && e.keyCode == 'c'){
141
                    copy(viewer.getStructuredSelection());
142
                }
143
                else if(e.stateMask == SWT.MOD1 && e.keyCode == 'v'){
144
                    paste(viewer.getStructuredSelection());
145
                }
146
            }
147
        });
148

    
149
        List<TermTree> trees = CdmStore.getService(ITermTreeService.class).list(TermTree.class, null, null, null, TREE_PROPERTY_PATH);
150
        viewer.setComparator(new FeatureTreeViewerComparator());
151
        viewer.setInput(trees);
152

    
153
        //create context menu
154
        menuService.registerContextMenu(viewer.getControl(), AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_STORE_POPUPMENU_FEATURETREEEDITOR);
155
    }
156

    
157
    public void paste(IStructuredSelection selection) {
158
        if (StoreUtil.promptCheckIsDirty(this)) {
159
            return;
160
        }
161

    
162
        ISelection clipBoardSelection = LocalSelectionTransfer.getTransfer().getSelection();
163
        Object firstElement = selection.getFirstElement();
164
        TermNode parentNode = null;
165
        if(firstElement instanceof TermNode){
166
            parentNode = (TermNode) firstElement;
167
        }
168
        else if(firstElement instanceof TermTree){
169
            parentNode = ((TermTree)firstElement).getRoot();
170
        }
171
        if(parentNode!=null){
172
        	TermNode copiedNode = (TermNode) ((IStructuredSelection)clipBoardSelection).getFirstElement();
173

    
174
            AddFeatureOperation operation = new AddFeatureOperation(copiedNode.getTerm().getUuid(), parentNode, this, this);
175
            AbstractUtility.executeOperation(operation, sync);
176
        }
177

    
178
    }
179

    
180
    public void copy(IStructuredSelection selection) {
181
        LocalSelectionTransfer.getTransfer().setSelection(selection);
182
    }
183

    
184
    private void initSession(){
185
        if(conversation == null){
186
            conversation = CdmStore.createConversation();
187
        }
188
        if(cdmEntitySession==null){
189
            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
190
        }
191
    }
192

    
193
    private void clearSession() {
194
        if(conversation!=null){
195
            conversation.close();
196
            conversation = null;
197
        }
198
        if(cdmEntitySession != null) {
199
            cdmEntitySession.dispose();
200
            cdmEntitySession = null;
201
        }
202
        dirty.setDirty(false);
203
    }
204

    
205
	public void setDirty(boolean isDirty){
206
	    this.dirty.setDirty(isDirty);
207
	}
208

    
209
	@Override
210
    public boolean isDirty(){
211
	    return dirty.isDirty();
212
	}
213

    
214
	@Override
215
	public void selectionChanged(SelectionChangedEvent event) {
216
		//propagate selection
217
		selService.setSelection(event.getSelection());
218
	}
219

    
220
	@Focus
221
	public void focus(){
222
	    if(viewer!=null){
223
	        viewer.getControl().setFocus();
224
	    }
225
        if(conversation!=null && !conversation.isBound()){
226
            conversation.bind();
227
        }
228
        if(cdmEntitySession != null) {
229
            cdmEntitySession.bind();
230
        }
231
	}
232

    
233
	@Override
234
    public void refresh(){
235
	    viewer.refresh();
236
	}
237

    
238
	public TreeViewer getViewer(){
239
	    return viewer;
240
	}
241

    
242
	@Override
243
	public IStructuredSelection getSelection() {
244
	    return (IStructuredSelection) viewer.getSelection();
245
	}
246

    
247
	@Override
248
	public ConversationHolder getConversationHolder() {
249
	    return conversation;
250
	}
251

    
252
	@Override
253
    @Persist
254
	public void save(IProgressMonitor monitor){
255
        if (!conversation.isBound()) {
256
            conversation.bind();
257
        }
258

    
259
        // commit the conversation and start a new transaction immediately
260
        conversation.commit(true);
261

    
262
        CdmStore.getService(ITermTreeService.class).saveOrUpdate(getRootEntities());
263

    
264
        List<TermTree> rootEntities = getRootEntities();
265
        for (TermTree featureTree : rootEntities) {
266
            if(featureTree.getTermType().equals(TermType.Character)){
267
                TermTree<Character> characterTree = featureTree;
268
                //save characters because they can be modified in this editor
269
                characterTree.getDistinctTerms().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
270
            }
271
        }
272

    
273
        initializeTrees();
274

    
275
        this.setDirty(false);
276
	}
277

    
278
    private void initializeTrees() {
279
        Object[] expandedElements = viewer.getExpandedElements();
280
        viewer.getTree().removeAll();
281
        List<TermTree> trees = CdmStore.getService(ITermTreeService.class).list(TermTree.class, null, null, null, null);
282
        viewer.setInput(trees);
283
        viewer.setExpandedElements(expandedElements);
284
    }
285

    
286
	@PreDestroy
287
	public void dispose(){
288
	    selService.setSelection(null);
289
	    clearSession();
290
	}
291

    
292
    @Override
293
    public ICdmEntitySession getCdmEntitySession() {
294
        return cdmEntitySession;
295
    }
296

    
297
    @Override
298
    public Map<Object, List<String>> getPropertyPathsMap() {
299
        List<String> propertyPaths = Arrays.asList(new String[] {
300
                "children", //$NON-NLS-1$
301
                "feature", //$NON-NLS-1$
302
                "featureTree", //$NON-NLS-1$
303
        });
304
        Map<Object, List<String>> propertyPathMap =
305
                new HashMap<Object, List<String>>();
306
        propertyPathMap.put(TermNode.class,propertyPaths);
307
        return propertyPathMap;
308
    }
309

    
310
    @Override
311
    public List<TermTree> getRootEntities() {
312
        return (List<TermTree>) viewer.getInput();
313
    }
314

    
315
    @Override
316
    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
317
    }
318

    
319
    @Override
320
    public void contextStop(IMemento memento, IProgressMonitor monitor) {
321
        //close view when workbench closes
322
        try{
323
            thisPart.getContext().get(EPartService.class).hidePart(thisPart);
324
        }
325
        catch(Exception e){
326
            //nothing
327
        }
328
    }
329

    
330
    @Override
331
    public void contextStart(IMemento memento, IProgressMonitor monitor) {
332
    }
333

    
334
    @Override
335
    public void contextRefresh(IProgressMonitor monitor) {
336
    }
337

    
338
    @Override
339
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
340
    }
341

    
342
    @Override
343
    public void update(CdmDataChangeMap arg0) {
344
    }
345

    
346
    @Override
347
    public void changed(Object element) {
348
        dirty.setDirty(true);
349
        viewer.refresh();
350
    }
351

    
352
    @Override
353
    public void forceDirty() {
354
        dirty.setDirty(true);
355
    }
356

    
357
    @Override
358
    public boolean postOperation(Object objectAffectedByOperation) {
359
        initializeTrees();
360
        viewer.refresh();
361
        if(objectAffectedByOperation instanceof TermNode){
362
        	TermNode node = (TermNode)objectAffectedByOperation;
363
            viewer.expandToLevel(node.getGraph(), 1);
364
        }
365
        if(objectAffectedByOperation!=null){
366
            StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
367
            viewer.setSelection(selection);
368
        }
369
        return true;
370
    }
371

    
372
    @Override
373
    public boolean onComplete() {
374
        return false;
375
    }
376

    
377
}
(3-3/5)