Project

General

Profile

Download (11.8 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.ITermService;
51
import eu.etaxonomy.cdm.api.service.IWorkingSetService;
52
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
53
import eu.etaxonomy.cdm.model.description.FeatureTree;
54
import eu.etaxonomy.cdm.model.description.WorkingSet;
55
import eu.etaxonomy.cdm.model.location.NamedArea;
56
import eu.etaxonomy.cdm.model.name.Rank;
57
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
58
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
59
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
60
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
61
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
62
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
63
import eu.etaxonomy.taxeditor.model.MessagingUtils;
64
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
65
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
66
import eu.etaxonomy.taxeditor.store.CdmStore;
67
import eu.etaxonomy.taxeditor.ui.dialog.selection.NamedAreaSelectionDialog;
68
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
69
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
70

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

    
80
    private WorkingSetComposite composite;
81

    
82
    private ConversationHolder conversation;
83

    
84
    private ICdmEntitySession cdmEntitySession;
85

    
86
    private WorkingSet workingSet;
87

    
88
    private final int dndOperations = DND.DROP_MOVE;
89

    
90
    @Inject
91
    private MDirtyable dirty;
92

    
93
    @Inject
94
    private ESelectionService selectionService;
95

    
96
    private ModifyListener labelModifyListener;
97

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

    
114
        composite = new WorkingSetComposite(parent, SWT.NONE);
115

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

    
126
        composite.getBtnChooseArea().addSelectionListener(new SelectionAdapter() {
127

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

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

    
146
        composite.getFeatureTreeEditorComposite().init(null, null, e->selectionService.setSelection(e.getSelection()), null, null);
147

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

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

    
171
    }
172

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

    
198
        composite.getTxt_label().addModifyListener(labelModifyListener);
199
    }
200

    
201
    public void addTaxonNode(TaxonNode taxonNode){
202
        //load into WS editor session
203
        taxonNode = getCdmEntitySession().load(taxonNode, false);
204
        Viewer taxonTreeViewer = getTaxonTreeViewer();
205
        Object input = taxonTreeViewer.getInput();
206
        Collection<TaxonNode> treeNodes;
207
        if(input==null){
208
            treeNodes = new ArrayList<>();
209
        }
210
        else{
211
            treeNodes = (Collection<TaxonNode>) input;
212
        }
213
        treeNodes.add(taxonNode);
214
        taxonTreeViewer.setInput(treeNodes);
215
        dirty.setDirty(true);
216
    }
217

    
218
    private void removeTaxonNode(TaxonNode taxonNode){
219
        Viewer taxonTreeViewer = getTaxonTreeViewer();
220
        Collection<TaxonNode> input = (Collection<TaxonNode>) taxonTreeViewer.getInput();
221
        input.remove(taxonNode);
222
        workingSet.removeTaxonSubtree(taxonNode);
223
        taxonTreeViewer.setInput(input);
224
        dirty.setDirty(true);
225
    }
226

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

    
252

    
253
        DefinedTermBase rankMaxSelection = composite.getRankMax().getSelection();
254
        Rank rankMax = null;
255
        if(rankMaxSelection instanceof Rank){
256
            rankMax = (Rank) rankMaxSelection;
257
        }
258
        DefinedTermBase rankMinSelection = composite.getRankMin().getSelection();
259
        Rank rankMin = null;
260
        if(rankMinSelection instanceof Rank){
261
            rankMin = (Rank) rankMinSelection;
262
        }
263

    
264
        workingSet.setMaxRank(rankMax);
265
        workingSet.setMinRank(rankMin);
266
        workingSet.setDescriptiveSystem(characters);
267
        workingSet.setGeoFilter(areas);
268

    
269
        conversation.commit();
270
        CdmStore.getService(IWorkingSetService.class).merge(workingSet, true);
271

    
272
        dirty.setDirty(false);
273
    }
274

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

    
288
    @Focus
289
    public void setFocus() {
290
        if(composite!=null){
291
            composite.setFocus();
292
        }
293
        if (getConversationHolder() != null) {
294
            getConversationHolder().bind();
295
        }
296
        if(cdmEntitySession != null) {
297
            cdmEntitySession.bind();
298
        }
299
    }
300

    
301
    public Viewer getTaxonTreeViewer() {
302
        return composite.getTaxonNodeTree();
303
    }
304

    
305
    public WorkingSet getWorkingSet() {
306
        return workingSet;
307
    }
308

    
309
    @Override
310
    public void update(CdmDataChangeMap arg0) {
311
    }
312

    
313
    @Override
314
    public ICdmEntitySession getCdmEntitySession() {
315
        return cdmEntitySession;
316
    }
317

    
318
    @Override
319
    public Collection<WorkingSet> getRootEntities() {
320
        return null;
321
    }
322

    
323
    @Override
324
    public Map<Object, List<String>> getPropertyPathsMap() {
325
        return null;
326
    }
327

    
328
    @Override
329
    public ConversationHolder getConversationHolder() {
330
        return conversation;
331
    }
332

    
333
    @Override
334
    public void changed(Object element) {
335
        dirty.setDirty(true);
336
    }
337

    
338
    @Override
339
    public void forceDirty() {
340
        dirty.setDirty(true);
341
    }
342

    
343
}
(3-3/4)