Project

General

Profile

Download (10.2 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
 * <p>Abstract AbstractCdmFormElement class.</p>
24
 *
25
 * @author n.hoffmann
26
 * @version $Id: $
27
 */
28
public abstract class AbstractCdmFormElement implements ICdmFormElement {
29

    
30
	protected CdmFormFactory formFactory;
31

    
32
	private List<IPropertyChangeListener> propertyChangeListeners;
33

    
34
	private Composite layoutComposite;
35

    
36
	private final Set<Control> controls = new HashSet<Control>();
37

    
38
	private final Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
39
	private ICdmFormElement parentElement;
40

    
41
	private Color persistentBackgroundColor;
42

    
43

    
44
	/**
45
	 * <p>Constructor for AbstractCdmFormElement.</p>
46
	 *
47
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.element.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.element.CdmFormFactory} object.
59
	 * @param formElement a {@link eu.etaxonomy.taxeditor.ui.element.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
	@Override
68
    public CdmFormFactory getFormFactory() {
69
		return formFactory;
70
	}
71

    
72
	/**
73
	 * Delegates the focus to <code>this</code> elements main input control
74
	 */
75
	public void setFocus(){
76
		// Override in subclasses where needed
77
	}
78

    
79
	/**
80
	 * Returns all Controls that are managed by this element
81
	 *
82
	 * @return a {@link java.util.Set} object.
83
	 */
84
	@Override
85
    public Set<Control> getControls(){
86
		return controls;
87
	}
88

    
89
	/**
90
	 * adds the control to the set of controls that are managed by this element
91
	 *
92
	 * @param child a {@link org.eclipse.swt.widgets.Control} object.
93
	 */
94
	protected void addControl(Control child){
95
		controls.add(child);
96
	}
97

    
98
	/**
99
	 * <p>removeControl</p>
100
	 *
101
	 * @param child a {@link org.eclipse.swt.widgets.Control} object.
102
	 */
103
	protected void removeControl(Control child){
104
		controls.remove(child);
105
	}
106

    
107
	/**
108
	 * <p>Getter for the field <code>elements</code>.</p>
109
	 *
110
	 * @return a {@link java.util.Set} object.
111
	 */
112
	@Override
113
    public Set<ICdmFormElement> getElements(){
114
		return elements;
115
	}
116

    
117
	/**
118
	 * <p>Getter for the field <code>parentElement</code>.</p>
119
	 *
120
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
121
	 */
122
	@Override
123
    public ICdmFormElement getParentElement(){
124
		return parentElement;
125
	}
126

    
127
	/** {@inheritDoc} */
128
	@Override
129
    public void addElement(ICdmFormElement element){
130
		elements.add(element);
131
	}
132

    
133
	/**
134
	 * <p>removeElement</p>
135
	 *
136
	 * @param element a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
137
	 */
138
	protected void removeElement(ICdmFormElement element){
139
		elements.remove(element);
140
	}
141

    
142
	/**
143
	 * Remove all child {@link ICdmFormElement}s and child {@link Control}s
144
	 * of the given and the element itself.
145
	 * @param formElement The element to remove
146
	 */
147
	public void removeElementsAndControls(ICdmFormElement formElement){
148
	    for(ICdmFormElement childElement : formElement.getElements()){
149
	        // recursion
150
	        childElement.removeElements();
151

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

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

    
163
	        // dispose of the controls
164
	        removeControls(childElement);
165
	    }
166
	    removeControls(formElement);
167
	}
168

    
169
	/**
170
	 * Removes all child {@link ICdmFormElement}s and child {@link Control}s
171
	 * and the element itself.
172
	 */
173
	@Override
174
    public void removeElements(){
175
		for(ICdmFormElement childElement : getElements()){
176
			// recursion
177
			childElement.removeElements();
178

    
179
			// unregister selection arbitrator
180
			if(childElement instanceof ISelectableElement){
181
				SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
182
				if(selectionArbitrator != null){
183
					formFactory.destroySelectionArbitrator(selectionArbitrator);
184
				}
185
			}
186

    
187
			// unregister from property changes
188
			formFactory.removePropertyChangeListener(childElement);
189

    
190
			// dispose of the controls
191
			removeControls(childElement);
192
		}
193
		removeControls(this);
194
		elements.clear();
195
	}
196

    
197
	private void removeControls(ICdmFormElement element){
198
		if(element instanceof Section){
199
			((Section) element).dispose();
200
			element = null;
201
		}else{
202
			for(Control control : element.getControls()){
203
				// we added the layoutComposite of the parental element as the layout composite to this formElement
204
				// but we do not want to destroy it.
205
				if(control.equals(element.getLayoutComposite())){
206
					continue;
207
				}else{
208
					control.dispose();
209
					control = null;
210
				}
211
			}
212
		}
213
	}
214

    
215
	/**
216
	 * <p>Getter for the field <code>layoutComposite</code>.</p>
217
	 *
218
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
219
	 */
220
	@Override
221
    public Composite getLayoutComposite() {
222
		return layoutComposite;
223
	}
224

    
225
	/**
226
	 * <p>Setter for the field <code>layoutComposite</code>.</p>
227
	 *
228
	 * @param layoutComposite a {@link org.eclipse.swt.widgets.Composite} object.
229
	 */
230
	public void setLayoutComposite(Composite layoutComposite){
231
		this.layoutComposite = layoutComposite;
232
	}
233

    
234
	/* (non-Javadoc)
235
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#getPropertyChangeListeners()
236
	 */
237
	/**
238
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
239
	 *
240
	 * @return a {@link java.util.Set} object.
241
	 */
242
	@Override
243
    public List<IPropertyChangeListener> getPropertyChangeListeners() {
244
		return propertyChangeListeners;
245
	}
246

    
247
	/* (non-Javadoc)
248
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#setPropertyChangeListeners(org.eclipse.core.runtime.ListenerList)
249
	 */
250
	/** {@inheritDoc} */
251
	@Override
252
    public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
253
		this.propertyChangeListeners = propertyChangeListeners;
254
	}
255

    
256
	/* (non-Javadoc)
257
	 * @see eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent()
258
	 */
259
	/* (non-Javadoc)
260
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormComposite#firePropertyChangeEvent(org.eclipse.jface.util.PropertyChangeEvent)
261
	 */
262
	/** {@inheritDoc} */
263
	@Override
264
    public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
265
	    //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
266
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
267

    
268
		try{
269
			for(Object listener : propertyChangeListeners){
270
				((IPropertyChangeListener)listener).propertyChange(event);
271
			}
272
		}catch(ConcurrentModificationException e){
273
			// There are two cases that produce a CME.
274
			// Described here: http://dev.e-taxonomy.eu/trac/ticket/2363#comment:2
275
			// and here: http://dev.e-taxonomy.eu/trac/ticket/2438
276
			// Ignoring the CME because nothing bad is happening
277
			MessagingUtils.warn(getClass(), "ConcurrentModificationException. Can be ignored.");
278
		}
279
	}
280

    
281
	/**
282
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
283
	 *
284
	 * @param object the object on which the property changed
285
	 */
286
	public void firePropertyChangeEvent(Object object){
287
		firePropertyChangeEvent(object, null);
288
	}
289

    
290
	/**
291
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
292
	 * originating event
293
	 *
294
	 * @param object the object on which the property changed
295
	 * @param originatingEvent the originating event
296
	 */
297
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
298
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
299
	}
300

    
301

    
302
	/**
303
	 * {@inheritDoc}
304
	 *
305
	 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
306
	 *
307
	 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
308
	 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
309
	 * @see eu.etaxonomy.taxeditor.ui.element.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
310
	 */
311
	@Override
312
    public void propertyChange(PropertyChangeEvent event) {
313
		// implement in subclasses
314
	}
315

    
316
	/** {@inheritDoc} */
317
	@Override
318
    public boolean containsFormElement(ICdmFormElement formElement){
319
		if(formElement == this){
320
			return true;
321
		}else{
322
			for(ICdmFormElement element : getElements()){
323
				boolean contains = element.containsFormElement(formElement);
324
				if(contains == true){
325
					return true;
326
				}
327
			}
328
			return false;
329
		}
330
	}
331

    
332
	/*
333
	 * (non-Javadoc)
334
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
335
	 */
336
	/**
337
	 * <p>refresh</p>
338
	 */
339
	@Override
340
    public void refresh() {
341
		// empty default implementation
342
	}
343

    
344

    
345
	/** {@inheritDoc} */
346
	@Override
347
	public void setBackground(Color color) {
348
		for(ICdmFormElement element : getElements()){
349
			element.setBackground(color);
350
		}
351
	}
352

    
353
	@Override
354
	public void setPersistentBackground(Color color) {
355
		persistentBackgroundColor = color;
356
		setBackground(color);
357
	}
358

    
359
	@Override
360
	public Color getPersistentBackground() {
361
		return persistentBackgroundColor;
362
	}
363

    
364
	public Color getColor(String colorId){
365
		return AbstractUtility.getColor(colorId);
366
	}
367
}
(2-2/40)