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.di.UISynchronize;
27
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
28
import org.eclipse.e4.ui.services.EMenuService;
29
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
30
import org.eclipse.jface.viewers.ISelection;
31
import org.eclipse.jface.viewers.ISelectionChangedListener;
32
import org.eclipse.jface.viewers.IStructuredSelection;
33
import org.eclipse.jface.viewers.SelectionChangedEvent;
34
import org.eclipse.jface.viewers.StructuredSelection;
35
import org.eclipse.jface.viewers.TreeSelection;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.custom.SashForm;
38
import org.eclipse.swt.events.ModifyEvent;
39
import org.eclipse.swt.events.ModifyListener;
40
import org.eclipse.swt.events.SelectionAdapter;
41
import org.eclipse.swt.events.SelectionEvent;
42
import org.eclipse.swt.layout.GridData;
43
import org.eclipse.swt.layout.GridLayout;
44
import org.eclipse.swt.widgets.Button;
45
import org.eclipse.swt.widgets.Composite;
46
import org.eclipse.swt.widgets.Display;
47
import org.eclipse.swt.widgets.Text;
48
import org.eclipse.ui.forms.widgets.FormToolkit;
49

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

    
75
/**
76
 * Editor for combining structure and property terms to characters.
77
 * @author pplitzner
78
 * @date 24.05.2017
79
 *
80
 */
81
public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled, ISelectionChangedListener,
82
        ModifyListener, IE4ViewerPart, IPartContentHasDetails, IPartContentHasSupplementalData, IDirtyMarkable {
83

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

    
90
    @Inject
91
    private ESelectionService selService;
92

    
93
    @Inject
94
    private UISynchronize sync;
95

    
96
    @Inject
97
    private MDirtyable dirty;
98

    
99
    private ConversationHolder conversation;
100

    
101
    private ICdmEntitySession cdmEntitySession;
102
    private Composite composite;
103

    
104
    public CharacterEditor() {
105
    }
106

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

    
125
        SashForm sashForm = new SashForm(parent, SWT.NONE);
126
        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
127
        formToolkit.adapt(sashForm);
128
        formToolkit.paintBordersFor(sashForm);
129

    
130
        composite = new Composite(sashForm, SWT.NONE);
131
        formToolkit.adapt(composite);
132
        formToolkit.paintBordersFor(composite);
133
        GridLayout gl_composite = new GridLayout(1, false);
134
        gl_composite.marginWidth = 0;
135
        composite.setLayout(gl_composite);
136

    
137
        structuresTreeEditorComposite = addFeatureTreeEditor(composite);
138
        initFeatureTreeComposite(structuresTreeEditorComposite, null, null);
139
        structuresTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_STRUCTURES);
140

    
141
        Composite composite_1 = new Composite(sashForm, SWT.NONE);
142
        formToolkit.adapt(composite_1);
143
        formToolkit.paintBordersFor(composite_1);
144
        GridLayout gl_composite_1 = new GridLayout(1, false);
145
        gl_composite_1.marginWidth = 0;
146
        composite_1.setLayout(gl_composite_1);
147

    
148
        propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
149
        initFeatureTreeComposite(propertiesTreeEditorComposite, new CharacterDragListener(structuresTreeEditorComposite.getViewer(), propertiesTreeEditorComposite.getViewer()), null);
150
        propertiesTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_PROPERTIES);
151

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

    
159
        btnAddCharacter = new Button(composite_3, SWT.NONE);
160
        btnAddCharacter.setText(">>"); //$NON-NLS-1$
161
        formToolkit.adapt(btnAddCharacter, true, true);
162

    
163
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
164
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync));
165
        characterTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_CHARACTERS);
166

    
167
        //add context menu to character viewer//create context menu
168
        menuService.registerContextMenu(characterTreeEditorComposite.getViewer().getControl(),
169
                AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_EDITOR_POPUPMENU_CHARACTEREDITOR);
170

    
171
        init();
172
    }
173

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

    
180
    private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
181
            FeatureNodeDragListener featureNodeDragListener, FeatureTreeDropAdapter featureNodeDropAdapter) {
182
        featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
183
                new FeatureTreeChooserListener(featureTreeEditorComposite), this);
184
    }
185

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

    
199
    private void init(){
200
        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
201
            /**
202
             * {@inheritDoc}
203
             */
204
            @Override
205
            public void widgetSelected(SelectionEvent e) {
206
                ISelection structureTreeSelection = structuresTreeEditorComposite.getViewer().getSelection();
207
                ISelection propertyTreeSelection = propertiesTreeEditorComposite.getViewer().getSelection();
208
                if(structureTreeSelection==null || propertyTreeSelection==null || characterTreeEditorComposite.getFeatureTree()==null){
209
                    MessagingUtils.warningDialog(Messages.CharacterEditor_CANNOT_PERFORM_TITLE, CharacterEditor.this,
210
                            Messages.CharacterEditor_CANNOT_PERFORM_MESSAGE);
211
                    return;
212
                }
213
                List<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
214
                for (Character character : characters) {
215
                    //add new Character to feature tree
216
                    FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
217
                    CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(parent.getUuid(), character.getUuid());
218
                }
219

    
220
                setDirty();
221
                characterTreeEditorComposite.getViewer().refresh();
222
            }
223
        });
224
    }
225

    
226
    public static List<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
227
        List<Character> characters = new ArrayList<>();
228
        //get selected structures and properties
229
        Iterator<FeatureNode> structureIterator = structureTreeSelection.iterator();
230

    
231
        //create all combinations of structures and properties
232
        while(structureIterator.hasNext()){
233
            FeatureNode structureNode = structureIterator.next();
234
            Iterator<FeatureNode> propertiesIterator = propertyTreeSelection.iterator();
235
            while(propertiesIterator.hasNext()){
236
                FeatureNode propertyNode = propertiesIterator.next();
237
                //create new Character
238
                String label = structureNode.getFeature().generateTitle()+" "+propertyNode.getFeature().generateTitle(); //$NON-NLS-1$
239
                Character character = Character.NewInstance(structureNode, propertyNode, "", label, label); //$NON-NLS-1$
240
                characters.add(HibernateProxyHelper.deproxy(CdmStore.getService(ITermService.class).save(character), Character.class));
241
            }
242
        }
243
        return characters;
244
    }
245

    
246
    @Override
247
    @Persist
248
    public void save(IProgressMonitor monitor){
249
        if (!conversation.isBound()) {
250
            conversation.bind();
251
        }
252

    
253
        // commit the conversation and start a new transaction immediately
254
        conversation.commit(true);
255

    
256
        FeatureTree featureTree = characterTreeEditorComposite.getFeatureTree();
257
        if(featureTree!=null){
258
            //save characters because they can be modified in this editor
259
            featureTree.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
260
        }
261
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
262

    
263

    
264
        dirty.setDirty(false);
265
    }
266

    
267
    @Override
268
    public boolean isDirty() {
269
        return dirty.isDirty();
270
    }
271

    
272
    @PreDestroy
273
    public void dispose(){
274
        if(conversation!=null){
275
            conversation.close();
276
            conversation = null;
277
        }
278
        if(cdmEntitySession != null) {
279
            cdmEntitySession.dispose();
280
            cdmEntitySession = null;
281
        }
282
        dirty.setDirty(false);
283
    }
284

    
285
    @Override
286
    public Map<Object, List<String>> getPropertyPathsMap() {
287
        List<String> propertyPaths = Arrays.asList(new String[] {
288
                "children", //$NON-NLS-1$
289
                "feature", //$NON-NLS-1$
290
                "featureTree", //$NON-NLS-1$
291
        });
292
        Map<Object, List<String>> propertyPathMap =
293
                new HashMap<Object, List<String>>();
294
        propertyPathMap.put(FeatureNode.class,propertyPaths);
295
        return propertyPathMap;
296
    }
297

    
298
    @Override
299
    public List<FeatureTree> getRootEntities() {
300
        List<FeatureTree> root = new ArrayList<>();
301
        root.add(characterTreeEditorComposite.getFeatureTree());
302
        return root;
303
    }
304

    
305
    @Override
306
    public ICdmEntitySession getCdmEntitySession() {
307
        return cdmEntitySession;
308
    }
309

    
310
    @Focus
311
    public void setFocus() {
312
        if(conversation!=null && !conversation.isBound()){
313
            conversation.bind();
314
        }
315
    }
316

    
317
    @Override
318
    public void selectionChanged(SelectionChangedEvent event) {
319
        //propagate selection
320
        selService.setSelection(event.getSelection());
321
    }
322

    
323

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

    
330

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

    
335
    @Override
336
    public IStructuredSelection getSelection() {
337
        return (IStructuredSelection) characterTreeEditorComposite.getViewer().getSelection();
338
    }
339

    
340
    public FeatureTree getCharacterTree(){
341
        return characterTreeEditorComposite.getFeatureTree();
342
    }
343

    
344
    @Override
345
    public void refresh(){
346
        structuresTreeEditorComposite.getViewer().refresh();
347
        propertiesTreeEditorComposite.getViewer().refresh();
348
        characterTreeEditorComposite.getViewer().refresh();
349
    }
350

    
351
    private class FeatureTreeChooserListener extends SelectionAdapter{
352
        FeatureTreeEditorComposite featureTreeEditorComposite;
353

    
354
        public FeatureTreeChooserListener(FeatureTreeEditorComposite featureTreeEditorComposite) {
355
            super();
356
            this.featureTreeEditorComposite = featureTreeEditorComposite;
357
        }
358

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

    
370
    @Override
371
    public void update(CdmDataChangeMap arg0) {
372
    }
373

    
374
    @Override
375
    public ConversationHolder getConversationHolder() {
376
        return conversation;
377
    }
378

    
379
    @Override
380
    public void changed(Object element) {
381
        setDirty();
382
    }
383

    
384
    @Override
385
    public void forceDirty() {
386
        setDirty();
387
    }
388

    
389
    @Override
390
    public boolean postOperation(Object objectAffectedByOperation) {
391
        characterTreeEditorComposite.getViewer().refresh();
392
        if(objectAffectedByOperation instanceof FeatureNode){
393
            StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
394
            characterTreeEditorComposite.getViewer().setSelection(selection);
395
        }
396
        return true;
397
    }
398

    
399
    @Override
400
    public boolean onComplete() {
401
        return false;
402
    }
403

    
404
}
(3-3/3)