Project

General

Profile

Download (16.9 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.Text;
52
import org.eclipse.ui.forms.widgets.FormToolkit;
53

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

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

    
91
    private FeatureTreeEditorComposite characterTreeEditorComposite;
92
    private FeatureTreeEditorComposite propertiesTreeEditorComposite;
93
    private FeatureTreeEditorComposite structuresTreeEditorComposite;
94
    private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
95
    private Button btnAddCharacter;
96

    
97
    @Inject
98
    private ESelectionService selService;
99

    
100
    @Inject
101
    private UISynchronize sync;
102

    
103
    @Inject
104
    private MDirtyable dirty;
105

    
106
    private ConversationHolder conversation;
107

    
108
    private ICdmEntitySession cdmEntitySession;
109
    private Composite composite;
110

    
111
    public CharacterEditor() {
112
    }
113

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

    
132
        SashForm sashForm = new SashForm(parent, SWT.NONE);
133
        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
134
        formToolkit.adapt(sashForm);
135
        formToolkit.paintBordersFor(sashForm);
136

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

    
144
        structuresTreeEditorComposite = addFeatureTreeEditor(composite);
145
        initFeatureTreeComposite(structuresTreeEditorComposite,
146
                new FeatureNodeDragListener(structuresTreeEditorComposite.getViewer()), null, null, null, null);
147
        structuresTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_STRUCTURES);
148

    
149
        Composite composite_1 = new Composite(sashForm, SWT.NONE);
150
        formToolkit.adapt(composite_1);
151
        formToolkit.paintBordersFor(composite_1);
152
        GridLayout gl_composite_1 = new GridLayout(1, false);
153
        gl_composite_1.marginWidth = 0;
154
        composite_1.setLayout(gl_composite_1);
155

    
156
        propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
157
        initFeatureTreeComposite(propertiesTreeEditorComposite,
158
                new CharacterDragListener(structuresTreeEditorComposite.getViewer(), propertiesTreeEditorComposite.getViewer()),
159
                null,
160
                new Transfer[] {CharacterTransfer.getInstance()},
161
                null,
162
                null
163
        );
164
        propertiesTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_PROPERTIES);
165

    
166
        Composite composite_3 = new Composite(sashForm, SWT.NONE);
167
        formToolkit.adapt(composite_3);
168
        formToolkit.paintBordersFor(composite_3);
169
        GridLayout gl_composite_3 = new GridLayout(2, false);
170
        gl_composite_3.marginWidth = 0;
171
        composite_3.setLayout(gl_composite_3);
172

    
173
        btnAddCharacter = new Button(composite_3, SWT.NONE);
174
        btnAddCharacter.setText(">>"); //$NON-NLS-1$
175
        formToolkit.adapt(btnAddCharacter, true, true);
176

    
177
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
178
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()),
179
                new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync),
180
                new Transfer[] {FeatureNodeTransfer.getInstance(), CharacterTransfer.getInstance()},
181
                this,
182
                this);
183
        characterTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_CHARACTERS);
184

    
185
        //add context menu to character viewer//create context menu
186
        menuService.registerContextMenu(characterTreeEditorComposite.getViewer().getControl(),
187
                AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_EDITOR_POPUPMENU_CHARACTEREDITOR);
188

    
189
        init();
190
    }
191

    
192
    private FeatureTreeEditorComposite addFeatureTreeEditor(Composite composite_3) {
193
        FeatureTreeEditorComposite featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.NONE);
194
        featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
195
        return featureTreeEditorComposite;
196
    }
197

    
198
    private void initFeatureTreeComposite(
199
            FeatureTreeEditorComposite featureTreeEditorComposite,
200
            FeatureNodeDragListener featureNodeDragListener,
201
            FeatureTreeDropAdapter featureNodeDropAdapter,
202
            Transfer[] transfers,
203
            ISelectionChangedListener viewerSelectionChangedListener,
204
            ModifyListener modifyListener) {
205
        featureTreeEditorComposite.init(
206
                featureNodeDragListener,
207
                featureNodeDropAdapter,
208
                transfers,
209
                viewerSelectionChangedListener,
210
                new FeatureTreeChooserListener(featureTreeEditorComposite),
211
                modifyListener);
212
    }
213

    
214
    @Focus
215
    public void focus(){
216
        if(characterTreeEditorComposite!=null){
217
            characterTreeEditorComposite.getViewer().getControl().setFocus();
218
        }
219
        if(conversation!=null && !conversation.isBound()){
220
            conversation.bind();
221
        }
222
        if(cdmEntitySession != null) {
223
            cdmEntitySession.bind();
224
        }
225
    }
226

    
227
    private void init(){
228
        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
229
            @Override
230
            public void widgetSelected(SelectionEvent e) {
231
                ISelection structureTreeSelection = structuresTreeEditorComposite.getViewer().getSelection();
232
                ISelection propertyTreeSelection = propertiesTreeEditorComposite.getViewer().getSelection();
233
                if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
234
                    MessagingUtils.warningDialog(Messages.CharacterEditor_CANNOT_PERFORM_TITLE, CharacterEditor.this,
235
                            Messages.CharacterEditor_CANNOT_PERFORM_MESSAGE);
236
                    return;
237
                }
238
                Collection<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
239
                for (Character character : characters) {
240
                    //add new Character to feature tree
241
                    FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
242
                    CdmStore.getService(IFeatureNodeService.class).createChildFeatureNode(parent, character);
243
                }
244
                characterTreeEditorComposite.getViewer().refresh();
245
            }
246
        });
247
    }
248

    
249
    public static Collection<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
250
        Set<Character> characters = new HashSet<>();
251
        //get selected structures and properties
252
        Iterator<FeatureNode> structureIterator = structureTreeSelection.iterator();
253

    
254
        //create all combinations of structures and properties
255
        while(structureIterator.hasNext()){
256
            FeatureNode structureNode = structureIterator.next();
257
            Iterator<FeatureNode> propertiesIterator = propertyTreeSelection.iterator();
258
            while(propertiesIterator.hasNext()){
259
                FeatureNode propertyNode = propertiesIterator.next();
260
                Representation structureRepresentation = structureNode.getFeature().getRepresentation(PreferencesUtil.getGlobalLanguage());
261
                Representation propertyRepresentation = propertyNode.getFeature().getRepresentation(PreferencesUtil.getGlobalLanguage());
262
                String label = null;
263
                String abbrevLabel = null;
264
                if(structureRepresentation.getLabel()!=null && propertyRepresentation.getLabel()!=null){
265
                    label = structureRepresentation.getLabel()+" "+propertyRepresentation.getLabel();
266
                }
267
                if(structureRepresentation.getAbbreviatedLabel()!=null && propertyRepresentation.getAbbreviatedLabel()!=null){
268
                    abbrevLabel = structureRepresentation.getAbbreviatedLabel()+" "+propertyRepresentation.getAbbreviatedLabel();
269
                }
270
                //create new Character
271
                Character character = Character.NewInstance(structureNode, propertyNode, null, label, abbrevLabel);
272
                characters.add(character);
273
            }
274
        }
275
        return characters;
276
    }
277

    
278
    @Override
279
    @Persist
280
    public void save(IProgressMonitor monitor){
281
        if (!conversation.isBound()) {
282
            conversation.bind();
283
        }
284

    
285
        // commit the conversation and start a new transaction immediately
286
        conversation.commit(true);
287

    
288
        FeatureTree featureTree = characterTreeEditorComposite.getFeatureTree();
289
        if(featureTree!=null){
290
            //save characters because they can be modified in this editor
291
            featureTree.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
292
        }
293
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
294

    
295

    
296
        dirty.setDirty(false);
297
    }
298

    
299
    @Override
300
    public boolean isDirty() {
301
        return dirty.isDirty();
302
    }
303

    
304
    @PreDestroy
305
    public void dispose(){
306
        if(conversation!=null){
307
            conversation.close();
308
            conversation = null;
309
        }
310
        if(cdmEntitySession != null) {
311
            cdmEntitySession.dispose();
312
            cdmEntitySession = null;
313
        }
314
        dirty.setDirty(false);
315
    }
316

    
317
    @Override
318
    public Map<Object, List<String>> getPropertyPathsMap() {
319
        List<String> propertyPaths = Arrays.asList(new String[] {
320
                "children", //$NON-NLS-1$
321
                "feature", //$NON-NLS-1$
322
                "featureTree", //$NON-NLS-1$
323
        });
324
        Map<Object, List<String>> propertyPathMap =
325
                new HashMap<Object, List<String>>();
326
        propertyPathMap.put(FeatureNode.class,propertyPaths);
327
        return propertyPathMap;
328
    }
329

    
330
    @Override
331
    public List<FeatureTree> getRootEntities() {
332
        List<FeatureTree> root = new ArrayList<>();
333
        root.add(characterTreeEditorComposite.getFeatureTree());
334
        return root;
335
    }
336

    
337
    @Override
338
    public ICdmEntitySession getCdmEntitySession() {
339
        return cdmEntitySession;
340
    }
341

    
342
    @Focus
343
    public void setFocus() {
344
        if(conversation!=null && !conversation.isBound()){
345
            conversation.bind();
346
        }
347
    }
348

    
349
    @Override
350
    public void selectionChanged(SelectionChangedEvent event) {
351
        //propagate selection
352
        selService.setSelection(event.getSelection());
353
    }
354

    
355

    
356
    @Override
357
    public void modifyText(ModifyEvent e) {
358
        characterTreeEditorComposite.getFeatureTree().setTitleCache(((Text) e.widget).getText(), true);
359
        setDirty();
360
    }
361

    
362

    
363
    private void setDirty() {
364
        dirty.setDirty(true);
365
    }
366

    
367
    @Override
368
    public IStructuredSelection getSelection() {
369
        return (IStructuredSelection) characterTreeEditorComposite.getViewer().getSelection();
370
    }
371

    
372
    public FeatureTree getCharacterTree(){
373
        return characterTreeEditorComposite.getFeatureTree();
374
    }
375

    
376
    @Override
377
    public void refresh(){
378
        structuresTreeEditorComposite.getViewer().refresh();
379
        propertiesTreeEditorComposite.getViewer().refresh();
380
        characterTreeEditorComposite.getViewer().refresh();
381
    }
382

    
383
    private class FeatureTreeChooserListener extends SelectionAdapter{
384
        FeatureTreeEditorComposite featureTreeEditorComposite;
385

    
386
        public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
387
            super();
388
            this.featureTreeEditorComposite = featureTreeEditorComposite;
389
        }
390

    
391
        @Override
392
        public void widgetSelected(SelectionEvent e) {
393
            FeatureTree tree = FeatureTreeSelectionDialog.select(featureTreeEditorComposite.getDisplay().getActiveShell(), //conversation,
394
                    null);
395
            if(tree!=null){
396
                featureTreeEditorComposite.setSelectedTree(tree);
397
                featureTreeEditorComposite.getText_title().setEnabled(false);
398
            }
399
        }
400
    }
401

    
402
    @Override
403
    public void update(CdmDataChangeMap arg0) {
404
    }
405

    
406
    @Override
407
    public ConversationHolder getConversationHolder() {
408
        return conversation;
409
    }
410

    
411
    @Override
412
    public void changed(Object element) {
413
        setDirty();
414
    }
415

    
416
    @Override
417
    public void forceDirty() {
418
        setDirty();
419
    }
420

    
421
    @Override
422
    public boolean postOperation(Object objectAffectedByOperation) {
423
        characterTreeEditorComposite.getViewer().refresh();
424
        if(objectAffectedByOperation instanceof FeatureNode){
425
            StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
426
            characterTreeEditorComposite.getViewer().setSelection(selection);
427
        }
428
        return true;
429
    }
430

    
431
    @Override
432
    public boolean onComplete() {
433
        return false;
434
    }
435

    
436
}
(3-3/3)