Merge branch 'develop' into wset
[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.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.core.runtime.NullProgressMonitor;
24 import org.eclipse.e4.ui.di.Focus;
25 import org.eclipse.e4.ui.di.Persist;
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.viewers.ISelectionChangedListener;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.jface.viewers.SelectionChangedEvent;
34 import org.eclipse.jface.viewers.TreeViewer;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.events.ModifyEvent;
37 import org.eclipse.swt.events.ModifyListener;
38 import org.eclipse.swt.events.SelectionAdapter;
39 import org.eclipse.swt.events.SelectionEvent;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.ui.IMemento;
42
43 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
44 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
45 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
46 import eu.etaxonomy.cdm.model.description.FeatureNode;
47 import eu.etaxonomy.cdm.model.description.FeatureTree;
48 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
49 import eu.etaxonomy.taxeditor.model.AbstractUtility;
50 import eu.etaxonomy.taxeditor.model.IContextListener;
51 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
52 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
53 import eu.etaxonomy.taxeditor.model.MessagingUtils;
54 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
55 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
56 import eu.etaxonomy.taxeditor.store.CdmStore;
57 import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
58 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
59 import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
60
61 /**
62 *
63 * @author pplitzner
64 * @date 06.06.2017
65 *
66 */
67 public class FeatureTreeEditor implements ICdmEntitySessionEnabled, ModifyListener, ISelectionChangedListener,
68 IE4ViewerPart, IE4SavablePart, IPartContentHasDetails, IPartContentHasSupplementalData, IContextListener, IConversationEnabled {
69
70 private ConversationHolder conversation;
71
72 private ICdmEntitySession cdmEntitySession;
73
74 @Inject
75 private ESelectionService selService;
76
77 @Inject
78 private MDirtyable dirty;
79
80 private FeatureTreeEditorComposite composite;
81
82 @Inject
83 private MPart thisPart;
84
85 @Inject
86 public FeatureTreeEditor() {
87 CdmStore.getContextManager().addContextListener(this);
88 }
89
90 /** {@inheritDoc} */
91 @PostConstruct
92 public void createControl(Composite parent, EMenuService menuService){
93 if (CdmStore.isActive()){
94 if(conversation == null){
95 conversation = CdmStore.createConversation();
96 }
97 if(cdmEntitySession!=null){
98 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
99 }
100 }
101 else{
102 return;
103 }
104 composite = new FeatureTreeEditorComposite(parent, SWT.NULL);
105 composite.init(new FeatureNodeDragListener(composite.getViewer()),
106 new FeatureNodeDropAdapter(dirty, composite.getViewer()), this, new SelectionAdapter() {
107 @Override
108 public void widgetSelected(SelectionEvent e) {
109 if(isDirty()){
110 if(MessagingUtils.confirmDialog("Editor has to be saved", "You have to save before loading another feature tree. Save now?")){
111 save(new NullProgressMonitor());
112 }
113 else{
114 return;
115 }
116
117 }
118 FeatureTree tree = FeatureTreeSelectionDialog.select(composite.getDisplay().getActiveShell(), //conversation,
119 null);
120 if (tree != null) {
121 composite.setSelectedTree(tree, FeatureTreeEditor.this);
122 }
123 }
124 });
125
126 //create context menu
127 menuService.registerContextMenu(composite.getViewer().getControl(), "eu.etaxonomy.taxeditor.store.popupmenu.featureTreeEditor");
128 }
129
130 public void setDirty(boolean isDirty){
131 this.dirty.setDirty(isDirty);
132 }
133
134 public boolean isDirty(){
135 return dirty.isDirty();
136 }
137
138 public FeatureTree getSelectedFeatureTree(){
139 return composite.getFeatureTree();
140 }
141
142 /** {@inheritDoc} */
143 @Override
144 public void modifyText(ModifyEvent e) {
145 composite.getFeatureTree().setTitleCache(composite.getText_title().getText(), true);
146 setDirty(true);
147 }
148
149 /** {@inheritDoc} */
150 @Override
151 public void selectionChanged(SelectionChangedEvent event) {
152 //propagate selection
153 selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event));
154 }
155
156 @Focus
157 public void focus(){
158 if(composite!=null){
159 composite.getViewer().getControl().setFocus();
160 }
161 if(conversation!=null && !conversation.isBound()){
162 conversation.bind();
163 }
164 if(cdmEntitySession != null) {
165 cdmEntitySession.bind();
166 }
167 }
168
169 @Override
170 public void refresh(){
171 composite.getViewer().refresh();
172 }
173
174 public TreeViewer getViewer(){
175 return composite.getViewer();
176 }
177
178 /**
179 * {@inheritDoc}
180 */
181 @Override
182 public IStructuredSelection getSelection() {
183 return (IStructuredSelection) composite.getViewer().getSelection();
184 }
185
186 /**
187 * {@inheritDoc}
188 */
189 @Override
190 public ConversationHolder getConversationHolder() {
191 return conversation;
192 }
193
194 @Override
195 @Persist
196 public void save(IProgressMonitor monitor){
197 if (!conversation.isBound()) {
198 conversation.bind();
199 }
200
201 // commit the conversation and start a new transaction immediately
202 conversation.commit(true);
203
204 CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(composite.getFeatureTree());
205
206 this.setDirty(false);
207 }
208
209 @PreDestroy
210 public void dispose(){
211 if(conversation!=null){
212 conversation.close();
213 conversation = null;
214 }
215 if(cdmEntitySession != null) {
216 cdmEntitySession.dispose();
217 cdmEntitySession = null;
218 }
219 }
220
221 @Override
222 public ICdmEntitySession getCdmEntitySession() {
223 return cdmEntitySession;
224 }
225
226 @Override
227 public Map<Object, List<String>> getPropertyPathsMap() {
228 List<String> propertyPaths = Arrays.asList(new String[] {
229 "children", //$NON-NLS-1$
230 "feature", //$NON-NLS-1$
231 "featureTree", //$NON-NLS-1$
232 });
233 Map<Object, List<String>> propertyPathMap =
234 new HashMap<Object, List<String>>();
235 propertyPathMap.put(FeatureNode.class,propertyPaths);
236 return propertyPathMap;
237 }
238
239 /**
240 * {@inheritDoc}
241 */
242 @Override
243 public List<FeatureTree> getRootEntities() {
244 List<FeatureTree> root = new ArrayList<>();
245 root.add(composite.getFeatureTree());
246 return root;
247 }
248
249 /**
250 * {@inheritDoc}
251 */
252 @Override
253 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
254 }
255
256 /**
257 * {@inheritDoc}
258 */
259 @Override
260 public void contextStop(IMemento memento, IProgressMonitor monitor) {
261 //close view when workbench closes
262 try{
263 thisPart.getContext().get(EPartService.class).hidePart(thisPart);
264 }
265 catch(Exception e){
266 //nothing
267 }
268 }
269
270 /**
271 * {@inheritDoc}
272 */
273 @Override
274 public void contextStart(IMemento memento, IProgressMonitor monitor) {
275 }
276
277 /**
278 * {@inheritDoc}
279 */
280 @Override
281 public void contextRefresh(IProgressMonitor monitor) {
282 }
283
284 /**
285 * {@inheritDoc}
286 */
287 @Override
288 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
289 }
290
291 /**
292 * {@inheritDoc}
293 */
294 @Override
295 public void update(CdmDataChangeMap arg0) {
296 }
297
298 }