Project

General

Profile

Download (9.09 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.singlesource.ui.forms.CdmFormFactoryFacade;
20
import eu.etaxonomy.taxeditor.store.StoreUtil;
21

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

    
30
	protected CdmFormFactoryFacade formFactory;
31

    
32
	private List<IPropertyChangeListener> propertyChangeListeners;
33

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

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

    
276
	/**
277
	 * {@inheritDoc}
278
	 *
279
	 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
280
	 *
281
	 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
282
	 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
283
	 * @see eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
284
	 */
285
	public void propertyChange(PropertyChangeEvent event) {
286
		// implement in subclasses
287
	}
288
	
289
	/** {@inheritDoc} */
290
	public boolean containsFormElement(ICdmFormElement formElement){
291
		if(formElement == this){
292
			return true;
293
		}else{
294
			for(ICdmFormElement element : getElements()){
295
				boolean contains = element.containsFormElement(formElement);
296
				if(contains == true){
297
					return true;
298
				}
299
			}
300
			return false;
301
		}
302
	}
303
	
304
	/*
305
	 * (non-Javadoc)
306
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
307
	 */
308
	/**
309
	 * <p>refresh</p>
310
	 */
311
	public void refresh() {
312
		// empty default implementation	
313
	}
314
	
315
	/** {@inheritDoc} */
316
	@Override
317
	public void setBackground(Color color) {
318
		for(ICdmFormElement element : getElements()){
319
			element.setBackground(color);
320
		}
321
	}
322
	
323
	public Color getColor(String colorId){
324
		return StoreUtil.getColor(colorId);
325
	}
326
}
(2-2/31)