Project

General

Profile

Download (18.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.Collection;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21

    
22
import javax.annotation.PostConstruct;
23
import javax.annotation.PreDestroy;
24
import javax.inject.Inject;
25

    
26
import org.eclipse.core.runtime.IProgressMonitor;
27
import org.eclipse.e4.ui.di.Focus;
28
import org.eclipse.e4.ui.di.Persist;
29
import org.eclipse.e4.ui.di.UISynchronize;
30
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
31
import org.eclipse.e4.ui.services.EMenuService;
32
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
33
import org.eclipse.jface.viewers.ISelection;
34
import org.eclipse.jface.viewers.ISelectionChangedListener;
35
import org.eclipse.jface.viewers.IStructuredSelection;
36
import org.eclipse.jface.viewers.SelectionChangedEvent;
37
import org.eclipse.jface.viewers.StructuredSelection;
38
import org.eclipse.jface.viewers.TreeSelection;
39
import org.eclipse.swt.SWT;
40
import org.eclipse.swt.custom.SashForm;
41
import org.eclipse.swt.dnd.Transfer;
42
import org.eclipse.swt.events.ModifyEvent;
43
import org.eclipse.swt.events.ModifyListener;
44
import org.eclipse.swt.events.SelectionAdapter;
45
import org.eclipse.swt.events.SelectionEvent;
46
import org.eclipse.swt.layout.GridData;
47
import org.eclipse.swt.layout.GridLayout;
48
import org.eclipse.swt.widgets.Button;
49
import org.eclipse.swt.widgets.Composite;
50
import org.eclipse.swt.widgets.Display;
51
import org.eclipse.swt.widgets.Label;
52
import org.eclipse.swt.widgets.Text;
53
import org.eclipse.ui.forms.widgets.FormToolkit;
54

    
55
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
56
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
57
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
58
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
59
import eu.etaxonomy.cdm.api.service.ITermService;
60
import eu.etaxonomy.cdm.model.common.Representation;
61
import eu.etaxonomy.cdm.model.common.TermVocabulary;
62
import eu.etaxonomy.cdm.model.description.Character;
63
import eu.etaxonomy.cdm.model.description.FeatureNode;
64
import eu.etaxonomy.cdm.model.description.FeatureTree;
65
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
66
import eu.etaxonomy.taxeditor.editor.AppModelId;
67
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
68
import eu.etaxonomy.taxeditor.featuretree.CharacterTransfer;
69
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
70
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
71
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeDropAdapter;
72
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
73
import eu.etaxonomy.taxeditor.featuretree.e4.IFeatureTreeEditor;
74
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
75
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
76
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
77
import eu.etaxonomy.taxeditor.model.ImageResources;
78
import eu.etaxonomy.taxeditor.model.MessagingUtils;
79
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
80
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
81
import eu.etaxonomy.taxeditor.store.CdmStore;
82
import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
83
import eu.etaxonomy.taxeditor.ui.dialog.selection.TermVocabularySelectionDialog;
84
import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
85

    
86
/**
87
 * Editor for combining structure and property terms to characters.
88
 * @author pplitzner
89
 * @date 24.05.2017
90
 *
91
 */
92
public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled, ISelectionChangedListener,
93
        ModifyListener, IE4ViewerPart, IPartContentHasDetails, IPartContentHasSupplementalData, IDirtyMarkable {
94

    
95
    private FeatureTreeEditorComposite characterTreeEditorComposite;
96
    private FeatureTreeEditorComposite propertiesTreeEditorComposite;
97
    private FeatureTreeEditorComposite structuresTreeEditorComposite;
98
    private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
99

    
100
    @Inject
101
    private ESelectionService selService;
102

    
103
    @Inject
104
    private UISynchronize sync;
105

    
106
    @Inject
107
    private MDirtyable dirty;
108

    
109
    private ConversationHolder conversation;
110

    
111
    private ICdmEntitySession cdmEntitySession;
112
    private Composite composite;
113

    
114
    private TermVocabulary vocabulary;
115

    
116
    public CharacterEditor() {
117
    }
118

    
119
    /**
120
     * Create contents of the view part.
121
     */
122
    @PostConstruct
123
    public void createControls(Composite parent, EMenuService menuService ) {
124
        if (CdmStore.isActive()){
125
            if(conversation == null){
126
                conversation = CdmStore.createConversation();
127
            }
128
            if(cdmEntitySession!=null){
129
                cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
130
            }
131
        }
132
        else{
133
            return;
134
        }
135
        parent.setLayout(new GridLayout(1, false));
136

    
137
        Composite vocChooserComposite = new Composite(parent, SWT.NONE);
138
        vocChooserComposite.setLayout(new GridLayout(3, false));
139
        vocChooserComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false, 2, 1));
140
        Label lblVocImport = new Label(vocChooserComposite, SWT.NONE);
141
        lblVocImport.setText("Character vocabulary");
142
        Text txtVocabulary = new Text(vocChooserComposite, SWT.NONE);
143
        Button btnChooseVoc = new Button(vocChooserComposite, SWT.PUSH);
144
        btnChooseVoc.setImage(ImageResources.getImage(ImageResources.BROWSE_ICON));
145
        btnChooseVoc.addSelectionListener(new SelectionAdapter() {
146

    
147
            @Override
148
            public void widgetSelected(SelectionEvent e) {
149
                vocabulary = TermVocabularySelectionDialog.select("Select vocabulary for characters", btnChooseVoc.getShell(), null);
150
                txtVocabulary.setText(vocabulary.getLabel());
151
            }
152
        });
153

    
154
        SashForm sashForm = new SashForm(parent, SWT.NONE);
155
        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
156
        formToolkit.adapt(sashForm);
157
        formToolkit.paintBordersFor(sashForm);
158

    
159
        composite = new Composite(sashForm, SWT.NONE);
160
        formToolkit.adapt(composite);
161
        formToolkit.paintBordersFor(composite);
162
        GridLayout gl_composite = new GridLayout(1, false);
163
        gl_composite.marginWidth = 0;
164
        composite.setLayout(gl_composite);
165

    
166
        structuresTreeEditorComposite = addFeatureTreeEditor(composite);
167

    
168
        initFeatureTreeComposite(structuresTreeEditorComposite,
169
                new FeatureNodeDragListener(structuresTreeEditorComposite.getViewer()), null, null, null, null);
170

    
171
        structuresTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_STRUCTURES);
172

    
173
        Composite composite_1 = new Composite(sashForm, SWT.NONE);
174
        formToolkit.adapt(composite_1);
175
        formToolkit.paintBordersFor(composite_1);
176
        GridLayout gl_composite_1 = new GridLayout(1, false);
177
        gl_composite_1.marginWidth = 0;
178
        composite_1.setLayout(gl_composite_1);
179

    
180
        propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
181
        initFeatureTreeComposite(propertiesTreeEditorComposite,
182

    
183
                new CharacterDragListener(structuresTreeEditorComposite.getViewer(), propertiesTreeEditorComposite.getViewer()),
184
                null,
185
                new Transfer[] {CharacterTransfer.getInstance()},
186
                null,
187
                null
188

    
189
        );
190
        propertiesTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_PROPERTIES);
191

    
192
        Composite composite_3 = new Composite(sashForm, SWT.NONE);
193
        formToolkit.adapt(composite_3);
194
        formToolkit.paintBordersFor(composite_3);
195
        GridLayout gl_composite_3 = new GridLayout(2, false);
196
        gl_composite_3.marginWidth = 0;
197
        composite_3.setLayout(gl_composite_3);
198

    
199
        Button btnAddCharacter = new Button(composite_3, SWT.NONE);
200
        btnAddCharacter.setText(">>"); //$NON-NLS-1$
201
        formToolkit.adapt(btnAddCharacter, true, true);
202
        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
203
            @Override
204
            public void widgetSelected(SelectionEvent e) {
205
                if(!isVocabularySet()){
206
                    return;
207
                }
208
                ISelection structureTreeSelection = structuresTreeEditorComposite.getViewer().getSelection();
209
                ISelection propertyTreeSelection = propertiesTreeEditorComposite.getViewer().getSelection();
210
                if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
211
                    MessagingUtils.warningDialog(Messages.CharacterEditor_CANNOT_PERFORM_TITLE, CharacterEditor.this,
212
                            Messages.CharacterEditor_CANNOT_PERFORM_MESSAGE);
213
                    return;
214
                }
215
                Collection<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
216
                for (Character character : characters) {
217
                    //add new Character to feature tree
218
                    FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
219
                    vocabulary.addTerm(character);
220
                    CdmStore.getService(IFeatureNodeService.class).createChildFeatureNode(parent, character);
221
                }
222
                characterTreeEditorComposite.getViewer().refresh();
223
            }
224
        });
225

    
226
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
227
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()),
228
                new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync),
229

    
230
                new Transfer[] {FeatureNodeTransfer.getInstance(), CharacterTransfer.getInstance()},
231
                this,
232
                this);
233

    
234
        characterTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_CHARACTERS);
235

    
236
        //add context menu to character viewer
237
        menuService.registerContextMenu(characterTreeEditorComposite.getViewer().getControl(),
238
                AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_EDITOR_POPUPMENU_CHARACTEREDITOR);
239

    
240
    }
241

    
242
    private FeatureTreeEditorComposite addFeatureTreeEditor(Composite composite_3) {
243
        FeatureTreeEditorComposite featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.NONE);
244
        featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
245
        return featureTreeEditorComposite;
246
    }
247

    
248
    private void initFeatureTreeComposite(
249
            FeatureTreeEditorComposite featureTreeEditorComposite,
250
            FeatureNodeDragListener featureNodeDragListener,
251
            FeatureTreeDropAdapter featureNodeDropAdapter,
252
            Transfer[] transfers,
253
            ISelectionChangedListener viewerSelectionChangedListener,
254
            ModifyListener modifyListener) {
255

    
256
        featureTreeEditorComposite.init(
257
                featureNodeDragListener,
258
                featureNodeDropAdapter,
259
                transfers,
260
                viewerSelectionChangedListener,
261
                new FeatureTreeChooserListener(featureTreeEditorComposite),
262
                modifyListener);
263
    }
264

    
265
    @Focus
266
    public void focus(){
267
        if(characterTreeEditorComposite!=null){
268
            characterTreeEditorComposite.getViewer().getControl().setFocus();
269
        }
270
        if(conversation!=null && !conversation.isBound()){
271
            conversation.bind();
272
        }
273
        if(cdmEntitySession != null) {
274
            cdmEntitySession.bind();
275
        }
276
    }
277

    
278
    public static Collection<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
279
        Set<Character> characters = new HashSet<>();
280
        //get selected structures and properties
281
        Iterator<FeatureNode> structureIterator = structureTreeSelection.iterator();
282

    
283
        //create all combinations of structures and properties
284
        while(structureIterator.hasNext()){
285
            FeatureNode structureNode = structureIterator.next();
286
            Iterator<FeatureNode> propertiesIterator = propertyTreeSelection.iterator();
287
            while(propertiesIterator.hasNext()){
288
                FeatureNode propertyNode = propertiesIterator.next();
289
                Representation structureRepresentation = structureNode.getFeature().getRepresentation(PreferencesUtil.getGlobalLanguage());
290
                Representation propertyRepresentation = propertyNode.getFeature().getRepresentation(PreferencesUtil.getGlobalLanguage());
291
                String label = null;
292
                String abbrevLabel = null;
293
                if(structureRepresentation.getLabel()!=null && propertyRepresentation.getLabel()!=null){
294
                    label = structureRepresentation.getLabel()+" "+propertyRepresentation.getLabel();
295
                }
296
                if(structureRepresentation.getAbbreviatedLabel()!=null && propertyRepresentation.getAbbreviatedLabel()!=null){
297
                    abbrevLabel = structureRepresentation.getAbbreviatedLabel()+" "+propertyRepresentation.getAbbreviatedLabel();
298
                }
299
                //create new Character
300
                Character character = Character.NewInstance(structureNode, propertyNode, null, label, abbrevLabel);
301
                characters.add(character);
302
            }
303
        }
304
        return characters;
305
    }
306

    
307
    @Override
308
    @Persist
309
    public void save(IProgressMonitor monitor){
310
        if (!conversation.isBound()) {
311
            conversation.bind();
312
        }
313

    
314
        // commit the conversation and start a new transaction immediately
315
        conversation.commit(true);
316

    
317
        FeatureTree featureTree = characterTreeEditorComposite.getFeatureTree();
318
        if(featureTree!=null){
319
            //save characters because they can be modified in this editor
320
            featureTree.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
321
        }
322
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
323

    
324

    
325
        dirty.setDirty(false);
326
    }
327

    
328
    @Override
329
    public boolean isDirty() {
330
        return dirty.isDirty();
331
    }
332

    
333
    @PreDestroy
334
    public void dispose(){
335
        if(conversation!=null){
336
            conversation.close();
337
            conversation = null;
338
        }
339
        if(cdmEntitySession != null) {
340
            cdmEntitySession.dispose();
341
            cdmEntitySession = null;
342
        }
343
        dirty.setDirty(false);
344
    }
345

    
346
    public boolean isVocabularySet() {
347
        if(vocabulary==null){
348
            MessagingUtils.warningDialog("Character creation not possible", this.getClass(), "Please select a vocabulary for the characters.");
349
        }
350
        return vocabulary!=null;
351
    }
352

    
353
    public TermVocabulary getVocabulary() {
354
        return vocabulary;
355
    }
356

    
357
    @Override
358
    public Map<Object, List<String>> getPropertyPathsMap() {
359
        List<String> propertyPaths = Arrays.asList(new String[] {
360
                "children", //$NON-NLS-1$
361
                "feature", //$NON-NLS-1$
362
                "featureTree", //$NON-NLS-1$
363
        });
364
        Map<Object, List<String>> propertyPathMap =
365
                new HashMap<Object, List<String>>();
366
        propertyPathMap.put(FeatureNode.class,propertyPaths);
367
        return propertyPathMap;
368
    }
369

    
370
    @Override
371
    public List<FeatureTree> getRootEntities() {
372
        List<FeatureTree> root = new ArrayList<>();
373
        root.add(characterTreeEditorComposite.getFeatureTree());
374
        return root;
375
    }
376

    
377
    @Override
378
    public ICdmEntitySession getCdmEntitySession() {
379
        return cdmEntitySession;
380
    }
381

    
382
    @Focus
383
    public void setFocus() {
384
        if(conversation!=null && !conversation.isBound()){
385
            conversation.bind();
386
        }
387
    }
388

    
389
    @Override
390
    public void selectionChanged(SelectionChangedEvent event) {
391
        //propagate selection
392
        selService.setSelection(event.getSelection());
393
    }
394

    
395

    
396
    @Override
397
    public void modifyText(ModifyEvent e) {
398
        characterTreeEditorComposite.getFeatureTree().setTitleCache(((Text) e.widget).getText(), true);
399
        setDirty();
400
    }
401

    
402

    
403
    private void setDirty() {
404
        dirty.setDirty(true);
405
    }
406

    
407
    @Override
408
    public IStructuredSelection getSelection() {
409
        return (IStructuredSelection) characterTreeEditorComposite.getViewer().getSelection();
410
    }
411

    
412
    public FeatureTree getCharacterTree(){
413
        return characterTreeEditorComposite.getFeatureTree();
414
    }
415

    
416
    @Override
417
    public void refresh(){
418
        structuresTreeEditorComposite.getViewer().refresh();
419
        propertiesTreeEditorComposite.getViewer().refresh();
420
        characterTreeEditorComposite.getViewer().refresh();
421
    }
422

    
423
    private class FeatureTreeChooserListener extends SelectionAdapter{
424
        FeatureTreeEditorComposite featureTreeEditorComposite;
425

    
426
        public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
427
            super();
428
            this.featureTreeEditorComposite = featureTreeEditorComposite;
429
        }
430

    
431
        @Override
432
        public void widgetSelected(SelectionEvent e) {
433
            FeatureTree tree = FeatureTreeSelectionDialog.select(featureTreeEditorComposite.getDisplay().getActiveShell(), //conversation,
434
                    null);
435
            if(tree!=null){
436
                featureTreeEditorComposite.setSelectedTree(tree);
437
                featureTreeEditorComposite.getText_title().setEnabled(false);
438
            }
439
        }
440
    }
441

    
442
    @Override
443
    public void update(CdmDataChangeMap arg0) {
444
    }
445

    
446
    @Override
447
    public ConversationHolder getConversationHolder() {
448
        return conversation;
449
    }
450

    
451
    @Override
452
    public void changed(Object element) {
453
        setDirty();
454
    }
455

    
456
    @Override
457
    public void forceDirty() {
458
        setDirty();
459
    }
460

    
461
    @Override
462
    public boolean postOperation(Object objectAffectedByOperation) {
463
        characterTreeEditorComposite.getViewer().refresh();
464
        if(objectAffectedByOperation instanceof FeatureNode){
465
            StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
466
            characterTreeEditorComposite.getViewer().setSelection(selection);
467
        }
468
        return true;
469
    }
470

    
471
    @Override
472
    public boolean onComplete() {
473
        return false;
474
    }
475

    
476
}
(3-3/3)