Project

General

Profile

Download (9.51 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.ArrayList;
13
import java.util.Arrays;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17

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

    
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.e4.ui.di.Focus;
24
import org.eclipse.e4.ui.di.Persist;
25
import org.eclipse.e4.ui.di.UISynchronize;
26
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
27
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
28
import org.eclipse.e4.ui.services.EMenuService;
29
import org.eclipse.e4.ui.workbench.modeling.EPartService;
30
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
31
import org.eclipse.jface.util.LocalSelectionTransfer;
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.TreeViewer;
36
import org.eclipse.swt.dnd.DND;
37
import org.eclipse.swt.dnd.Transfer;
38
import org.eclipse.swt.layout.FillLayout;
39
import org.eclipse.swt.widgets.Composite;
40
import org.eclipse.ui.IMemento;
41

    
42
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
43
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
44
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
45
import eu.etaxonomy.cdm.model.description.FeatureNode;
46
import eu.etaxonomy.cdm.model.description.FeatureTree;
47
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
48
import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
49
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
50
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
51
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
52
import eu.etaxonomy.taxeditor.model.AbstractUtility;
53
import eu.etaxonomy.taxeditor.model.IContextListener;
54
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
55
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
56
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
57
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
58
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
59
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
60
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
61
import eu.etaxonomy.taxeditor.store.CdmStore;
62
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
63
import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
64

    
65
/**
66
 *
67
 * @author pplitzner
68
 * @date 06.06.2017
69
 *
70
 */
71
public class FeatureTreeEditor implements ICdmEntitySessionEnabled, ISelectionChangedListener,
72
        IE4ViewerPart, IE4SavablePart, IPartContentHasDetails, IPartContentHasSupplementalData,
73
        IContextListener, IConversationEnabled, IDirtyMarkable, IPostOperationEnabled {
74

    
75
    private ConversationHolder conversation;
76

    
77
    private ICdmEntitySession cdmEntitySession;
78

    
79
    @Inject
80
    private ESelectionService selService;
81

    
82
    @Inject
83
    private MDirtyable dirty;
84

    
85
    @Inject
86
    private MPart thisPart;
87

    
88
    @Inject
89
    private UISynchronize sync;
90

    
91
    private TreeViewer viewer;
92

    
93
    private List<AbstractPostOperation> operations = new ArrayList<>();
94

    
95
    @Inject
96
    public FeatureTreeEditor() {
97
        CdmStore.getContextManager().addContextListener(this);
98
    }
99

    
100
	/** {@inheritDoc} */
101
    @PostConstruct
102
    public void createControl(Composite parent, EMenuService menuService){
103
        if (CdmStore.isActive()){
104
            initSession();
105
        }
106
        else{
107
            return;
108
        }
109
        parent.setLayout(new FillLayout());
110
        viewer = new TreeViewer(parent);
111
        viewer.setContentProvider(new FeatureTreeContentProvider());
112
        viewer.setLabelProvider(new FeatureTreeLabelProvider());
113

    
114
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
115
        Transfer[] transfers = new Transfer[] {
116
                FeatureNodeTransfer.getInstance(),
117
                TermTransfer.getInstance(),
118
                LocalSelectionTransfer.getTransfer()};
119
        viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(viewer));
120
        viewer.addDropSupport(ops, transfers, new FeatureNodeDropAdapter(dirty, this, viewer));
121
        viewer.addSelectionChangedListener(this);
122

    
123
        List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
124
        viewer.setInput(trees);
125

    
126
        //create context menu
127
        menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.store.popupmenu.featureTreeEditor");
128
    }
129

    
130
    private void initSession(){
131
        if(conversation == null){
132
            conversation = CdmStore.createConversation();
133
        }
134
        if(cdmEntitySession==null){
135
            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
136
        }
137
    }
138

    
139
    private void clearSession() {
140
        if(conversation!=null){
141
            conversation.close();
142
            conversation = null;
143
        }
144
        if(cdmEntitySession != null) {
145
            cdmEntitySession.dispose();
146
            cdmEntitySession = null;
147
        }
148
        dirty.setDirty(false);
149
    }
150

    
151
	public void setDirty(boolean isDirty){
152
	    this.dirty.setDirty(isDirty);
153
	}
154

    
155
	public boolean isDirty(){
156
	    return dirty.isDirty();
157
	}
158

    
159
	public void addOperation(AbstractPostOperation operation){
160
	    operations.add(operation);
161
	}
162

    
163
	/** {@inheritDoc} */
164
	@Override
165
	public void selectionChanged(SelectionChangedEvent event) {
166
		//propagate selection
167
		selService.setSelection(event.getSelection());
168
	}
169

    
170
	@Focus
171
	public void focus(){
172
	    if(viewer!=null){
173
	        viewer.getControl().setFocus();
174
	    }
175
        if(conversation!=null && !conversation.isBound()){
176
            conversation.bind();
177
        }
178
        if(cdmEntitySession != null) {
179
            cdmEntitySession.bind();
180
        }
181
	}
182

    
183
	@Override
184
    public void refresh(){
185
	    viewer.refresh();
186
	}
187

    
188
	public TreeViewer getViewer(){
189
	    return viewer;
190
	}
191

    
192
	/**
193
	 * {@inheritDoc}
194
	 */
195
	@Override
196
	public IStructuredSelection getSelection() {
197
	    return (IStructuredSelection) viewer.getSelection();
198
	}
199

    
200
	/**
201
	 * {@inheritDoc}
202
	 */
203
	@Override
204
	public ConversationHolder getConversationHolder() {
205
	    return conversation;
206
	}
207

    
208
	@Override
209
    @Persist
210
	public void save(IProgressMonitor monitor){
211
        if (!conversation.isBound()) {
212
            conversation.bind();
213
        }
214

    
215
        // commit the conversation and start a new transaction immediately
216
        conversation.commit(true);
217
        operations.forEach(operation->AbstractUtility.executeOperation(operation, sync));
218
        operations.clear();
219

    
220
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(getRootEntities());
221

    
222
        /*
223
         * reload feature trees is needed to update i.e.
224
         * temporarily created feature nodes by adding features.
225
         * This is related to the current saving strategy which
226
         * emulates all changes on the visible feature tree but
227
         * the actual change is done when saving via executeOperation()
228
         */
229
        Object[] expandedElements = viewer.getExpandedElements();
230
        viewer.getTree().removeAll();
231
        List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
232
        viewer.setInput(trees);
233
        viewer.setExpandedElements(expandedElements);
234

    
235
        this.setDirty(false);
236
	}
237

    
238
	@PreDestroy
239
	public void dispose(){
240
	    selService.setSelection(null);
241
	    clearSession();
242
	}
243

    
244
    @Override
245
    public ICdmEntitySession getCdmEntitySession() {
246
        return cdmEntitySession;
247
    }
248

    
249
    @Override
250
    public Map<Object, List<String>> getPropertyPathsMap() {
251
        List<String> propertyPaths = Arrays.asList(new String[] {
252
                "children", //$NON-NLS-1$
253
                "feature", //$NON-NLS-1$
254
                "featureTree", //$NON-NLS-1$
255
        });
256
        Map<Object, List<String>> propertyPathMap =
257
                new HashMap<Object, List<String>>();
258
        propertyPathMap.put(FeatureNode.class,propertyPaths);
259
        return propertyPathMap;
260
    }
261

    
262
    @Override
263
    public List<FeatureTree> getRootEntities() {
264
        return (List<FeatureTree>) viewer.getInput();
265
    }
266

    
267
    @Override
268
    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
269
    }
270

    
271
    @Override
272
    public void contextStop(IMemento memento, IProgressMonitor monitor) {
273
        //close view when workbench closes
274
        try{
275
            thisPart.getContext().get(EPartService.class).hidePart(thisPart);
276
        }
277
        catch(Exception e){
278
            //nothing
279
        }
280
    }
281

    
282
    @Override
283
    public void contextStart(IMemento memento, IProgressMonitor monitor) {
284
    }
285

    
286
    @Override
287
    public void contextRefresh(IProgressMonitor monitor) {
288
    }
289

    
290
    @Override
291
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
292
    }
293

    
294
    @Override
295
    public void update(CdmDataChangeMap arg0) {
296
    }
297

    
298
    @Override
299
    public void changed(Object element) {
300
        dirty.setDirty(true);
301
        viewer.refresh();
302
    }
303

    
304
    @Override
305
    public void forceDirty() {
306
        dirty.setDirty(true);
307
    }
308

    
309
    /**
310
     * {@inheritDoc}
311
     */
312
    @Override
313
    public boolean postOperation(Object objectAffectedByOperation) {
314
        return false;
315
    }
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
321
    public boolean onComplete() {
322
        return false;
323
    }
324

    
325
}
(3-3/4)