Project

General

Profile

Download (9.1 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
		if(this instanceof ISelectableElement){
170
            SelectionArbitrator selectionArbitrator = ((ISelectableElement) this).getSelectionArbitrator();
171
            if(selectionArbitrator != null){
172
                formFactory.destroySelectionArbitrator(selectionArbitrator);
173
            }
174
        }
175
		removeControls(this);
176
		elements.clear();
177
	}
178

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

    
197
	/**
198
	 * <p>Getter for the field <code>layoutComposite</code>.</p>
199
	 *
200
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
201
	 */
202
	@Override
203
    public Composite getLayoutComposite() {
204
		return layoutComposite;
205
	}
206

    
207
	/**
208
	 * <p>Setter for the field <code>layoutComposite</code>.</p>
209
	 *
210
	 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
211
	 */
212
	public void setLayoutComposite(Composite layoutComposite){
213
		this.layoutComposite = layoutComposite;
214
	}
215

    
216
	/**
217
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
218
	 *
219
	 * @return a {@link java.util.Set} object.
220
	 */
221
	@Override
222
    public List<IPropertyChangeListener> getPropertyChangeListeners() {
223
		return propertyChangeListeners;
224
	}
225

    
226
	/** {@inheritDoc} */
227
	@Override
228
    public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
229
		this.propertyChangeListeners = propertyChangeListeners;
230
	}
231

    
232
	/** {@inheritDoc} */
233
	@Override
234
    public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
235
	    //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
236
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
237

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

    
251
	/**
252
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
253
	 *
254
	 * @param object the object on which the property changed
255
	 */
256
	public void firePropertyChangeEvent(Object object){
257
		firePropertyChangeEvent(object, null);
258
	}
259

    
260
	/**
261
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
262
	 * originating event
263
	 *
264
	 * @param object the object on which the property changed
265
	 * @param originatingEvent the originating event
266
	 */
267
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
268
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
269
	}
270

    
271

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

    
286
	/** {@inheritDoc} */
287
	@Override
288
    public boolean containsFormElement(ICdmFormElement formElement){
289
		if(formElement == this){
290
			return true;
291
		}else{
292
			for(ICdmFormElement element : getElements()){
293
				boolean contains = element.containsFormElement(formElement);
294
				if(contains == true){
295
					return true;
296
				}
297
			}
298
			return false;
299
		}
300
	}
301

    
302
	@Override
303
    public void refresh() {
304
		// empty default implementation
305
	}
306

    
307

    
308
	/** {@inheritDoc} */
309
	@Override
310
	public void setBackground(Color color) {
311
		for(ICdmFormElement element : getElements()){
312
			element.setBackground(color);
313
		}
314
	}
315

    
316
	@Override
317
	public void setPersistentBackground(Color color) {
318
		persistentBackgroundColor = color;
319
		setBackground(color);
320
	}
321

    
322
	@Override
323
	public Color getPersistentBackground() {
324
		return persistentBackgroundColor;
325
	}
326

    
327
	public Color getColor(String colorId){
328
		return AbstractUtility.getColor(colorId);
329
	}
330
}
(2-2/47)