Merge branch 'develop' into featureTreeEditor
[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 public FeatureTree getSelectedFeatureTree(){
129 return this.featureTree;
130 }
131
132 /** {@inheritDoc} */
133 @Override
134 public void modifyText(ModifyEvent e) {
135 featureTree.setTitleCache(composite.getText_title().getText(), true);
136 setDirty(true);
137 }
138
139 /** {@inheritDoc} */
140 @Override
141 public void selectionChanged(SelectionChangedEvent event) {
142 IStructuredSelection selection = (IStructuredSelection) event
143 .getSelection();
144
145 composite.getButton_add().setEnabled(selection.size() <= 1);
146 composite.getButton_remove().setEnabled(selection.size() > 0);
147 //propagate selection
148 selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event));
149 }
150
151 @Focus
152 public void focus(){
153 composite.getViewer().getControl().setFocus();
154 if(conversation!=null && !conversation.isBound()){
155 conversation.bind();
156 }
157 if(cdmEntitySession != null) {
158 cdmEntitySession.bind();
159 }
160 }
161
162 @Persist
163 public void save(){
164 if (!conversation.isBound()) {
165 conversation.bind();
166 }
167
168 // commit the conversation and start a new transaction immediately
169 conversation.commit(true);
170
171 CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
172
173 this.setDirty(false);
174 }
175
176 @PreDestroy
177 public void dispose(){
178 if(conversation!=null){
179 conversation.close();
180 }
181 if(cdmEntitySession != null) {
182 cdmEntitySession.dispose();
183 }
184 }
185
186 @Override
187 public ICdmEntitySession getCdmEntitySession() {
188 return cdmEntitySession;
189 }
190
191 @Override
192 public Map<Object, List<String>> getPropertyPathsMap() {
193 List<String> propertyPaths = Arrays.asList(new String[] {
194 "children", //$NON-NLS-1$
195 "feature", //$NON-NLS-1$
196 "featureTree", //$NON-NLS-1$
197 });
198 Map<Object, List<String>> propertyPathMap =
199 new HashMap<Object, List<String>>();
200 propertyPathMap.put(FeatureNode.class,propertyPaths);
201 return propertyPathMap;
202 }
203
204 /**
205 * {@inheritDoc}
206 */
207 @Override
208 public List<FeatureTree> getRootEntities() {
209 List<FeatureTree> root = new ArrayList<>();
210 root.add(featureTree);
211 return root;
212 }
213
214 private class AddButtonListener extends SelectionAdapter {
215 @Override
216 public void widgetSelected(SelectionEvent e) {
217 AvailableFeaturesWizard wizard = new AvailableFeaturesWizard(
218 featureTree);
219 WizardDialog dialog = new WizardDialog(shell, wizard);
220
221 if (dialog.open() == IStatus.OK) {
222 FeatureNode parent = ((FeatureTree) composite.getViewer().getInput()).getRoot();
223 Collection<Feature> additionalFeatures = wizard.getAdditionalFeatures();
224 for (Feature feature : additionalFeatures) {
225 CdmStore.getService(IFeatureNodeService.class).addChildFeaturNode(parent, feature);
226 }
227 setDirty(true);
228 composite.getViewer().refresh();
229 composite.getViewer().expandToLevel(parent, 1);
230 }
231 }
232
233 }
234
235 private class RemoveSelectionListener extends SelectionAdapter {
236 @Override
237 public void widgetSelected(SelectionEvent e) {
238 IStructuredSelection selection = (IStructuredSelection) composite.getViewer()
239 .getSelection();
240
241 for (Object selectedObject : selection.toArray()) {
242 FeatureNode featureNode = (FeatureNode) selectedObject;
243 CdmStore.getService(IFeatureNodeService.class).deleteFeatureNode(featureNode.getUuid(), new FeatureNodeDeletionConfigurator());
244
245 }
246 setDirty(true);
247 composite.getViewer().refresh();
248 }
249 }
250 }