Project

General

Profile

Download (22 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.ContainerFactoryE4;
77
import eu.etaxonomy.taxeditor.editor.name.e4.container.HomotypicalSynonymGroupE4;
78
import eu.etaxonomy.taxeditor.editor.name.e4.container.MisappliedGroupE4;
79
import eu.etaxonomy.taxeditor.editor.name.e4.dnd.NameEditorDropTargetListenerE4;
80
import eu.etaxonomy.taxeditor.event.EventUtility;
81
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
82
import eu.etaxonomy.taxeditor.model.AbstractUtility;
83
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
84
import eu.etaxonomy.taxeditor.model.IPartChangeListener;
85
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
86
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
87
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
88
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
89
import eu.etaxonomy.taxeditor.model.MessagingUtils;
90
import eu.etaxonomy.taxeditor.model.TaxeditorPartService;
91
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
92
import eu.etaxonomy.taxeditor.preference.Resources;
93
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
94
import eu.etaxonomy.taxeditor.store.CdmStore;
95
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
96

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

    
107
	private Taxon taxon;
108

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

    
114
	private TaxonBase selection;
115

    
116
	private ConversationHolder conversation;
117

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

    
122
	private DropTarget target;
123

    
124
	@Inject
125
	UISynchronize sync;
126

    
127
	private TaxonBase objectAffectedByLastOperation;
128

    
129
	@Inject
130
	private EMenuService menuService;
131

    
132
	@Inject
133
	private ESelectionService selService;
134

    
135
	@Inject
136
	private IEclipseContext context;
137

    
138
	@Inject
139
	private MDirtyable dirty;
140

    
141
	private MPart thisPart;
142

    
143
    private TaxonEditorInputE4 input;
144

    
145
    private UndoContext undoContext;
146

    
147
    @Inject
148
    private IEventBroker eventBroker;
149

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

    
155

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

    
160
        createManagedForm(parent);
161

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

    
165
	}
166

    
167
	protected void createManagedForm(Composite composite) {
168

    
169
		managedForm = new ManagedForm(composite) {
170

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

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

    
189

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

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

    
197
		parent.setData(taxon);
198

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

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

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

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

    
224

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

    
230

    
231
	}
232

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

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

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

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

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

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

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

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

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

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

    
300
		createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
301

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

    
306
		return true;
307
	}
308

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

    
312
		changed(objectAffectedByOperation);
313

    
314
		redraw(true, true,true, true);
315

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

    
320
		return true;
321
	}
322

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

    
327

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

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

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

    
355
		return containersWithEmptyNames;
356
	}
357

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

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

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

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

    
379
	        monitor.subTask(Messages.TaxonNameEditor_SAVING_COMPOSITES
380
	                + container.getTaxonBase().getTitleCache());
381
	        container.persistName();
382

    
383
	        // In case the progress monitor was canceled throw an exception.
384
	        if (monitor.isCanceled()) {
385
	            throw new OperationCanceledException();
386
	        }
387

    
388
	     // Otherwise declare this step as done.
389
	        monitor.worked(1);
390

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

    
397

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

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

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

    
423
		this.input = input;
424
		conversation = input.getConversationHolder();
425

    
426
        createOrUpdateNameComposites(true, true, true);
427

    
428
        createDragSupport();
429

    
430
        setPartName();
431

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

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

    
452
	public AcceptedNameContainerE4 getAcceptedNameContainer() {
453
		return getAcceptedGroup().getAcceptedNameContainer();
454
	}
455

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

    
464
		return null;
465
	}
466

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

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

    
483
		return dirtyNames;
484
	}
485

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

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

    
495
		return groupedComposites;
496
	}
497

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

    
501
		allGroups.add(getAcceptedGroup());
502

    
503
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
504

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

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

    
513
		return allGroups;
514
	}
515

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

    
521
	public boolean isDirty() {
522
		return dirty.isDirty();
523
	}
524

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

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

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

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

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

    
562

    
563
	public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
564
		this.misappliedGroup = misappliedGroup;
565
	}
566

    
567
	public FormToolkit getToolkit() {
568
		return managedForm.getToolkit();
569
	}
570

    
571
	public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
572
		return heterotypicSynonymGroups;
573
	}
574

    
575
	public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
576
		heterotypicSynonymGroups.add(group);
577
	}
578

    
579
	public AcceptedGroupE4 getAcceptedGroup() {
580
		return acceptedGroup;
581
	}
582

    
583
	public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
584
		this.acceptedGroup = acceptedGroup;
585
	}
586

    
587
	public MisappliedGroupE4 getMisappliedGroup() {
588
		return misappliedGroup;
589
	}
590

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

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

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

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

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

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

    
631
    public void setOnError() {
632
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
633
		setEnabled(false, disabledColor);
634
	}
635

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

    
641
	protected void setEnabled(boolean enabled, Color background) {
642

    
643
		for(AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()){
644
			groupedContainer.setEnabled(enabled);
645
		}
646

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

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

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

    
669
        if (element instanceof TaxonBase) {
670
            AbstractGroupedContainerE4 container = getContainer((TaxonBase) element);
671
            if (container != null) {
672
                container.refresh();
673
            }
674
        }
675
        if (element instanceof TaxonRelationship) {
676
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
677
            if (container != null) {
678
                container.refresh();
679
            }
680
        }
681
    }
682

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

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

    
694

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

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

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

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

    
712

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

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

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

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

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

    
744

    
745
        }
746
    }
747

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

    
766
        }
767

    
768

    
769

    
770

    
771
    }
772

    
773
}
(2-2/2)