adcee70c07420756c7dc64e640aba06c882962c4
[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.session.ICdmEntitySession;
52 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
53 import eu.etaxonomy.taxeditor.store.CdmStore;
54 import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
55
56 /**
57 *
58 * @author pplitzner
59 * @date 06.06.2017
60 *
61 */
62 public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
63 ModifyListener, ISelectionChangedListener {
64
65 private ConversationHolder conversation;
66
67 private ICdmEntitySession cdmEntitySession;
68
69 @Inject
70 private ESelectionService selService;
71
72 @Inject
73 private MDirtyable dirty;
74
75 private Shell shell;
76
77 private FeatureTree featureTree;
78
79 private FeatureTreeEditorComposite composite;
80
81 @Inject
82 public FeatureTreeEditor(@Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
83 this.shell = shell;
84 if(conversation==null){
85 conversation = CdmStore.createConversation();
86 }
87 if (CdmStore.isActive()) {
88 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
89 }
90 }
91
92 /** {@inheritDoc} */
93 @PostConstruct
94 public void createControl(Composite parent, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
95 composite = new FeatureTreeEditorComposite(parent, SWT.NULL);
96 composite.init(new FeatureNodeDragListener(composite.getViewer()), new FeatureNodeDropAdapter(this, composite.getViewer()), this, new SelectionAdapter() {
97 @Override
98 public void widgetSelected(SelectionEvent e) {
99 FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
100 if(tree!=null){
101 setSelectedTree(tree);
102 }
103 }
104 }, new AddButtonListener(), new RemoveSelectionListener());
105 composite.getText_title().setEnabled(false);
106 }
107
108 public void setDirty(boolean isDirty){
109 this.dirty.setDirty(isDirty);
110 }
111
112 public boolean isDirty(){
113 return dirty.isDirty();
114 }
115
116 public void setSelectedTree(FeatureTree featureTree) {
117 this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
118 this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
119 composite.getViewer().setInput(featureTree);
120
121 composite.getText_title().setEnabled(true);
122 composite.getText_title().removeModifyListener(this);
123 composite.getText_title().setText(featureTree.getTitleCache());
124 composite.getText_title().addModifyListener(this);
125 }
126
127 /** {@inheritDoc} */
128 @Override
129 public void modifyText(ModifyEvent e) {
130 featureTree.setTitleCache(composite.getText_title().getText(), true);
131 setDirty(true);
132 }
133
134 /** {@inheritDoc} */
135 @Override
136 public void selectionChanged(SelectionChangedEvent event) {
137 IStructuredSelection selection = (IStructuredSelection) event
138 .getSelection();
139
140 composite.getButton_add().setEnabled(selection.size() <= 1);
141 composite.getButton_remove().setEnabled(selection.size() > 0);
142 //propagate selection
143 IStructuredSelection isel = (IStructuredSelection) event.getSelection();
144 selService.setSelection((isel.size() == 1 ? isel.getFirstElement() : isel.toArray()));
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 }