ref #7837 Make feature tree export experimental
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / featuretree / e4 / FeatureTreeEditor.java
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.model.application.ui.MDirtyable;
25 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
26 import org.eclipse.e4.ui.services.EMenuService;
27 import org.eclipse.e4.ui.workbench.modeling.EPartService;
28 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
29 import org.eclipse.jface.util.LocalSelectionTransfer;
30 import org.eclipse.jface.viewers.ISelectionChangedListener;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.SelectionChangedEvent;
33 import org.eclipse.jface.viewers.StructuredSelection;
34 import org.eclipse.jface.viewers.TreeViewer;
35 import org.eclipse.swt.dnd.DND;
36 import org.eclipse.swt.dnd.Transfer;
37 import org.eclipse.swt.layout.FillLayout;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.ui.IMemento;
40
41 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
42 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
43 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
44 import eu.etaxonomy.cdm.model.description.FeatureNode;
45 import eu.etaxonomy.cdm.model.description.FeatureTree;
46 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
47 import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
48 import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
49 import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
50 import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
51 import eu.etaxonomy.taxeditor.model.IContextListener;
52 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
53 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
54 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
55 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
56 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
57 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
58 import eu.etaxonomy.taxeditor.store.CdmStore;
59 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
60 import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
61
62 /**
63 *
64 * @author pplitzner
65 * @date 06.06.2017
66 *
67 */
68 public class FeatureTreeEditor implements ICdmEntitySessionEnabled, ISelectionChangedListener,
69 IE4ViewerPart, IE4SavablePart, IPartContentHasDetails, IPartContentHasSupplementalData,
70 IContextListener, IConversationEnabled, IDirtyMarkable, IPostOperationEnabled {
71
72 private ConversationHolder conversation;
73
74 private ICdmEntitySession cdmEntitySession;
75
76 @Inject
77 private ESelectionService selService;
78
79 @Inject
80 private MDirtyable dirty;
81
82 @Inject
83 private MPart thisPart;
84
85 private TreeViewer viewer;
86
87 @Inject
88 public FeatureTreeEditor() {
89 CdmStore.getContextManager().addContextListener(this);
90 }
91
92 @PostConstruct
93 public void createControl(Composite parent, EMenuService menuService){
94 if (CdmStore.isActive()){
95 initSession();
96 }
97 else{
98 return;
99 }
100 parent.setLayout(new FillLayout());
101 viewer = new TreeViewer(parent);
102 viewer.setContentProvider(new FeatureTreeContentProvider());
103 viewer.setLabelProvider(new FeatureTreeLabelProvider());
104
105 int ops = DND.DROP_COPY | DND.DROP_MOVE;
106 Transfer[] transfers = new Transfer[] {
107 FeatureNodeTransfer.getInstance(),
108 TermTransfer.getInstance(),
109 LocalSelectionTransfer.getTransfer()};
110 viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(viewer));
111 viewer.addDropSupport(ops, transfers, new FeatureNodeDropAdapter(dirty, this, viewer));
112 viewer.addSelectionChangedListener(this);
113
114 List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
115 viewer.setInput(trees);
116
117 //create context menu
118 menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.store.popupmenu.featureTreeEditor");
119 }
120
121 private void initSession(){
122 if(conversation == null){
123 conversation = CdmStore.createConversation();
124 }
125 if(cdmEntitySession==null){
126 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
127 }
128 }
129
130 private void clearSession() {
131 if(conversation!=null){
132 conversation.close();
133 conversation = null;
134 }
135 if(cdmEntitySession != null) {
136 cdmEntitySession.dispose();
137 cdmEntitySession = null;
138 }
139 dirty.setDirty(false);
140 }
141
142 public void setDirty(boolean isDirty){
143 this.dirty.setDirty(isDirty);
144 }
145
146 @Override
147 public boolean isDirty(){
148 return dirty.isDirty();
149 }
150
151 @Override
152 public void selectionChanged(SelectionChangedEvent event) {
153 //propagate selection
154 selService.setSelection(event.getSelection());
155 }
156
157 @Focus
158 public void focus(){
159 if(viewer!=null){
160 viewer.getControl().setFocus();
161 }
162 if(conversation!=null && !conversation.isBound()){
163 conversation.bind();
164 }
165 if(cdmEntitySession != null) {
166 cdmEntitySession.bind();
167 }
168 }
169
170 @Override
171 public void refresh(){
172 viewer.refresh();
173 }
174
175 public TreeViewer getViewer(){
176 return viewer;
177 }
178
179 @Override
180 public IStructuredSelection getSelection() {
181 return (IStructuredSelection) viewer.getSelection();
182 }
183
184 @Override
185 public ConversationHolder getConversationHolder() {
186 return conversation;
187 }
188
189 @Override
190 @Persist
191 public void save(IProgressMonitor monitor){
192 if (!conversation.isBound()) {
193 conversation.bind();
194 }
195
196 // commit the conversation and start a new transaction immediately
197 conversation.commit(true);
198
199 CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(getRootEntities());
200
201 initialiseRootEntities();
202
203 this.setDirty(false);
204 }
205
206 private void initialiseRootEntities() {
207 Object[] expandedElements = viewer.getExpandedElements();
208 viewer.getTree().removeAll();
209 List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
210 viewer.setInput(trees);
211 viewer.setExpandedElements(expandedElements);
212 }
213
214 @PreDestroy
215 public void dispose(){
216 selService.setSelection(null);
217 clearSession();
218 }
219
220 @Override
221 public ICdmEntitySession getCdmEntitySession() {
222 return cdmEntitySession;
223 }
224
225 @Override
226 public Map<Object, List<String>> getPropertyPathsMap() {
227 List<String> propertyPaths = Arrays.asList(new String[] {
228 "children", //$NON-NLS-1$
229 "feature", //$NON-NLS-1$
230 "featureTree", //$NON-NLS-1$
231 });
232 Map<Object, List<String>> propertyPathMap =
233 new HashMap<Object, List<String>>();
234 propertyPathMap.put(FeatureNode.class,propertyPaths);
235 return propertyPathMap;
236 }
237
238 @Override
239 public List<FeatureTree> getRootEntities() {
240 return (List<FeatureTree>) viewer.getInput();
241 }
242
243 @Override
244 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
245 }
246
247 @Override
248 public void contextStop(IMemento memento, IProgressMonitor monitor) {
249 //close view when workbench closes
250 try{
251 thisPart.getContext().get(EPartService.class).hidePart(thisPart);
252 }
253 catch(Exception e){
254 //nothing
255 }
256 }
257
258 @Override
259 public void contextStart(IMemento memento, IProgressMonitor monitor) {
260 }
261
262 @Override
263 public void contextRefresh(IProgressMonitor monitor) {
264 }
265
266 @Override
267 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
268 }
269
270 @Override
271 public void update(CdmDataChangeMap arg0) {
272 }
273
274 @Override
275 public void changed(Object element) {
276 dirty.setDirty(true);
277 viewer.refresh();
278 }
279
280 @Override
281 public void forceDirty() {
282 dirty.setDirty(true);
283 }
284
285 @Override
286 public boolean postOperation(Object objectAffectedByOperation) {
287 initialiseRootEntities();
288 viewer.refresh();
289 if(objectAffectedByOperation instanceof FeatureNode){
290 FeatureNode node = (FeatureNode)objectAffectedByOperation;
291 viewer.expandToLevel(node.getFeatureTree(), 1);
292 StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
293 viewer.setSelection(selection);
294 }
295 return true;
296 }
297
298 @Override
299 public boolean onComplete() {
300 return false;
301 }
302
303 }