Project

General

Profile

Download (15.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

    
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.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.OperationCanceledException;
25
import org.eclipse.e4.ui.di.Focus;
26
import org.eclipse.e4.ui.di.Persist;
27
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
28
import org.eclipse.e4.ui.services.EMenuService;
29
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
30
import org.eclipse.jface.action.MenuManager;
31
import org.eclipse.jface.viewers.ISelection;
32
import org.eclipse.jface.viewers.ISelectionChangedListener;
33
import org.eclipse.jface.viewers.ISelectionProvider;
34
import org.eclipse.jface.viewers.StructuredSelection;
35
import org.eclipse.swt.graphics.Color;
36
import org.eclipse.swt.widgets.Composite;
37
import org.eclipse.swt.widgets.Menu;
38
import org.eclipse.ui.ISelectionListener;
39
import org.eclipse.ui.ISelectionService;
40
import org.eclipse.ui.IWorkbenchPart;
41
import org.eclipse.ui.IWorkbenchPartReference;
42
import org.eclipse.ui.PartInitException;
43
import org.eclipse.ui.PlatformUI;
44
import org.eclipse.ui.forms.ManagedForm;
45
import org.eclipse.ui.forms.widgets.FormToolkit;
46
import org.eclipse.ui.forms.widgets.ScrolledForm;
47
import org.eclipse.ui.forms.widgets.TableWrapLayout;
48

    
49
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
51
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
52
import eu.etaxonomy.cdm.model.common.CdmBase;
53
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
56
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
57
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
58
import eu.etaxonomy.taxeditor.editor.ISecuredEditor;
59
import eu.etaxonomy.taxeditor.editor.e4.TaxonEditorInputE4;
60
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
61
import eu.etaxonomy.taxeditor.editor.name.container.AbstractGroupedContainer;
62
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupE4;
63
import eu.etaxonomy.taxeditor.editor.name.e4.container.AbstractGroupedContainerE4;
64
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedGroupE4;
65
import eu.etaxonomy.taxeditor.editor.name.e4.container.AcceptedNameContainerE4;
66
import eu.etaxonomy.taxeditor.editor.name.e4.container.ContainerFactoryE4;
67
import eu.etaxonomy.taxeditor.editor.name.e4.container.HomotypicalSynonymGroupE4;
68
import eu.etaxonomy.taxeditor.editor.name.e4.container.MisappliedGroupE4;
69
import eu.etaxonomy.taxeditor.model.AbstractUtility;
70
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
71
import eu.etaxonomy.taxeditor.model.IPartChangeListener;
72
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
73
import eu.etaxonomy.taxeditor.model.TaxeditorPartService;
74
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
75
import eu.etaxonomy.taxeditor.preference.Resources;
76
import eu.etaxonomy.taxeditor.security.RequiredPermissions;
77
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
78
import eu.etaxonomy.taxeditor.store.CdmStore;
79

    
80
/**
81
 *
82
 * @author pplitzner
83
 * @date Aug 24, 2017
84
 *
85
 */
86
public class TaxonNameEditorE4 implements
87
		IConversationEnabled, IDirtyMarkable,
88
		IPartContentHasDetails, IPartChangeListener,
89
		ISelectionListener, ISecuredEditor, IPostOperationEnabled {
90

    
91
	private Taxon taxon;
92

    
93
	private ManagedForm managedForm;
94
	private ScrolledForm scrolledForm;
95
	private Composite parent;
96
	private ISelectionProvider simpleSelectionProvider;
97

    
98
	private TaxonBase selection;
99

    
100
	private ConversationHolder conversation;
101

    
102
	private MenuManager menuManager;
103
	private Menu menu;
104

    
105
	private AcceptedGroupE4 acceptedGroup;
106
	private List<HomotypicalSynonymGroupE4> heterotypicSynonymGroups = new ArrayList<>();
107
	private MisappliedGroupE4 misappliedGroup;
108

    
109
	private ISelectionService selectionService;
110

    
111
	private TaxonBase objectAffectedByLastOperation;
112

    
113
	private ICdmEntitySession cdmEntitySession;
114

    
115
	@Inject
116
	private ESelectionService selService;
117

    
118
	@Inject
119
	private MDirtyable dirty;
120

    
121
	private ISelectionChangedListener selectionChangedListener;
122

    
123
    private TaxonEditorInputE4 input;
124

    
125
	@Inject
126
	public TaxonNameEditorE4() {
127
	}
128

    
129

    
130
	@PostConstruct
131
    public void createPartControl(Composite parent, EMenuService menuService) {
132
        if (CdmStore.isActive()){
133
            if(conversation == null){
134
                conversation = CdmStore.createConversation();
135
            }
136
        }
137
        else{
138
            return;
139
        }
140

    
141
		createManagedForm(parent);
142

    
143
		//propagate selection
144
        selectionChangedListener = (event -> selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event)));
145
        //FIXME E4 migrate
146
//        viewer.addSelectionChangedListener(selectionChangedListener);
147

    
148
        //create context menu
149
        menuService.registerContextMenu(managedForm, "eu.etaxonomy.taxeditor.editor.popupmenu.nameeditor");
150

    
151
		TaxeditorPartService.getInstance().addListener(
152
				TaxeditorPartService.PART_ACTIVATED, this);
153

    
154
	}
155

    
156
	protected void createManagedForm(Composite composite) {
157

    
158
		managedForm = new ManagedForm(composite) {
159

    
160
			@Override
161
			public void dirtyStateChanged() {
162
			    dirty.setDirty(true);
163
			    //FIXME E4 migrate
164
//				firePropertyChange(PROP_DIRTY);
165
			}
166

    
167
			@Override
168
			public boolean setInput(Object input) {
169
				if (input instanceof AbstractGroupedContainer) {
170
					selection = ((AbstractGroupedContainer) input).getData();
171

    
172
			        selectionChangedListener = (event -> selService.setSelection(new StructuredSelection(selection)));
173
				}else if(input == null){
174
					selection = null;
175
                    selectionChangedListener = (event -> selService.setSelection(new StructuredSelection()));
176
				}
177

    
178

    
179
				return super.setInput(input);
180
			}
181
		};
182

    
183
		scrolledForm = managedForm.getForm();
184
		parent = scrolledForm.getBody();
185

    
186
		parent.setData(taxon);
187

    
188
		TableWrapLayout layout = new TableWrapLayout();
189
		layout.leftMargin = 0;
190
		layout.rightMargin = 0;
191
		layout.topMargin = 0;
192
		layout.bottomMargin = 0;
193

    
194
		layout.verticalSpacing = 0;
195
		layout.horizontalSpacing = 0;
196

    
197
		parent.setLayout(layout);
198
		parent.setBackground(AbstractUtility
199
				.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
200
	}
201

    
202
	public void createOrUpdateNameComposites() {
203
		ContainerFactoryE4.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
204
		ContainerFactoryE4.createOrUpdateHeterotypicSynonymyGroups(this);
205
		ContainerFactoryE4.createOrUpdateMisapplicationsGroup(this);
206

    
207

    
208
		// Redraw composite
209
		managedForm.reflow(true);
210
	}
211

    
212
	public Taxon getTaxon() {
213
		return HibernateProxyHelper.deproxy(taxon);
214
	}
215

    
216
	public void setDirty() {
217
		managedForm.dirtyStateChanged();
218
	}
219

    
220
	@Focus
221
	public void setFocus() {
222
	    if(input!=null){
223
	        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().setFocus();
224
	        if (getSelectedContainer() == null) {
225
	            throw new IllegalStateException(
226
	                    Messages.TaxonNameEditor_THERE_SHOULD_ALWAYS_BE);
227
	        }
228
	        getSelectedContainer().setSelected();
229

    
230
	        // check permissions
231
	        boolean doEnable = permissionsSatisfied();
232
	        managedForm.getForm().setEnabled(doEnable);
233
	    }
234
	}
235

    
236
	@Override
237
	public boolean permissionsSatisfied() {
238
		TaxonNode taxonNode = input.getTaxonNode();
239
		boolean doEnable = CdmStore.currentAuthentiationHasPermission(taxonNode, RequiredPermissions.TAXONNODE_EDIT);
240
		return doEnable;
241
	}
242

    
243
	@Override
244
    public ConversationHolder getConversationHolder() {
245
		return conversation;
246
	}
247

    
248
	/** {@inheritDoc} */
249
	@Override
250
    public void update(CdmDataChangeMap events) {
251
		// redraw();
252
	}
253

    
254
	/**
255
	 * Redraws this editor return true on success
256
	 *
257
	 * @return a boolean.
258
	 */
259
    public boolean redraw() {
260
		return redraw(true);
261
	}
262

    
263
	/**
264
	 * {@inheritDoc}
265
	 *
266
	 * Redraws the editor controls
267
	 */
268
    public boolean redraw(boolean focus) {
269

    
270
		createOrUpdateNameComposites();
271

    
272
		if (focus) {
273
			setFocus();
274
		}
275

    
276
		return true;
277
	}
278

    
279
	@Override
280
    public boolean postOperation(CdmBase objectAffectedByOperation) {
281

    
282
		changed(objectAffectedByOperation);
283

    
284
		redraw(false);
285

    
286
		if (objectAffectedByOperation instanceof TaxonBase) {
287
			objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
288
		}
289

    
290
		return true;
291
	}
292

    
293
	public ManagedForm getManagedForm() {
294
		return managedForm;
295
	}
296

    
297
	public Menu getMenu() {
298
		if (menu == null || menu.isDisposed()) {
299
			// Creating the menu because it was either not initialised or
300
			// disposed while refreshing the editor
301
			menu = menuManager.createContextMenu(parent);
302
		}
303
		return menu;
304
	}
305

    
306
	/**
307
	 * <p>
308
	 * checkForEmptyNames
309
	 * </p>
310
	 *
311
	 * @return true if there are empty names
312
	 */
313
	public boolean checkForEmptyNames() {
314
		for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
315
			if (container.getName() == null
316
					|| StringUtils.isEmpty(container.getName().getTitleCache())) {
317
				return true;
318
			}
319
		}
320
		return false;
321
	}
322

    
323
	public Set<AbstractGroupedContainerE4> getEmptyContainers() {
324
		Set<AbstractGroupedContainerE4> containersWithEmptyNames = new HashSet<>();
325

    
326
		for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
327
			if (container.getName() == null
328
					|| StringUtils.isEmpty(container.getName().getTitleCache())) {
329
				containersWithEmptyNames.add(container);
330
			}
331
		}
332

    
333
		return containersWithEmptyNames;
334
	}
335

    
336
	/** {@inheritDoc} */
337
	@Persist
338
	public void doSave(IProgressMonitor monitor) {
339

    
340
		monitor.beginTask(Messages.TaxonNameEditor_SAVING_NAMES, getGroupedContainers().size());
341

    
342
		try {
343
			// check for empty names
344
			for (AbstractGroupedContainerE4 container : getGroupedContainers()) {
345

    
346
				monitor.subTask(Messages.TaxonNameEditor_SAVING_COMPOSITES
347
						+ container.getTaxonBase().getTitleCache());
348
				container.persistName();
349

    
350
				// In case the progress monitor was canceled throw an exception.
351
				if (monitor.isCanceled()) {
352
					throw new OperationCanceledException();
353
				}
354

    
355
				// Otherwise declare this step as done.
356
				monitor.worked(1);
357
			}
358
		} finally {
359

    
360
			// Stop the progress monitor.
361
			monitor.done();
362
		}
363

    
364
	}
365

    
366
	public void init(TaxonEditorInputE4 input)
367
			throws PartInitException {
368

    
369
		if (!(input != null)) {
370
            throw new PartInitException(Messages.TaxonNameEditor_INVALID_INPUT);
371
        }
372

    
373
		if (input.getAdapter(Taxon.class) != null) {
374
			taxon = CdmBase.deproxy(input.getAdapter(Taxon.class), Taxon.class);
375
		} else {
376
			throw new PartInitException(Messages.TaxonNameEditor_INVALID_INPUT_TAXON_NULL);
377
		}
378

    
379
		this.input = input;
380

    
381
        createOrUpdateNameComposites();
382

    
383
        setFocus();
384
	}
385

    
386

    
387
	public AcceptedNameContainerE4 getAcceptedNameContainer() {
388
		return getAcceptedGroup().getAcceptedNameContainer();
389
	}
390

    
391
	public HomotypicalSynonymGroupE4 getHomotypicalGroupContainer(
392
			HomotypicalGroup homotypicalGroup) {
393
		for (HomotypicalSynonymGroupE4 group : getHeterotypicSynonymGroups()) {
394
			if (group.getGroup().equals(homotypicalGroup)) {
395
				return group;
396
			}
397
		}
398

    
399
		return null;
400
	}
401

    
402
	/**
403
	 * <p>
404
	 * getDirtyNames
405
	 * </p>
406
	 *
407
	 * @return a Set containing all composites that have been edited
408
	 */
409
	public Set<AbstractGroupedContainerE4> getDirtyNames() {
410
		Set<AbstractGroupedContainerE4> dirtyNames = new HashSet<>();
411

    
412
		for (AbstractGroupedContainerE4 composite : getGroupedContainers()) {
413
			if (composite.isDirty()) {
414
				dirtyNames.add(composite);
415
			}
416
		}
417

    
418
		return dirtyNames;
419
	}
420

    
421
	public List<AbstractGroupedContainerE4> getGroupedContainers() {
422
		List<AbstractGroupedContainerE4> groupedComposites = new ArrayList<>();
423

    
424
		for (AbstractGroupE4 group : getAllGroups()) {
425
			groupedComposites.addAll(group.getGroupedContainers());
426
		}
427

    
428
		return groupedComposites;
429
	}
430

    
431
	public List<AbstractGroupE4> getAllGroups() {
432
		List<AbstractGroupE4> allGroups = new ArrayList<>();
433

    
434
		allGroups.add(getAcceptedGroup());
435

    
436
		heterotypicSynonymGroups = getHeterotypicSynonymGroups();
437

    
438
		if (heterotypicSynonymGroups != null) {
439
			allGroups.addAll(heterotypicSynonymGroups);
440
		}
441

    
442
		if (misappliedGroup != null) {
443
			allGroups.add(misappliedGroup);
444
		}
445

    
446
		return allGroups;
447
	}
448

    
449
	public boolean isDirty() {
450
		return dirty.isDirty();
451
	}
452

    
453
	@PreDestroy
454
	public void dispose() {
455
		conversation.unregisterForDataStoreChanges(this);
456
	}
457

    
458
	/** {@inheritDoc} */
459
	@Override
460
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
461

    
462
	}
463

    
464
	public AbstractGroupedContainerE4 getSelectedContainer() {
465

    
466
		TaxonBase selectedTaxonBase = null;
467

    
468
		if (input.getInitiallySelectedTaxonBase() != null) {
469
			selectedTaxonBase = input.getInitiallySelectedTaxonBase();
470
		} else {
471
			if (selection != null) {
472
				selectedTaxonBase = selection;
473
			}
474
		}
475

    
476
		return (selectedTaxonBase != null) ? getContainer(selectedTaxonBase)
477
				: getAcceptedNameContainer();
478
	}
479

    
480
	public void setMisapplicationsGroup(MisappliedGroupE4 misappliedGroup) {
481
		this.misappliedGroup = misappliedGroup;
482
	}
483

    
484
	public FormToolkit getToolkit() {
485
		return managedForm.getToolkit();
486
	}
487

    
488
	public List<HomotypicalSynonymGroupE4> getHeterotypicSynonymGroups() {
489
		return heterotypicSynonymGroups;
490
	}
491

    
492
	public void addHeterotypicSynonymGroup(HomotypicalSynonymGroupE4 group) {
493
		heterotypicSynonymGroups.add(group);
494
	}
495

    
496
	public AcceptedGroupE4 getAcceptedGroup() {
497
		return acceptedGroup;
498
	}
499

    
500
	public void setAcceptedGroup(AcceptedGroupE4 acceptedGroup) {
501
		this.acceptedGroup = acceptedGroup;
502
	}
503

    
504
	public MisappliedGroupE4 getMisappliedGroup() {
505
		return misappliedGroup;
506
	}
507

    
508
	public boolean isActive() {
509
		return this.equals(AbstractUtility.getActiveE4Part());
510
	}
511

    
512
    @Override
513
    public boolean onComplete() {
514
		getContainer(objectAffectedByLastOperation).setSelected();
515
		return true;
516
	}
517

    
518
	/** {@inheritDoc} */
519
	@Override
520
    public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
521
		if (!partRef.getPart(false).equals(this)) {
522
			// getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
523
		}
524
	}
525

    
526
	public void removeGroup(AbstractGroupE4 group) {
527
		if (group != null) {
528
			group.dispose();
529

    
530
			//if (heterotypicSynonymGroups != null) {
531
			heterotypicSynonymGroups.remove(group);
532
			//}
533
		}
534
	}
535

    
536
	public AbstractGroupedContainerE4 getContainer(TaxonBase taxonBase) {
537
		List<AbstractGroupedContainerE4> groupedContainers = getGroupedContainers();
538
		for (AbstractGroupedContainerE4 container : groupedContainers) {
539
			if (container.getData().equals(taxonBase)
540
					&& container.getNameViewer().getTextWidget() != null) {
541
				return container;
542
			}
543
		}
544
		return getAcceptedNameContainer();
545
	}
546

    
547
    public void setOnError() {
548
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_EDITOR_ERROR);
549
		setEnabled(false, disabledColor);
550
	}
551

    
552
	public void setDisabled(){
553
		Color disabledColor =  AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND);
554
		setEnabled(false, disabledColor);
555
	}
556

    
557
	protected void setEnabled(boolean enabled, Color background) {
558

    
559
		for(AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()){
560
			groupedContainer.setEnabled(enabled);
561
		}
562

    
563
		// send an empty selection to the current provider - TODO only on error ???
564
		if (!enabled) {
565
			getManagedForm().setInput(null);
566

    
567
			for (AbstractGroupedContainerE4 groupedContainer : getGroupedContainers()) {
568
				groupedContainer.setBackground(background);
569
			}
570
		}
571
		managedForm.getForm().setBackground(background);
572
	}
573

    
574
    @Override
575
    public void changed(Object element) {
576
        // TODO Auto-generated method stub
577

    
578
    }
579

    
580
    @Override
581
    public void forceDirty() {
582
        setDirty();
583
    }
584

    
585

    
586
    public IUndoContext getUndoContext() {
587
        //FIXME E4 is this needed
588
        return null;
589
    }
590

    
591
}
(2-2/2)