Project

General

Profile

Download (12.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.editor.descriptiveDataSet;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

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

    
26
import org.eclipse.core.runtime.IProgressMonitor;
27
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
28
import org.eclipse.e4.core.contexts.IEclipseContext;
29
import org.eclipse.e4.ui.di.Focus;
30
import org.eclipse.e4.ui.di.Persist;
31
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
32
import org.eclipse.e4.ui.services.IServiceConstants;
33
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
34
import org.eclipse.jface.util.LocalSelectionTransfer;
35
import org.eclipse.jface.viewers.IStructuredSelection;
36
import org.eclipse.jface.viewers.Viewer;
37
import org.eclipse.swt.SWT;
38
import org.eclipse.swt.dnd.DND;
39
import org.eclipse.swt.dnd.Transfer;
40
import org.eclipse.swt.events.KeyAdapter;
41
import org.eclipse.swt.events.KeyEvent;
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.widgets.Composite;
46
import org.eclipse.swt.widgets.Display;
47
import org.eclipse.swt.widgets.Shell;
48

    
49
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
51
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
52
import eu.etaxonomy.cdm.api.service.ITermService;
53
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
54
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
55
import eu.etaxonomy.cdm.model.description.FeatureTree;
56
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
57
import eu.etaxonomy.cdm.model.location.NamedArea;
58
import eu.etaxonomy.cdm.model.name.Rank;
59
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
60
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
62
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
63
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
64
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
65
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
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.NamedAreaSelectionDialog;
71
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
72
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
73

    
74
/**
75
 * Editor for configuring DescriptiveDataSets
76
 * @author pplitzner
77
 * @since Nov 21, 2017
78
 *
79
 */
80
public class DescriptiveDataSetEditor implements IE4SavablePart, IConversationEnabled, ICdmEntitySessionEnabled,
81
IPartContentHasDetails, IDirtyMarkable {
82

    
83
    private DescriptiveDataSetComposite composite;
84

    
85
    private ConversationHolder conversation;
86

    
87
    private ICdmEntitySession cdmEntitySession;
88

    
89
    private DescriptiveDataSet descriptiveDataSet;
90

    
91
    private final int dndOperations = DND.DROP_MOVE;
92

    
93
    @Inject
94
    private MDirtyable dirty;
95

    
96
    @Inject
97
    private ESelectionService selectionService;
98

    
99
    private ModifyListener labelModifyListener;
100

    
101
    @PostConstruct
102
    public void create(Composite parent, IEclipseContext context, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell){
103
        if (CdmStore.isActive()){
104
            if(conversation == null){
105
                conversation = CdmStore.createConversation();
106
            }
107
            if(cdmEntitySession == null){
108
                cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
109
            }
110
        }
111
        else{
112
            return;
113
        }
114
        CdmFormFactory cdmFormFactory = new CdmFormFactory(Display.getCurrent());
115
        ContextInjectionFactory.inject(cdmFormFactory, context);
116

    
117
        composite = new DescriptiveDataSetComposite(parent, SWT.NONE);
118

    
119
        labelModifyListener = new ModifyListener() {
120
            @Override
121
            public void modifyText(ModifyEvent e) {
122
                descriptiveDataSet.setLabel(composite.getTxt_label().getText());
123
                dirty.setDirty(true);
124
            }
125
        };
126
        composite.getRankMin().addSelectionChangedListener(event->dirty.setDirty(true));
127
        composite.getRankMax().addSelectionChangedListener(event->dirty.setDirty(true));
128

    
129
        composite.getBtnChooseArea().addSelectionListener(new SelectionAdapter() {
130

    
131
            @Override
132
            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
133
                NamedArea area = NamedAreaSelectionDialog.select(shell, null, null);
134
                if(area!=null){
135
                    composite.setArea(area);
136
                }
137
                dirty.setDirty(true);
138
            }
139
        });
140
        composite.getBtnRemoveArea().addSelectionListener(new SelectionAdapter() {
141

    
142
            @Override
143
            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
144
                composite.removeArea();
145
                dirty.setDirty(true);
146
            }
147
        });
148

    
149
        composite.getFeatureTreeEditorComposite().init(null, null, e->selectionService.setSelection(e.getSelection()), this, null);
150

    
151
        //add drag'n'drop support
152
        Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer()};
153
        composite.getTaxonNodeTree().addDropSupport(dndOperations, transfers, new TaxonNodeDropAdapter(this));
154

    
155
        composite.getTaxonNodeTree().getTree().addKeyListener(new KeyAdapter() {
156
            @Override
157
            public void keyPressed(KeyEvent e) {
158
                if(e.character==SWT.DEL){
159
                    IStructuredSelection selection = (IStructuredSelection) composite.getTaxonNodeTree().getSelection();
160
                    if(selection.toList().stream().anyMatch(object->!(object instanceof TaxonNode))){
161
                        MessagingUtils.warningDialog(Messages.DescriptiveDataSetEditor_DELETE_FAIL_TITLE, this.getClass(), Messages.DescriptiveDataSetEditor_DELETE_FAIL_MESSAGE);
162
                        return;
163
                    }
164
                    Iterator<Object> iterator = selection.iterator();
165
                    while(iterator.hasNext()){
166
                        Object next = iterator.next();
167
                        TaxonNode taxonNode = (TaxonNode) next;
168
                        removeTaxonNode(taxonNode);
169
                    }
170
                }
171
            }
172
        });
173

    
174
    }
175

    
176
    public void init(UUID descriptiveDataSetUuid) {
177
        this.descriptiveDataSet = cdmEntitySession.remoteLoad(CdmStore.getService(IDescriptiveDataSetService.class), descriptiveDataSetUuid);
178
        if(descriptiveDataSet.getLabel()!=null){
179
            composite.getTxt_label().setText(descriptiveDataSet.getLabel());
180
        }
181
        if(descriptiveDataSet.getDescriptiveSystem()!=null){
182
            composite.setCharacters(descriptiveDataSet.getDescriptiveSystem());
183
        }
184
        Rank maxRank = descriptiveDataSet.getMaxRank();
185
        if(maxRank!=null){
186
            composite.setRankMax(maxRank);
187
        }
188
        Rank minRank = descriptiveDataSet.getMinRank();
189
        if(minRank!=null){
190
            composite.setRankMin(minRank);
191
        }
192
        Set<NamedArea> geoFilter = descriptiveDataSet.getGeoFilter();
193
        if(geoFilter!=null && !geoFilter.isEmpty()){
194
            composite.setArea(geoFilter.iterator().next());
195
        }
196
        Set<TaxonNode> taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter();
197
        if(taxonSubtreeFilter!=null){
198
            composite.getTaxonNodeTree().setInput(taxonSubtreeFilter);
199
        }
200

    
201
        composite.getTxt_label().addModifyListener(labelModifyListener);
202
    }
203

    
204
    public void addTaxonNode(TaxonNodeDto taxonNodeDto){
205
        TaxonNode taxonNode = cdmEntitySession.remoteLoad(CdmStore.getService(ITaxonNodeService.class), taxonNodeDto.getUuid());
206
        //check if node belongs to same classification
207
        Set<TaxonNode> taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter();
208
        if(taxonSubtreeFilter!=null && !taxonSubtreeFilter.isEmpty()){
209
            if(!taxonSubtreeFilter.iterator().next().getClassification().equals(taxonNode.getClassification())){
210
                MessagingUtils.warningDialog(Messages.TaxonNodeDropAdapter_CLASSIFICATIONS_NO_MATCH, this.getClass(),
211
                        Messages.TaxonNodeDropAdapter_CLASSIFICATIONS_NO_MATCH_MESSAGE);
212
                return;
213
            }
214
        }
215
        Viewer taxonTreeViewer = getTaxonTreeViewer();
216
        Object input = taxonTreeViewer.getInput();
217
        Collection<TaxonNode> treeNodes;
218
        if(input==null){
219
            treeNodes = new ArrayList<>();
220
        }
221
        else{
222
            treeNodes = (Collection<TaxonNode>) input;
223
        }
224
        treeNodes.add(taxonNode);
225
        taxonTreeViewer.setInput(treeNodes);
226
        dirty.setDirty(true);
227
    }
228

    
229
    private void removeTaxonNode(TaxonNode taxonNode){
230
        Viewer taxonTreeViewer = getTaxonTreeViewer();
231
        Collection<TaxonNode> input = (Collection<TaxonNode>) taxonTreeViewer.getInput();
232
        input.remove(taxonNode);
233
        descriptiveDataSet.removeTaxonSubtree(taxonNode);
234
        taxonTreeViewer.setInput(input);
235
        dirty.setDirty(true);
236
    }
237

    
238
    @Persist
239
    @Override
240
    public void save(IProgressMonitor monitor) {
241
        NamedArea area = composite.getArea();
242
        Set<NamedArea> areas = new HashSet<>();
243
        if(area!=null){
244
            areas.add(area);
245
        }
246
        Object input = composite.getTaxonNodeTree().getInput();
247
        if(input!=null){
248
            descriptiveDataSet.setTaxonSubtreeFilter(new HashSet<>());//clear existing filter
249
            Collection<ITaxonTreeNode> taxonNodes = (Collection<ITaxonTreeNode>) input;
250
            for (ITaxonTreeNode taxonTreeNode : taxonNodes) {
251
                if(taxonTreeNode instanceof TaxonNode){
252
                    TaxonNode taxonNode = (TaxonNode)taxonTreeNode;
253
                    descriptiveDataSet.addTaxonSubtree(taxonNode);
254
                }
255
            }
256
        }
257
        FeatureTree characters = composite.getCharacters();
258
        if(characters!=null){
259
            //save characters because they can be modified in this editor
260
            characters.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
261
        }
262

    
263

    
264
        DefinedTermBase rankMaxSelection = composite.getRankMax().getSelection();
265
        Rank rankMax = null;
266
        if(rankMaxSelection instanceof Rank){
267
            rankMax = (Rank) rankMaxSelection;
268
        }
269
        DefinedTermBase rankMinSelection = composite.getRankMin().getSelection();
270
        Rank rankMin = null;
271
        if(rankMinSelection instanceof Rank){
272
            rankMin = (Rank) rankMinSelection;
273
        }
274

    
275
        descriptiveDataSet.setMaxRank(rankMax);
276
        descriptiveDataSet.setMinRank(rankMin);
277
        descriptiveDataSet.setDescriptiveSystem(characters);
278
        descriptiveDataSet.setGeoFilter(areas);
279

    
280
        conversation.commit();
281
        CdmStore.getService(IDescriptiveDataSetService.class).merge(descriptiveDataSet, true);
282

    
283
        dirty.setDirty(false);
284
    }
285

    
286
    @PreDestroy
287
    public void dispose() {
288
        if (conversation != null) {
289
            conversation.close();
290
            conversation = null;
291
        }
292
        if(cdmEntitySession != null) {
293
            cdmEntitySession.dispose();
294
            cdmEntitySession = null;
295
        }
296
        dirty.setDirty(false);
297
    }
298

    
299
    @Focus
300
    public void setFocus() {
301
        if(composite!=null){
302
            composite.setFocus();
303
        }
304
        if (getConversationHolder() != null) {
305
            getConversationHolder().bind();
306
        }
307
        if(cdmEntitySession != null) {
308
            cdmEntitySession.bind();
309
        }
310
    }
311

    
312
    public Viewer getTaxonTreeViewer() {
313
        return composite.getTaxonNodeTree();
314
    }
315

    
316
    public DescriptiveDataSet getDescriptiveDataSet() {
317
        return descriptiveDataSet;
318
    }
319

    
320
    @Override
321
    public void update(CdmDataChangeMap arg0) {
322
    }
323

    
324
    @Override
325
    public ICdmEntitySession getCdmEntitySession() {
326
        return cdmEntitySession;
327
    }
328

    
329
    @Override
330
    public Collection<DescriptiveDataSet> getRootEntities() {
331
        return Collections.singleton(descriptiveDataSet);
332
    }
333

    
334
    @Override
335
    public Map<Object, List<String>> getPropertyPathsMap() {
336
        return null;
337
    }
338

    
339
    @Override
340
    public ConversationHolder getConversationHolder() {
341
        return conversation;
342
    }
343

    
344
    @Override
345
    public void changed(Object element) {
346
        dirty.setDirty(true);
347
    }
348

    
349
    @Override
350
    public void forceDirty() {
351
        dirty.setDirty(true);
352
    }
353

    
354
}
(2-2/4)