Project

General

Profile

Download (12.5 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.workingSet;
10

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

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

    
25
import org.eclipse.core.runtime.IProgressMonitor;
26
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
27
import org.eclipse.e4.core.contexts.IEclipseContext;
28
import org.eclipse.e4.ui.di.Focus;
29
import org.eclipse.e4.ui.di.Persist;
30
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
31
import org.eclipse.e4.ui.services.IServiceConstants;
32
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
33
import org.eclipse.jface.util.LocalSelectionTransfer;
34
import org.eclipse.jface.viewers.IStructuredSelection;
35
import org.eclipse.jface.viewers.Viewer;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.dnd.DND;
38
import org.eclipse.swt.dnd.Transfer;
39
import org.eclipse.swt.events.KeyAdapter;
40
import org.eclipse.swt.events.KeyEvent;
41
import org.eclipse.swt.events.ModifyEvent;
42
import org.eclipse.swt.events.ModifyListener;
43
import org.eclipse.swt.events.SelectionAdapter;
44
import org.eclipse.swt.widgets.Composite;
45
import org.eclipse.swt.widgets.Display;
46
import org.eclipse.swt.widgets.Shell;
47

    
48
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
49
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
50
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
51
import eu.etaxonomy.cdm.api.service.ITermService;
52
import eu.etaxonomy.cdm.api.service.IWorkingSetService;
53
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
54
import eu.etaxonomy.cdm.model.description.FeatureTree;
55
import eu.etaxonomy.cdm.model.description.WorkingSet;
56
import eu.etaxonomy.cdm.model.location.NamedArea;
57
import eu.etaxonomy.cdm.model.name.Rank;
58
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
59
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
60
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
61
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
62
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
63
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
64
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
65
import eu.etaxonomy.taxeditor.model.MessagingUtils;
66
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
67
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
68
import eu.etaxonomy.taxeditor.store.CdmStore;
69
import eu.etaxonomy.taxeditor.ui.dialog.selection.NamedAreaSelectionDialog;
70
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
71
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
72

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

    
82
    private WorkingSetComposite composite;
83

    
84
    private ConversationHolder conversation;
85

    
86
    private ICdmEntitySession cdmEntitySession;
87

    
88
    private WorkingSet workingSet;
89

    
90
    private final int dndOperations = DND.DROP_MOVE;
91

    
92
    @Inject
93
    private MDirtyable dirty;
94

    
95
    @Inject
96
    private ESelectionService selectionService;
97

    
98
    private ModifyListener labelModifyListener;
99

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

    
116
        composite = new WorkingSetComposite(parent, SWT.NONE);
117

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

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

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

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

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

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

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

    
173
    }
174

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

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

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

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

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

    
262

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

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

    
279
        conversation.commit();
280
        CdmStore.getService(IWorkingSetService.class).merge(workingSet, true);
281

    
282
        dirty.setDirty(false);
283
    }
284

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

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

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

    
315
    public WorkingSet getWorkingSet() {
316
        return workingSet;
317
    }
318

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

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

    
328
    @Override
329
    public Collection<WorkingSet> getRootEntities() {
330
        return null;
331
    }
332

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

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

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

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

    
353
}
(3-3/4)