2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.taxeditor
.view
.e4
;
11 import java
.util
.Collection
;
14 import javax
.annotation
.PreDestroy
;
15 import javax
.inject
.Inject
;
16 import javax
.inject
.Named
;
18 import org
.apache
.log4j
.Logger
;
19 import org
.eclipse
.e4
.core
.contexts
.IEclipseContext
;
20 import org
.eclipse
.e4
.core
.di
.annotations
.Optional
;
21 import org
.eclipse
.e4
.ui
.di
.PersistState
;
22 import org
.eclipse
.e4
.ui
.di
.UISynchronize
;
23 import org
.eclipse
.e4
.ui
.model
.application
.ui
.basic
.MPart
;
24 import org
.eclipse
.e4
.ui
.services
.IServiceConstants
;
25 import org
.eclipse
.e4
.ui
.workbench
.modeling
.EPartService
;
26 import org
.eclipse
.e4
.ui
.workbench
.modeling
.ESelectionService
;
27 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
28 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
29 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
30 import org
.eclipse
.jface
.viewers
.Viewer
;
31 import org
.eclipse
.swt
.SWTException
;
32 import org
.springframework
.security
.core
.GrantedAuthority
;
34 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
35 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
36 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
37 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
38 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
39 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
43 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermDto
;
44 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermVocabularyDto
;
45 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
46 import eu
.etaxonomy
.taxeditor
.editor
.ITaxonEditor
;
47 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkable
;
48 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
49 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
50 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
51 import eu
.etaxonomy
.taxeditor
.security
.RequiredPermissions
;
52 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
53 import eu
.etaxonomy
.taxeditor
.view
.e4
.details
.DetailsPartE4
;
54 import eu
.etaxonomy
.taxeditor
.view
.e4
.details
.DetailsViewerE4
;
55 import eu
.etaxonomy
.taxeditor
.workbench
.WorkbenchUtility
;
56 import eu
.etaxonomy
.taxeditor
.workbench
.part
.ISelectionElementEditingPart
;
63 public abstract class AbstractCdmEditorPartE4
64 implements IConversationEnabled
, IDirtyMarkable
, ISelectionElementEditingPart
, IPostOperationEnabled
{
66 private DelaySelection delaySelection
= null;
68 * This is the monitor for the DelaySelection runnable.
69 * If it is <code>true</code> then it is currently delaying a selection.
71 private boolean isInDelay
;
72 private boolean isEnabled
= true;
73 private static final Logger logger
= Logger
.getLogger(AbstractCdmEditorPartE4
.class);
76 * This class invokes internal_selectionChanged() in a separate thread.
77 * This allows an asynchronous and/or delayed handling of selection changes
79 private class DelaySelection
implements Runnable
{
80 private Object selection
;
81 private MPart activePart
;
82 private MPart thisPart
;
84 public DelaySelection(Object selection
, MPart activePart
, MPart thisPart
) {
86 this.selection
= selection
;
87 this.activePart
= activePart
;
88 this.thisPart
= thisPart
;
94 selectionChanged_internal(selection
, activePart
, thisPart
);
101 public synchronized void setSelection(Object selection
) {
102 this.selection
= selection
;
105 public synchronized void setActivePart(MPart activePart
) {
106 this.activePart
= activePart
;
109 public synchronized void setThisPart(MPart thisPart
) {
110 this.thisPart
= thisPart
;
115 protected Viewer viewer
;
117 protected MPart thisPart
;
119 protected MPart selectionProvidingPart
;
121 protected Object previousSelection
;
123 protected ISelectionChangedListener selectionChangedListener
;
125 public ISelectionChangedListener
getSelectionChangedListener() {
126 return selectionChangedListener
;
130 protected ESelectionService selService
;
133 protected IEclipseContext context
;
135 protected abstract void selectionChanged_internal(Object selection
, MPart activePart
, MPart thisPart
);
138 public void selectionChanged(
139 @Optional@Named(IServiceConstants
.ACTIVE_SELECTION
)Object selection
,
140 @Optional@Named(IServiceConstants
.ACTIVE_PART
)MPart activePart
,
141 MPart thisPart
, UISynchronize sync
, EPartService partService
){
142 //multiple selections are not supported
145 && !activePart
.equals(thisPart
)
146 && selection
instanceof IStructuredSelection
147 && ((IStructuredSelection
) selection
).size()>1){
151 // no active editor found
152 if(activePart
==thisPart
&& WorkbenchUtility
.getActiveEditorPart(partService
)==null){
156 if (viewer
!= null && viewer
.getControl()!= null && viewer
.getInput() != null && !viewer
.getControl().isDisposed()){
158 viewer
.getControl().setEnabled(isEnabled
);
159 }catch(SWTException e
){
160 logger
.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e
);
165 if((previousSelection
!=null && selection
!=null) && (activePart
!= null && selectionProvidingPart
!= null && activePart
.equals(selectionProvidingPart
)) &&
166 (previousSelection
==selection
167 || previousSelection
.equals(selection
)
168 || new StructuredSelection(selection
).equals(previousSelection
))
172 if(delaySelection
==null){
173 delaySelection
= new DelaySelection(selection
, activePart
, thisPart
);
175 delaySelection
.setSelection(selection
);
176 delaySelection
.setActivePart(activePart
);
177 delaySelection
.setThisPart(thisPart
);
180 sync
.asyncExec(delaySelection
);
181 previousSelection
= selection
;
187 public void changed(Object object
) {
188 if(selectionProvidingPart
!=null){
189 Object part
= selectionProvidingPart
.getObject();
190 if(part
instanceof IDirtyMarkable
){
191 ((IDirtyMarkable
) part
).changed(object
);
196 public Viewer
getViewer() {
200 public boolean isEnabled() {
204 public void setEnabled(boolean isEnabled
) {
205 this.isEnabled
= isEnabled
;
208 protected void showViewer(IStructuredSelection selection
, MPart activePart
, Viewer viewer
){
209 if(CdmStore
.getCurrentSessionManager().getActiveSession()==null){
212 if(viewer
!=null && viewer
.getControl()!=null && !viewer
.getControl().isDisposed()){
213 Object element
= selection
.getFirstElement();
214 Object part
= createPartObject(activePart
);
215 if (viewer
.getControl().isDisposed()){
218 viewer
.getControl().setEnabled(true);
219 if(selection
.getFirstElement()!=null){
220 if (element
instanceof Taxon
){
222 Taxon taxon
= HibernateProxyHelper
.deproxy(element
, Taxon
.class);
223 if (part
instanceof ITaxonEditor
){
224 TaxonNode node
= ((ITaxonEditor
) part
).getTaxonNode();
226 boolean doEnable
= CdmStore
.currentAuthentiationHasPermission(node
,
227 RequiredPermissions
.TAXON_EDIT
);
229 //check whether there are explicit TaxonNode rights
230 boolean taxonnodePermissionExists
= false;
231 Collection
<?
extends GrantedAuthority
> authorities
= CdmStore
.getCurrentAuthentiation().getAuthorities();
232 for (GrantedAuthority grantedAuthority
: authorities
){
233 if (grantedAuthority
.getAuthority().startsWith("TAXONNODE")){
234 taxonnodePermissionExists
= true;
237 if (!taxonnodePermissionExists
){
242 //TODO: differ between the views
243 this.isEnabled
= doEnable
;
248 if (taxon
.isMisapplication() || taxon
.isProparteSynonym() || taxon
.isInvalidDesignation()){
250 if(part
instanceof ITaxonEditor
){
251 Taxon accepted
= ((ITaxonEditor
) part
).getTaxon();
253 Set
<TaxonRelationship
> rels
= taxon
.getTaxonRelations(accepted
);
255 if (rels
!= null && rels
.iterator().hasNext() && !taxon
.equals(accepted
)){
256 TaxonRelationship rel
= rels
.iterator().next();
257 if ((rel
.getType().isMisappliedNameOrInvalidDesignation() || rel
.getType().isAnySynonym()) && !rel
.getFromTaxon().equals(((ITaxonEditor
) part
).getTaxon())){
258 viewer
.setInput(rel
);
259 selectionProvidingPart
= activePart
;
269 if(element
instanceof TermDto
){
270 element
= CdmStore
.getService(ITermService
.class).load(((TermDto
) element
).getUuid());
272 else if(element
instanceof TermVocabularyDto
){
273 element
= CdmStore
.getService(IVocabularyService
.class).load(((TermVocabularyDto
) element
).getUuid());
276 selectionProvidingPart
= activePart
;
277 if (viewer
instanceof DetailsViewerE4
){
279 if (selectionProvidingPart
.getElementId().equals("eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart")){
280 ((DetailsViewerE4
)viewer
).setDetailsEnabled(false);
282 ((DetailsViewerE4
)viewer
).setDetailsEnabled(isEnabled
);
284 ((DetailsViewerE4
)viewer
).setInput(element
, part
);
289 if (activePart
.getObject() instanceof DetailsPartE4
&& element
instanceof TaxonName
){
290 selectionProvidingPart
= ((DetailsPartE4
)activePart
.getObject()).getSelectionProvidingPart();
293 viewer
.setInput(element
);
294 viewer
.getControl().setEnabled(isEnabled
);
302 protected Object
createPartObject(MPart activePart
) {
303 Object partObject
= activePart
;
304 Object wrappedPart
= WorkbenchUtility
.getE4WrappedPart(activePart
);
305 if(wrappedPart
!=null){
306 partObject
= wrappedPart
;
311 protected void showEmptyPage() {
312 if(viewer
!=null && viewer
.getControl()!=null && !viewer
.getControl().isDisposed() ){
313 viewer
.setInput(null);
315 if (!viewer
.getControl().isDisposed()){
316 viewer
.getControl().setEnabled(false);
318 }catch(SWTException e
){
319 if (PreferencesUtil
.isShowUpWidgetIsDisposedMessages() && e
.getMessage().equals("Widget is disposed")){
320 MessagingUtils
.errorDialog("Widget is disposed",
322 MessagingUtils
.WIDGET_IS_DISPOSED_MESSAGE
,
333 thisPart
.setLabel(getViewName());
337 protected IStructuredSelection
createSelection(Object selection
) {
341 IStructuredSelection structuredSelection
;
342 if(!(selection
instanceof IStructuredSelection
)){
343 structuredSelection
= new StructuredSelection(selection
);
346 structuredSelection
= (IStructuredSelection
) selection
;
348 return structuredSelection
;
355 public ConversationHolder
getConversationHolder() {
356 if(selectionProvidingPart
!= null && selectionProvidingPart
instanceof IConversationEnabled
) {
357 return ((IConversationEnabled
) selectionProvidingPart
).getConversationHolder();
366 public boolean postOperation(Object objectAffectedByOperation
) {
367 changed(objectAffectedByOperation
);
375 public boolean onComplete() {
384 public MPart
getSelectionProvidingPart() {
385 return selectionProvidingPart
;
389 private void dispose() {
392 private void reset(){
393 previousSelection
= null;
394 selectionProvidingPart
= null;
395 delaySelection
= null;
396 context
.deactivate();
400 private void persistState(){
408 public void update(CdmDataChangeMap arg0
) {
415 public void forceDirty() {
418 protected abstract String
getViewName();