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 if (toggleableCache
!= null){
160 element
.addDependsOnCache(toggleableCache
);
164 // updateCacheRelevance();
168 * Updates the cache relevance state of all internal elements of this
169 * AbstractCdmDetailElement.
172 public void updateCacheRelevance(){
173 CacheRelevanceHelper
.updateCacheRelevanceForSubelements(getElements());
177 * Create all content elements
179 protected abstract void createControls(ICdmFormElement formElement
,
180 T entity
, int style
);
183 public void propertyChange(PropertyChangeEvent event
) {
188 handleTitleCacheRelevantChange(event
);
190 Object eventSource
= event
.getSource();
192 if (eventSource
instanceof ICdmFormElement
) {
193 ICdmFormElement eventElement
= (ICdmFormElement
) eventSource
;
194 ICdmFormElement eventElementContainer
= eventElement
.getParentElement();
195 if (eventElementContainer
== this) {
196 if (event
instanceof CdmPropertyChangeEvent
) {
197 if (((CdmPropertyChangeEvent
) event
).hasException()) {
198 handleException((CdmPropertyChangeEvent
) event
);
202 // call specific handler implementation
203 handleEvent(eventSource
);
205 firePropertyChangeEvent(this, event
);
206 // update possible parents
207 updateParentSection();
212 protected void handleTitleCacheRelevantChange(PropertyChangeEvent event
) {
213 boolean isRelevant
= getEntity() instanceof TaxonName
214 || getEntity() instanceof TaxonBase
;
215 isRelevant
&= this instanceof AbstractIdentifiableEntityDetailElement
;
218 ((AbstractIdentifiableEntityDetailElement
<?
>)this).updateToggleableCacheField();
222 private void updateParentSection() {
223 if (getParentElement() instanceof AbstractCdmDetailSection
) {
224 ((AbstractCdmDetailSection
<?
>) getParentElement()).updateTitle();
226 //NOTE: This slows down the rendering of the details view
227 // StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
231 * Gets called when the source of the event is a child widget of this
234 public abstract void handleEvent(Object eventSource
);
236 public void handleException(CdmPropertyChangeEvent event
) {
237 // override this in subclasses if you want to deal with the error
238 MessagingUtils
.error(event
.getSource().getClass(), event
.getException());
242 public ConversationHolder
getConversationHolder() {
243 if (getParentElement() instanceof IConversationEnabled
) {
244 return ((IConversationEnabled
) getParentElement())
245 .getConversationHolder();
247 throw new IllegalArgumentException(
248 "Parent element should be IConversationEnabled");
252 public void update(CdmDataChangeMap changeEvents
) {
256 public void update(Observable o
, Object arg
){
257 if(o
instanceof LoginManager
){
258 updateControlStates();
262 protected void updateControlStates(){
263 Collection
<Object
> except
= new ArrayList
<Object
>();
264 for(ICdmFormElement formElement
:getElements()){
265 if(formElement
instanceof IEnableableFormElement
&& !((IEnableableFormElement
) formElement
).isEnabled()){
266 except
.add(formElement
);
269 if (getEntity() != null && getEntity() instanceof CdmBase
){
270 enabled
= CdmStore
.currentAuthentiationHasPermission(StoreUtil
.getCdmEntity(getEntity()), requiredCrud
);
274 setEnabled(enabled
, except
);
277 public LabelElement
getWarnForReferencedObjects() {
278 return warnForReferencedObjects
;
281 public void setWarnForReferencedObjects(LabelElement warnForReferencedObjects
) {
282 this.warnForReferencedObjects
= warnForReferencedObjects
;
285 public void setWarnForReferencingObjects(ICdmFormElement formElement
, int defaultReferencingObjects
){
286 if (getEntity() instanceof CdmBase
){
287 CdmBase cdmBase
= (CdmBase
) getEntity();
288 if (cdmBase
.getId() != 0){
289 long referencingObjectsCount
= CdmStore
.getCommonService().getReferencingObjectsCount(cdmBase
);
291 if (referencingObjectsCount
> defaultReferencingObjects
){
292 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")));
293 getWarnForReferencedObjects().setBackground(Display
.getCurrent().getSystemColor(SWT
.COLOR_RED
));
294 getWarnForReferencedObjects().setLayout(LayoutConstants
.FILL(2, 3));
295 getWarnForReferencedObjects().setForeground(Display
.getCurrent().getSystemColor(SWT
.COLOR_RED
));
296 formFactory
.createLabel(formElement
, "");
302 public void setWarnForReferencingObjects(ICdmFormElement formElement
){
303 setWarnForReferencingObjects(formElement
, 1);
306 public void setWarnForReferencingObjectsVisible(boolean isVisible
){
307 if (getWarnForReferencedObjects() != null){
308 getWarnForReferencedObjects().setVisible(isVisible
);