- converted Browse, Edit, Delete functionality of EntitySelection
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / element / AbstractCdmFormElement.java
1 /**
2 *
3 */
4 package eu.etaxonomy.taxeditor.ui.element;
5
6 import java.util.ConcurrentModificationException;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import org.eclipse.core.runtime.Assert;
12 import org.eclipse.jface.util.IPropertyChangeListener;
13 import org.eclipse.jface.util.PropertyChangeEvent;
14 import org.eclipse.swt.graphics.Color;
15 import org.eclipse.swt.widgets.Composite;
16 import org.eclipse.swt.widgets.Control;
17 import org.eclipse.ui.forms.widgets.Section;
18
19 import eu.etaxonomy.taxeditor.model.AbstractUtility;
20
21 /**
22 * <p>Abstract AbstractCdmFormElement class.</p>
23 *
24 * @author n.hoffmann
25 * @version $Id: $
26 */
27 public abstract class AbstractCdmFormElement implements ICdmFormElement {
28
29 protected CdmFormFactory formFactory;
30
31 private List<IPropertyChangeListener> propertyChangeListeners;
32
33 private Composite layoutComposite;
34
35 private final Set<Control> controls = new HashSet<Control>();
36
37 private final Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
38 private ICdmFormElement parentElement;
39
40 private Color persistentBackgroundColor;
41
42
43 /**
44 * <p>Constructor for AbstractCdmFormElement.</p>
45 *
46 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
47 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
48 */
49 protected AbstractCdmFormElement(CdmFormFactory formFactory, Composite layoutComposite){
50 this.layoutComposite = layoutComposite;
51 this.formFactory = formFactory;
52 }
53
54 /**
55 * <p>Constructor for AbstractCdmFormElement.</p>
56 *
57 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
58 * @param formElement a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
59 */
60 public AbstractCdmFormElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
61 this(formFactory, formElement.getLayoutComposite());
62 this.parentElement = formElement;
63 // addControl(layoutComposite);
64 }
65
66 @Override
67 public CdmFormFactory getFormFactory() {
68 return formFactory;
69 }
70
71 /**
72 * Delegates the focus to <code>this</code> elements main input control
73 */
74 public void setFocus(){
75 // Override in subclasses where needed
76 }
77
78 /**
79 * Returns all Controls that are managed by this element
80 *
81 * @return a {@link java.util.Set} object.
82 */
83 @Override
84 public Set<Control> getControls(){
85 return controls;
86 }
87
88 /**
89 * adds the control to the set of controls that are managed by this element
90 *
91 * @param child a {@link org.eclipse.swt.widgets.Control} object.
92 */
93 protected void addControl(Control child){
94 controls.add(child);
95 }
96
97 /**
98 * <p>removeControl</p>
99 *
100 * @param child a {@link org.eclipse.swt.widgets.Control} object.
101 */
102 protected void removeControl(Control child){
103 controls.remove(child);
104 }
105
106 /**
107 * <p>Getter for the field <code>elements</code>.</p>
108 *
109 * @return a {@link java.util.Set} object.
110 */
111 @Override
112 public Set<ICdmFormElement> getElements(){
113 return elements;
114 }
115
116 /**
117 * <p>Getter for the field <code>parentElement</code>.</p>
118 *
119 * @return a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
120 */
121 @Override
122 public ICdmFormElement getParentElement(){
123 return parentElement;
124 }
125
126 /** {@inheritDoc} */
127 @Override
128 public void addElement(ICdmFormElement element){
129 elements.add(element);
130 }
131
132 /**
133 * <p>removeElement</p>
134 *
135 * @param element a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
136 */
137 protected void removeElement(ICdmFormElement element){
138 elements.remove(element);
139 }
140
141 /**
142 * <p>removeElements</p>
143 */
144 @Override
145 public void removeElements(){
146 for(ICdmFormElement childElement : getElements()){
147 // recursion
148 childElement.removeElements();
149
150 // unregister selection arbitrator
151 if(childElement instanceof ISelectableElement){
152 SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
153 if(selectionArbitrator != null){
154 formFactory.destroySelectionArbitrator(selectionArbitrator);
155 }
156 }
157
158 // unregister from property changes
159 formFactory.removePropertyChangeListener(childElement);
160
161 // dispose of the controls
162 removeControls(childElement);
163 }
164 removeControls(this);
165 elements.clear();
166 }
167
168 private void removeControls(ICdmFormElement element){
169 if(element instanceof Section){
170 ((Section) element).dispose();
171 element = null;
172 }else{
173 for(Control control : element.getControls()){
174 // we added the layoutComposite of the parental element as the layout composite to this formElement
175 // but we do not want to destroy it.
176 if(control.equals(element.getLayoutComposite())){
177 continue;
178 }else{
179 control.dispose();
180 control = null;
181 }
182 }
183 }
184 }
185
186 /**
187 * <p>Getter for the field <code>layoutComposite</code>.</p>
188 *
189 * @return a {@link org.eclipse.swt.widgets.Composite} object.
190 */
191 @Override
192 public Composite getLayoutComposite() {
193 return layoutComposite;
194 }
195
196 /**
197 * <p>Setter for the field <code>layoutComposite</code>.</p>
198 *
199 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
200 */
201 public void setLayoutComposite(Composite layoutComposite){
202 this.layoutComposite = layoutComposite;
203 }
204
205 /* (non-Javadoc)
206 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#getPropertyChangeListeners()
207 */
208 /**
209 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
210 *
211 * @return a {@link java.util.Set} object.
212 */
213 @Override
214 public List<IPropertyChangeListener> getPropertyChangeListeners() {
215 return propertyChangeListeners;
216 }
217
218 /* (non-Javadoc)
219 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#setPropertyChangeListeners(org.eclipse.core.runtime.ListenerList)
220 */
221 /** {@inheritDoc} */
222 @Override
223 public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
224 this.propertyChangeListeners = propertyChangeListeners;
225 }
226
227 /* (non-Javadoc)
228 * @see eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent()
229 */
230 /* (non-Javadoc)
231 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#firePropertyChangeEvent(org.eclipse.jface.util.PropertyChangeEvent)
232 */
233 /** {@inheritDoc} */
234 @Override
235 public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
236 //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
237 Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
238
239 try{
240 for(Object listener : propertyChangeListeners){
241 ((IPropertyChangeListener)listener).propertyChange(event);
242 }
243 }catch(ConcurrentModificationException e){
244 // There are two cases that produce a CME.
245 // Described here: http://dev.e-taxonomy.eu/trac/ticket/2363#comment:2
246 // and here: http://dev.e-taxonomy.eu/trac/ticket/2438
247 // Ignoring the CME because nothing bad is happening
248 AbstractUtility.warn(getClass(), "ConcurrentModificationException. Can be ignored.");
249 }
250 }
251
252 /**
253 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
254 *
255 * @param object the object on which the property changed
256 */
257 public void firePropertyChangeEvent(Object object){
258 firePropertyChangeEvent(object, null);
259 }
260
261 /**
262 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
263 * originating event
264 *
265 * @param object the object on which the property changed
266 * @param originatingEvent the originating event
267 */
268 public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
269 firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
270 }
271
272
273 /**
274 * {@inheritDoc}
275 *
276 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
277 *
278 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
279 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
280 * @see eu.etaxonomy.taxeditor.ui.element.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
281 */
282 @Override
283 public void propertyChange(PropertyChangeEvent event) {
284 // implement in subclasses
285 }
286
287 /** {@inheritDoc} */
288 @Override
289 public boolean containsFormElement(ICdmFormElement formElement){
290 if(formElement == this){
291 return true;
292 }else{
293 for(ICdmFormElement element : getElements()){
294 boolean contains = element.containsFormElement(formElement);
295 if(contains == true){
296 return true;
297 }
298 }
299 return false;
300 }
301 }
302
303 /*
304 * (non-Javadoc)
305 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
306 */
307 /**
308 * <p>refresh</p>
309 */
310 @Override
311 public void refresh() {
312 // empty default implementation
313 }
314
315
316 /** {@inheritDoc} */
317 @Override
318 public void setBackground(Color color) {
319 for(ICdmFormElement element : getElements()){
320 element.setBackground(color);
321 }
322 }
323
324 @Override
325 public void setPersistentBackground(Color color) {
326 persistentBackgroundColor = color;
327 setBackground(color);
328 }
329
330 @Override
331 public Color getPersistentBackground() {
332 return persistentBackgroundColor;
333 }
334
335 public Color getColor(String colorId){
336 return AbstractUtility.getColor(colorId);
337 }
338 }