ref #6762 Use FeatureTreeEditorComposite for all tree viewers
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / workingSet / CharacterEditor.java
1 // $Id$
2 /**
3 * Copyright (C) 2017 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.taxeditor.editor.workingSet;
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 import javax.inject.Named;
22
23 import org.eclipse.e4.core.di.annotations.Optional;
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.services.IServiceConstants;
28 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
29 import org.eclipse.jface.viewers.ISelection;
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.TreeSelection;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.custom.SashForm;
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.layout.GridData;
41 import org.eclipse.swt.layout.GridLayout;
42 import org.eclipse.swt.widgets.Button;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Display;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.Shell;
47 import org.eclipse.ui.forms.widgets.FormToolkit;
48
49 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
51 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
52 import eu.etaxonomy.cdm.model.description.Character;
53 import eu.etaxonomy.cdm.model.description.FeatureNode;
54 import eu.etaxonomy.cdm.model.description.FeatureTree;
55 import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDragListener;
56 import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDropAdapter;
57 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
58 import eu.etaxonomy.taxeditor.model.MessagingUtils;
59 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
60 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
61 import eu.etaxonomy.taxeditor.store.CdmStore;
62 import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
63
64 /**
65 * @author pplitzner
66 * @date 24.05.2017
67 *
68 */
69 public class CharacterEditor implements ICdmEntitySessionEnabled, ISelectionChangedListener, ModifyListener{
70
71
72 private FeatureTreeEditorComposite characterTreeEditorComposite;
73 private FeatureTreeEditorComposite treeViewerProperties;
74 private FeatureTreeEditorComposite treeViewerStructures;
75 private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
76 private Button btnAddCharacter;
77
78 @Inject
79 private ESelectionService selService;
80
81 @Inject
82 private MDirtyable dirty;
83
84 private Shell shell;
85
86 private ConversationHolder conversation;
87
88 private ICdmEntitySession cdmEntitySession;
89
90 public CharacterEditor() {
91 }
92
93 /**
94 * Create contents of the view part.
95 */
96 @PostConstruct
97 public void createControls(Composite parent) {
98 if (CdmStore.isActive()){
99 if(conversation == null){
100 conversation = CdmStore.createConversation();
101 }
102 if(cdmEntitySession!=null){
103 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
104 }
105 }
106 else{
107 return;
108 }
109 parent.setLayout(new GridLayout(1, false));
110
111 SashForm sashForm = new SashForm(parent, SWT.NONE);
112 sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
113 formToolkit.adapt(sashForm);
114 formToolkit.paintBordersFor(sashForm);
115
116 Composite composite = new Composite(sashForm, SWT.NONE);
117 formToolkit.adapt(composite);
118 formToolkit.paintBordersFor(composite);
119 composite.setLayout(new GridLayout(1, false));
120
121 Label lblNewLabel = new Label(composite, SWT.NONE);
122 lblNewLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
123 formToolkit.adapt(lblNewLabel, true, true);
124 lblNewLabel.setText("Structures");
125
126 treeViewerStructures = addFeatureTreeEditor(composite);
127 initFeatureTreeComposite(treeViewerStructures, null, null);
128
129 Composite composite_1 = new Composite(sashForm, SWT.NONE);
130 formToolkit.adapt(composite_1);
131 formToolkit.paintBordersFor(composite_1);
132 composite_1.setLayout(new GridLayout(1, false));
133
134 Label lblNewLabel_1 = new Label(composite_1, SWT.NONE);
135 lblNewLabel_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
136 formToolkit.adapt(lblNewLabel_1, true, true);
137 lblNewLabel_1.setText("Properties");
138
139 treeViewerProperties = addFeatureTreeEditor(composite_1);
140 initFeatureTreeComposite(treeViewerProperties, new CharacterDragListener(treeViewerStructures.getViewer(), treeViewerProperties.getViewer()), null);
141
142 Composite composite_2 = new Composite(sashForm, SWT.NONE);
143 formToolkit.adapt(composite_2);
144 formToolkit.paintBordersFor(composite_2);
145 composite_2.setLayout(new GridLayout(1, false));
146
147 btnAddCharacter = new Button(composite_2, SWT.NONE);
148 btnAddCharacter.setText(">>");
149 btnAddCharacter.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true, 1, 1));
150 formToolkit.adapt(btnAddCharacter, true, true);
151
152 Composite composite_3 = new Composite(sashForm, SWT.NONE);
153 formToolkit.adapt(composite_3);
154 formToolkit.paintBordersFor(composite_3);
155 composite_3.setLayout(new GridLayout(1, false));
156
157 characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
158 initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new FeatureNodeDropAdapter(characterTreeEditorComposite.getViewer()));
159
160 sashForm.setWeights(new int[] {3, 3, 1, 3});
161
162 init();
163 }
164
165 private FeatureTreeEditorComposite addFeatureTreeEditor(Composite composite_3) {
166 FeatureTreeEditorComposite featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.BORDER);
167 featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
168 featureTreeEditorComposite.getButton_add().setVisible(false);
169 featureTreeEditorComposite.getButton_remove().setVisible(false);
170 return featureTreeEditorComposite;
171 }
172
173 private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
174 FeatureNodeDragListener featureNodeDragListener, FeatureNodeDropAdapter featureNodeDropAdapter) {
175 featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
176 new FeatureTreeChooserListener(featureTreeEditorComposite), new SelectionAdapter() {
177 }, new SelectionAdapter() {
178 });
179 }
180
181 @Focus
182 public void focus(@Optional@Named(IServiceConstants.ACTIVE_SHELL)Shell shell){
183 this.shell = shell;
184 if(characterTreeEditorComposite!=null){
185 characterTreeEditorComposite.getViewer().getControl().setFocus();
186 }
187 if(conversation!=null && !conversation.isBound()){
188 conversation.bind();
189 }
190 if(cdmEntitySession != null) {
191 cdmEntitySession.bind();
192 }
193 }
194
195 private void init(){
196 btnAddCharacter.addSelectionListener(new SelectionAdapter() {
197 /**
198 * {@inheritDoc}
199 */
200 @Override
201 public void widgetSelected(SelectionEvent e) {
202 ISelection structureTreeSelection = treeViewerStructures.getViewer().getSelection();
203 ISelection propertyTreeSelection = treeViewerProperties.getViewer().getSelection();
204 if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
205 MessagingUtils.warningDialog("Cannot perform action", CharacterEditor.this,
206 "You have to select a structure, a property and a feature tree to perform this action.");
207 return;
208 }
209 //get selected structure and property
210 FeatureNode structureNode = (FeatureNode) ((TreeSelection)structureTreeSelection).getFirstElement();
211 FeatureNode propertyNode = (FeatureNode) ((TreeSelection)propertyTreeSelection).getFirstElement();
212 //create new Character
213 String label = structureNode.getFeature().toString()+" "+propertyNode.getFeature().toString();
214 Character character = Character.NewInstance(structureNode, propertyNode, null, label, label);
215
216 //add new Character to feature tree
217 FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
218 CdmStore.getService(IFeatureNodeService.class).addChildFeaturNode(parent.getUuid(), character.getUuid());
219
220 setDirty(true);
221 characterTreeEditorComposite.getViewer().refresh();
222 }
223 });
224 }
225
226 @Persist
227 public void save(){
228 if (!conversation.isBound()) {
229 conversation.bind();
230 }
231
232 // commit the conversation and start a new transaction immediately
233 conversation.commit(true);
234
235 CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(characterTreeEditorComposite.getFeatureTree());
236
237 this.setDirty(false);
238 }
239
240 @PreDestroy
241 public void dispose(){
242 if(conversation!=null){
243 conversation.close();
244 }
245 if(cdmEntitySession != null) {
246 cdmEntitySession.dispose();
247 }
248 }
249
250 @Override
251 public Map<Object, List<String>> getPropertyPathsMap() {
252 List<String> propertyPaths = Arrays.asList(new String[] {
253 "children", //$NON-NLS-1$
254 "feature", //$NON-NLS-1$
255 "featureTree", //$NON-NLS-1$
256 });
257 Map<Object, List<String>> propertyPathMap =
258 new HashMap<Object, List<String>>();
259 propertyPathMap.put(FeatureNode.class,propertyPaths);
260 return propertyPathMap;
261 }
262
263 /**
264 * {@inheritDoc}
265 */
266 @Override
267 public List<FeatureTree> getRootEntities() {
268 List<FeatureTree> root = new ArrayList<>();
269 root.add(characterTreeEditorComposite.getFeatureTree());
270 return root;
271 }
272
273 @Override
274 public ICdmEntitySession getCdmEntitySession() {
275 return cdmEntitySession;
276 }
277
278 @Focus
279 public void setFocus() {
280 if(conversation!=null && !conversation.isBound()){
281 conversation.bind();
282 }
283 }
284
285 /**
286 * {@inheritDoc}
287 */
288 @Override
289 public void selectionChanged(SelectionChangedEvent event) {
290 //propagate selection
291 IStructuredSelection isel = (IStructuredSelection) event.getSelection();
292 selService.setSelection((isel.size() == 1 ? isel.getFirstElement() : isel.toArray()));
293 }
294
295
296 /**
297 * {@inheritDoc}
298 */
299 @Override
300 public void modifyText(ModifyEvent e) {
301 characterTreeEditorComposite.getFeatureTree().setTitleCache(characterTreeEditorComposite.getText_title().getText(), true);
302 setDirty(true);
303 }
304
305
306 public void setDirty(boolean isDirty) {
307 dirty.setDirty(isDirty);
308 }
309
310 private class FeatureTreeChooserListener extends SelectionAdapter{
311 FeatureTreeEditorComposite featureTreeEditorComposite;
312
313 public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
314 super();
315 this.featureTreeEditorComposite = featureTreeEditorComposite;
316 }
317
318 @Override
319 public void widgetSelected(SelectionEvent e) {
320 FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
321 if(tree!=null){
322 featureTreeEditorComposite.setSelectedTree(tree, CharacterEditor.this);
323 }
324 }
325 }
326
327 }