Project

General

Profile

Download (9.89 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.Iterator;
9
import java.util.List;
10
import java.util.Set;
11

    
12
import org.eclipse.core.runtime.Assert;
13
import org.eclipse.jface.util.IPropertyChangeListener;
14
import org.eclipse.jface.util.PropertyChangeEvent;
15
import org.eclipse.swt.graphics.Color;
16
import org.eclipse.swt.layout.GridData;
17
import org.eclipse.swt.widgets.Composite;
18
import org.eclipse.swt.widgets.Control;
19
import org.eclipse.ui.forms.widgets.Section;
20
import org.eclipse.ui.forms.widgets.TableWrapData;
21

    
22
import eu.etaxonomy.taxeditor.model.AbstractUtility;
23
import eu.etaxonomy.taxeditor.model.MessagingUtils;
24

    
25
/**
26
 * @author n.hoffmann
27
 * @version $Id: $
28
 */
29
public abstract class AbstractCdmFormElement implements ICdmFormElement {
30

    
31
	protected CdmFormFactory formFactory;
32

    
33
	private List<IPropertyChangeListener> propertyChangeListeners;
34

    
35
	private Composite layoutComposite;
36

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

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

    
42
	private Color persistentBackgroundColor;
43

    
44

    
45
	protected AbstractCdmFormElement(CdmFormFactory formFactory, Composite layoutComposite){
46
		this.layoutComposite = layoutComposite;
47
		this.formFactory = formFactory;
48
	}
49

    
50
	public AbstractCdmFormElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
51
		this(formFactory, formElement.getLayoutComposite());
52
		this.parentElement = formElement;
53
//		addControl(layoutComposite);
54
	}
55

    
56
	@Override
57
    public CdmFormFactory getFormFactory() {
58
		return formFactory;
59
	}
60

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

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

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

    
87
	protected void removeControl(Control child){
88
		controls.remove(child);
89
	}
90

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

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

    
111
	/** {@inheritDoc} */
112
	@Override
113
    public void addElement(ICdmFormElement element){
114
		elements.add(element);
115
	}
116

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

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

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

    
138
	        // dispose of the controls
139
	        removeControls(childElement);
140
	    }
141
	    removeControls(formElement);
142
	    this.elements.remove(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 (Iterator<ICdmFormElement> iterator = getElements().iterator();iterator.hasNext();) {
152
            ICdmFormElement childElement = iterator.next();
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
			formFactory.removePropertyChangeListener(childElement);
166

    
167
			// dispose of the controls
168
			removeControls(childElement);
169
		}
170
		if(this instanceof ISelectableElement){
171
            SelectionArbitrator selectionArbitrator = ((ISelectableElement) this).getSelectionArbitrator();
172
            if(selectionArbitrator != null){
173
                formFactory.destroySelectionArbitrator(selectionArbitrator);
174
            }
175
        }
176
		removeControls(this);
177
		elements.clear();
178
	}
179

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

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

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

    
217
	public void addIndent(int indent)
218
	{  this.layoutComposite = formFactory.createComposite(layoutComposite);
219

    
220
	    if (this.layoutComposite.getParent().getLayoutData() instanceof TableWrapData){
221
	        TableWrapData tableWrap = (TableWrapData)this.layoutComposite.getParent().getLayoutData();
222
	        tableWrap.indent = indent;
223

    
224
	        this.layoutComposite.setLayoutData(tableWrap);
225
	    }
226
	    if (this.layoutComposite.getLayoutData() instanceof GridData){
227
	        GridData gridData = new GridData();
228
	        gridData.verticalIndent = indent;
229
            this.layoutComposite.setLayoutData(gridData);
230

    
231
        }
232
	}
233
	/**
234
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
235
	 *
236
	 * @return a {@link java.util.Set} object.
237
	 */
238
	@Override
239
    public List<IPropertyChangeListener> getPropertyChangeListeners() {
240
		return propertyChangeListeners;
241
	}
242

    
243
	/** {@inheritDoc} */
244
	@Override
245
    public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
246
		this.propertyChangeListeners = propertyChangeListeners;
247
	}
248

    
249
	/** {@inheritDoc} */
250
	@Override
251
    public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
252
	    //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
253
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
254

    
255
		try{
256
			for(Object listener : propertyChangeListeners){
257
				((IPropertyChangeListener)listener).propertyChange(event);
258
			}
259
		}catch(ConcurrentModificationException e){
260
			// There are two cases that produce a CME.
261
			// Described here: http://dev.e-taxonomy.eu/trac/ticket/2363#comment:2
262
			// and here: http://dev.e-taxonomy.eu/trac/ticket/2438
263
			// Ignoring the CME because nothing bad is happening
264
			MessagingUtils.warn(getClass(), "ConcurrentModificationException. Can be ignored.");
265
		}
266
	}
267

    
268
	/**
269
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
270
	 *
271
	 * @param object the object on which the property changed
272
	 */
273
	public void firePropertyChangeEvent(Object object){
274
		firePropertyChangeEvent(object, null);
275
	}
276

    
277
	/**
278
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
279
	 * originating event
280
	 *
281
	 * @param object the object on which the property changed
282
	 * @param originatingEvent the originating event
283
	 */
284
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
285
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
286
	}
287

    
288

    
289
	/**
290
	 * {@inheritDoc}
291
	 *
292
	 * This method gets called whenever the toolkit this composite was created with gets a property change notification.
293
	 *
294
	 * It is good advice to check whether the PropertyChangeEvent is destined for the implementing composite.
295
	 * Implementations should also check for null PropertyChangeEvents and return immediately in that case.
296
	 * @see eu.etaxonomy.taxeditor.ui.element.ICdmFormElement#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
297
	 */
298
	@Override
299
    public void propertyChange(PropertyChangeEvent event) {
300
		// implement in subclasses
301
	}
302

    
303
	/** {@inheritDoc} */
304
	@Override
305
    public boolean containsFormElement(ICdmFormElement formElement){
306
		if(formElement == this){
307
			return true;
308
		}else{
309
			for(ICdmFormElement element : getElements()){
310
				boolean contains = element.containsFormElement(formElement);
311
				if(contains == true){
312
					return true;
313
				}
314
			}
315
			return false;
316
		}
317
	}
318

    
319
	@Override
320
    public void refresh() {
321
		// empty default implementation
322
	}
323

    
324

    
325
	/** {@inheritDoc} */
326
	@Override
327
	public void setBackground(Color color) {
328
		for(ICdmFormElement element : getElements()){
329
		    element.setBackground(color);
330
		}
331
	}
332

    
333
	@Override
334
	public void setPersistentBackground(Color color) {
335
		persistentBackgroundColor = color;
336
		setBackground(color);
337
	}
338

    
339
	@Override
340
	public Color getPersistentBackground() {
341
		return persistentBackgroundColor;
342
	}
343

    
344
	public Color getColor(String colorId){
345
		return AbstractUtility.getColor(colorId);
346
	}
347
}
(2-2/48)