Project

General

Profile

Download (22.7 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.operation.IPostOperationEnabled;
94
import eu.etaxonomy.taxeditor.preference.Resources;
95
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
96
import eu.etaxonomy.taxeditor.store.CdmStore;
97
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
98

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

    
109
	private Taxon taxon;
110

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

    
116
	private TaxonBase selection;
117

    
118
	private ConversationHolder conversation;
119

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

    
124
	private DropTarget target;
125

    
126
	@Inject
127
	UISynchronize sync;
128

    
129
	private TaxonBase objectAffectedByLastOperation;
130

    
131
	@Inject
132
	private EMenuService menuService;
133

    
134
	@Inject
135
	private ESelectionService selService;
136

    
137
	@Inject
138
	private IEclipseContext context;
139

    
140
	@Inject
141
	private MDirtyable dirty;
142

    
143
	private MPart thisPart;
144

    
145
    private TaxonEditorInputE4 input;
146

    
147
    private UndoContext undoContext;
148

    
149
    @Inject
150
    private IEventBroker eventBroker;
151

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

    
157

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

    
162
        createManagedForm(parent);
163

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

    
167
	}
168

    
169
	protected void createManagedForm(Composite composite) {
170

    
171
		managedForm = new ManagedForm(composite) {
172

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

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

    
191

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

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

    
199
		parent.setData(taxon);
200

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

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

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

    
215
	public void createOrUpdateNameComposites(boolean accepted, boolean heterotypicGroups, boolean misappliedNames) {
216
	    if (accepted){
217
	        ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
218
	    }
219
	    if (heterotypicGroups){
220
	        ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
221
	    }
222
	    if (misappliedNames){
223
	        ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
224
	    }
225

    
226

    
227
		// Redraw composite
228
	    parent.pack();
229
		managedForm.refresh();
230
		managedForm.reflow(true);
231

    
232

    
233
	}
234

    
235
	@Override
236
    public Taxon getTaxon() {
237
		return HibernateProxyHelper.deproxy(taxon);
238
	}
239

    
240
	public void setDirty() {
241
		managedForm.dirtyStateChanged();
242
	}
243

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

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

    
261
	        // check permissions
262
	        boolean doEnable = permissionsSatisfied();
263
	        managedForm.getForm().setEnabled(doEnable);
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(), RequiredPermissions.TAXON_EDIT);
272
		return doEnable;
273
	}
274

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

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

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

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

    
302
		createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
303

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

    
308
		return true;
309
	}
310

    
311
	@Override
312
    public boolean postOperation(CdmBase objectAffectedByOperation) {
313

    
314
		changed(objectAffectedByOperation);
315

    
316
		redraw(true, true,true, true);
317

    
318
		if (objectAffectedByOperation instanceof TaxonBase) {
319
			objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
320
		}
321

    
322
		return true;
323
	}
324

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

    
329

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

    
347
	public Set<AbstractGroupedContainerE4> getEmptyContainers() {
348
		Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
349

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

    
357
		return containersWithEmptyNames;
358
	}
359

    
360
	/** {@inheritDoc} */
361
	@Override
362
    @Persist
363
	public void save(IProgressMonitor monitor) {
364

    
365
	    monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
366
	    if (!conversation.isBound()) {
367
	        conversation.bind();
368

    
369
	    }
370
	    conversation.commit(true);
371
	    monitor.worked(1);
372

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

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

    
393
	     // Otherwise declare this step as done.
394
	        monitor.worked(1);
395

    
396
	    }
397
	    input.setSync(sync);
398
	    input.merge();
399
	    // commit the conversation and start a new transaction immediately
400
        conversation.commit(true);
401

    
402

    
403
        dirty.setDirty(false);
404
        EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
405
	    // Stop the progress monitor.
406
	    monitor.done();
407
	}
408

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

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

    
428
		this.input = input;
429
		conversation = input.getConversationHolder();
430

    
431
        createOrUpdateNameComposites(true, true, true);
432

    
433
        createDragSupport();
434

    
435
        setPartName();
436

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

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

    
457
	public AcceptedNameContainerE4 getAcceptedNameContainer() {
458
		return getAcceptedGroup().getAcceptedNameContainer();
459
	}
460

    
461
	public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(
462
			HomotypicalGroup homotypicalGroup) {
463
		for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
464
			if (group.getGroup().equals(homotypicalGroup)) {
465
				return group;
466
			}
467
		}
468

    
469
		return null;
470
	}
471

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

    
482
		for (AbstractGroupedContainerE4 composite : getGroupedContainers()) {
483
			if (composite.isDirty()) {
484
				dirtyNames.add(composite);
485
			}
486
		}
487

    
488
		return dirtyNames;
489
	}
490

    
491
	public List<AbstractGroupedContainerE4> getGroupedContainers() {
492
		List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
493

    
494
		for (AbstractGroupE4 group : getAllGroups()) {
495
		    if (group!= null){
496
		        groupedComposites.addAll(group.getGroupedContainers());
497
		    }
498
		}
499

    
500
		return groupedComposites;
501
	}
502

    
503
	public List<AbstractGroupE4> getAllGroups() {
504
		List<AbstractGroupE4> allGroups = new ArrayList<>();
505

    
506
		allGroups.add(getAcceptedGroup());
507

    
508
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
509

    
510
		if (heterotypicSynonymGroups != null) {
511
			allGroups.addAll(heterotypicSynonymGroups);
512
		}
513

    
514
		if (misappliedGroup != null) {
515
			allGroups.add(misappliedGroup);
516
		}
517

    
518
		return allGroups;
519
	}
520

    
521
	@Override
522
	public IEclipseContext getContext() {
523
	    return context;
524
	}
525

    
526
	public boolean isDirty() {
527
		return dirty.isDirty();
528
	}
529

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

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

    
549
	public AbstractGroupedContainerE4 getSelectedContainer() {
550
		return (selection != null) ? getContainer(selection)
551
				: getAcceptedNameContainer();
552
	}
553

    
554
    @Override
555
    public void dragEntered() {
556
        // TODO change this
557
        getControl().setBackground(
558
                AbstractUtility.getColor(Resources.COLOR_DRAG_ENTER));
559
    }
560

    
561
    @Override
562
    public void dragLeft() {
563
        getControl().setBackground(
564
                AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
565
    }
566

    
567

    
568
	public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
569
		this.misappliedGroup = misappliedGroup;
570
	}
571

    
572
	public FormToolkit getToolkit() {
573
		return managedForm.getToolkit();
574
	}
575

    
576
	public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
577
		return heterotypicSynonymGroups;
578
	}
579

    
580
	public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
581
		heterotypicSynonymGroups.add(group);
582
	}
583

    
584
	public AcceptedGroupE4 getAcceptedGroup() {
585
		return acceptedGroup;
586
	}
587

    
588
	public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
589
		this.acceptedGroup = acceptedGroup;
590
	}
591

    
592
	public MisappliedGroupE4 getMisappliedGroup() {
593
		return misappliedGroup;
594
	}
595

    
596
	public boolean isActive() {
597
		return this.equals(AbstractUtility.getActivePart());
598
	}
599

    
600
    @Override
601
    public boolean onComplete() {
602
		getContainer(objectAffectedByLastOperation).setSelected();
603
		return true;
604
	}
605

    
606
	/** {@inheritDoc} */
607
	@Override
608
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
609
		if (!partRef.getPart(false).equals(this)) {
610
			// getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
611
		}
612
	}
613

    
614
	public void removeGroup(AbstractGroupE4 group) {
615
		if (group != null) {
616
			group.dispose();
617

    
618
			//if (heterotypicSynonymGroups != null) {
619
			heterotypicSynonymGroups.remove(group);
620
			//}
621
		}
622
	}
623

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

    
636
    public void setOnError() {
637
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
638
		setEnabled(false, disabledColor);
639
	}
640

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

    
646
	protected void setEnabled(boolean enabled, Color background) {
647

    
648
		for(AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()){
649
			groupedContainer.setEnabled(enabled);
650
		}
651

    
652
		// send an empty selection to the current provider - TODO only on error ???
653
		if (!enabled) {
654
			getManagedForm().setInput(null);
655

    
656
			for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
657
				groupedContainer.setBackground(background);
658
			}
659
		}
660
		getControl().setBackground(background);
661
	}
662

    
663
    @Override
664
    public void changed(Object element) {
665
        // setDirty(true);
666
        // 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
667
        if (element != null){
668
            dirty.setDirty(true);
669
            //refresh part title
670
            //TODO: refresh taxon node in taxon navigator
671
            setPartName();
672
        }
673

    
674
        if (element instanceof TaxonBase) {
675
            AbstractGroupedContainerE4 container = getContainer((TaxonBase) element);
676
            if (container != null) {
677
                container.refresh();
678
            }
679
        }
680
        if (element instanceof TaxonRelationship) {
681
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
682
            if (container != null) {
683
                container.refresh();
684
            }
685
        }
686
    }
687

    
688
    public void setPartName(){
689
        //FIXME: temporary fix for #6437 to avoid outdated title caches
690
        thisPart.setLabel(this.taxon.getName().generateFullTitle());
691
//        thisPart.setLabel(this.taxon.getName().getFullTitleCache());
692
    }
693

    
694
    @Override
695
    public void forceDirty() {
696
        setDirty();
697
    }
698

    
699

    
700
    public IUndoContext getUndoContext() {
701
        return undoContext;
702
    }
703

    
704
    @Override
705
    public Composite getControl(){
706
        return managedForm.getForm().getBody();
707
    }
708

    
709
    public EMenuService getMenuService() {
710
        return menuService;
711
    }
712

    
713
    public ESelectionService getSelectionService() {
714
        return selService;
715
    }
716

    
717

    
718
    /**
719
     * {@inheritDoc}
720
     */
721
    @Override
722
    public boolean canAttachMedia() {
723
        return true;
724
    }
725

    
726
    public TaxonEditorInputE4 getEditorInput() {
727
        return input;
728
    }
729

    
730
    /**
731
     * {@inheritDoc}
732
     */
733
    @Override
734
    public TaxonNameEditorE4 getEditor() {
735
        return this;
736
    }
737

    
738
    @Inject
739
    @Optional
740
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR)CdmBase cdmbase){
741

    
742
        if (EventUtility.getTaxonEditor().equals(this) || (this.taxon.equals(cdmbase) || this.taxon.getName().equals(cdmbase))){
743
            this.redraw(false, true, true, true);
744
            this.setDirty();
745
            if (cdmbase instanceof TaxonBase){
746
                this.selection = (TaxonBase) cdmbase;
747
            }
748

    
749

    
750
        }
751
    }
752

    
753
    @Inject
754
    @Optional
755
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR)UUID cdmbaseUuid){
756

    
757
        if (this.taxon.getUuid().equals(cdmbaseUuid)){
758
            TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(cdmbaseUuid);
759
            init(input);
760
        }
761
    }
762

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

    
781
        }
782

    
783

    
784

    
785

    
786
    }
787

    
788
}
(2-2/2)