Project

General

Profile

Download (22.9 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

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

    
161
        createManagedForm(parent);
162

    
163
		TaxeditorPartService.getInstance().addListener(
164
				TaxeditorPartService.PART_ACTIVATED, this);
165

    
166
	}
167

    
168
	protected void createManagedForm(Composite composite) {
169

    
170
		managedForm = new ManagedForm(composite) {
171

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

    
177
			@Override
178
			public boolean setInput(Object input) {
179
				if (input instanceof AbstractGroupedContainerE4) {
180
				    TaxonBase newSelection = ((AbstractGroupedContainerE4) input).getData();
181
				    if(selection!=newSelection || TaxonNameEditorE4.this.isDirty()){
182
				        selection = newSelection;
183
				        selService.setSelection(new StructuredSelection(selection));
184
				    }
185
				}else if(input == null){
186
					selection = null;
187
                    selService.setSelection(new StructuredSelection());
188
				}
189

    
190

    
191
				return super.setInput(input);
192
			}
193
		};
194

    
195
		scrolledForm = managedForm.getForm();
196
		parent = scrolledForm.getBody();
197

    
198
		parent.setData(taxon);
199

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

    
206
		layout.verticalSpacing = 0;
207
		layout.horizontalSpacing = 0;
208

    
209
		parent.setLayout(layout);
210
		parent.setBackground(AbstractUtility
211
				.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
212
	}
213

    
214
	public void createOrUpdateNameComposites(boolean accepted, boolean heterotypicGroups, boolean misappliedNames) {
215

    
216

    
217
	    if (accepted){
218
            ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
219
        }
220
        if (heterotypicGroups){
221
            ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
222
        }
223
        if (misappliedNames){
224
            ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
225
        }
226
        ContainerFactoryE4.setMenuToAllContainers(this);
227

    
228

    
229

    
230
		// Redraw composite
231
	    parent.pack();
232
		managedForm.refresh();
233
		managedForm.reflow(true);
234

    
235

    
236
	}
237

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

    
243
	public void setDirty() {
244
		managedForm.dirtyStateChanged();
245
	}
246

    
247
	@Focus
248
	public void setFocus() {
249
	    //make sure to bind again if maybe in another view the conversation was unbound
250
        if(conversation!=null && !conversation.isBound()){
251
            conversation.bind();
252
        }
253

    
254
	    if(input!=null){
255
	        if (getSelectedContainer() == null) {
256
	            throw new IllegalStateException(
257
	                    Messages.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE);
258
	        }
259
	        getSelectedContainer().setSelected();
260
	        if (!input.getCdmEntitySession().isActive()){
261
	            input.bind();
262
	        }
263

    
264
	        // check permissions
265
	        boolean doEnable = permissionsSatisfied();
266
	        managedForm.getForm().setEnabled(doEnable);
267
	    }
268
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
269
	}
270

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

    
278
	@Override
279
    public ConversationHolder getConversationHolder() {
280
		return conversation;
281
	}
282

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

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

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

    
305
		createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
306

    
307
		if (focus) {
308
			setFocus();
309
		}
310

    
311
		return true;
312
	}
313

    
314
	@Override
315
    public boolean postOperation(Object objectAffectedByOperation) {
316

    
317
		changed(objectAffectedByOperation);
318

    
319
		redraw(true, true,true, true);
320

    
321
		if (objectAffectedByOperation instanceof TaxonBase) {
322
			objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
323
		}
324

    
325
		return true;
326
	}
327

    
328
	public ManagedForm getManagedForm() {
329
		return managedForm;
330
	}
331

    
332

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

    
350
	public Set<AbstractGroupedContainerE4> getEmptyContainers() {
351
		Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
352

    
353
		for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
354
			if (container.getName() == null
355
					|| StringUtils.isEmpty(container.getName().getTitleCache())) {
356
				containersWithEmptyNames.add(container);
357
			}
358
		}
359

    
360
		return containersWithEmptyNames;
361
	}
362

    
363
	/** {@inheritDoc} */
364
	@Override
365
    @Persist
366
	public void save(IProgressMonitor monitor) {
367

    
368
	    monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
369
	    if (!conversation.isBound()) {
370
	        conversation.bind();
371

    
372
	    }
373
	    conversation.commit(true);
374
	    monitor.worked(1);
375

    
376
	    // check for empty names
377
	    if (checkForEmptyNames()) {
378
	        MessageDialog.openWarning(AbstractUtility.getShell(), Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED,
379
	                Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE);
380
	        return;
381
	    }
382
	    for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
383

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

    
396
	     // Otherwise declare this step as done.
397
	        monitor.worked(1);
398

    
399
	    }
400
	    input.setSync(sync);
401
	    input.merge();
402
	    // commit the conversation and start a new transaction immediately
403
        conversation.commit(true);
404

    
405

    
406
        dirty.setDirty(false);
407
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
408
        EventUtility.postEvent(WorkbenchEventConstants.SAVE_TAXON, true);
409
	    // Stop the progress monitor.
410
	    monitor.done();
411
	}
412

    
413
	public void init(TaxonEditorInputE4 input) {
414
		if (this.input != null){
415
			this.input.dispose();
416
//			this.acceptedGroup = null;
417
//			this.heterotypicSynonymGroups.clear();
418
//			this.misappliedGroup = null;
419
		}
420
		if (!(input != null)) {
421
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT));
422
            return;
423
        }
424

    
425
		if (input.getAdapter(Taxon.class) != null) {
426
			taxon = CdmBase.deproxy(input.getAdapter(Taxon.class), Taxon.class);
427
		} else {
428
		    MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT_TAXON_NULL));
429
		    return;
430
		}
431

    
432
		this.input = input;
433
		conversation = input.getConversationHolder();
434

    
435
        createOrUpdateNameComposites(true, true, true);
436

    
437
        createDragSupport();
438

    
439
        setPartName();
440

    
441
        //set initial selection
442
        TaxonBase initiallySelectedTaxonBase = input.getInitiallySelectedTaxonBase();
443
        if(initiallySelectedTaxonBase!=null){
444
            selService.setSelection(new StructuredSelection(initiallySelectedTaxonBase));
445
            getContainer(initiallySelectedTaxonBase).setSelected();
446
        }
447
	}
448

    
449
   private void createDragSupport() {
450
       // Listen for names being dragged outside of existing homotypic groups -
451
       // user wants to create a new group
452
       Transfer[] types = new Transfer[] { CdmDataTransfer.getInstance() };
453
       int operations = DND.DROP_MOVE;
454
       if (target == null) {
455
           target = new DropTarget(parent, operations);
456
           target.setTransfer(types);
457
           target.addDropListener(new NameEditorDropTargetListenerE4(this));
458
       }
459
   }
460

    
461
	public AcceptedNameContainerE4 getAcceptedNameContainer() {
462
		return getAcceptedGroup().getAcceptedNameContainer();
463
	}
464

    
465
	public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(
466
			HomotypicalGroup homotypicalGroup) {
467
		for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
468
			if (group.getGroup().equals(homotypicalGroup)) {
469
				return group;
470
			}
471
		}
472

    
473
		return null;
474
	}
475

    
476
	/**
477
	 * <p>
478
	 * getDirtyNames
479
	 * </p>
480
	 *
481
	 * @return a Set containing all composites that have been edited
482
	 */
483
	public Set<AbstractGroupedContainerE4> getDirtyNames() {
484
		Set<AbstractGroupedContainerE4> dirtyNames = new HashSet<>();
485

    
486
		for (AbstractGroupedContainerE4 composite : getGroupedContainers()) {
487
			if (composite.isDirty()) {
488
				dirtyNames.add(composite);
489
			}
490
		}
491

    
492
		return dirtyNames;
493
	}
494

    
495
	public List<AbstractGroupedContainerE4> getGroupedContainers() {
496
		List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
497

    
498
		for (AbstractGroupE4 group : getAllGroups()) {
499
		    if (group!= null){
500
		        groupedComposites.addAll(group.getGroupedContainers());
501
		    }
502
		}
503

    
504
		return groupedComposites;
505
	}
506

    
507
	public List<AbstractGroupE4> getAllGroups() {
508
		List<AbstractGroupE4> allGroups = new ArrayList<>();
509

    
510
		allGroups.add(getAcceptedGroup());
511

    
512
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
513

    
514
		if (heterotypicSynonymGroups != null) {
515
			allGroups.addAll(heterotypicSynonymGroups);
516
		}
517

    
518
		if (misappliedGroup != null) {
519
			allGroups.add(misappliedGroup);
520
		}
521

    
522
		return allGroups;
523
	}
524

    
525
	@Override
526
	public IEclipseContext getContext() {
527
	    return context;
528
	}
529

    
530
	@Override
531
    public boolean isDirty() {
532
		return dirty.isDirty();
533
	}
534

    
535
	@PreDestroy
536
	public void dispose() {
537
        if(conversation!=null){
538
            conversation.unregisterForDataStoreChanges(this);
539
            conversation.close();
540
        }
541
        if(input!=null){
542
            input.dispose();
543
        }
544
        dirty.setDirty(false);
545
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null);
546
	}
547

    
548
	/** {@inheritDoc} */
549
	@Override
550
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
551
	    System.err.println("Bla");
552
	}
553

    
554
	public AbstractGroupedContainerE4 getSelectedContainer() {
555
		return (selection != null) ? getContainer(selection)
556
				: getAcceptedNameContainer();
557
	}
558

    
559
    @Override
560
    public void dragEntered() {
561
        // TODO change this
562
        getControl().setBackground(
563
                AbstractUtility.getColor(Resources.COLOR_DRAG_ENTER));
564
    }
565

    
566
    @Override
567
    public void dragLeft() {
568
        getControl().setBackground(
569
                AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
570
    }
571

    
572

    
573
	public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
574
		this.misappliedGroup = misappliedGroup;
575
	}
576

    
577
	public FormToolkit getToolkit() {
578
		return managedForm.getToolkit();
579
	}
580

    
581
	public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
582
		return heterotypicSynonymGroups;
583
	}
584

    
585
	public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
586
		heterotypicSynonymGroups.add(group);
587
	}
588

    
589
	public AcceptedGroupE4 getAcceptedGroup() {
590
		return acceptedGroup;
591
	}
592

    
593
	public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
594
		this.acceptedGroup = acceptedGroup;
595
	}
596

    
597
	public MisappliedGroupE4 getMisappliedGroup() {
598
		return misappliedGroup;
599
	}
600

    
601
	public boolean isActive() {
602
		return this.equals(AbstractUtility.getActivePart());
603
	}
604

    
605
    @Override
606
    public boolean onComplete() {
607
		getContainer(objectAffectedByLastOperation).setSelected();
608
		return true;
609
	}
610

    
611
	/** {@inheritDoc} */
612
	@Override
613
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
614
		if (!partRef.getPart(false).equals(this)) {
615
			// getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
616
		}
617
	}
618

    
619
	public void removeGroup(AbstractGroupE4 group) {
620
		if (group != null) {
621
			group.dispose();
622

    
623
			//if (heterotypicSynonymGroups != null) {
624
			heterotypicSynonymGroups.remove(group);
625
			//}
626
		}
627
	}
628

    
629
	public AbstractGroupedContainerE4 getContainer(TaxonBase taxonBase) {
630
		@SuppressWarnings("rawtypes")
631
        List<AbstractGroupedContainerE4> groupedContainers = getGroupedContainers();
632
		for (AbstractGroupedContainerE4 container : groupedContainers) {
633
			if (container.getData().equals(taxonBase)
634
					&& container.getNameViewer().getTextWidget() != null) {
635
				return container;
636
			}
637
		}
638
		return getAcceptedNameContainer();
639
	}
640

    
641
    public void setOnError() {
642
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
643
		setEnabled(false, disabledColor);
644
	}
645

    
646
	public void setDisabled(){
647
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND);
648
		setEnabled(false, disabledColor);
649
	}
650

    
651
	protected void setEnabled(boolean enabled, Color background) {
652

    
653
		for(AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()){
654
			groupedContainer.setEnabled(enabled);
655
		}
656

    
657
		// send an empty selection to the current provider - TODO only on error ???
658
		if (!enabled) {
659
			getManagedForm().setInput(null);
660

    
661
			for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
662
				groupedContainer.setBackground(background);
663
			}
664
		}
665
		getControl().setBackground(background);
666
	}
667

    
668
    @Override
669
    public void changed(Object element) {
670
        // setDirty(true);
671
        // if the attribute is null then do not set the dirty flag -> hotfix for the problem that for tasks done in service methods the changes are saved automatically
672
        if (element != null){
673
            dirty.setDirty(true);
674
            //refresh part title
675
            //TODO: refresh taxon node in taxon navigator
676
            setPartName();
677
        }
678

    
679
        if (element instanceof TaxonBase) {
680
            AbstractGroupedContainerE4 container = getContainer((TaxonBase) element);
681
            if (container != null) {
682
                container.refresh();
683
            }
684
        }
685

    
686
        if (element instanceof TaxonRelationship) {
687
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
688
            if (container != null) {
689
                container.refresh();
690
            }
691
        }
692
    }
693

    
694
    public void setPartName(){
695
        //FIXME: temporary fix for #6437 to avoid outdated title caches
696
        thisPart.setLabel(this.taxon.getName().generateFullTitle());
697
//        thisPart.setLabel(this.taxon.getName().getFullTitleCache());
698
    }
699

    
700
    @Override
701
    public void forceDirty() {
702
        setDirty();
703
    }
704

    
705

    
706
    public IUndoContext getUndoContext() {
707
        return undoContext;
708
    }
709

    
710
    @Override
711
    public Composite getControl(){
712
        return managedForm.getForm().getBody();
713
    }
714

    
715
    public EMenuService getMenuService() {
716
        return menuService;
717
    }
718

    
719
    public ESelectionService getSelectionService() {
720
        return selService;
721
    }
722

    
723

    
724
    /**
725
     * {@inheritDoc}
726
     */
727
    @Override
728
    public boolean canAttachMedia() {
729
        return true;
730
    }
731

    
732
    public TaxonEditorInputE4 getEditorInput() {
733
        return input;
734
    }
735

    
736
    /**
737
     * {@inheritDoc}
738
     */
739
    @Override
740
    public TaxonNameEditorE4 getEditor() {
741
        return this;
742
    }
743

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

    
748
        if ((EventUtility.getTaxonEditor() != null && EventUtility.getTaxonEditor().equals(this)) || (this.taxon != null && (this.taxon.equals(cdmbase) || (this.taxon.getName() != null && this.taxon.getName().equals(cdmbase))))){
749
            this.redraw(false, true, true, true);
750
            this.setDirty();
751
            if (cdmbase instanceof TaxonBase){
752
                this.selection = (TaxonBase) cdmbase;
753
            }
754

    
755

    
756
        }
757
    }
758

    
759
    @Inject
760
    @Optional
761
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR)UUID cdmbaseUuid){
762

    
763
        if (this.taxon.getUuid().equals(cdmbaseUuid)){
764
            TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(cdmbaseUuid);
765
            init(input);
766
        }
767
    }
768

    
769
    @Inject
770
    @Optional
771
    private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants.DELETE_DERIVATIVE)DeleteResult result){
772
        if(taxon.getName()==null){
773
            return;
774
        }
775
        Set<DerivedUnit> typeDesignationSpecimens = new HashSet<>();
776
        this.taxon.getName().getSpecimenTypeDesignations().forEach(designation->typeDesignationSpecimens.add(designation.getTypeSpecimen()));
777
        //check if any deleted object was a type specimen
778
        if(result.getUpdatedObjects().stream()
779
                //filter only DerivedUnits
780
                .filter(cdmBase->cdmBase.isInstanceOf(DerivedUnit.class))
781
                //deproxy from CdmBase to DerivedUnit
782
                .map(unit->HibernateProxyHelper.deproxy(unit, DerivedUnit.class))
783
                //check for match in type designations
784
                .anyMatch(unit->typeDesignationSpecimens.contains(unit))){
785
                EditorUtil.updateEditor(this.input.getTaxonNode(), this);
786

    
787
        }
788

    
789

    
790

    
791

    
792
    }
793

    
794
}
(2-2/2)