ref #6596 Keep track of active "editor"
[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.Collection;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 import javax.annotation.PostConstruct;
20 import javax.annotation.PreDestroy;
21 import javax.inject.Inject;
22 import javax.inject.Named;
23
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.e4.ui.di.Focus;
26 import org.eclipse.e4.ui.di.Persist;
27 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
28 import org.eclipse.e4.ui.services.IServiceConstants;
29 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
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.wizard.WizardDialog;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.ModifyEvent;
36 import org.eclipse.swt.events.ModifyListener;
37 import org.eclipse.swt.events.SelectionAdapter;
38 import org.eclipse.swt.events.SelectionEvent;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Shell;
41
42 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
43 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
44 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
45 import eu.etaxonomy.cdm.api.service.config.FeatureNodeDeletionConfigurator;
46 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
47 import eu.etaxonomy.cdm.model.description.Feature;
48 import eu.etaxonomy.cdm.model.description.FeatureNode;
49 import eu.etaxonomy.cdm.model.description.FeatureTree;
50 import eu.etaxonomy.taxeditor.featuretree.AvailableFeaturesWizard;
51 import eu.etaxonomy.taxeditor.model.AbstractUtility;
52 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
53 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
54 import eu.etaxonomy.taxeditor.store.CdmStore;
55 import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
56
57 /**
58 *
59 * @author pplitzner
60 * @date 06.06.2017
61 *
62 */
63 public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
64 ModifyListener, ISelectionChangedListener {
65
66 private ConversationHolder conversation;
67
68 private ICdmEntitySession cdmEntitySession;
69
70 @Inject
71 private ESelectionService selService;
72
73 @Inject
74 private MDirtyable dirty;
75
76 private Shell shell;
77
78 private FeatureTree featureTree;
79
80 private FeatureTreeEditorComposite composite;
81
82 @Inject
83 public FeatureTreeEditor(@Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
84 this.shell = shell;
85 if(conversation==null){
86 conversation = CdmStore.createConversation();
87 }
88 if (CdmStore.isActive()) {
89 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
90 }
91 }
92
93 /** {@inheritDoc} */
94 @PostConstruct
95 public void createControl(Composite parent, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
96 composite = new FeatureTreeEditorComposite(parent, SWT.NULL);
97 composite.init(new FeatureNodeDragListener(composite.getViewer()), new FeatureNodeDropAdapter(this, composite.getViewer()), this, new SelectionAdapter() {
98 @Override
99 public void widgetSelected(SelectionEvent e) {
100 FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
101 if(tree!=null){
102 setSelectedTree(tree);
103 }
104 }
105 }, new AddButtonListener(), new RemoveSelectionListener());
106 composite.getText_title().setEnabled(false);
107 }
108
109 public void setDirty(boolean isDirty){
110 this.dirty.setDirty(isDirty);
111 }
112
113 public boolean isDirty(){
114 return dirty.isDirty();
115 }
116
117 public void setSelectedTree(FeatureTree featureTree) {
118 this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
119 this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
120 composite.getViewer().setInput(featureTree);
121
122 composite.getText_title().setEnabled(true);
123 composite.getText_title().removeModifyListener(this);
124 composite.getText_title().setText(featureTree.getTitleCache());
125 composite.getText_title().addModifyListener(this);
126 }
127
128 /** {@inheritDoc} */
129 @Override
130 public void modifyText(ModifyEvent e) {
131 featureTree.setTitleCache(composite.getText_title().getText(), true);
132 setDirty(true);
133 }
134
135 /** {@inheritDoc} */
136 @Override
137 public void selectionChanged(SelectionChangedEvent event) {
138 IStructuredSelection selection = (IStructuredSelection) event
139 .getSelection();
140
141 composite.getButton_add().setEnabled(selection.size() <= 1);
142 composite.getButton_remove().setEnabled(selection.size() > 0);
143 //propagate selection
144 selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event));
145 }
146
147 @Focus
148 public void focus(){
149 composite.getViewer().getControl().setFocus();
150 if(conversation!=null && !conversation.isBound()){
151 conversation.bind();
152 }
153 if(cdmEntitySession != null) {
154 cdmEntitySession.bind();
155 }
156 }
157
158 @Persist
159 public void save(){
160 if (!conversation.isBound()) {
161 conversation.bind();
162 }
163
164 // commit the conversation and start a new transaction immediately
165 conversation.commit(true);
166
167 CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
168
169 this.setDirty(false);
170 }
171
172 @PreDestroy
173 public void dispose(){
174 if(conversation!=null){
175 conversation.close();
176 }
177 if(cdmEntitySession != null) {
178 cdmEntitySession.dispose();
179 }
180 }
181
182 @Override
183 public ICdmEntitySession getCdmEntitySession() {
184 return cdmEntitySession;
185 }
186
187 @Override
188 public Map<Object, List<String>> getPropertyPathsMap() {
189 List<String> propertyPaths = Arrays.asList(new String[] {
190 "children", //$NON-NLS-1$
191 "feature", //$NON-NLS-1$
192 "featureTree", //$NON-NLS-1$
193 });
194 Map<Object, List<String>> propertyPathMap =
195 new HashMap<Object, List<String>>();
196 propertyPathMap.put(FeatureNode.class,propertyPaths);
197 return propertyPathMap;
198 }
199
200 /**
201 * {@inheritDoc}
202 */
203 @Override
204 public List<FeatureTree> getRootEntities() {
205 List<FeatureTree> root = new ArrayList<>();
206 root.add(featureTree);
207 return root;
208 }
209
210 private class AddButtonListener extends SelectionAdapter {
211 @Override
212 public void widgetSelected(SelectionEvent e) {
213 AvailableFeaturesWizard wizard = new AvailableFeaturesWizard(
214 featureTree);
215 WizardDialog dialog = new WizardDialog(shell, wizard);
216
217 if (dialog.open() == IStatus.OK) {
218 FeatureNode parent = ((FeatureTree) composite.getViewer().getInput()).getRoot();
219 Collection<Feature> additionalFeatures = wizard.getAdditionalFeatures();
220 for (Feature feature : additionalFeatures) {
221 CdmStore.getService(IFeatureNodeService.class).addChildFeaturNode(parent, feature);
222 }
223 setDirty(true);
224 composite.getViewer().refresh();
225 composite.getViewer().expandToLevel(parent, 1);
226 }
227 }
228
229 }
230
231 private class RemoveSelectionListener extends SelectionAdapter {
232 @Override
233 public void widgetSelected(SelectionEvent e) {
234 IStructuredSelection selection = (IStructuredSelection) composite.getViewer()
235 .getSelection();
236
237 for (Object selectedObject : selection.toArray()) {
238 FeatureNode featureNode = (FeatureNode) selectedObject;
239 CdmStore.getService(IFeatureNodeService.class).deleteFeatureNode(featureNode.getUuid(), new FeatureNodeDeletionConfigurator());
240
241 }
242 setDirty(true);
243 composite.getViewer().refresh();
244 }
245 }
246 }