Project

General

Profile

Download (21.5 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.model.application.MApplication;
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.EPartService;
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.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.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
	private TaxonBase objectAffectedByLastOperation;
125

    
126
	@Inject
127
	private EMenuService menuService;
128

    
129
	@Inject
130
	private ESelectionService selService;
131

    
132
	@Inject
133
	private IEclipseContext context;
134

    
135
	@Inject
136
	private MDirtyable dirty;
137

    
138
	private MPart thisPart;
139

    
140
    private TaxonEditorInputE4 input;
141

    
142
    private UndoContext undoContext;
143

    
144
    @Inject
145
    private IEventBroker eventBroker;
146

    
147
	@Inject
148
	public TaxonNameEditorE4() {
149
	    undoContext = new UndoContext();
150
	}
151

    
152

    
153
	@PostConstruct
154
    public void createPartControl(Composite parent, MPart thisPart) {
155
	    this.thisPart = thisPart;
156

    
157
        createManagedForm(parent);
158

    
159
		TaxeditorPartService.getInstance().addListener(
160
				TaxeditorPartService.PART_ACTIVATED, this);
161

    
162
	}
163

    
164
	protected void createManagedForm(Composite composite) {
165

    
166
		managedForm = new ManagedForm(composite) {
167

    
168
			@Override
169
			public void dirtyStateChanged() {
170
			    dirty.setDirty(true);
171
			}
172

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

    
186

    
187
				return super.setInput(input);
188
			}
189
		};
190

    
191
		scrolledForm = managedForm.getForm();
192
		parent = scrolledForm.getBody();
193

    
194
		parent.setData(taxon);
195

    
196
		TableWrapLayout layout = new TableWrapLayout();
197
		layout.leftMargin = 0;
198
		layout.rightMargin = 0;
199
		layout.topMargin = 0;
200
		layout.bottomMargin = 0;
201

    
202
		layout.verticalSpacing = 0;
203
		layout.horizontalSpacing = 0;
204

    
205
		parent.setLayout(layout);
206
		parent.setBackground(AbstractUtility
207
				.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
208
	}
209

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

    
221

    
222
		// Redraw composite
223
		managedForm.reflow(true);
224
		managedForm.refresh();
225
	}
226

    
227
	@Override
228
    public Taxon getTaxon() {
229
		return HibernateProxyHelper.deproxy(taxon);
230
	}
231

    
232
	public void setDirty() {
233
		managedForm.dirtyStateChanged();
234
	}
235

    
236
	@Focus
237
	public void setFocus() {
238
	    //make sure to bind again if maybe in another view the conversation was unbound
239
        if(conversation!=null && !conversation.isBound()){
240
            conversation.bind();
241
        }
242

    
243
	    if(input!=null){
244
	        if (getSelectedContainer() == null) {
245
	            throw new IllegalStateException(
246
	                    Messages.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE);
247
	        }
248
	        getSelectedContainer().setSelected();
249
	        if (!input.getCdmEntitySession().isActive()){
250
	            input.bind();
251
	        }
252

    
253
	        // check permissions
254
	        boolean doEnable = permissionsSatisfied();
255
	        managedForm.getForm().setEnabled(doEnable);
256
	    }
257
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, this);
258
	}
259

    
260
	@Override
261
	public boolean permissionsSatisfied() {
262
		TaxonNode taxonNode = input.getTaxonNode();
263
		boolean doEnable = CdmStore.currentAuthentiationHasPermission(taxonNode, RequiredPermissions.TAXONNODE_EDIT);
264
		return doEnable;
265
	}
266

    
267
	@Override
268
    public ConversationHolder getConversationHolder() {
269
		return conversation;
270
	}
271

    
272
	/** {@inheritDoc} */
273
	@Override
274
    public void update(CdmDataChangeMap events) {
275
		// redraw();
276
	}
277

    
278
	/**
279
	 * Redraws this editor return true on success
280
	 *
281
	 * @return a boolean.
282
	 */
283
    public boolean redraw() {
284
		return redraw(true, true, true, true);
285
	}
286

    
287
	/**
288
	 * {@inheritDoc}
289
	 *
290
	 * Redraws the editor controls
291
	 */
292
    public boolean redraw(boolean focus, boolean accepted, boolean heterotypic, boolean misappliedNames) {
293

    
294
		createOrUpdateNameComposites(accepted, heterotypic, misappliedNames);
295

    
296
		if (focus) {
297
			setFocus();
298
		}
299

    
300
		return true;
301
	}
302

    
303
	@Override
304
    public boolean postOperation(CdmBase objectAffectedByOperation) {
305

    
306
		changed(objectAffectedByOperation);
307

    
308
		redraw(true, true,true, true);
309

    
310
		if (objectAffectedByOperation instanceof TaxonBase) {
311
			objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
312
		}
313

    
314
		return true;
315
	}
316

    
317
	public ManagedForm getManagedForm() {
318
		return managedForm;
319
	}
320

    
321

    
322
	/**
323
	 * <p>
324
	 * checkForEmptyNames
325
	 * </p>
326
	 *
327
	 * @return true if there are empty names
328
	 */
329
	public boolean checkForEmptyNames() {
330
		for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
331
			if (container.getName() == null
332
					|| StringUtils.isEmpty(container.getName().getTitleCache())) {
333
				return true;
334
			}
335
		}
336
		return false;
337
	}
338

    
339
	public Set<AbstractGroupedContainerE4> getEmptyContainers() {
340
		Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
341

    
342
		for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
343
			if (container.getName() == null
344
					|| StringUtils.isEmpty(container.getName().getTitleCache())) {
345
				containersWithEmptyNames.add(container);
346
			}
347
		}
348

    
349
		return containersWithEmptyNames;
350
	}
351

    
352
	/** {@inheritDoc} */
353
	@Override
354
    @Persist
355
	public void save(IProgressMonitor monitor) {
356

    
357
	    monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
358
	    if (!conversation.isBound()) {
359
	        conversation.bind();
360

    
361
	    }
362
	    conversation.commit(true);
363
	    monitor.worked(1);
364

    
365
	    // check for empty names
366
	    if (checkForEmptyNames()) {
367
	        MessageDialog.openWarning(AbstractUtility.getShell(), Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED,
368
	                Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE);
369
	        return;
370
	    }
371
	    for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
372

    
373
	        monitor.subTask(Messages.TaxonNameEditor_SAVING_COMPOSITES
374
	                + container.getTaxonBase().getTitleCache());
375
	        container.persistName();
376

    
377
	        // In case the progress monitor was canceled throw an exception.
378
	        if (monitor.isCanceled()) {
379
	            throw new OperationCanceledException();
380
	        }
381

    
382
	     // Otherwise declare this step as done.
383
	        monitor.worked(1);
384

    
385
	    }
386
	    input.merge();
387
	    // commit the conversation and start a new transaction immediately
388
        conversation.commit(true);
389

    
390

    
391
        dirty.setDirty(false);
392

    
393
	    // Stop the progress monitor.
394
	    monitor.done();
395
	}
396

    
397
	public void init(TaxonEditorInputE4 input) {
398
		if (this.input != null){
399
			this.input.dispose();
400
//			this.acceptedGroup = null;
401
//			this.heterotypicSynonymGroups.clear();
402
//			this.misappliedGroup = null;
403
		}
404
		if (!(input != null)) {
405
            MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT));
406
            return;
407
        }
408

    
409
		if (input.getAdapter(Taxon.class) != null) {
410
			taxon = CdmBase.deproxy(input.getAdapter(Taxon.class), Taxon.class);
411
		} else {
412
		    MessagingUtils.error(this.getClass(), new Exception(Messages.TaxonNameEditor_INVALID_INPUT_TAXON_NULL));
413
		    return;
414
		}
415

    
416
		this.input = input;
417
		conversation = input.getConversationHolder();
418

    
419
        createOrUpdateNameComposites(true, true, true);
420

    
421
        createDragSupport();
422

    
423
        setPartName();
424

    
425
        //set initial selection
426
        TaxonBase initiallySelectedTaxonBase = input.getInitiallySelectedTaxonBase();
427
        if(initiallySelectedTaxonBase!=null){
428
            selService.setSelection(new StructuredSelection(initiallySelectedTaxonBase));
429
            getContainer(initiallySelectedTaxonBase).setSelected();
430
        }
431
	}
432

    
433
   private void createDragSupport() {
434
       // Listen for names being dragged outside of existing homotypic groups -
435
       // user wants to create a new group
436
       Transfer[] types = new Transfer[] { CdmDataTransfer.getInstance() };
437
       int operations = DND.DROP_MOVE;
438
       if (target == null) {
439
           target = new DropTarget(parent, operations);
440
           target.setTransfer(types);
441
           target.addDropListener(new NameEditorDropTargetListenerE4(this));
442
       }
443
   }
444

    
445
	public AcceptedNameContainerE4 getAcceptedNameContainer() {
446
		return getAcceptedGroup().getAcceptedNameContainer();
447
	}
448

    
449
	public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(
450
			HomotypicalGroup homotypicalGroup) {
451
		for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
452
			if (group.getGroup().equals(homotypicalGroup)) {
453
				return group;
454
			}
455
		}
456

    
457
		return null;
458
	}
459

    
460
	/**
461
	 * <p>
462
	 * getDirtyNames
463
	 * </p>
464
	 *
465
	 * @return a Set containing all composites that have been edited
466
	 */
467
	public Set<AbstractGroupedContainerE4> getDirtyNames() {
468
		Set<AbstractGroupedContainerE4> dirtyNames = new HashSet<>();
469

    
470
		for (AbstractGroupedContainerE4 composite : getGroupedContainers()) {
471
			if (composite.isDirty()) {
472
				dirtyNames.add(composite);
473
			}
474
		}
475

    
476
		return dirtyNames;
477
	}
478

    
479
	public List<AbstractGroupedContainerE4> getGroupedContainers() {
480
		List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
481

    
482
		for (AbstractGroupE4 group : getAllGroups()) {
483
		    if (group!= null){
484
		        groupedComposites.addAll(group.getGroupedContainers());
485
		    }
486
		}
487

    
488
		return groupedComposites;
489
	}
490

    
491
	public List<AbstractGroupE4> getAllGroups() {
492
		List<AbstractGroupE4> allGroups = new ArrayList<>();
493

    
494
		allGroups.add(getAcceptedGroup());
495

    
496
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
497

    
498
		if (heterotypicSynonymGroups != null) {
499
			allGroups.addAll(heterotypicSynonymGroups);
500
		}
501

    
502
		if (misappliedGroup != null) {
503
			allGroups.add(misappliedGroup);
504
		}
505

    
506
		return allGroups;
507
	}
508

    
509
	@Override
510
	public IEclipseContext getContext() {
511
	    return context;
512
	}
513

    
514
	public boolean isDirty() {
515
		return dirty.isDirty();
516
	}
517

    
518
	@PreDestroy
519
	public void dispose() {
520
        if(conversation!=null){
521
            conversation.unregisterForDataStoreChanges(this);
522
            conversation.close();
523
        }
524
        if(input!=null){
525
            input.dispose();
526
        }
527
        eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null);
528
	}
529

    
530
	/** {@inheritDoc} */
531
	@Override
532
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
533
	    System.err.println("Bla");
534
	}
535

    
536
	public AbstractGroupedContainerE4 getSelectedContainer() {
537
		return (selection != null) ? getContainer(selection)
538
				: getAcceptedNameContainer();
539
	}
540

    
541
    @Override
542
    public void dragEntered() {
543
        // TODO change this
544
        getControl().setBackground(
545
                AbstractUtility.getColor(Resources.COLOR_DRAG_ENTER));
546
    }
547

    
548
    @Override
549
    public void dragLeft() {
550
        getControl().setBackground(
551
                AbstractUtility.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
552
    }
553

    
554

    
555
	public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
556
		this.misappliedGroup = misappliedGroup;
557
	}
558

    
559
	public FormToolkit getToolkit() {
560
		return managedForm.getToolkit();
561
	}
562

    
563
	public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
564
		return heterotypicSynonymGroups;
565
	}
566

    
567
	public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
568
		heterotypicSynonymGroups.add(group);
569
	}
570

    
571
	public AcceptedGroupE4 getAcceptedGroup() {
572
		return acceptedGroup;
573
	}
574

    
575
	public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
576
		this.acceptedGroup = acceptedGroup;
577
	}
578

    
579
	public MisappliedGroupE4 getMisappliedGroup() {
580
		return misappliedGroup;
581
	}
582

    
583
	public boolean isActive() {
584
		return this.equals(AbstractUtility.getActivePart());
585
	}
586

    
587
    @Override
588
    public boolean onComplete() {
589
		getContainer(objectAffectedByLastOperation).setSelected();
590
		return true;
591
	}
592

    
593
	/** {@inheritDoc} */
594
	@Override
595
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
596
		if (!partRef.getPart(false).equals(this)) {
597
			// getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
598
		}
599
	}
600

    
601
	public void removeGroup(AbstractGroupE4 group) {
602
		if (group != null) {
603
			group.dispose();
604

    
605
			//if (heterotypicSynonymGroups != null) {
606
			heterotypicSynonymGroups.remove(group);
607
			//}
608
		}
609
	}
610

    
611
	public AbstractGroupedContainerE4 getContainer(TaxonBase taxonBase) {
612
		@SuppressWarnings("rawtypes")
613
        List<AbstractGroupedContainerE4> groupedContainers = getGroupedContainers();
614
		for (AbstractGroupedContainerE4 container : groupedContainers) {
615
			if (container.getData().equals(taxonBase)
616
					&& container.getNameViewer().getTextWidget() != null) {
617
				return container;
618
			}
619
		}
620
		return getAcceptedNameContainer();
621
	}
622

    
623
    public void setOnError() {
624
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
625
		setEnabled(false, disabledColor);
626
	}
627

    
628
	public void setDisabled(){
629
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND);
630
		setEnabled(false, disabledColor);
631
	}
632

    
633
	protected void setEnabled(boolean enabled, Color background) {
634

    
635
		for(AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()){
636
			groupedContainer.setEnabled(enabled);
637
		}
638

    
639
		// send an empty selection to the current provider - TODO only on error ???
640
		if (!enabled) {
641
			getManagedForm().setInput(null);
642

    
643
			for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
644
				groupedContainer.setBackground(background);
645
			}
646
		}
647
		getControl().setBackground(background);
648
	}
649

    
650
    @Override
651
    public void changed(Object element) {
652
        // setDirty(true);
653
        // 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
654
        if (element != null){
655
            dirty.setDirty(true);
656
            //refresh part title
657
            //TODO: refresh taxon node in taxon navigator
658
            setPartName();
659
        }
660

    
661
        if (element instanceof TaxonBase) {
662
            AbstractGroupedContainerE4 container = getContainer((TaxonBase) element);
663
            if (container != null) {
664
                container.refresh();
665
            }
666
        }
667
        if (element instanceof TaxonRelationship) {
668
            AbstractGroupedContainerE4 container = getContainer(((TaxonRelationship) element).getFromTaxon());
669
            if (container != null) {
670
                container.refresh();
671
            }
672
        }
673
    }
674

    
675
    public void setPartName(){
676
        thisPart.setLabel(this.taxon.getName().getFullTitleCache());
677
    }
678

    
679
    @Override
680
    public void forceDirty() {
681
        setDirty();
682
    }
683

    
684

    
685
    public IUndoContext getUndoContext() {
686
        return undoContext;
687
    }
688

    
689
    @Override
690
    public Composite getControl(){
691
        return managedForm.getForm().getBody();
692
    }
693

    
694
    public EMenuService getMenuService() {
695
        return menuService;
696
    }
697

    
698
    public ESelectionService getSelectionService() {
699
        return selService;
700
    }
701

    
702

    
703
    /**
704
     * {@inheritDoc}
705
     */
706
    @Override
707
    public boolean canAttachMedia() {
708
        return true;
709
    }
710

    
711
    public TaxonEditorInputE4 getEditorInput() {
712
        return input;
713
    }
714

    
715
    /**
716
     * {@inheritDoc}
717
     */
718
    @Override
719
    public TaxonNameEditorE4 getEditor() {
720
        return this;
721
    }
722

    
723
    @Inject
724
    @Optional
725
    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR)boolean refresh){
726
        if(refresh){
727
            this.redraw(false, false, false, true);
728
        }
729
    }
730

    
731
    @Inject
732
    @Optional
733
    private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants.DELETE_DERIVATIVE)DeleteResult result,
734
            EPartService partService, MApplication application){
735
        if(taxon.getName()==null){
736
            return;
737
        }
738
        Set<DerivedUnit> typeDesignationSpecimens = new HashSet<>();
739
        this.taxon.getName().getSpecimenTypeDesignations().forEach(designation->typeDesignationSpecimens.add(designation.getTypeSpecimen()));
740
        //check if any deleted object was a type specimen
741
        if(result.getUpdatedObjects().stream()
742
                //filter only DerivedUnits
743
                .filter(cdmBase->cdmBase.isInstanceOf(DerivedUnit.class))
744
                //deproxy from CdmBase to DerivedUnit
745
                .map(unit->HibernateProxyHelper.deproxy(unit, DerivedUnit.class))
746
                //check for match in type designations
747
                .anyMatch(unit->typeDesignationSpecimens.contains(unit))){
748
                EditorUtil.updateEditor(this.input.getTaxonNode(), this);
749
        }
750
    }
751

    
752
}
(2-2/2)