Project

General

Profile

Download (15.4 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.StructuredSelection;
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.editor.AppModelId;
60
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
61
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
62
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
63
import eu.etaxonomy.taxeditor.featuretree.e4.IFeatureTreeEditor;
64
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
66
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
67
import eu.etaxonomy.taxeditor.model.MessagingUtils;
68
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
69
import eu.etaxonomy.taxeditor.store.CdmStore;
70
import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
71
import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
72

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

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

    
87
    @Inject
88
    private ESelectionService selService;
89

    
90
    @Inject
91
    private MDirtyable dirty;
92

    
93
    private ConversationHolder conversation;
94

    
95
    private ICdmEntitySession cdmEntitySession;
96
    private Composite composite;
97

    
98
    public CharacterEditor() {
99
    }
100

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

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

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

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

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

    
142
        propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
143
        initFeatureTreeComposite(propertiesTreeEditorComposite, new CharacterDragListener(structuresTreeEditorComposite.getViewer(), propertiesTreeEditorComposite.getViewer()), null);
144
        propertiesTreeEditorComposite.getLabel_title().setText("Properties");
145

    
146
        Composite composite_3 = new Composite(sashForm, SWT.NONE);
147
        formToolkit.adapt(composite_3);
148
        formToolkit.paintBordersFor(composite_3);
149
        GridLayout gl_composite_3 = new GridLayout(2, false);
150
        gl_composite_3.marginWidth = 0;
151
        composite_3.setLayout(gl_composite_3);
152

    
153
        btnAddCharacter = new Button(composite_3, SWT.NONE);
154
        btnAddCharacter.setText(">>");
155
        formToolkit.adapt(btnAddCharacter, true, true);
156

    
157
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
158
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer()));
159
        characterTreeEditorComposite.getLabel_title().setText("Characters");
160

    
161
        //add context menu to character viewer//create context menu
162
        menuService.registerContextMenu(characterTreeEditorComposite.getViewer().getControl(),
163
                AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_EDITOR_POPUPMENU_CHARACTEREDITOR);
164

    
165
        init();
166
    }
167

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

    
174
    private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
175
            FeatureNodeDragListener featureNodeDragListener, FeatureNodeDropAdapter featureNodeDropAdapter) {
176
        featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
177
                new FeatureTreeChooserListener(featureTreeEditorComposite), this);
178
    }
179

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

    
193
    private void init(){
194
        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
195
            /**
196
             * {@inheritDoc}
197
             */
198
            @Override
199
            public void widgetSelected(SelectionEvent e) {
200
                ISelection structureTreeSelection = structuresTreeEditorComposite.getViewer().getSelection();
201
                ISelection propertyTreeSelection = propertiesTreeEditorComposite.getViewer().getSelection();
202
                if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
203
                    MessagingUtils.warningDialog("Cannot perform action", CharacterEditor.this,
204
                            "You have to select a structure, a property and a feature tree to perform this action.");
205
                    return;
206
                }
207
                List<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
208
                for (Character character : characters) {
209
                    //add new Character to feature tree
210
                    FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
211
                    CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(parent.getUuid(), character.getUuid());
212
                }
213

    
214
                setDirty();
215
                characterTreeEditorComposite.getViewer().refresh();
216
            }
217
        });
218
    }
219

    
220
    public static List<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
221
        List<Character> characters = new ArrayList<>();
222
        //get selected structures and properties
223
        Iterator<FeatureNode> structureIterator = structureTreeSelection.iterator();
224

    
225
        //create all combinations of structures and properties
226
        while(structureIterator.hasNext()){
227
            FeatureNode structureNode = structureIterator.next();
228
            Iterator<FeatureNode> propertiesIterator = propertyTreeSelection.iterator();
229
            while(propertiesIterator.hasNext()){
230
                FeatureNode propertyNode = propertiesIterator.next();
231
                //create new Character
232
                String label = structureNode.getFeature().generateTitle()+" "+propertyNode.getFeature().generateTitle();
233
                Character character = Character.NewInstance(structureNode, propertyNode, "", label, label);
234
                characters.add(HibernateProxyHelper.deproxy(CdmStore.getService(ITermService.class).save(character), Character.class));
235
            }
236
        }
237
        return characters;
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
    @Override
262
    public boolean isDirty() {
263
        return dirty.isDirty();
264
    }
265

    
266
    @PreDestroy
267
    public void dispose(){
268
        if(conversation!=null){
269
            conversation.close();
270
            conversation = null;
271
        }
272
        if(cdmEntitySession != null) {
273
            cdmEntitySession.dispose();
274
            cdmEntitySession = null;
275
        }
276
        dirty.setDirty(false);
277
    }
278

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

    
292
    /**
293
     * {@inheritDoc}
294
     */
295
    @Override
296
    public List<FeatureTree> getRootEntities() {
297
        List<FeatureTree> root = new ArrayList<>();
298
        root.add(characterTreeEditorComposite.getFeatureTree());
299
        return root;
300
    }
301

    
302
    @Override
303
    public ICdmEntitySession getCdmEntitySession() {
304
        return cdmEntitySession;
305
    }
306

    
307
    @Focus
308
    public void setFocus() {
309
        if(conversation!=null && !conversation.isBound()){
310
            conversation.bind();
311
        }
312
    }
313

    
314
    /** {@inheritDoc} */
315
    @Override
316
    public void selectionChanged(SelectionChangedEvent event) {
317
        //propagate selection
318
        selService.setSelection(event.getSelection());
319
    }
320

    
321

    
322
    /**
323
     * {@inheritDoc}
324
     */
325
    @Override
326
    public void modifyText(ModifyEvent e) {
327
        characterTreeEditorComposite.getFeatureTree().setTitleCache(((Text) e.widget).getText(), true);
328
        setDirty();
329
    }
330

    
331

    
332
    private void setDirty() {
333
        dirty.setDirty(true);
334
    }
335

    
336
    /**
337
     * {@inheritDoc}
338
     */
339
    @Override
340
    public IStructuredSelection getSelection() {
341
        return (IStructuredSelection) characterTreeEditorComposite.getViewer().getSelection();
342
    }
343

    
344
    public FeatureTree getCharacterTree(){
345
        return characterTreeEditorComposite.getFeatureTree();
346
    }
347

    
348
    @Override
349
    public void refresh(){
350
        structuresTreeEditorComposite.getViewer().refresh();
351
        propertiesTreeEditorComposite.getViewer().refresh();
352
        characterTreeEditorComposite.getViewer().refresh();
353
    }
354

    
355
    private class FeatureTreeChooserListener extends SelectionAdapter{
356
        FeatureTreeEditorComposite featureTreeEditorComposite;
357

    
358
        public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
359
            super();
360
            this.featureTreeEditorComposite = featureTreeEditorComposite;
361
        }
362

    
363
        @Override
364
        public void widgetSelected(SelectionEvent e) {
365
            FeatureTree tree = FeatureTreeSelectionDialog.select(featureTreeEditorComposite.getDisplay().getActiveShell(), //conversation,
366
                    null);
367
            if(tree!=null){
368
                featureTreeEditorComposite.setSelectedTree(tree);
369
                featureTreeEditorComposite.getText_title().setEnabled(false);
370
            }
371
        }
372
    }
373

    
374
    /**
375
     * {@inheritDoc}
376
     */
377
    @Override
378
    public void update(CdmDataChangeMap arg0) {
379
    }
380

    
381
    /**
382
     * {@inheritDoc}
383
     */
384
    @Override
385
    public ConversationHolder getConversationHolder() {
386
        return conversation;
387
    }
388

    
389
    /**
390
     * {@inheritDoc}
391
     */
392
    @Override
393
    public void changed(Object element) {
394
        setDirty();
395
    }
396

    
397
    /**
398
     * {@inheritDoc}
399
     */
400
    @Override
401
    public void forceDirty() {
402
        setDirty();
403
    }
404

    
405
    /**
406
     * {@inheritDoc}
407
     */
408
    @Override
409
    public boolean postOperation(Object objectAffectedByOperation) {
410
        characterTreeEditorComposite.getViewer().refresh();
411
        if(objectAffectedByOperation instanceof FeatureNode){
412
            StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
413
            characterTreeEditorComposite.getViewer().setSelection(selection);
414
        }
415
        return true;
416
    }
417

    
418
    /**
419
     * {@inheritDoc}
420
     */
421
    @Override
422
    public boolean onComplete() {
423
        return false;
424
    }
425

    
426
}
(3-3/3)