2 * Copyright (C) 2007 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
.ui
.section
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Collection
;
13 import java
.util
.EnumSet
;
14 import java
.util
.Observable
;
15 import java
.util
.Observer
;
17 import org
.eclipse
.jface
.util
.PropertyChangeEvent
;
18 import org
.eclipse
.swt
.SWT
;
19 import org
.eclipse
.swt
.events
.DisposeEvent
;
20 import org
.eclipse
.swt
.events
.DisposeListener
;
21 import org
.eclipse
.swt
.widgets
.Composite
;
22 import org
.eclipse
.swt
.widgets
.Display
;
24 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
25 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
26 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
27 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
28 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
29 import eu
.etaxonomy
.cdm
.model
.permission
.CRUD
;
30 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
31 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
32 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
33 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
34 import eu
.etaxonomy
.taxeditor
.store
.LoginManager
;
35 import eu
.etaxonomy
.taxeditor
.store
.StoreUtil
;
36 import eu
.etaxonomy
.taxeditor
.ui
.element
.AbstractRelevanceFormElement
;
37 import eu
.etaxonomy
.taxeditor
.ui
.element
.CacheRelevance
;
38 import eu
.etaxonomy
.taxeditor
.ui
.element
.CacheRelevanceHelper
;
39 import eu
.etaxonomy
.taxeditor
.ui
.element
.CdmFormFactory
;
40 import eu
.etaxonomy
.taxeditor
.ui
.element
.CdmPropertyChangeEvent
;
41 import eu
.etaxonomy
.taxeditor
.ui
.element
.ICacheRelevantFormElement
;
42 import eu
.etaxonomy
.taxeditor
.ui
.element
.ICdmFormElement
;
43 import eu
.etaxonomy
.taxeditor
.ui
.element
.IEnableableFormElement
;
44 import eu
.etaxonomy
.taxeditor
.ui
.element
.LabelElement
;
45 import eu
.etaxonomy
.taxeditor
.ui
.element
.LayoutConstants
;
46 import eu
.etaxonomy
.taxeditor
.ui
.element
.ToggleableTextElement
;
50 * @created Feb 26, 2010
52 public abstract class AbstractCdmDetailElement
<T
>
53 extends AbstractRelevanceFormElement
54 implements ICdmDetailElement
<T
>, Observer
{
58 protected boolean enabled
= true;
60 private LabelElement warnForReferencedObjects
;
62 protected EnumSet
<CRUD
> requiredCrud
= null;
64 public AbstractCdmDetailElement(CdmFormFactory formFactory
,
65 ICdmFormElement formElement
) {
66 super(formFactory
, formElement
);
67 // register as property change listener
68 formFactory
.addPropertyChangeListener(this);
69 CdmStore
.getLoginManager().addObserver(this);
71 getLayoutComposite().getParent().addDisposeListener(new DisposeListener() {
74 public void widgetDisposed(DisposeEvent e
) {
75 CdmStore
.getLoginManager().deleteObserver(AbstractCdmDetailElement
.this);
81 * Sets the entity and updates controls
84 public void setEntity(T entity
) {
86 // the id is always 0 if the entity was not yet saved, so it is new in this case
87 if(getEntity() == null || (getEntity() instanceof CdmBase
&& StoreUtil
.getCdmEntity(getEntity()).getId() == 0)) {
88 // new entity, not yet saved
89 requiredCrud
= EnumSet
.of(CRUD
.CREATE
);
91 requiredCrud
= EnumSet
.of(CRUD
.UPDATE
);
97 public T
getEntity() {
102 * Updates all widgets to display the latest data
104 protected void updateContent() {
106 createControls(this, entity
, SWT
.NONE
);
107 updateControlStates();
111 public void setSelected(boolean selected
) {
112 Composite section
= getLayoutComposite().getParent();
113 section
.setBackground(selected ? SELECTED
: getPersistentBackground());
117 * Sets all field to the given enablement state except the objects in
118 * the collection except parameter.
120 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#setEnabled(boolean)
122 public void setEnabled(boolean enabled
, Collection
<Object
> except
) {
123 this.enabled
= enabled
;
124 for (ICdmFormElement element
: getElements()) {
125 if (element
instanceof IEnableableFormElement
) {
126 IEnableableFormElement enableableElement
= (IEnableableFormElement
) element
;
127 if (except
!= null && except
.contains(enableableElement
)) {
128 // enableableElement.setEnabled(enabled);
130 enableableElement
.setEnabled(enabled
);
137 public boolean isEnabled() {
142 public void setEnabled(boolean enabled
) {
143 setEnabled(enabled
, null);
147 public CacheRelevance
cacheRelevance() {
148 return cacheRelevanceHelper
.cacheRelevance();
152 public void addDependsOnCache(ToggleableTextElement toggleElement
) {
153 cacheRelevanceHelper
.addDependsOnCache(toggleElement
);
156 protected void registerCacheRelevance(ICacheRelevantFormElement element
, ToggleableTextElement
... toggleableCaches
) {
157 if (element
!= null && toggleableCaches
!= null) {
158 for (ToggleableTextElement toggleableCache
: toggleableCaches
){
159 element
.addDependsOnCache(toggleableCache
);
162 // updateCacheRelevance();
166 * Updates the cache relevance state of all internal elements of this
167 * AbstractCdmDetailElement.
170 public void updateCacheRelevance(){
171 CacheRelevanceHelper
.updateCacheRelevanceForSubelements(getElements());
175 * Create all content elements
177 protected abstract void createControls(ICdmFormElement formElement
,
178 T entity
, int style
);
181 public void propertyChange(PropertyChangeEvent event
) {
186 handleTitleCacheRelevantChange(event
);
188 Object eventSource
= event
.getSource();
190 if (eventSource
instanceof ICdmFormElement
) {
191 ICdmFormElement eventElement
= (ICdmFormElement
) eventSource
;
192 ICdmFormElement eventElementContainer
= eventElement
.getParentElement();
193 if (eventElementContainer
== this) {
194 if (event
instanceof CdmPropertyChangeEvent
) {
195 if (((CdmPropertyChangeEvent
) event
).hasException()) {
196 handleException((CdmPropertyChangeEvent
) event
);
200 // call specific handler implementation
201 handleEvent(eventSource
);
203 firePropertyChangeEvent(this, event
);
204 // update possible parents
205 updateParentSection();
210 protected void handleTitleCacheRelevantChange(PropertyChangeEvent event
) {
211 boolean isRelevant
= getEntity() instanceof TaxonName
212 || getEntity() instanceof TaxonBase
;
213 isRelevant
&= this instanceof AbstractIdentifiableEntityDetailElement
;
216 ((AbstractIdentifiableEntityDetailElement
<?
>)this).updateToggleableCacheField();
220 private void updateParentSection() {
221 if (getParentElement() instanceof AbstractCdmDetailSection
) {
222 ((AbstractCdmDetailSection
<?
>) getParentElement()).updateTitle();
224 //NOTE: This slows down the rendering of the details view
225 // StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
229 * Gets called when the source of the event is a child widget of this
232 public abstract void handleEvent(Object eventSource
);
234 public void handleException(CdmPropertyChangeEvent event
) {
235 // override this in subclasses if you want to deal with the error
236 MessagingUtils
.error(event
.getSource().getClass(), event
.getException());
240 public ConversationHolder
getConversationHolder() {
241 if (getParentElement() instanceof IConversationEnabled
) {
242 return ((IConversationEnabled
) getParentElement())
243 .getConversationHolder();
245 throw new IllegalArgumentException(
246 "Parent element should be IConversationEnabled");
250 public void update(CdmDataChangeMap changeEvents
) {
254 public void update(Observable o
, Object arg
){
255 if(o
instanceof LoginManager
){
256 updateControlStates();
260 protected void updateControlStates(){
261 Collection
<Object
> except
= new ArrayList
<Object
>();
262 for(ICdmFormElement formElement
:getElements()){
263 if(formElement
instanceof IEnableableFormElement
&& !((IEnableableFormElement
) formElement
).isEnabled()){
264 except
.add(formElement
);
267 if (getEntity() != null && getEntity() instanceof CdmBase
){
268 enabled
= CdmStore
.currentAuthentiationHasPermission(StoreUtil
.getCdmEntity(getEntity()), requiredCrud
);
272 setEnabled(enabled
, except
);
275 public LabelElement
getWarnForReferencedObjects() {
276 return warnForReferencedObjects
;
279 public void setWarnForReferencedObjects(LabelElement warnForReferencedObjects
) {
280 this.warnForReferencedObjects
= warnForReferencedObjects
;
283 public void setWarnForReferencingObjects(ICdmFormElement formElement
, int defaultReferencingObjects
){
284 if (getEntity() instanceof CdmBase
){
285 CdmBase cdmBase
= (CdmBase
) getEntity();
286 if (cdmBase
.getId() != 0){
287 long referencingObjectsCount
= CdmStore
.getCommonService().getReferencingObjectsCount(cdmBase
);
289 if (referencingObjectsCount
> defaultReferencingObjects
){
290 setWarnForReferencedObjects(formFactory
.createLabel(formElement
, CdmUtils
.Nz("The "+ cdmBase
.getUserFriendlyTypeName()+" is referenced by " + referencingObjectsCount
+ " objects, if you change it, it is changed for all these objects")));
291 getWarnForReferencedObjects().setBackground(Display
.getCurrent().getSystemColor(SWT
.COLOR_RED
));
292 getWarnForReferencedObjects().setLayout(LayoutConstants
.FILL(2, 3));
293 getWarnForReferencedObjects().setForeground(Display
.getCurrent().getSystemColor(SWT
.COLOR_RED
));
294 formFactory
.createLabel(formElement
, "");
300 public void setWarnForReferencingObjects(ICdmFormElement formElement
){
301 setWarnForReferencingObjects(formElement
, 1);
304 public void setWarnForReferencingObjectsVisible(boolean isVisible
){
305 if (getWarnForReferencedObjects() != null){
306 getWarnForReferencedObjects().setVisible(isVisible
);