Project

General

Profile

Download (26.6 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
package eu.etaxonomy.taxeditor.editor.name.e4;
10

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

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

    
21
import org.apache.commons.lang3.StringUtils;
22
import org.eclipse.core.commands.operations.IUndoContext;
23
import org.eclipse.core.commands.operations.UndoContext;
24
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.core.runtime.OperationCanceledException;
26
import org.eclipse.e4.core.contexts.IEclipseContext;
27
import org.eclipse.e4.core.di.annotations.Optional;
28
import org.eclipse.e4.core.services.events.IEventBroker;
29
import org.eclipse.e4.ui.di.Focus;
30
import org.eclipse.e4.ui.di.Persist;
31
import org.eclipse.e4.ui.di.UIEventTopic;
32
import org.eclipse.e4.ui.di.UISynchronize;
33
import org.eclipse.e4.ui.model.application.MApplication;
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.EModelService;
38
import org.eclipse.e4.ui.workbench.modeling.EPartService;
39
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
40
import org.eclipse.jface.dialogs.MessageDialog;
41
import org.eclipse.jface.viewers.ISelection;
42
import org.eclipse.jface.viewers.StructuredSelection;
43
import org.eclipse.swt.dnd.DND;
44
import org.eclipse.swt.dnd.DropTarget;
45
import org.eclipse.swt.dnd.Transfer;
46
import org.eclipse.swt.graphics.Color;
47
import org.eclipse.swt.widgets.Composite;
48
import org.eclipse.ui.ISelectionListener;
49
import org.eclipse.ui.IWorkbenchPart;
50
import org.eclipse.ui.IWorkbenchPartReference;
51
import org.eclipse.ui.forms.ManagedForm;
52
import org.eclipse.ui.forms.widgets.FormToolkit;
53
import org.eclipse.ui.forms.widgets.ScrolledForm;
54
import org.eclipse.ui.forms.widgets.TableWrapLayout;
55

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

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

    
111
    private Taxon taxon;
112

    
113
    private ManagedForm managedForm;
114
    private ScrolledForm scrolledForm;
115
    private Composite parent;
116
    @Inject
117
    private EModelService modelService;
118

    
119
    @Inject
120
    private EPartService partService;
121
    private TaxonBase<?> selection;
122

    
123
    private ConversationHolder conversation;
124

    
125
    private AcceptedGroupE4 acceptedGroup;
126
    private List<HomotypicalSynonymGroupE4> heterotypicSynonymGroups = new ArrayList<>();
127
    private MisappliedGroupE4 misappliedGroup;
128

    
129
    private DropTarget target;
130

    
131
    @Inject
132
    UISynchronize sync;
133

    
134
    private TaxonBase<?> objectAffectedByLastOperation;
135

    
136
    @Inject
137
    private EMenuService menuService;
138

    
139
    @Inject
140
    private ESelectionService selService;
141

    
142
    @Inject
143
    private IEclipseContext context;
144

    
145
    @Inject
146
    private MDirtyable dirty;
147

    
148
    @Inject
149
    private MApplication application;
150

    
151
    private MPart thisPart;
152

    
153
    private TaxonEditorInputE4 input;
154

    
155
    private UndoContext undoContext;
156

    
157
    @Inject
158
    private IEventBroker eventBroker;
159

    
160
    @Inject
161
    public TaxonNameEditorE4() {
162
        undoContext = new UndoContext();
163
    }
164

    
165
    @PostConstruct
166
    public void createPartControl(Composite parent, MPart thisPart) {
167
        this.thisPart = thisPart;
168

    
169
        createManagedForm(parent);
170

    
171
        TaxeditorPartService.getInstance().addListener(TaxeditorPartService.PART_ACTIVATED, this);
172
    }
173

    
174
    protected void createManagedForm(Composite composite) {
175

    
176
        managedForm = new ManagedForm(composite) {
177

    
178
            @Override
179
            public void dirtyStateChanged() {
180
                dirty.setDirty(true);
181
            }
182

    
183
            @Override
184
            public boolean setInput(Object input) {
185
                if (input instanceof AbstractGroupedContainerE4) {
186
                    TaxonBase<?> newSelection = ((AbstractGroupedContainerE4<?>) input).getData();
187
                    if (selection != newSelection || TaxonNameEditorE4.this.isDirty()) {
188
                        selection = newSelection;
189
                        selService.setSelection(new StructuredSelection(selection));
190

    
191
                    }
192
                } else if (input == null) {
193
                    selection = null;
194
                    selService.setSelection(new StructuredSelection());
195
                }
196

    
197
                return super.setInput(input);
198
            }
199
        };
200

    
201
        scrolledForm = managedForm.getForm();
202
        parent = scrolledForm.getBody();
203

    
204
        parent.setData(taxon);
205

    
206
        TableWrapLayout layout = new TableWrapLayout();
207
        layout.leftMargin = 0;
208
        layout.rightMargin = 0;
209
        layout.topMargin = 0;
210
        layout.bottomMargin = 0;
211

    
212
        layout.verticalSpacing = 0;
213
        layout.horizontalSpacing = 0;
214

    
215
        parent.setLayout(layout);
216
        parent.setBackground(AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
217
    }
218

    
219
    public void createOrUpdateNameComposites(boolean accepted, boolean heterotypicGroups, boolean misappliedNames) {
220

    
221
        if (accepted) {
222
            ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
223
        }
224
        if (heterotypicGroups) {
225
            ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
226
        }
227
        if (misappliedNames) {
228
            ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
229
        }
230
        ContainerFactoryE4.setMenuToAllContainers(this);
231

    
232
        // Redraw composite
233
        parent.pack();
234
        managedForm.refresh();
235
        managedForm.reflow(true);
236
    }
237

    
238
    @Override
239
    public Taxon getTaxon() {
240
        return HibernateProxyHelper.deproxy(taxon);
241
    }
242

    
243
    @Override
244
    public void addOperation(AbstractPostOperation operation) {
245
        input.addOperation(operation);
246
    }
247

    
248
    public void setDirty() {
249
        managedForm.dirtyStateChanged();
250
    }
251

    
252
    @Focus
253
    public void setFocus() {
254
        // make sure to bind again if maybe in another view the conversation was
255
        // unbound
256
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
257
        if (conversation != null && !conversation.isBound()) {
258
            conversation.bind();
259
        }
260
        if (EditorUtil.isFactsVisible()){
261
            EditorUtil.showFacts(modelService, partService);
262
        }
263
        if (EditorUtil.isMediaVisible()){
264
            EditorUtil.showMedia(modelService, partService);
265
        }
266
        if (input != null) {
267
            if (getSelectedContainer() == null) {
268
                throw new IllegalStateException(Messages.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE);
269
            }
270
            getSelectedContainer().setSelected();
271

    
272
            if (input.getCdmEntitySession() != null && !input.getCdmEntitySession().isActive()) {
273
                input.bind();
274
            }
275
        }
276
//        if(selection!=null){
277
//            selService.setSelection(new StructuredSelection(selection));
278
//        }
279
        // check permissions
280
        boolean doEnable = permissionsSatisfied();
281
        managedForm.getForm().setEnabled(doEnable);
282
    }
283

    
284
    @Override
285
    public boolean permissionsSatisfied() {
286
        boolean doEnable = false;
287
        if (input != null){
288
            TaxonNode taxonNode = input.getTaxonNode();
289
            doEnable = CdmStore.currentAuthentiationHasPermission(taxonNode,
290
                    RequiredPermissions.TAXON_EDIT);
291
        }
292
        return doEnable;
293
    }
294

    
295
    @Override
296
    public ConversationHolder getConversationHolder() {
297
        return conversation;
298
    }
299

    
300
    @Override
301
    public void update(CdmDataChangeMap events) {
302
        // redraw();
303
    }
304

    
305
    /**
306
     * Redraws this editor return true on success
307
     *
308
     * @return a boolean.
309
     */
310
    public boolean redraw() {
311
        return redraw(true, true, true, true);
312
    }
313

    
314
    /**
315
     * {@inheritDoc}
316
     *
317
     * Redraws the editor controls
318
     */
319
    public boolean redraw(boolean focus, boolean accepted, boolean heterotypic, boolean misappliedNames) {
320

    
321
        createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
322

    
323
        if (focus) {
324
            setFocus();
325
        }
326

    
327
        return true;
328
    }
329

    
330
    @Override
331
    public boolean postOperation(Object objectAffectedByOperation) {
332
        if (objectAffectedByOperation instanceof TaxonBase) {
333
            objectAffectedByLastOperation = (TaxonBase<?>) objectAffectedByOperation;
334
        }
335
        redraw(true, true, true, true);
336
        changed(objectAffectedByOperation);
337
        onComplete();
338
        getContainer(objectAffectedByLastOperation).setFocus();
339
        return true;
340
    }
341

    
342
    public ManagedForm getManagedForm() {
343
        return managedForm;
344
    }
345

    
346
    /**
347
     * <p>
348
     * checkForEmptyNames
349
     * </p>
350
     *
351
     * @return true if there are empty names
352
     */
353
    public boolean checkForEmptyNames() {
354
        for (AbstractGroupedContainerE4<?> container : getGroupedContainers()) {
355
            if (container != null
356
                    && (container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache()))) {
357
                return true;
358
            }
359
        }
360
        return false;
361
    }
362

    
363
    public Set<AbstractGroupedContainerE4> getEmptyContainers() {
364
        Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
365

    
366
        for (AbstractGroupedContainerE4<?> container : getGroupedContainers()) {
367
            if (container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache())) {
368
                containersWithEmptyNames.add(container);
369
            }
370
        }
371

    
372
        return containersWithEmptyNames;
373
    }
374

    
375
    @Override
376
    @Persist
377
    public void save(IProgressMonitor monitor) {
378

    
379
        monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
380
        if (!conversation.isBound()) {
381
            conversation.bind();
382

    
383
        }
384
        conversation.commit(true);
385
        monitor.worked(1);
386

    
387
        // check for empty names
388
        if (checkForEmptyNames()) {
389
            MessageDialog.openWarning(AbstractUtility.getShell(), Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED,
390
                    Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE);
391
            return;
392
        }
393
        for (AbstractGroupedContainerE4<?> container : getGroupedContainers()) {
394

    
395
            monitor.subTask(Messages.TaxonNameEditor_SAVING_COMPOSITES + container.getTaxonBase().getTitleCache());
396
            container.persistName();
397
            // because of missing cascading the concepts need to be saved
398
            // separately
399
            if (container instanceof ConceptContainerE4) {
400
                input.addToSaveConcept((Taxon) container.getData());
401
            }
402
            // In case the progress monitor was canceled throw an exception.
403
            if (monitor.isCanceled()) {
404
                throw new OperationCanceledException();
405
            }
406

    
407
            // Otherwise declare this step as done.
408
            monitor.worked(1);
409
        }
410
        input.setSync(sync);
411
        input.merge();
412
        // commit the conversation and start a new transaction immediately
413
        conversation.commit(true);
414

    
415
        dirty.setDirty(false);
416
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, new TaxonNodeDto(input.getTaxonNode().getParent()));
417
        EventUtility.postEvent(WorkbenchEventConstants.SAVE_TAXON, true);
418
        // Stop the progress monitor.
419
        monitor.done();
420
    }
421

    
422
    public void init(TaxonEditorInputE4 input) {
423
        if (this.input != null) {
424
            this.input.dispose();
425
            // this.acceptedGroup = null;
426
            // this.heterotypicSynonymGroups.clear();
427
            // this.misappliedGroup = null;
428
        }
429
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
430
        if (!(input != null)) {
431
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT));
432
            return;
433
        }
434

    
435
        if (input.getAdapter(Taxon.class) != null) {
436
            taxon = CdmBase.deproxy(input.getAdapter(Taxon.class), Taxon.class);
437
        } else {
438
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT_TAXON_NULL));
439
            return;
440
        }
441

    
442
        this.input = input;
443
        conversation = input.getConversationHolder();
444

    
445
        createOrUpdateNameComposites(true, true, true);
446

    
447
        createDragSupport();
448

    
449
        setPartName();
450
//        this.setFocus();
451
        // set initial selection
452
        TaxonBase<?> initiallySelectedTaxonBase = input.getInitiallySelectedTaxonBase();
453
        if (initiallySelectedTaxonBase != null) {
454
            selService.setSelection(new StructuredSelection(initiallySelectedTaxonBase));
455
            getContainer(initiallySelectedTaxonBase).setSelected();
456
        }
457
    }
458

    
459
    private void createDragSupport() {
460
        // Listen for names being dragged outside of existing homotypic groups -
461
        // user wants to create a new group
462
        Transfer[] types = new Transfer[] { CdmDataTransfer.getInstance() };
463
        int operations = DND.DROP_MOVE;
464
        if (target == null) {
465
            target = new DropTarget(parent, operations);
466
            target.setTransfer(types);
467
            target.addDropListener(new NameEditorDropTargetListenerE4(this));
468
        }
469
    }
470

    
471
    public AcceptedNameContainerE4 getAcceptedNameContainer() {
472
        return getAcceptedGroup().getAcceptedNameContainer();
473
    }
474

    
475
    public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(HomotypicalGroup homotypicalGroup) {
476
        for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
477
            if (group.getGroup().equals(homotypicalGroup)) {
478
                return group;
479
            }
480
        }
481

    
482
        return null;
483
    }
484

    
485
    /**
486
     * <p>
487
     * getDirtyNames
488
     * </p>
489
     *
490
     * @return a Set containing all composites that have been edited
491
     */
492
    public Set<AbstractGroupedContainerE4> getDirtyNames() {
493
        Set<AbstractGroupedContainerE4> dirtyNames = new HashSet<>();
494

    
495
        for (AbstractGroupedContainerE4<?> composite : getGroupedContainers()) {
496
            if (composite.isDirty()) {
497
                dirtyNames.add(composite);
498
            }
499
        }
500

    
501
        return dirtyNames;
502
    }
503

    
504
    public List<AbstractGroupedContainerE4> getGroupedContainers() {
505
        List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
506

    
507
        for (AbstractGroupE4 group : getAllGroups()) {
508
            if (group != null) {
509
                groupedComposites.addAll(group.getGroupedContainers());
510
            }
511
        }
512

    
513
        return groupedComposites;
514
    }
515

    
516
    public List<AbstractGroupE4> getAllGroups() {
517
        List<AbstractGroupE4> allGroups = new ArrayList<>();
518

    
519
        allGroups.add(getAcceptedGroup());
520

    
521
        heterotypicSynonymGroups = getHeterotypicSynonymGroups();
522

    
523
        if (heterotypicSynonymGroups != null) {
524
            allGroups.addAll(heterotypicSynonymGroups);
525
        }
526

    
527
        if (misappliedGroup != null) {
528
            allGroups.add(misappliedGroup);
529
        }
530

    
531
        return allGroups;
532
    }
533

    
534
    @Override
535
    public IEclipseContext getContext() {
536
        return context;
537
    }
538

    
539
    @Override
540
    public boolean isDirty() {
541
        return dirty.isDirty();
542
    }
543

    
544
    @PreDestroy
545
    public void dispose() {
546
        if (conversation != null) {
547
            conversation.unregisterForDataStoreChanges(this);
548
            conversation.close();
549
        }
550
        if (input != null) {
551
            input.dispose();
552
        }
553
        dirty.setDirty(false);
554
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null);
555
    }
556

    
557
    @Override
558
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
559

    
560
    }
561

    
562
    public AbstractGroupedContainerE4 getSelectedContainer() {
563
        if (selection == null && input != null){
564
            selection = this.input.getTaxon();
565
        }
566
        return (selection != null) ? getContainer(selection) : getAcceptedNameContainer();
567
    }
568

    
569
    @Override
570
    public void dragEntered() {
571
        // TODO change this
572
        getControl().setBackground(AbstractUtility.getColor(Resources.COLOR_DRAG_ENTER));
573
    }
574

    
575
    @Override
576
    public void dragLeft() {
577
        getControl().setBackground(AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
578
    }
579

    
580
    public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
581
        this.misappliedGroup = misappliedGroup;
582
    }
583

    
584
    public FormToolkit getToolkit() {
585
        return managedForm.getToolkit();
586
    }
587

    
588
    public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
589
        return heterotypicSynonymGroups;
590
    }
591

    
592
    public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
593
        heterotypicSynonymGroups.add(group);
594
    }
595

    
596
    public AcceptedGroupE4 getAcceptedGroup() {
597
        return acceptedGroup;
598
    }
599

    
600
    public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
601
        this.acceptedGroup = acceptedGroup;
602
    }
603

    
604
    public MisappliedGroupE4 getMisappliedGroup() {
605
        return misappliedGroup;
606
    }
607

    
608
    public boolean isActive() {
609
        return this.equals(AbstractUtility.getActivePart());
610
    }
611

    
612
    @Override
613
    public boolean onComplete() {
614
        getContainer(objectAffectedByLastOperation).setSelected();
615
        return true;
616
    }
617

    
618
    @Override
619
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
620
        if (!partRef.getPart(false).equals(this)) {
621

    
622

    
623
        }
624
    }
625

    
626
    public void removeGroup(AbstractGroupE4 group) {
627
        if (group != null) {
628
            group.dispose();
629

    
630
            // if (heterotypicSynonymGroups != null) {
631
            heterotypicSynonymGroups.remove(group);
632
            // }
633
        }
634
    }
635

    
636
    public AbstractGroupedContainerE4 getContainer(TaxonBase taxonBase) {
637
        @SuppressWarnings("rawtypes")
638
        List<AbstractGroupedContainerE4> groupedContainers = getGroupedContainers();
639
        for (AbstractGroupedContainerE4<?> container : groupedContainers) {
640
            if (container.getData().equals(taxonBase) && container.getNameViewer().getTextWidget() != null) {
641
                return container;
642
            }
643
        }
644
        return getAcceptedNameContainer();
645
    }
646

    
647
    public void setOnError() {
648
        Color disabledColor = AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
649
        setEnabled(false, disabledColor);
650
    }
651

    
652
    public void setDisabled() {
653
        Color disabledColor = AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND);
654
        setEnabled(false, disabledColor);
655
    }
656

    
657
    protected void setEnabled(boolean enabled, Color background) {
658

    
659
        for (AbstractGroupedContainerE4<?> groupedContainer : getGroupedContainers()) {
660
            groupedContainer.setEnabled(enabled);
661
        }
662

    
663
        // send an empty selection to the current provider - TODO only on error
664
        // ???
665
        if (!enabled) {
666
            getManagedForm().setInput(null);
667

    
668
            for (AbstractGroupedContainerE4<?> groupedContainer : getGroupedContainers()) {
669
                groupedContainer.setBackground(background);
670
            }
671
        }
672
        getControl().setBackground(background);
673
    }
674

    
675
    @Override
676
    public void changed(Object element) {
677
        // setDirty(true);
678
        // if the attribute is null then do not set the dirty flag -> hotfix for
679
        // the problem that for tasks done in service methods the changes are
680
        // saved automatically
681
        if (element != null) {
682
            dirty.setDirty(true);
683
            // refresh part title
684
            // TODO: refresh taxon node in taxon navigator
685
            setPartName();
686
        }
687

    
688
        if (element instanceof TaxonBase) {
689
            AbstractGroupedContainerE4<?> container = getContainer((TaxonBase<?>) element);
690
            if (container != null) {
691
                container.refresh();
692
            }
693
        }
694

    
695
        if (element instanceof TaxonRelationship) {
696
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
697
            if (container != null) {
698
                container.refresh();
699
            }
700
        }
701
    }
702

    
703
    public void setPartName() {
704
        // FIXME: temporary fix for #6437 to avoid outdated title caches
705
        thisPart.setLabel(this.taxon.getName().generateFullTitle());
706
        // thisPart.setLabel(this.taxon.getName().getFullTitleCache());
707
    }
708

    
709
    @Override
710
    public void forceDirty() {
711
        setDirty();
712
    }
713

    
714
    public IUndoContext getUndoContext() {
715
        return undoContext;
716
    }
717

    
718
    @Override
719
    public Composite getControl() {
720
        return managedForm.getForm().getBody();
721
    }
722

    
723
    public EMenuService getMenuService() {
724
        return menuService;
725
    }
726

    
727
    public ESelectionService getSelectionService() {
728
        return selService;
729
    }
730

    
731
    @Override
732
    public boolean canAttachMedia() {
733
        return true;
734
    }
735

    
736
    public TaxonEditorInputE4 getEditorInput() {
737
        return input;
738
    }
739

    
740
    @Override
741
    public TaxonNameEditorE4 getEditor() {
742
        return this;
743
    }
744

    
745
    @Inject
746
    @Optional
747
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) CdmBase cdmbase) {
748

    
749
          if(this.taxon != null && (this.taxon.equals(cdmbase)
750
                        || (this.taxon.getName() != null && this.taxon.getName().equals(cdmbase)))) {
751
            this.redraw(false, true, true, true);
752
            this.setDirty();
753
            if (cdmbase instanceof TaxonBase) {
754
                this.selection = (TaxonBase<?>) cdmbase;
755
            }
756
        }
757
    }
758

    
759
    @Inject
760
    @Optional
761
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) List<CdmBase> cdmBases) {
762

    
763
        for (CdmBase cdmBase: cdmBases){
764
            if (cdmBase instanceof Taxon || cdmBase instanceof TaxonName){
765
                if (this.taxon != null && (this.taxon.equals(cdmBase)
766
                                || (this.taxon.getName() != null && this.taxon.getName().equals(cdmBase)))) {
767
                    update();
768
                }
769
            }
770
        }
771
    }
772

    
773
    @Inject
774
    @Optional
775
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) UUID cdmbaseUuid) {
776
        if (this.taxon.getUuid().equals(cdmbaseUuid)) {
777
            TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(cdmbaseUuid);
778
            init(input);
779
        }
780
    }
781

    
782
    @Inject
783
    @Optional
784
    private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants.DELETE_DERIVATIVE) DeleteResult result) {
785
        if (taxon.getName() == null) {
786
            return;
787
        }
788
        Set<DerivedUnit> typeDesignationSpecimens = new HashSet<>();
789
        this.taxon.getName().getSpecimenTypeDesignations()
790
                .forEach(designation -> typeDesignationSpecimens.add(designation.getTypeSpecimen()));
791
        // check if any deleted object was a type specimen
792
        if (result.getUpdatedObjects().stream()
793
                // filter only DerivedUnits
794
                .filter(cdmBase -> cdmBase.isInstanceOf(DerivedUnit.class))
795
                // deproxy from CdmBase to DerivedUnit
796
                .map(unit -> HibernateProxyHelper.deproxy(unit, DerivedUnit.class))
797
                // check for match in type designations
798
                .anyMatch(unit -> typeDesignationSpecimens.contains(unit))) {
799
            EditorUtil.updateEditor(this.input.getTaxonNode(), this);
800
        }
801
    }
802

    
803
    @Override
804
    public void update() {
805
        EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
806
        EModelService modelService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EModelService.class);
807
        EditorUtil.openTaxonBaseE4(this.getTaxon().getUuid(), modelService, partService, application);
808
    }
809

    
810
    @Override
811
    public TaxonNode getTaxonNode() {
812
        return input.getTaxonNode();
813
    }
814
}
(2-2/2)