Revert "Split up composites of FeatureTreeEditor"
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / section / AbstractCdmDetailElement.java
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.ui.section;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.EnumSet;
15 import java.util.Observable;
16 import java.util.Observer;
17
18 import org.eclipse.jface.util.PropertyChangeEvent;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.DisposeEvent;
21 import org.eclipse.swt.events.DisposeListener;
22 import org.eclipse.swt.widgets.Composite;
23
24 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
25 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
26 import eu.etaxonomy.cdm.model.name.TaxonName;
27 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
28 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
29 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
30 import eu.etaxonomy.taxeditor.model.MessagingUtils;
31 import eu.etaxonomy.taxeditor.store.CdmStore;
32 import eu.etaxonomy.taxeditor.store.LoginManager;
33 import eu.etaxonomy.taxeditor.store.StoreUtil;
34 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
35 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
36 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
37 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
38 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
39
40 /**
41 *
42 * @author n.hoffmann
43 * @created Feb 26, 2010
44 */
45 public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement implements ICdmDetailElement<T>, Observer {
46
47 private T entity;
48
49 private boolean irrelevant;
50
51 private boolean enabled;
52
53 private EnumSet<CRUD> requiredCrud = null;
54
55 public AbstractCdmDetailElement(CdmFormFactory formFactory,
56 ICdmFormElement formElement) {
57 super(formFactory, formElement);
58 // register as property change listener
59 formFactory.addPropertyChangeListener(this);
60 CdmStore.getLoginManager().addObserver(this);
61
62 getLayoutComposite().getParent().addDisposeListener(new DisposeListener() {
63
64 @Override
65 public void widgetDisposed(DisposeEvent e) {
66 CdmStore.getLoginManager().deleteObserver(AbstractCdmDetailElement.this);
67 }
68 });
69 }
70
71 /**
72 * Sets the entity and updates controls
73 *
74 * @param entity
75 * a T object.
76 */
77 @Override
78 public void setEntity(T entity) {
79 this.entity = entity;
80 // the id is always 0 if the entity was not yet saved, so it is new in this case
81 if(getEntity() == null || StoreUtil.getCdmEntity(getEntity()).getId() == 0) {
82 // new entity, not yet saved
83 requiredCrud = EnumSet.of(CRUD.CREATE);
84 } else {
85 requiredCrud = EnumSet.of(CRUD.UPDATE);
86 }
87 updateContent();
88 }
89
90 @Override
91 public T getEntity() {
92 return entity;
93 }
94
95 /**
96 * Updates all widgets to display the latest data
97 */
98 protected void updateContent() {
99 removeElements();
100 createControls(this, entity, SWT.WRAP);
101 reflowParentScrolledForm(true);
102
103 updateControlStates();
104 }
105
106 @Override
107 public void setSelected(boolean selected) {
108 Composite section = getLayoutComposite().getParent();
109 section.setBackground(selected ? SELECTED : getPersistentBackground());
110 }
111
112 /**
113 * Sets all field to the given enablement state except the objects in
114 * collection except
115 *
116 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#setEnabled(boolean)
117 * @param enabled
118 * a boolean.
119 * @param except
120 * a {@link java.util.Collection} object.
121 */
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);
129 } else {
130 enableableElement.setEnabled(enabled);
131 }
132 }
133 }
134 }
135
136 @Override
137 public boolean isEnabled() {
138 return enabled;
139 }
140
141 /**
142 * <p>
143 * Setter for the field <code>irrelevant</code>.
144 * </p>
145 *
146 * @param irrelevant
147 * a boolean.
148 * @param except
149 * a {@link java.util.Collection} object.
150 */
151 public void setIrrelevant(boolean irrelevant, Collection<Object> except) {
152 // logger.warn("Setting " + this.getClass().getSimpleName() +
153 // " to irrelevant state: " + irrelevant);
154 for (ICdmFormElement element : getElements()) {
155 if (element instanceof IEnableableFormElement) {
156 IEnableableFormElement relevantElement = (IEnableableFormElement) element;
157 if (except != null && except.contains(relevantElement)) {
158 // do nothing
159 // logger.warn("not setting elements irrelevance: " +
160 // relevantElement.getClass().getSimpleName() + " in :" +
161 // this.getClass().getSimpleName());
162 } else {
163 relevantElement.setIrrelevant(irrelevant);
164 }
165 }
166 }
167 }
168
169 /** {@inheritDoc} */
170 @Override
171 public void setEnabled(boolean enabled) {
172 setEnabled(enabled, null);
173 }
174
175 /** {@inheritDoc} */
176 @Override
177 public void setIrrelevant(boolean irrelevant) {
178 this.irrelevant = irrelevant;
179 setIrrelevant(irrelevant, null);
180 }
181
182 /**
183 * Create all content elements
184 *
185 * @param formElement
186 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
187 * object.
188 * @param entity
189 * a T object.
190 * @param style
191 * a int.
192 */
193 protected abstract void createControls(ICdmFormElement formElement,
194 T entity, int style);
195
196 /** {@inheritDoc} */
197 @Override
198 public void propertyChange(PropertyChangeEvent event) {
199 if (event == null) {
200 return;
201 }
202
203 handleTitleCacheRelevantChange(event);
204
205 Object eventSource = event.getSource();
206
207 if (eventSource instanceof ICdmFormElement) {
208 ICdmFormElement eventElement = (ICdmFormElement) eventSource;
209 ICdmFormElement eventElementContainer = eventElement
210 .getParentElement();
211
212 if (eventElementContainer == this) {
213 if (event instanceof CdmPropertyChangeEvent) {
214 if (((CdmPropertyChangeEvent) event).hasException()) {
215 handleException((CdmPropertyChangeEvent) event);
216 return;
217 }
218 }
219 // call specific handler implementation
220 handleEvent(eventSource);
221 // refire the event
222 firePropertyChangeEvent(this, event);
223 // update possible parents
224 updateParentSection();
225 }
226 }
227 }
228
229 protected void handleTitleCacheRelevantChange(PropertyChangeEvent event) {
230 boolean isRelevant = getEntity() instanceof TaxonName
231 || getEntity() instanceof TaxonBase;
232 isRelevant &= this instanceof AbstractIdentifiableEntityDetailElement;
233
234 if (isRelevant) {
235 ((AbstractIdentifiableEntityDetailElement) this)
236 .updateToggleableCacheField();
237 updateParentSection();
238 }
239 }
240
241 private void updateParentSection() {
242 if (getParentElement() instanceof AbstractCdmDetailSection) {
243 ((AbstractCdmDetailSection) getParentElement()).updateTitle();
244 }
245 reflowParentScrolledForm(true);
246 }
247
248 /**
249 * Gets called when the source of the event is a child widget of this
250 * widget.
251 *
252 * @param eventSource
253 * a {@link java.lang.Object} object.
254 */
255 public abstract void handleEvent(Object eventSource);
256
257 public void handleException(CdmPropertyChangeEvent event) {
258 // override this in subclasses if you want to deal with the error
259 MessagingUtils.error(event.getSource().getClass(), event.getException());
260 }
261
262 public boolean isIrrelevant() {
263 return irrelevant;
264 }
265
266 @Override
267 public ConversationHolder getConversationHolder() {
268 if (getParentElement() instanceof IConversationEnabled) {
269 return ((IConversationEnabled) getParentElement())
270 .getConversationHolder();
271 }
272 throw new IllegalArgumentException(
273 "Parent element should be IConversationEnabled");
274 }
275
276 /** {@inheritDoc} */
277 @Override
278 public void update(CdmDataChangeMap changeEvents) {
279 }
280
281 @Override
282 public void update(Observable o, Object arg){
283 if(o instanceof LoginManager){
284 updateControlStates();
285 }
286 }
287
288
289 protected void updateControlStates(){
290 Collection<Object> except = new ArrayList<Object>();
291 for(ICdmFormElement formElement:getElements()){
292 if(formElement instanceof IEnableableFormElement && !((IEnableableFormElement) formElement).isEnabled()){
293 except.add(formElement);
294 }
295 }
296 setEnabled(getEntity() != null && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), requiredCrud), except);
297 }
298 }