Project

General

Profile

Download (9.02 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
	/**
115
	 * Remove all child {@link ICdmFormElement}s and child {@link Control}s
116
	 * of the given and the element itself.
117
	 * @param formElement The element to remove
118
	 */
119
	public void removeElementsAndControls(ICdmFormElement formElement){
120
	    for(ICdmFormElement childElement : formElement.getElements()){
121
	        // recursion
122
	        childElement.removeElements();
123

    
124
	        // unregister selection arbitrator
125
	        if(childElement instanceof ISelectableElement){
126
	            SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
127
	            if(selectionArbitrator != null){
128
	                formFactory.destroySelectionArbitrator(selectionArbitrator);
129
	            }
130
	        }
131

    
132
	        // unregister from property changes
133
	        formFactory.removePropertyChangeListener(childElement);
134

    
135
	        // dispose of the controls
136
	        removeControls(childElement);
137
	    }
138
	    removeControls(formElement);
139
	}
140

    
141
	/**
142
	 * Removes all child {@link ICdmFormElement}s and child {@link Control}s
143
	 * and the element itself.
144
	 */
145
	@Override
146
    public void removeElements(){
147
		for(ICdmFormElement childElement : getElements()){
148
			// recursion
149
			childElement.removeElements();
150

    
151
			// unregister selection arbitrator
152
			if(childElement instanceof ISelectableElement){
153
				SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
154
				if(selectionArbitrator != null){
155
					formFactory.destroySelectionArbitrator(selectionArbitrator);
156
				}
157
			}
158

    
159
			// unregister from property changes
160
			formFactory.removePropertyChangeListener(childElement);
161

    
162
			// dispose of the controls
163
			removeControls(childElement);
164
		}
165
		if(this instanceof ISelectableElement){
166
            SelectionArbitrator selectionArbitrator = ((ISelectableElement) this).getSelectionArbitrator();
167
            if(selectionArbitrator != null){
168
                formFactory.destroySelectionArbitrator(selectionArbitrator);
169
            }
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
	@Override
199
    public Composite getLayoutComposite() {
200
		return layoutComposite;
201
	}
202

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

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

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

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

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

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

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

    
267

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

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

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

    
303

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

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

    
318
	@Override
319
	public Color getPersistentBackground() {
320
		return persistentBackgroundColor;
321
	}
322

    
323
	public Color getColor(String colorId){
324
		return AbstractUtility.getColor(colorId);
325
	}
326
}
(2-2/47)