Project

General

Profile

Download (14.6 KB) Statistics
| Branch: | Tag: | Revision:
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.descriptiveDataSet.character;
11

    
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.HashMap;
15
import java.util.Iterator;
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

    
23
import org.eclipse.core.runtime.IProgressMonitor;
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.EMenuService;
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.TreePath;
34
import org.eclipse.jface.viewers.TreeSelection;
35
import org.eclipse.swt.SWT;
36
import org.eclipse.swt.custom.SashForm;
37
import org.eclipse.swt.events.ModifyEvent;
38
import org.eclipse.swt.events.ModifyListener;
39
import org.eclipse.swt.events.SelectionAdapter;
40
import org.eclipse.swt.events.SelectionEvent;
41
import org.eclipse.swt.layout.GridData;
42
import org.eclipse.swt.layout.GridLayout;
43
import org.eclipse.swt.widgets.Button;
44
import org.eclipse.swt.widgets.Composite;
45
import org.eclipse.swt.widgets.Display;
46
import org.eclipse.swt.widgets.Text;
47
import org.eclipse.ui.forms.widgets.FormToolkit;
48

    
49
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
51
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
52
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
53
import eu.etaxonomy.cdm.api.service.ITermService;
54
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
55
import eu.etaxonomy.cdm.model.description.Character;
56
import eu.etaxonomy.cdm.model.description.FeatureNode;
57
import eu.etaxonomy.cdm.model.description.FeatureTree;
58
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
59
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
60
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
61
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
62
import eu.etaxonomy.taxeditor.model.AbstractUtility;
63
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
64
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
66
import eu.etaxonomy.taxeditor.model.MessagingUtils;
67
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
68
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
69
import eu.etaxonomy.taxeditor.store.CdmStore;
70
import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
71
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
72
import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
73

    
74
/**
75
 * @author pplitzner
76
 * @date 24.05.2017
77
 *
78
 */
79
public class CharacterEditor implements ICdmEntitySessionEnabled, IConversationEnabled, ISelectionChangedListener,
80
        ModifyListener, IE4ViewerPart, IPartContentHasDetails, IPartContentHasSupplementalData, IE4SavablePart,
81
        IDirtyMarkable {
82

    
83
    private FeatureTreeEditorComposite characterTreeEditorComposite;
84
    private FeatureTreeEditorComposite propertiesTreeEditorComposite;
85
    private FeatureTreeEditorComposite structuresTreeEditorComposite;
86
    private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
87
    private Button btnAddCharacter;
88

    
89
    @Inject
90
    private ESelectionService selService;
91

    
92
    @Inject
93
    private MDirtyable dirty;
94

    
95
    private ConversationHolder conversation;
96

    
97
    private ICdmEntitySession cdmEntitySession;
98
    private Composite composite;
99

    
100
    public CharacterEditor() {
101
    }
102

    
103
    /**
104
     * Create contents of the view part.
105
     */
106
    @PostConstruct
107
    public void createControls(Composite parent, EMenuService menuService ) {
108
        if (CdmStore.isActive()){
109
            if(conversation == null){
110
                conversation = CdmStore.createConversation();
111
            }
112
            if(cdmEntitySession!=null){
113
                cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
114
            }
115
        }
116
        else{
117
            return;
118
        }
119
        parent.setLayout(new GridLayout(1, false));
120

    
121
        SashForm sashForm = new SashForm(parent, SWT.NONE);
122
        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
123
        formToolkit.adapt(sashForm);
124
        formToolkit.paintBordersFor(sashForm);
125

    
126
        composite = new Composite(sashForm, SWT.NONE);
127
        formToolkit.adapt(composite);
128
        formToolkit.paintBordersFor(composite);
129
        GridLayout gl_composite = new GridLayout(1, false);
130
        gl_composite.marginWidth = 0;
131
        composite.setLayout(gl_composite);
132

    
133
        structuresTreeEditorComposite = addFeatureTreeEditor(composite);
134
        initFeatureTreeComposite(structuresTreeEditorComposite, null, null);
135
        structuresTreeEditorComposite.getLabel_title().setText("Structures");
136

    
137
        Composite composite_1 = new Composite(sashForm, SWT.NONE);
138
        formToolkit.adapt(composite_1);
139
        formToolkit.paintBordersFor(composite_1);
140
        GridLayout gl_composite_1 = new GridLayout(1, false);
141
        gl_composite_1.marginWidth = 0;
142
        composite_1.setLayout(gl_composite_1);
143

    
144
        propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
145
        initFeatureTreeComposite(propertiesTreeEditorComposite, null, null);
146
        propertiesTreeEditorComposite.getLabel_title().setText("Properties");
147
        //TODO: fix drag and drop
148
//        initFeatureTreeComposite(treeViewerProperties, new CharacterDragListener(treeViewerStructures.getViewer(), treeViewerProperties.getViewer()), null);
149

    
150
        Composite composite_3 = new Composite(sashForm, SWT.NONE);
151
        formToolkit.adapt(composite_3);
152
        formToolkit.paintBordersFor(composite_3);
153
        GridLayout gl_composite_3 = new GridLayout(2, false);
154
        gl_composite_3.marginWidth = 0;
155
        composite_3.setLayout(gl_composite_3);
156

    
157
        btnAddCharacter = new Button(composite_3, SWT.NONE);
158
        btnAddCharacter.setText(">>");
159
        formToolkit.adapt(btnAddCharacter, true, true);
160

    
161
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
162
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new FeatureNodeDropAdapter(dirty, characterTreeEditorComposite.getViewer()));
163
        characterTreeEditorComposite.getLabel_title().setText("Characters");
164

    
165
        //add context menu to character viewer//create context menu
166
        menuService.registerContextMenu(characterTreeEditorComposite.getViewer().getControl(), "eu.etaxonomy.taxeditor.editor.popupmenu.characterEditor");
167

    
168
        init();
169
    }
170

    
171
    private FeatureTreeEditorComposite addFeatureTreeEditor(Composite composite_3) {
172
        FeatureTreeEditorComposite featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.NONE);
173
        featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
174
        return featureTreeEditorComposite;
175
    }
176

    
177
    private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
178
            FeatureNodeDragListener featureNodeDragListener, FeatureNodeDropAdapter featureNodeDropAdapter) {
179
        featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
180
                new FeatureTreeChooserListener(featureTreeEditorComposite), this);
181
    }
182

    
183
    @Focus
184
    public void focus(){
185
        if(characterTreeEditorComposite!=null){
186
            characterTreeEditorComposite.getViewer().getControl().setFocus();
187
        }
188
        if(conversation!=null && !conversation.isBound()){
189
            conversation.bind();
190
        }
191
        if(cdmEntitySession != null) {
192
            cdmEntitySession.bind();
193
        }
194
    }
195

    
196
    private void init(){
197
        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
198
            /**
199
             * {@inheritDoc}
200
             */
201
            @Override
202
            public void widgetSelected(SelectionEvent e) {
203
                ISelection structureTreeSelection = structuresTreeEditorComposite.getViewer().getSelection();
204
                ISelection propertyTreeSelection = propertiesTreeEditorComposite.getViewer().getSelection();
205
                if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
206
                    MessagingUtils.warningDialog("Cannot perform action", CharacterEditor.this,
207
                            "You have to select a structure, a property and a feature tree to perform this action.");
208
                    return;
209
                }
210
                //get selected structures and properties
211
                Iterator<FeatureNode> structureIterator = ((TreeSelection)structureTreeSelection).iterator();
212

    
213
                //create all combinations of structures and properties
214
                while(structureIterator.hasNext()){
215
                    FeatureNode structureNode = structureIterator.next();
216
                    Iterator<FeatureNode> propertiesIterator = ((TreeSelection)propertyTreeSelection).iterator();
217
                    while(propertiesIterator.hasNext()){
218
                        FeatureNode propertyNode = propertiesIterator.next();
219
                        //create new Character
220
                        String label = structureNode.getFeature().generateTitle()+" "+propertyNode.getFeature().generateTitle();
221
                        Character character = Character.NewInstance(structureNode, propertyNode, "", label, label);
222
                        character = HibernateProxyHelper.deproxy(CdmStore.getService(ITermService.class).merge(character), Character.class);
223

    
224
                        addCharacterSorted(character);
225
                    }
226
                }
227

    
228
                setDirty();
229
                characterTreeEditorComposite.getViewer().refresh();
230
            }
231
        });
232
    }
233

    
234
    private void addCharacterSorted(Character character){
235
        //add new Character to feature tree
236
        FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
237
        CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(parent.getUuid(), character.getUuid());
238
    }
239

    
240
    @Override
241
    @Persist
242
    public void save(IProgressMonitor monitor){
243
        if (!conversation.isBound()) {
244
            conversation.bind();
245
        }
246

    
247
        // commit the conversation and start a new transaction immediately
248
        conversation.commit(true);
249

    
250
        FeatureTree featureTree = characterTreeEditorComposite.getFeatureTree();
251
        if(featureTree!=null){
252
            //save characters because they can be modified in this editor
253
            featureTree.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
254
        }
255
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
256

    
257

    
258
        dirty.setDirty(false);
259
    }
260

    
261
    @PreDestroy
262
    public void dispose(){
263
        if(conversation!=null){
264
            conversation.close();
265
            conversation = null;
266
        }
267
        if(cdmEntitySession != null) {
268
            cdmEntitySession.dispose();
269
            cdmEntitySession = null;
270
        }
271
        dirty.setDirty(false);
272
    }
273

    
274
    @Override
275
    public Map<Object, List<String>> getPropertyPathsMap() {
276
        List<String> propertyPaths = Arrays.asList(new String[] {
277
                "children", //$NON-NLS-1$
278
                "feature", //$NON-NLS-1$
279
                "featureTree", //$NON-NLS-1$
280
        });
281
        Map<Object, List<String>> propertyPathMap =
282
                new HashMap<Object, List<String>>();
283
        propertyPathMap.put(FeatureNode.class,propertyPaths);
284
        return propertyPathMap;
285
    }
286

    
287
    /**
288
     * {@inheritDoc}
289
     */
290
    @Override
291
    public List<FeatureTree> getRootEntities() {
292
        List<FeatureTree> root = new ArrayList<>();
293
        root.add(characterTreeEditorComposite.getFeatureTree());
294
        return root;
295
    }
296

    
297
    @Override
298
    public ICdmEntitySession getCdmEntitySession() {
299
        return cdmEntitySession;
300
    }
301

    
302
    @Focus
303
    public void setFocus() {
304
        if(conversation!=null && !conversation.isBound()){
305
            conversation.bind();
306
        }
307
    }
308

    
309
    /** {@inheritDoc} */
310
    @Override
311
    public void selectionChanged(SelectionChangedEvent event) {
312
        //propagate selection
313
        selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event));
314
    }
315

    
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
321
    public void modifyText(ModifyEvent e) {
322
        characterTreeEditorComposite.getFeatureTree().setTitleCache(((Text) e.widget).getText(), true);
323
        setDirty();
324
    }
325

    
326

    
327
    private void setDirty() {
328
        dirty.setDirty(true);
329
    }
330

    
331
    /**
332
     * {@inheritDoc}
333
     */
334
    @Override
335
    public IStructuredSelection getSelection() {
336
        return (IStructuredSelection) characterTreeEditorComposite.getViewer().getSelection();
337
    }
338

    
339
    @Override
340
    public void refresh(){
341
        structuresTreeEditorComposite.getViewer().refresh();
342
        propertiesTreeEditorComposite.getViewer().refresh();
343
        characterTreeEditorComposite.getViewer().refresh();
344
    }
345

    
346
    private class FeatureTreeChooserListener extends SelectionAdapter{
347
        FeatureTreeEditorComposite featureTreeEditorComposite;
348

    
349
        public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
350
            super();
351
            this.featureTreeEditorComposite = featureTreeEditorComposite;
352
        }
353

    
354
        @Override
355
        public void widgetSelected(SelectionEvent e) {
356
            FeatureTree tree = FeatureTreeSelectionDialog.select(featureTreeEditorComposite.getDisplay().getActiveShell(), //conversation,
357
                    null);
358
            if(tree!=null){
359
                featureTreeEditorComposite.setSelectedTree(tree);
360
                featureTreeEditorComposite.getText_title().setEnabled(false);
361
            }
362
        }
363
    }
364

    
365
    /**
366
     * {@inheritDoc}
367
     */
368
    @Override
369
    public void update(CdmDataChangeMap arg0) {
370
    }
371

    
372
    /**
373
     * {@inheritDoc}
374
     */
375
    @Override
376
    public ConversationHolder getConversationHolder() {
377
        return conversation;
378
    }
379

    
380
    /**
381
     * {@inheritDoc}
382
     */
383
    @Override
384
    public void changed(Object element) {
385
        setDirty();
386
    }
387

    
388
    /**
389
     * {@inheritDoc}
390
     */
391
    @Override
392
    public void forceDirty() {
393
        setDirty();
394
    }
395

    
396
}
(3-3/3)