Project

General

Profile

Download (9.56 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.ui.element;
10

    
11
import java.util.ConcurrentModificationException;
12
import java.util.HashSet;
13
import java.util.List;
14
import java.util.Set;
15

    
16
import org.eclipse.core.runtime.Assert;
17
import org.eclipse.jface.util.IPropertyChangeListener;
18
import org.eclipse.jface.util.PropertyChangeEvent;
19
import org.eclipse.swt.graphics.Color;
20
import org.eclipse.swt.layout.GridData;
21
import org.eclipse.swt.widgets.Composite;
22
import org.eclipse.swt.widgets.Control;
23
import org.eclipse.ui.forms.widgets.Section;
24
import org.eclipse.ui.forms.widgets.TableWrapData;
25

    
26
import eu.etaxonomy.taxeditor.model.AbstractUtility;
27
import eu.etaxonomy.taxeditor.model.MessagingUtils;
28

    
29
/**
30
 * @author n.hoffmann
31
 */
32
public abstract class AbstractCdmFormElement implements ICdmFormElement {
33

    
34
	protected CdmFormFactory formFactory;
35

    
36
	private List<IPropertyChangeListener> propertyChangeListeners;
37

    
38
	private Composite layoutComposite;
39

    
40
	private final Set<Control> controls = new HashSet<>();
41

    
42
	private final Set<ICdmFormElement> elements = new HashSet<>();
43
	private ICdmFormElement parentElement;
44

    
45
	private Color persistentBackgroundColor;
46

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

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

    
58
	@Override
59
    public CdmFormFactory getFormFactory() {
60
		return formFactory;
61
	}
62

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

    
70
	/**
71
	 * Returns all Controls that are managed by this element
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
	protected void addControl(Control child){
82
		controls.add(child);
83
	}
84

    
85
	protected void removeControl(Control child){
86
		controls.remove(child);
87
	}
88

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

    
99
	@Override
100
    public ICdmFormElement getParentElement(){
101
		return parentElement;
102
	}
103

    
104
	@Override
105
    public void addElement(ICdmFormElement element){
106
		elements.add(element);
107
	}
108

    
109
	/**
110
	 * Remove all child {@link ICdmFormElement}s and child {@link Control}s
111
	 * of the given and the element itself.
112
	 * @param formElement The element to remove
113
	 */
114
	public void removeElementsAndControls(ICdmFormElement formElement){
115
	    for(ICdmFormElement childElement : formElement.getElements()){
116
	        // recursion
117
	        childElement.removeElements();
118

    
119
	        // unregister selection arbitrator
120
	        if(childElement instanceof ISelectableElement){
121
	            SelectionArbitrator selectionArbitrator = ((ISelectableElement) childElement).getSelectionArbitrator();
122
	            if(selectionArbitrator != null){
123
	                formFactory.destroySelectionArbitrator(selectionArbitrator);
124
	            }
125
	        }
126

    
127
	        // unregister from property changes
128
	        formFactory.removePropertyChangeListener(childElement);
129

    
130
	        // dispose of the controls
131
	        removeControls(childElement);
132
	    }
133
	    removeControls(formElement);
134
	    this.elements.remove(formElement);
135
	}
136

    
137
	/**
138
	 * Removes all child {@link ICdmFormElement}s and child {@link Control}s
139
	 * and the element itself.
140
	 */
141
	@Override
142
    public void removeElements(){
143
	    Set<ICdmFormElement> tmpElements = new HashSet<>(getElements());
144
        for (ICdmFormElement childElement : tmpElements) {
145
            // recursion
146
			childElement.removeElements();
147

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

    
156
			// unregister from property changes
157
			formFactory.removePropertyChangeListener(childElement);
158

    
159
			// dispose of the controls
160
			removeControls(childElement);
161
		}
162
		if(this instanceof ISelectableElement){
163
            SelectionArbitrator selectionArbitrator = ((ISelectableElement) this).getSelectionArbitrator();
164
            if(selectionArbitrator != null){
165
                formFactory.destroySelectionArbitrator(selectionArbitrator);
166
            }
167
        }
168
		removeControls(this);
169
		elements.clear();
170
	}
171

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

    
190
	@Override
191
    public Composite getLayoutComposite() {
192
		return layoutComposite;
193
	}
194
	public void setLayoutComposite(Composite layoutComposite){
195
		this.layoutComposite = layoutComposite;
196
	}
197

    
198
	public void addIndent(int indent)
199
	{  this.layoutComposite = formFactory.createComposite(layoutComposite);
200

    
201
	    if (this.layoutComposite.getParent().getLayoutData() instanceof TableWrapData){
202
	        TableWrapData tableWrap = (TableWrapData)this.layoutComposite.getParent().getLayoutData();
203
	        tableWrap.indent = indent;
204

    
205
	        this.layoutComposite.setLayoutData(tableWrap);
206
	    }
207
	    if (this.layoutComposite.getLayoutData() instanceof GridData){
208
	        GridData gridData = new GridData();
209
	        gridData.verticalIndent = indent;
210
            this.layoutComposite.setLayoutData(gridData);
211
        }
212
	}
213

    
214
	@Override
215
    public List<IPropertyChangeListener> getPropertyChangeListeners() {
216
		return propertyChangeListeners;
217
	}
218
	@Override
219
    public void setPropertyChangeListeners(List<IPropertyChangeListener> propertyChangeListeners){
220
		this.propertyChangeListeners = propertyChangeListeners;
221
	}
222

    
223
	@Override
224
    public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
225
	    //TODO: replace propertyChangeListeners with formFactory.getPropertyChangeListeners() and remove member propertyChangeListeners from AbstractCdmFormElement
226
		Assert.isNotNull(propertyChangeListeners, "Property change listeners are not present");
227

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

    
241
	/**
242
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
243
	 *
244
	 * @param object the object on which the property changed
245
	 */
246
	public void firePropertyChangeEvent(Object object){
247
		firePropertyChangeEvent(object, null);
248
	}
249

    
250
	/**
251
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
252
	 * originating event
253
	 *
254
	 * @param object the object on which the property changed
255
	 * @param originatingEvent the originating event
256
	 */
257
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
258
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
259
	}
260

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

    
275
	@Override
276
    public boolean containsFormElement(ICdmFormElement formElement){
277
		if(formElement == this){
278
			return true;
279
		}else{
280
			for(ICdmFormElement element : getElements()){
281
				boolean contains = element.containsFormElement(formElement);
282
				if(contains == true){
283
					return true;
284
				}
285
			}
286
			return false;
287
		}
288
	}
289

    
290
	@Override
291
    public void refresh() {
292
		// empty default implementation
293
	}
294

    
295
	@Override
296
	public void setBackground(Color color) {
297
		for(ICdmFormElement element : getElements()){
298
		    element.setBackground(color);
299
		}
300
	}
301

    
302
	@Override
303
	public void setPersistentBackground(Color color) {
304
		persistentBackgroundColor = color;
305
		setBackground(color);
306
	}
307

    
308
	@Override
309
	public Color getPersistentBackground() {
310
		return persistentBackgroundColor;
311
	}
312

    
313
	public Color getColor(String colorId){
314
		return AbstractUtility.getColor(colorId);
315
	}
316
}
(2-2/57)