Project

General

Profile

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

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

    
21
import org.apache.commons.lang.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.ui.MDirtyable;
34
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
35
import org.eclipse.e4.ui.services.EMenuService;
36
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
37
import org.eclipse.jface.dialogs.MessageDialog;
38
import org.eclipse.jface.viewers.ISelection;
39
import org.eclipse.jface.viewers.ISelectionProvider;
40
import org.eclipse.jface.viewers.StructuredSelection;
41
import org.eclipse.swt.dnd.DND;
42
import org.eclipse.swt.dnd.DropTarget;
43
import org.eclipse.swt.dnd.Transfer;
44
import org.eclipse.swt.graphics.Color;
45
import org.eclipse.swt.widgets.Composite;
46
import org.eclipse.ui.ISelectionListener;
47
import org.eclipse.ui.IWorkbenchPart;
48
import org.eclipse.ui.IWorkbenchPartReference;
49
import org.eclipse.ui.forms.ManagedForm;
50
import org.eclipse.ui.forms.widgets.FormToolkit;
51
import org.eclipse.ui.forms.widgets.ScrolledForm;
52
import org.eclipse.ui.forms.widgets.TableWrapLayout;
53

    
54
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
55
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
56
import eu.etaxonomy.cdm.api.service.DeleteResult;
57
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
58
import eu.etaxonomy.cdm.model.common.CdmBase;
59
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
60
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
61
import eu.etaxonomy.cdm.model.taxon.Taxon;
62
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
63
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
64
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
65
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
66
import eu.etaxonomy.taxeditor.editor.CdmDataTransfer;
67
import eu.etaxonomy.taxeditor.editor.EditorUtil;
68
import eu.etaxonomy.taxeditor.editor.ISecuredEditor;
69
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
70
import eu.etaxonomy.taxeditor.editor.e4.TaxonEditorInputE4;
71
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
72
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupE4;
73
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupedContainerE4;
74
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedGroupE4;
75
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedNameContainerE4;
76
import eu.etaxonomy.taxeditor.editor.name.e4.container.ConceptContainerE4;
77
import eu.etaxonomy.taxeditor.editor.name.e4.container.ContainerFactoryE4;
78
import eu.etaxonomy.taxeditor.editor.name.e4.container.HomotypicalSynonymGroupE4;
79
import eu.etaxonomy.taxeditor.editor.name.e4.container.MisappliedGroupE4;
80
import eu.etaxonomy.taxeditor.editor.name.e4.dnd.NameEditorDropTargetListenerE4;
81
import eu.etaxonomy.taxeditor.event.EventUtility;
82
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
83
import eu.etaxonomy.taxeditor.model.AbstractUtility;
84
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
85
import eu.etaxonomy.taxeditor.model.IPartChangeListener;
86
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
87
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
88
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
89
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
90
import eu.etaxonomy.taxeditor.model.MessagingUtils;
91
import eu.etaxonomy.taxeditor.model.TaxeditorPartService;
92
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
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, IPostOperationEnabled, 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
	    if (accepted){
216
	        ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
217
	    }
218
	    if (heterotypicGroups){
219
	        ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
220
	    }
221
	    if (misappliedNames){
222
	        ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
223
	    }
224

    
225

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

    
231

    
232
	}
233

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

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

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

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

    
260
	        // check permissions
261
	        boolean doEnable = permissionsSatisfied();
262
	        managedForm.getForm().setEnabled(doEnable);
263
	    }
264
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
265
	}
266

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

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

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

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

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

    
301
		createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
302

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

    
307
		return true;
308
	}
309

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

    
313
		changed(objectAffectedByOperation);
314

    
315
		redraw(true, true,true, true);
316

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

    
321
		return true;
322
	}
323

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

    
328

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

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

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

    
356
		return containersWithEmptyNames;
357
	}
358

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

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

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

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

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

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

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

    
401

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

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

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

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

    
430
        createOrUpdateNameComposites(true, true, true);
431

    
432
        createDragSupport();
433

    
434
        setPartName();
435

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

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

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

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

    
468
		return null;
469
	}
470

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

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

    
487
		return dirtyNames;
488
	}
489

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

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

    
499
		return groupedComposites;
500
	}
501

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

    
505
		allGroups.add(getAcceptedGroup());
506

    
507
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
508

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

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

    
517
		return allGroups;
518
	}
519

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

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

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

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

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

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

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

    
566

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
698

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

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

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

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

    
716

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

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

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

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

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

    
748

    
749
        }
750
    }
751

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

    
770
        }
771

    
772

    
773

    
774

    
775
    }
776

    
777
}
(2-2/2)