Project

General

Profile

Download (24.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2007 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

    
10
package eu.etaxonomy.taxeditor.editor.name.e4;
11

    
12
import java.util.ArrayList;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import javax.annotation.PostConstruct;
19
import javax.annotation.PreDestroy;
20
import javax.inject.Inject;
21

    
22
import org.apache.commons.lang.StringUtils;
23
import org.eclipse.core.commands.operations.IUndoContext;
24
import org.eclipse.core.commands.operations.UndoContext;
25
import org.eclipse.core.runtime.IProgressMonitor;
26
import org.eclipse.core.runtime.OperationCanceledException;
27
import org.eclipse.e4.core.contexts.IEclipseContext;
28
import org.eclipse.e4.core.di.annotations.Optional;
29
import org.eclipse.e4.core.services.events.IEventBroker;
30
import org.eclipse.e4.ui.di.Focus;
31
import org.eclipse.e4.ui.di.Persist;
32
import org.eclipse.e4.ui.di.UIEventTopic;
33
import org.eclipse.e4.ui.di.UISynchronize;
34
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
35
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
36
import org.eclipse.e4.ui.services.EMenuService;
37
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
38
import org.eclipse.jface.dialogs.MessageDialog;
39
import org.eclipse.jface.viewers.ISelection;
40
import org.eclipse.jface.viewers.ISelectionProvider;
41
import org.eclipse.jface.viewers.StructuredSelection;
42
import org.eclipse.swt.dnd.DND;
43
import org.eclipse.swt.dnd.DropTarget;
44
import org.eclipse.swt.dnd.Transfer;
45
import org.eclipse.swt.graphics.Color;
46
import org.eclipse.swt.widgets.Composite;
47
import org.eclipse.ui.ISelectionListener;
48
import org.eclipse.ui.IWorkbenchPart;
49
import org.eclipse.ui.IWorkbenchPartReference;
50
import org.eclipse.ui.forms.ManagedForm;
51
import org.eclipse.ui.forms.widgets.FormToolkit;
52
import org.eclipse.ui.forms.widgets.ScrolledForm;
53
import org.eclipse.ui.forms.widgets.TableWrapLayout;
54

    
55
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
56
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
57
import eu.etaxonomy.cdm.api.service.DeleteResult;
58
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
59
import eu.etaxonomy.cdm.model.common.CdmBase;
60
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
61
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
62
import eu.etaxonomy.cdm.model.taxon.Taxon;
63
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
65
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
66
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
67
import eu.etaxonomy.taxeditor.editor.CdmDataTransfer;
68
import eu.etaxonomy.taxeditor.editor.EditorUtil;
69
import eu.etaxonomy.taxeditor.editor.ISecuredEditor;
70
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
71
import eu.etaxonomy.taxeditor.editor.e4.TaxonEditorInputE4;
72
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
73
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupE4;
74
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupedContainerE4;
75
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedGroupE4;
76
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedNameContainerE4;
77
import eu.etaxonomy.taxeditor.editor.name.e4.container.ConceptContainerE4;
78
import eu.etaxonomy.taxeditor.editor.name.e4.container.ContainerFactoryE4;
79
import eu.etaxonomy.taxeditor.editor.name.e4.container.HomotypicalSynonymGroupE4;
80
import eu.etaxonomy.taxeditor.editor.name.e4.container.MisappliedGroupE4;
81
import eu.etaxonomy.taxeditor.editor.name.e4.dnd.NameEditorDropTargetListenerE4;
82
import eu.etaxonomy.taxeditor.event.EventUtility;
83
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
84
import eu.etaxonomy.taxeditor.model.AbstractUtility;
85
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
86
import eu.etaxonomy.taxeditor.model.IPartChangeListener;
87
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
88
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
89
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
90
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
91
import eu.etaxonomy.taxeditor.model.MessagingUtils;
92
import eu.etaxonomy.taxeditor.model.TaxeditorPartService;
93
import eu.etaxonomy.taxeditor.preference.Resources;
94
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
95
import eu.etaxonomy.taxeditor.store.CdmStore;
96
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
97

    
98
/**
99
 *
100
 * @author pplitzner
101
 * @date Aug 24, 2017
102
 *
103
 */
104
public class TaxonNameEditorE4 implements IConversationEnabled, IDirtyMarkable, IPartContentHasDetails,
105
        IPartContentHasSupplementalData, IPartContentHasMedia, IPartContentHasFactualData, IPartChangeListener,
106
        ISelectionListener, ISecuredEditor, IE4SavablePart, ITaxonEditor, IDropTargetableE4 {
107

    
108
    private Taxon taxon;
109

    
110
    private ManagedForm managedForm;
111
    private ScrolledForm scrolledForm;
112
    private Composite parent;
113
    private ISelectionProvider simpleSelectionProvider;
114

    
115
    private TaxonBase selection;
116

    
117
    private ConversationHolder conversation;
118

    
119
    private AcceptedGroupE4 acceptedGroup;
120
    private List<HomotypicalSynonymGroupE4> heterotypicSynonymGroups = new ArrayList<>();
121
    private MisappliedGroupE4 misappliedGroup;
122

    
123
    private DropTarget target;
124

    
125
    @Inject
126
    UISynchronize sync;
127

    
128
    private TaxonBase objectAffectedByLastOperation;
129

    
130
    @Inject
131
    private EMenuService menuService;
132

    
133
    @Inject
134
    private ESelectionService selService;
135

    
136
    @Inject
137
    private IEclipseContext context;
138

    
139
    @Inject
140
    private MDirtyable dirty;
141

    
142
    private MPart thisPart;
143

    
144
    private TaxonEditorInputE4 input;
145

    
146
    private UndoContext undoContext;
147

    
148
    @Inject
149
    private IEventBroker eventBroker;
150

    
151
    @Inject
152
    public TaxonNameEditorE4() {
153
        undoContext = new UndoContext();
154
    }
155

    
156
    @PostConstruct
157
    public void createPartControl(Composite parent, MPart thisPart) {
158
        this.thisPart = thisPart;
159

    
160
        createManagedForm(parent);
161

    
162
        TaxeditorPartService.getInstance().addListener(TaxeditorPartService.PART_ACTIVATED, this);
163

    
164
    }
165

    
166
    protected void createManagedForm(Composite composite) {
167

    
168
        managedForm = new ManagedForm(composite) {
169

    
170
            @Override
171
            public void dirtyStateChanged() {
172
                dirty.setDirty(true);
173
            }
174

    
175
            @Override
176
            public boolean setInput(Object input) {
177
                if (input instanceof AbstractGroupedContainerE4) {
178
                    TaxonBase newSelection = ((AbstractGroupedContainerE4) input).getData();
179
                    if (selection != newSelection || TaxonNameEditorE4.this.isDirty()) {
180
                        selection = newSelection;
181
                        selService.setSelection(new StructuredSelection(selection));
182

    
183
                    }
184
                } else if (input == null) {
185
                    selection = null;
186
                    selService.setSelection(new StructuredSelection());
187
                }
188

    
189
                return super.setInput(input);
190
            }
191
        };
192

    
193
        scrolledForm = managedForm.getForm();
194
        parent = scrolledForm.getBody();
195

    
196
        parent.setData(taxon);
197

    
198
        TableWrapLayout layout = new TableWrapLayout();
199
        layout.leftMargin = 0;
200
        layout.rightMargin = 0;
201
        layout.topMargin = 0;
202
        layout.bottomMargin = 0;
203

    
204
        layout.verticalSpacing = 0;
205
        layout.horizontalSpacing = 0;
206

    
207
        parent.setLayout(layout);
208
        parent.setBackground(AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
209
    }
210

    
211
    public void createOrUpdateNameComposites(boolean accepted, boolean heterotypicGroups, boolean misappliedNames) {
212

    
213
        if (accepted) {
214
            ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
215
        }
216
        if (heterotypicGroups) {
217
            ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
218
        }
219
        if (misappliedNames) {
220
            ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
221
        }
222
        ContainerFactoryE4.setMenuToAllContainers(this);
223

    
224
        // Redraw composite
225
        parent.pack();
226
        managedForm.refresh();
227
        managedForm.reflow(true);
228

    
229
    }
230

    
231
    @Override
232
    public Taxon getTaxon() {
233
        return HibernateProxyHelper.deproxy(taxon);
234
    }
235

    
236
    public void setDirty() {
237
        managedForm.dirtyStateChanged();
238
    }
239

    
240
    @Focus
241
    public void setFocus() {
242
        // make sure to bind again if maybe in another view the conversation was
243
        // unbound
244
        if (conversation != null && !conversation.isBound()) {
245
            conversation.bind();
246
        }
247

    
248
        if (input != null) {
249
            if (getSelectedContainer() == null) {
250
                throw new IllegalStateException(Messages.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE);
251
            }
252
            getSelectedContainer().setSelected();
253

    
254
            if (!input.getCdmEntitySession().isActive()) {
255
                input.bind();
256
            }
257

    
258
            // check permissions
259
            boolean doEnable = permissionsSatisfied();
260
            managedForm.getForm().setEnabled(doEnable);
261
        }
262
        if(selection!=null){
263
            selService.setSelection(new StructuredSelection(selection));
264
        }
265
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
266
    }
267

    
268
    @Override
269
    public boolean permissionsSatisfied() {
270
        TaxonNode taxonNode = input.getTaxonNode();
271
        boolean doEnable = CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(),
272
                RequiredPermissions.TAXON_EDIT);
273
        return doEnable;
274
    }
275

    
276
    @Override
277
    public ConversationHolder getConversationHolder() {
278
        return conversation;
279
    }
280

    
281
    /** {@inheritDoc} */
282
    @Override
283
    public void update(CdmDataChangeMap events) {
284
        // redraw();
285
    }
286

    
287
    /**
288
     * Redraws this editor return true on success
289
     *
290
     * @return a boolean.
291
     */
292
    public boolean redraw() {
293
        return redraw(true, true, true, true);
294
    }
295

    
296
    /**
297
     * {@inheritDoc}
298
     *
299
     * Redraws the editor controls
300
     */
301
    public boolean redraw(boolean focus, boolean accepted, boolean heterotypic, boolean misappliedNames) {
302

    
303
        createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
304

    
305
        if (focus) {
306
            setFocus();
307
        }
308

    
309
        return true;
310
    }
311

    
312
    @Override
313
    public boolean postOperation(Object objectAffectedByOperation) {
314
        if (objectAffectedByOperation instanceof TaxonBase) {
315
            objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
316
        }
317

    
318
        redraw(true, true, true, true);
319
        changed(objectAffectedByOperation);
320
        onComplete();
321
        return true;
322
    }
323

    
324
    public ManagedForm getManagedForm() {
325
        return managedForm;
326
    }
327

    
328
    /**
329
     * <p>
330
     * checkForEmptyNames
331
     * </p>
332
     *
333
     * @return true if there are empty names
334
     */
335
    public boolean checkForEmptyNames() {
336
        for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
337
            if (container != null
338
                    && (container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache()))) {
339
                return true;
340
            }
341
        }
342
        return false;
343
    }
344

    
345
    public Set<AbstractGroupedContainerE4> getEmptyContainers() {
346
        Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
347

    
348
        for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
349
            if (container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache())) {
350
                containersWithEmptyNames.add(container);
351
            }
352
        }
353

    
354
        return containersWithEmptyNames;
355
    }
356

    
357
    /** {@inheritDoc} */
358
    @Override
359
    @Persist
360
    public void save(IProgressMonitor monitor) {
361

    
362
        monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
363
        if (!conversation.isBound()) {
364
            conversation.bind();
365

    
366
        }
367
        conversation.commit(true);
368
        monitor.worked(1);
369

    
370
        // check for empty names
371
        if (checkForEmptyNames()) {
372
            MessageDialog.openWarning(AbstractUtility.getShell(), Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED,
373
                    Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE);
374
            return;
375
        }
376
        for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
377

    
378
            monitor.subTask(Messages.TaxonNameEditor_SAVING_COMPOSITES + container.getTaxonBase().getTitleCache());
379
            container.persistName();
380
            // because of missing cascading the concepts need to be saved
381
            // separately
382
            if (container instanceof ConceptContainerE4) {
383
                input.addToSaveNewConcept((Taxon) container.getData());
384
            }
385
            // In case the progress monitor was canceled throw an exception.
386
            if (monitor.isCanceled()) {
387
                throw new OperationCanceledException();
388
            }
389

    
390
            // Otherwise declare this step as done.
391
            monitor.worked(1);
392

    
393
        }
394
        input.setSync(sync);
395
        input.merge();
396
        // commit the conversation and start a new transaction immediately
397
        conversation.commit(true);
398

    
399
        dirty.setDirty(false);
400
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
401
        EventUtility.postEvent(WorkbenchEventConstants.SAVE_TAXON, true);
402
        // Stop the progress monitor.
403
        monitor.done();
404
    }
405

    
406
    public void init(TaxonEditorInputE4 input) {
407
        if (this.input != null) {
408
            this.input.dispose();
409
            // this.acceptedGroup = null;
410
            // this.heterotypicSynonymGroups.clear();
411
            // this.misappliedGroup = null;
412
        }
413
        if (!(input != null)) {
414
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT));
415
            return;
416
        }
417

    
418
        if (input.getAdapter(Taxon.class) != null) {
419
            taxon = CdmBase.deproxy(input.getAdapter(Taxon.class), Taxon.class);
420
        } else {
421
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT_TAXON_NULL));
422
            return;
423
        }
424

    
425
        this.input = input;
426
        conversation = input.getConversationHolder();
427

    
428
        createOrUpdateNameComposites(true, true, true);
429

    
430
        createDragSupport();
431

    
432
        setPartName();
433

    
434
        // set initial selection
435
        TaxonBase initiallySelectedTaxonBase = input.getInitiallySelectedTaxonBase();
436
        if (initiallySelectedTaxonBase != null) {
437
            selService.setSelection(new StructuredSelection(initiallySelectedTaxonBase));
438
            getContainer(initiallySelectedTaxonBase).setSelected();
439
        }
440
    }
441

    
442
    private void createDragSupport() {
443
        // Listen for names being dragged outside of existing homotypic groups -
444
        // user wants to create a new group
445
        Transfer[] types = new Transfer[] { CdmDataTransfer.getInstance() };
446
        int operations = DND.DROP_MOVE;
447
        if (target == null) {
448
            target = new DropTarget(parent, operations);
449
            target.setTransfer(types);
450
            target.addDropListener(new NameEditorDropTargetListenerE4(this));
451
        }
452
    }
453

    
454
    public AcceptedNameContainerE4 getAcceptedNameContainer() {
455
        return getAcceptedGroup().getAcceptedNameContainer();
456
    }
457

    
458
    public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(HomotypicalGroup homotypicalGroup) {
459
        for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
460
            if (group.getGroup().equals(homotypicalGroup)) {
461
                return group;
462
            }
463
        }
464

    
465
        return null;
466
    }
467

    
468
    /**
469
     * <p>
470
     * getDirtyNames
471
     * </p>
472
     *
473
     * @return a Set containing all composites that have been edited
474
     */
475
    public Set<AbstractGroupedContainerE4> getDirtyNames() {
476
        Set<AbstractGroupedContainerE4> dirtyNames = new HashSet<>();
477

    
478
        for (AbstractGroupedContainerE4 composite : getGroupedContainers()) {
479
            if (composite.isDirty()) {
480
                dirtyNames.add(composite);
481
            }
482
        }
483

    
484
        return dirtyNames;
485
    }
486

    
487
    public List<AbstractGroupedContainerE4> getGroupedContainers() {
488
        List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
489

    
490
        for (AbstractGroupE4 group : getAllGroups()) {
491
            if (group != null) {
492
                groupedComposites.addAll(group.getGroupedContainers());
493
            }
494
        }
495

    
496
        return groupedComposites;
497
    }
498

    
499
    public List<AbstractGroupE4> getAllGroups() {
500
        List<AbstractGroupE4> allGroups = new ArrayList<>();
501

    
502
        allGroups.add(getAcceptedGroup());
503

    
504
        heterotypicSynonymGroups = getHeterotypicSynonymGroups();
505

    
506
        if (heterotypicSynonymGroups != null) {
507
            allGroups.addAll(heterotypicSynonymGroups);
508
        }
509

    
510
        if (misappliedGroup != null) {
511
            allGroups.add(misappliedGroup);
512
        }
513

    
514
        return allGroups;
515
    }
516

    
517
    @Override
518
    public IEclipseContext getContext() {
519
        return context;
520
    }
521

    
522
    @Override
523
    public boolean isDirty() {
524
        return dirty.isDirty();
525
    }
526

    
527
    @PreDestroy
528
    public void dispose() {
529
        if (conversation != null) {
530
            conversation.unregisterForDataStoreChanges(this);
531
            conversation.close();
532
        }
533
        if (input != null) {
534
            input.dispose();
535
        }
536
        dirty.setDirty(false);
537
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null);
538
    }
539

    
540
    /** {@inheritDoc} */
541
    @Override
542
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
543
        System.err.println("Bla");
544
    }
545

    
546
    public AbstractGroupedContainerE4 getSelectedContainer() {
547
        return (selection != null) ? getContainer(selection) : getAcceptedNameContainer();
548
    }
549

    
550
    @Override
551
    public void dragEntered() {
552
        // TODO change this
553
        getControl().setBackground(AbstractUtility.getColor(Resources.COLOR_DRAG_ENTER));
554
    }
555

    
556
    @Override
557
    public void dragLeft() {
558
        getControl().setBackground(AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
559
    }
560

    
561
    public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
562
        this.misappliedGroup = misappliedGroup;
563
    }
564

    
565
    public FormToolkit getToolkit() {
566
        return managedForm.getToolkit();
567
    }
568

    
569
    public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
570
        return heterotypicSynonymGroups;
571
    }
572

    
573
    public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
574
        heterotypicSynonymGroups.add(group);
575
    }
576

    
577
    public AcceptedGroupE4 getAcceptedGroup() {
578
        return acceptedGroup;
579
    }
580

    
581
    public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
582
        this.acceptedGroup = acceptedGroup;
583
    }
584

    
585
    public MisappliedGroupE4 getMisappliedGroup() {
586
        return misappliedGroup;
587
    }
588

    
589
    public boolean isActive() {
590
        return this.equals(AbstractUtility.getActivePart());
591
    }
592

    
593
    @Override
594
    public boolean onComplete() {
595
        getContainer(objectAffectedByLastOperation).setSelected();
596
        return true;
597
    }
598

    
599
    /** {@inheritDoc} */
600
    @Override
601
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
602
        if (!partRef.getPart(false).equals(this)) {
603
            // getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
604
        }
605
    }
606

    
607
    public void removeGroup(AbstractGroupE4 group) {
608
        if (group != null) {
609
            group.dispose();
610

    
611
            // if (heterotypicSynonymGroups != null) {
612
            heterotypicSynonymGroups.remove(group);
613
            // }
614
        }
615
    }
616

    
617
    public AbstractGroupedContainerE4 getContainer(TaxonBase taxonBase) {
618
        @SuppressWarnings("rawtypes")
619
        List<AbstractGroupedContainerE4> groupedContainers = getGroupedContainers();
620
        for (AbstractGroupedContainerE4 container : groupedContainers) {
621
            if (container.getData().equals(taxonBase) && container.getNameViewer().getTextWidget() != null) {
622
                return container;
623
            }
624
        }
625
        return getAcceptedNameContainer();
626
    }
627

    
628
    public void setOnError() {
629
        Color disabledColor = AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
630
        setEnabled(false, disabledColor);
631
    }
632

    
633
    public void setDisabled() {
634
        Color disabledColor = AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND);
635
        setEnabled(false, disabledColor);
636
    }
637

    
638
    protected void setEnabled(boolean enabled, Color background) {
639

    
640
        for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
641
            groupedContainer.setEnabled(enabled);
642
        }
643

    
644
        // send an empty selection to the current provider - TODO only on error
645
        // ???
646
        if (!enabled) {
647
            getManagedForm().setInput(null);
648

    
649
            for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
650
                groupedContainer.setBackground(background);
651
            }
652
        }
653
        getControl().setBackground(background);
654
    }
655

    
656
    @Override
657
    public void changed(Object element) {
658
        // setDirty(true);
659
        // if the attribute is null then do not set the dirty flag -> hotfix for
660
        // the problem that for tasks done in service methods the changes are
661
        // saved automatically
662
        if (element != null) {
663
            dirty.setDirty(true);
664
            // refresh part title
665
            // TODO: refresh taxon node in taxon navigator
666
            setPartName();
667
        }
668

    
669
        if (element instanceof TaxonBase) {
670
            AbstractGroupedContainerE4 container = getContainer((TaxonBase) element);
671
            if (container != null) {
672
                container.refresh();
673
            }
674
        }
675

    
676
        if (element instanceof TaxonRelationship) {
677
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
678
            if (container != null) {
679
                container.refresh();
680
            }
681
        }
682
    }
683

    
684
    public void setPartName() {
685
        // FIXME: temporary fix for #6437 to avoid outdated title caches
686
        thisPart.setLabel(this.taxon.getName().generateFullTitle());
687
        // thisPart.setLabel(this.taxon.getName().getFullTitleCache());
688
    }
689

    
690
    @Override
691
    public void forceDirty() {
692
        setDirty();
693
    }
694

    
695
    public IUndoContext getUndoContext() {
696
        return undoContext;
697
    }
698

    
699
    @Override
700
    public Composite getControl() {
701
        return managedForm.getForm().getBody();
702
    }
703

    
704
    public EMenuService getMenuService() {
705
        return menuService;
706
    }
707

    
708
    public ESelectionService getSelectionService() {
709
        return selService;
710
    }
711

    
712
    /**
713
     * {@inheritDoc}
714
     */
715
    @Override
716
    public boolean canAttachMedia() {
717
        return true;
718
    }
719

    
720
    public TaxonEditorInputE4 getEditorInput() {
721
        return input;
722
    }
723

    
724
    /**
725
     * {@inheritDoc}
726
     */
727
    @Override
728
    public TaxonNameEditorE4 getEditor() {
729
        return this;
730
    }
731

    
732
    @Inject
733
    @Optional
734
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) CdmBase cdmbase) {
735

    
736
        if ((EventUtility.getTaxonEditor() != null && EventUtility.getTaxonEditor().equals(this))
737
                || (this.taxon != null && (this.taxon.equals(cdmbase)
738
                        || (this.taxon.getName() != null && this.taxon.getName().equals(cdmbase))))) {
739
            this.redraw(false, true, true, true);
740
            this.setDirty();
741
            if (cdmbase instanceof TaxonBase) {
742
                this.selection = (TaxonBase) cdmbase;
743
            }
744

    
745
        }
746
    }
747

    
748
    @Inject
749
    @Optional
750
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) UUID cdmbaseUuid) {
751

    
752
        if (this.taxon.getUuid().equals(cdmbaseUuid)) {
753
            TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(cdmbaseUuid);
754
            init(input);
755
        }
756
    }
757

    
758
    @Inject
759
    @Optional
760
    private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants.DELETE_DERIVATIVE) DeleteResult result) {
761
        if (taxon.getName() == null) {
762
            return;
763
        }
764
        Set<DerivedUnit> typeDesignationSpecimens = new HashSet<>();
765
        this.taxon.getName().getSpecimenTypeDesignations()
766
                .forEach(designation -> typeDesignationSpecimens.add(designation.getTypeSpecimen()));
767
        // check if any deleted object was a type specimen
768
        if (result.getUpdatedObjects().stream()
769
                // filter only DerivedUnits
770
                .filter(cdmBase -> cdmBase.isInstanceOf(DerivedUnit.class))
771
                // deproxy from CdmBase to DerivedUnit
772
                .map(unit -> HibernateProxyHelper.deproxy(unit, DerivedUnit.class))
773
                // check for match in type designations
774
                .anyMatch(unit -> typeDesignationSpecimens.contains(unit))) {
775
            EditorUtil.updateEditor(this.input.getTaxonNode(), this);
776

    
777
        }
778

    
779
    }
780

    
781
}
(2-2/2)