Project

General

Profile

Download (8.93 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * 
3
 */
4
package eu.etaxonomy.taxeditor.ui.forms;
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.store.StoreUtil;
20

    
21
/**
22
 * <p>Abstract AbstractCdmFormElement class.</p>
23
 *
24
 * @author n.hoffmann
25
 * @version $Id: $
26
 */
27
public abstract class AbstractCdmFormElement implements IPropertyChangeEmitter, ICdmFormElement, ISelectable {
28

    
29
	protected CdmFormFactory formFactory;
30

    
31
	private List<IPropertyChangeListener> propertyChangeListeners;
32

    
33
	private Composite layoutComposite;
34
	
35
	private Set<Control> controls = new HashSet<Control>();
36
	
37
	private Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
38
	private ICdmFormElement parentElement;
39
	
40
	protected AbstractCdmFormElement()
41
	{
42
	}
43
	
44
	/**
45
	 * <p>Constructor for AbstractCdmFormElement.</p>
46
	 *
47
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
48
	 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
49
	 */
50
	protected AbstractCdmFormElement(CdmFormFactory formFactory, Composite layoutComposite){
51
		this.layoutComposite = layoutComposite;
52
		this.formFactory = formFactory;
53
	}
54
	
55
	/**
56
	 * <p>Constructor for AbstractCdmFormElement.</p>
57
	 *
58
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
59
	 * @param formElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
60
	 */
61
	public AbstractCdmFormElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
62
		this(formFactory, formElement.getLayoutComposite());
63
		this.parentElement = formElement;
64
//		addControl(layoutComposite);
65
	}
66
	
67
	/**
68
	 * <p>Getter for the field <code>formFactory</code>.</p>
69
	 *
70
	 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
71
	 */
72
	public CdmFormFactory getFormFactory() {
73
		return formFactory;
74
	}
75
	
76
	/** {@inheritDoc} */
77
	public Color getColor(boolean selected) {
78
		return selected ? SELECTED : NOT_SELECTED;
79
	}
80
	
81
	/**
82
	 * Delegates the focus to <code>this</code> elements main input control
83
	 */
84
	public void setFocus(){
85
		// Override in subclasses where needed 
86
	}
87
	
88
	/**
89
	 * Returns all Controls that are managed by this element
90
	 *
91
	 * @return a {@link java.util.Set} object.
92
	 */
93
	public Set<Control> getControls(){
94
		return controls;
95
	}
96
	
97
	/**
98
	 * adds the control to the set of controls that are managed by this element
99
	 *
100
	 * @param child a {@link org.eclipse.swt.widgets.Control} object.
101
	 */
102
	protected void addControl(Control child){
103
		controls.add(child);
104
	}
105
	
106
	/**
107
	 * <p>removeControl</p>
108
	 *
109
	 * @param child a {@link org.eclipse.swt.widgets.Control} object.
110
	 */
111
	protected void removeControl(Control child){
112
		controls.remove(child);
113
	}
114
	
115
	/**
116
	 * <p>Getter for the field <code>elements</code>.</p>
117
	 *
118
	 * @return a {@link java.util.Set} object.
119
	 */
120
	public Set<ICdmFormElement> getElements(){
121
		return elements;
122
	}
123
	
124
	/**
125
	 * <p>Getter for the field <code>parentElement</code>.</p>
126
	 *
127
	 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
128
	 */
129
	public ICdmFormElement getParentElement(){
130
		return parentElement;
131
	}
132
	
133
	/** {@inheritDoc} */
134
	public void addElement(ICdmFormElement element){
135
		elements.add(element);
136
	}
137
	
138
	/**
139
	 * <p>removeElement</p>
140
	 *
141
	 * @param element a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
142
	 */
143
	protected void removeElement(ICdmFormElement element){
144
		elements.remove(element);
145
	}
146
	
147
	/**
148
	 * <p>removeElements</p>
149
	 */
150
	public void removeElements(){
151
		for(ICdmFormElement childElement : getElements()){
152
			// recursion
153
			childElement.removeElements();
154
			
155
			// unregister selection arbitrator
156
			if(childElement instanceof ISelectableElement){
157
				SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
158
				if(selectionArbitrator != null){
159
					formFactory.destroySelectionArbitrator(selectionArbitrator);
160
				}
161
			}
162
			
163
			// unregister from property changes
164
			if(childElement instanceof IPropertyChangeListener){
165
				formFactory.removePropertyChangeListener((IPropertyChangeListener) childElement); 
166
			}
167
			
168
			// dispose of the controls
169
			removeControls(childElement);
170
		}
171
		removeControls(this);
172
		elements.clear();
173
	}
174
	
175
	private void removeControls(ICdmFormElement element){
176
		if(element instanceof Section){
177
			((Section) element).dispose();
178
			element = null;
179
		}else{
180
			for(Control control : element.getControls()){
181
				// we added the layoutComposite of the parental element as the layout composite to this formElement
182
				// but we do not want to destroy it.
183
				if(control.equals(element.getLayoutComposite())){
184
					continue;
185
				}else{
186
					control.dispose();
187
					control = null;
188
				}
189
			}
190
		}
191
	}
192
	
193
	/**
194
	 * <p>Getter for the field <code>layoutComposite</code>.</p>
195
	 *
196
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
197
	 */
198
	public Composite getLayoutComposite() {
199
		return layoutComposite;
200
	}
201
	
202
	/**
203
	 * <p>Setter for the field <code>layoutComposite</code>.</p>
204
	 *
205
	 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
206
	 */
207
	public void setLayoutComposite(Composite layoutComposite){
208
		this.layoutComposite = layoutComposite;
209
	}
210
	
211
	/* (non-Javadoc)
212
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#getPropertyChangeListeners()
213
	 */
214
	/**
215
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
216
	 *
217
	 * @return a {@link java.util.Set} object.
218
	 */
219
	public List<IPropertyChangeListener> getPropertyChangeListeners() {
220
		return propertyChangeListeners;
221
	}
222
	
223
	/* (non-Javadoc)
224
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#setPropertyChangeListeners(org.eclipse.core.runtime.ListenerList)
225
	 */
226
	/** {@inheritDoc} */
227
	public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
228
		this.propertyChangeListeners = propertyChangeListeners;
229
	}
230
	
231
	/* (non-Javadoc)
232
	 * @see eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent()
233
	 */
234
	/* (non-Javadoc)
235
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#firePropertyChangeEvent(org.eclipse.jface.util.PropertyChangeEvent)
236
	 */
237
	/** {@inheritDoc} */
238
	public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
239
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
240

    
241
		try{
242
			for(Object listener : propertyChangeListeners){
243
				((IPropertyChangeListener)listener).propertyChange(event);
244
			}
245
		}catch(ConcurrentModificationException e){
246
			// There are two cases that produce a CME. 
247
			// Described here: http://dev.e-taxonomy.eu/trac/ticket/2363#comment:2
248
			// and here: http://dev.e-taxonomy.eu/trac/ticket/2438
249
			// Ignoring the CME because nothing bad is happening
250
			StoreUtil.warn(getClass(), "ConcurrentModificationException. Can be ignored.");
251
		}
252
	}
253
	
254
	/**
255
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
256
	 *  
257
	 * @param object the object on which the property changed
258
	 */
259
	public void firePropertyChangeEvent(Object object){
260
		firePropertyChangeEvent(object, null);
261
	}
262
	
263
	/**
264
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
265
	 * originating event
266
	 * 
267
	 * @param object the object on which the property changed
268
	 * @param originatingEvent the originating event
269
	 */
270
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
271
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
272
	}
273
	
274

    
275
	/**
276
	 * {@inheritDoc}
277
	 *
278
	 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
279
	 *
280
	 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
281
	 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
282
	 * @see eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
283
	 */
284
	public void propertyChange(PropertyChangeEvent event) {
285
		// implement in subclasses
286
	}
287
	
288
	/** {@inheritDoc} */
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
	public void refresh() {
311
		// empty default implementation	
312
	}
313
	
314
	/** {@inheritDoc} */
315
	@Override
316
	public void setBackground(Color color) {
317
		for(ICdmFormElement element : getElements()){
318
			element.setBackground(color);
319
		}
320
	}
321
	
322
	public Color getColor(String colorId){
323
		return StoreUtil.getColor(colorId);
324
	}
325
}
(2-2/35)