Project

General

Profile

Download (8.82 KB) Statistics
| Branch: | Tag: | Revision:
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
import eu.etaxonomy.taxeditor.model.MessagingUtils;
21

    
22
/**
23
 * @author n.hoffmann
24
 * @version $Id: $
25
 */
26
public abstract class AbstractCdmFormElement implements ICdmFormElement {
27

    
28
	protected CdmFormFactory formFactory;
29

    
30
	private List<IPropertyChangeListener> propertyChangeListeners;
31

    
32
	private Composite layoutComposite;
33

    
34
	private final Set<Control> controls = new HashSet<Control>();
35

    
36
	private final Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
37
	private ICdmFormElement parentElement;
38

    
39
	private Color persistentBackgroundColor;
40

    
41

    
42
	protected AbstractCdmFormElement(CdmFormFactory formFactory, Composite layoutComposite){
43
		this.layoutComposite = layoutComposite;
44
		this.formFactory = formFactory;
45
	}
46

    
47
	public AbstractCdmFormElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
48
		this(formFactory, formElement.getLayoutComposite());
49
		this.parentElement = formElement;
50
//		addControl(layoutComposite);
51
	}
52

    
53
	@Override
54
    public CdmFormFactory getFormFactory() {
55
		return formFactory;
56
	}
57

    
58
	/**
59
	 * Delegates the focus to <code>this</code> elements main input control
60
	 */
61
	public void setFocus(){
62
		// Override in subclasses where needed
63
	}
64

    
65
	/**
66
	 * Returns all Controls that are managed by this element
67
	 *
68
	 * @return a {@link java.util.Set} object.
69
	 */
70
	@Override
71
    public Set<Control> getControls(){
72
		return controls;
73
	}
74

    
75
	/**
76
	 * adds the control to the set of controls that are managed by this element
77
	 *
78
	 * @param child a {@link org.eclipse.swt.widgets.Control} object.
79
	 */
80
	protected void addControl(Control child){
81
		controls.add(child);
82
	}
83

    
84
	protected void removeControl(Control child){
85
		controls.remove(child);
86
	}
87

    
88
	/**
89
	 * <p>Getter for the field <code>elements</code>.</p>
90
	 *
91
	 * @return a {@link java.util.Set} object.
92
	 */
93
	@Override
94
    public Set<ICdmFormElement> getElements(){
95
		return elements;
96
	}
97

    
98
	/**
99
	 * <p>Getter for the field <code>parentElement</code>.</p>
100
	 *
101
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
102
	 */
103
	@Override
104
    public ICdmFormElement getParentElement(){
105
		return parentElement;
106
	}
107

    
108
	/** {@inheritDoc} */
109
	@Override
110
    public void addElement(ICdmFormElement element){
111
		elements.add(element);
112
	}
113

    
114
	protected void removeElement(ICdmFormElement element){
115
		elements.remove(element);
116
	}
117

    
118
	/**
119
	 * Remove all child {@link ICdmFormElement}s and child {@link Control}s
120
	 * of the given and the element itself.
121
	 * @param formElement The element to remove
122
	 */
123
	public void removeElementsAndControls(ICdmFormElement formElement){
124
	    for(ICdmFormElement childElement : formElement.getElements()){
125
	        // recursion
126
	        childElement.removeElements();
127

    
128
	        // unregister selection arbitrator
129
	        if(childElement instanceof ISelectableElement){
130
	            SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
131
	            if(selectionArbitrator != null){
132
	                formFactory.destroySelectionArbitrator(selectionArbitrator);
133
	            }
134
	        }
135

    
136
	        // unregister from property changes
137
	        formFactory.removePropertyChangeListener(childElement);
138

    
139
	        // dispose of the controls
140
	        removeControls(childElement);
141
	    }
142
	    removeControls(formElement);
143
	}
144

    
145
	/**
146
	 * Removes all child {@link ICdmFormElement}s and child {@link Control}s
147
	 * and the element itself.
148
	 */
149
	@Override
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
			formFactory.removePropertyChangeListener(childElement);
165

    
166
			// dispose of the controls
167
			removeControls(childElement);
168
		}
169
		removeControls(this);
170
		elements.clear();
171
	}
172

    
173
	private void removeControls(ICdmFormElement element){
174
		if(element instanceof Section){
175
			((Section) element).dispose();
176
			element = null;
177
		}else{
178
			for(Control control : element.getControls()){
179
				// we added the layoutComposite of the parental element as the layout composite to this formElement
180
				// but we do not want to destroy it.
181
				if(control.equals(element.getLayoutComposite())){
182
					continue;
183
				}else{
184
					control.dispose();
185
					control = null;
186
				}
187
			}
188
		}
189
	}
190

    
191
	/**
192
	 * <p>Getter for the field <code>layoutComposite</code>.</p>
193
	 *
194
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
195
	 */
196
	@Override
197
    public Composite getLayoutComposite() {
198
		return layoutComposite;
199
	}
200

    
201
	/**
202
	 * <p>Setter for the field <code>layoutComposite</code>.</p>
203
	 *
204
	 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
205
	 */
206
	public void setLayoutComposite(Composite layoutComposite){
207
		this.layoutComposite = layoutComposite;
208
	}
209

    
210
	/**
211
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
212
	 *
213
	 * @return a {@link java.util.Set} object.
214
	 */
215
	@Override
216
    public List<IPropertyChangeListener> getPropertyChangeListeners() {
217
		return propertyChangeListeners;
218
	}
219

    
220
	/** {@inheritDoc} */
221
	@Override
222
    public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
223
		this.propertyChangeListeners = propertyChangeListeners;
224
	}
225

    
226
	/** {@inheritDoc} */
227
	@Override
228
    public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
229
	    //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
230
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
231

    
232
		try{
233
			for(Object listener : propertyChangeListeners){
234
				((IPropertyChangeListener)listener).propertyChange(event);
235
			}
236
		}catch(ConcurrentModificationException e){
237
			// There are two cases that produce a CME.
238
			// Described here: http://dev.e-taxonomy.eu/trac/ticket/2363#comment:2
239
			// and here: http://dev.e-taxonomy.eu/trac/ticket/2438
240
			// Ignoring the CME because nothing bad is happening
241
			MessagingUtils.warn(getClass(), "ConcurrentModificationException. Can be ignored.");
242
		}
243
	}
244

    
245
	/**
246
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
247
	 *
248
	 * @param object the object on which the property changed
249
	 */
250
	public void firePropertyChangeEvent(Object object){
251
		firePropertyChangeEvent(object, null);
252
	}
253

    
254
	/**
255
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
256
	 * originating event
257
	 *
258
	 * @param object the object on which the property changed
259
	 * @param originatingEvent the originating event
260
	 */
261
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
262
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
263
	}
264

    
265

    
266
	/**
267
	 * {@inheritDoc}
268
	 *
269
	 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
270
	 *
271
	 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
272
	 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
273
	 * @see eu.etaxonomy.taxeditor.ui.element.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
274
	 */
275
	@Override
276
    public void propertyChange(PropertyChangeEvent event) {
277
		// implement in subclasses
278
	}
279

    
280
	/** {@inheritDoc} */
281
	@Override
282
    public boolean containsFormElement(ICdmFormElement formElement){
283
		if(formElement == this){
284
			return true;
285
		}else{
286
			for(ICdmFormElement element : getElements()){
287
				boolean contains = element.containsFormElement(formElement);
288
				if(contains == true){
289
					return true;
290
				}
291
			}
292
			return false;
293
		}
294
	}
295

    
296
	@Override
297
    public void refresh() {
298
		// empty default implementation
299
	}
300

    
301

    
302
	/** {@inheritDoc} */
303
	@Override
304
	public void setBackground(Color color) {
305
		for(ICdmFormElement element : getElements()){
306
			element.setBackground(color);
307
		}
308
	}
309

    
310
	@Override
311
	public void setPersistentBackground(Color color) {
312
		persistentBackgroundColor = color;
313
		setBackground(color);
314
	}
315

    
316
	@Override
317
	public Color getPersistentBackground() {
318
		return persistentBackgroundColor;
319
	}
320

    
321
	public Color getColor(String colorId){
322
		return AbstractUtility.getColor(colorId);
323
	}
324
}
(2-2/45)