Project

General

Profile

Download (12.2 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.jface.viewers.ISelectionChangedListener;
15
import org.eclipse.jface.viewers.ISelectionProvider;
16
import org.eclipse.jface.viewers.IStructuredSelection;
17
import org.eclipse.jface.viewers.SelectionChangedEvent;
18
import org.eclipse.jface.viewers.StructuredSelection;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.events.SelectionEvent;
21
import org.eclipse.swt.events.SelectionListener;
22
import org.eclipse.swt.graphics.Color;
23
import org.eclipse.swt.widgets.Composite;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.swt.widgets.TypedListener;
26
import org.eclipse.swt.widgets.Widget;
27
import org.eclipse.ui.forms.widgets.Section;
28
import org.eclipse.ui.forms.widgets.TableWrapLayout;
29
import org.eclipse.ui.forms.widgets.ToggleHyperlink;
30

    
31
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
32
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
33
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
34
import eu.etaxonomy.taxeditor.store.StoreUtil;
35
import eu.etaxonomy.taxeditor.store.singlesource.widget.DisplayProxy;
36

    
37
/**
38
 * <p>Abstract AbstractFormSection class.</p>
39
 *
40
 * @author n.hoffmann
41
 * @created Feb 22, 2010
42
 * @version 1.0
43
 * @param <T>
44
 */
45
public abstract class AbstractFormSection<ENTITY> extends Section implements ISelectionChangedListener, IEntityElement<ENTITY>, IConversationEnabled{
46
			
47
	private ISelectionProvider selectionProvider;
48
	
49
	private ENTITY entity; 
50
	
51
	private Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
52
	
53
	protected CdmFormFactory formFactory;
54
		
55
	private List<IPropertyChangeListener> propertyChangeListeners;
56

    
57
	private ICdmFormElement parentElement;
58
	
59
	private ConversationHolder conversation;
60

    
61
	private boolean handlingPropertyChange;
62

    
63
	/**
64
	 * <p>Constructor for AbstractFormSection.</p>
65
	 *
66
	 * @param conversation TODO
67
	 * @param style a int.
68
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
69
	 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
70
	 * @param <ENTITY> a ENTITY object.
71
	 */
72
	protected AbstractFormSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, int style) {
73
		super(parentElement.getLayoutComposite(), style);
74
		
75
		this.parentElement = parentElement;
76
		
77
		this.formFactory = formFactory;
78
		
79
		this.conversation = conversation;
80
		
81
		this.setLayoutData(CdmFormFactory.FILL());
82
		
83
		Composite client = formFactory.createComposite(this, SWT.WRAP);
84
		client.setBackgroundMode(SWT.INHERIT_DEFAULT);
85
		
86
		TableWrapLayout layout = CdmFormFactory.LAYOUT();
87
		layout.bottomMargin = 10;
88
		layout.rightMargin = 5;
89
		
90
		client.setLayout(layout);
91

    
92
		this.setClient(client);
93
	}
94

    
95
	/**
96
	 * <p>Constructor for AbstractFormSection.</p>
97
	 *
98
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
99
	 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
100
	 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
101
	 * @param selectionProvider a {@link org.eclipse.jface.viewers.ISelectionProvider} object.
102
	 * @param style a int.
103
	 */
104
	protected AbstractFormSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, ISelectionProvider selectionProvider, int style){
105
		this(formFactory, conversation, parentElement, style);
106
		this.selectionProvider = selectionProvider;
107
	}
108
	
109
	/**
110
	 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
111
	 *
112
	 * @return a {@link java.util.Set} object.
113
	 */
114
	public List<IPropertyChangeListener> getPropertyChangeListeners() {
115
		return propertyChangeListeners;
116
	}
117
	
118
	/** {@inheritDoc} */
119
	public void setPropertyChangeListeners(
120
			List<IPropertyChangeListener> propertyChangeListeners) {
121
		this.propertyChangeListeners = propertyChangeListeners;
122
	}
123

    
124
	/**
125
	 * <p>Setter for the field <code>entity</code>.</p>
126
	 *
127
	 * @param entity a ENTITY object.
128
	 */
129
	public void setEntity(ENTITY entity){
130
		this.entity = entity;
131
	}
132

    
133
	/*
134
	 * (non-Javadoc)
135
	 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
136
	 */
137
	/**
138
	 * <p>Getter for the field <code>entity</code>.</p>
139
	 *
140
	 * @return a ENTITY object.
141
	 */
142
	public ENTITY getEntity() {
143
		return entity;
144
	}
145
		
146
	/**
147
	 * <p>getToggle</p>
148
	 *
149
	 * @return a {@link org.eclipse.ui.forms.widgets.ToggleHyperlink} object.
150
	 */
151
	public ToggleHyperlink getToggle(){
152
		return this.toggle;
153
	}
154

    
155
	/**
156
	 * <p>getSection</p>
157
	 *
158
	 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.AbstractFormSection} object.
159
	 */
160
	public AbstractFormSection<ENTITY> getSection(){
161
		return this;
162
	}	
163
	
164
	/* (non-Javadoc)
165
	 * @see eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent()
166
	 */
167
	/** {@inheritDoc} */
168
	public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
169
		Assert.isNotNull(propertyChangeListeners, "No property change listeners.");
170
		try{
171
			for(Object listener : propertyChangeListeners){
172
				((IPropertyChangeListener) listener).propertyChange(event);
173
			}
174
		}catch(ConcurrentModificationException e){
175
			StoreUtil.warn(getClass(), "ConcurrentModificationException while handling PropertyChangeEvents." +
176
					" It seems like this is not critical");
177
		}
178
	}
179
	
180

    
181
	/**
182
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
183
	 *  
184
	 * @param object the object on which the property changed
185
	 */
186
	public void firePropertyChangeEvent(Object object){
187
		firePropertyChangeEvent(object, null);
188
	}
189
	
190
	/**
191
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source also containing the
192
	 * originating event
193
	 * 
194
	 * @param object the object on which the property changed
195
	 * @param originatingEvent the originating event
196
	 */
197
	public void firePropertyChangeEvent(Object object, PropertyChangeEvent originatingEvent){
198
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object, originatingEvent));
199
	}
200
	
201
	/* (non-Javadoc)
202
	 * @see org.eclipse.swt.widgets.Composite#setFocus()
203
	 */
204
	/** {@inheritDoc} */
205
	@Override
206
	public boolean setFocus() {
207
		return getClient().setFocus();
208
	}
209
	
210
	/* (non-Javadoc)
211
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
212
	 */
213
	/** {@inheritDoc} */
214
	public void propertyChange(PropertyChangeEvent event) {
215
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, event));
216
	}
217
	
218
	/* (non-Javadoc)
219
	 * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)
220
	 */
221
	/** {@inheritDoc} */
222
	@Override
223
	public void setBackground(Color color) {
224
		for(ICdmFormElement element : getElements()){
225
			element.setBackground(color);
226
		}
227
		getLayoutComposite().setBackground(color);
228
		super.setBackground(color);
229
	}
230
	
231
	/**
232
	 * <p>widgetSelected</p>
233
	 *
234
	 * @param e a {@link org.eclipse.swt.events.SelectionEvent} object.
235
	 */
236
	public void widgetSelected(SelectionEvent e) {
237
		Widget widget = e.widget;
238
		
239
		if(widget instanceof Control){
240
			Control control = (Control) widget;
241
			if(checkControlAncestryForWidget(control)){
242
				if(getEntity() != null){
243
					IStructuredSelection selection = new StructuredSelection(getEntity());
244
					if(selectionProvider != null){
245
						selectionProvider.setSelection(selection);
246
					}
247
				}
248
			}
249
		}	
250
	}
251
	
252
	private boolean checkControlAncestryForWidget(Control control){
253
		if(control.equals(this)){
254
			return true;
255
		}else{
256
			Control parent = control.getParent();
257
			if(parent == null){
258
				return false;
259
			}else{
260
				return checkControlAncestryForWidget(parent);
261
			}
262
		}
263
	}
264
	
265
	/** {@inheritDoc} */
266
	public void setSelected(boolean selected) {
267
		if(selected){
268
			setBackground(DisplayProxy.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION));
269
		}else{
270
			setBackground(DisplayProxy.getDefault().getSystemColor(SWT.COLOR_WHITE));
271
		}
272
	}
273
	
274

    
275
	/** {@inheritDoc} */
276
	public void selectionChanged(SelectionChangedEvent event) {
277
		if(event.getSelection() == CdmFormFactory.EMPTY_SELECTION){
278
			return;
279
		}
280
		
281
		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
282
		setSelected(false);
283
		
284
		Object selectedObject =  selection.getFirstElement();
285
		
286
		if(selectedObject != null && selectedObject.equals(getEntity())){
287
			setSelected(true);
288
		}
289
	}
290
	
291
	/**
292
	 * <p>addSelectionListener</p>
293
	 *
294
	 * @param listener a {@link org.eclipse.swt.events.SelectionListener} object.
295
	 */
296
	public void addSelectionListener(SelectionListener listener) {
297
		addListener(SWT.Selection, new TypedListener(listener));
298
	}
299
	 
300
	/**
301
	 * <p>removeSelectionListener</p>
302
	 *
303
	 * @param listener a {@link org.eclipse.swt.events.SelectionListener} object.
304
	 */
305
	public void removeSelectionListener(SelectionListener listener) {
306
		removeListener(SWT.Selection, listener);
307
	}
308
	
309
	/** {@inheritDoc} */
310
	public Color getColor(boolean selected) {
311
		return selected ? SELECTED : NOT_SELECTED;
312
	}
313
	
314
	/** {@inheritDoc} */
315
	public void addElement(ICdmFormElement element){
316
		elements.add(element);
317
	}
318
	
319
	/**
320
	 * <p>removeElement</p>
321
	 *
322
	 * @param element a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
323
	 */
324
	protected void removeElement(ICdmFormElement element){
325
		elements.remove(element);
326
	}
327
	
328
	/**
329
	 * <p>removeElements</p>
330
	 */
331
	public void removeElements() {
332
		for(ICdmFormElement childElement : getElements()){
333
			// recursion
334
			childElement.removeElements();
335
			
336
			// unregister selection arbitrator
337
			if(childElement instanceof ISelectableElement){
338
				ISelectableElement selectableElement = (ISelectableElement) childElement;
339
				if (selectableElement != null && selectableElement.getSelectionArbitrator() != null) {
340
					formFactory.destroySelectionArbitrator(selectableElement.getSelectionArbitrator());
341
				}
342
			}
343
			
344
			// unregister propertyChangeListener
345
			formFactory.removePropertyChangeListener(childElement);
346
			
347
			// dispose of the controls
348
			for(Control control : childElement.getControls()){
349
				// we added the layoutComposite of the parental element as the layout composite to this formElement
350
				// but we do not want to destroy it.
351
				if(control.equals(childElement.getLayoutComposite())){
352
					continue;
353
				}else{
354
					control.dispose();
355
					control = null;
356
				}
357
			}
358
		}
359
		
360
		elements.clear();
361
	}
362
	
363
	/**
364
	 * <p>Getter for the field <code>parentElement</code>.</p>
365
	 *
366
	 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
367
	 */
368
	public ICdmFormElement getParentElement() {
369
		return parentElement;
370
	}
371
	
372
	/**
373
	 * <p>Getter for the field <code>elements</code>.</p>
374
	 *
375
	 * @return a {@link java.util.Set} object.
376
	 */
377
	public Set<ICdmFormElement> getElements() {
378
		return elements;
379
	}
380
	
381
	/**
382
	 * <p>getControls</p>
383
	 *
384
	 * @return a {@link java.util.Set} object.
385
	 */
386
	public Set<Control> getControls() {
387
		Set<Control> controls = new HashSet<Control>();
388
		
389
		for (Control control : getChildren()){
390
			controls.add(control);
391
		}
392
		
393
		return controls; 
394
	}
395
	
396
	/** {@inheritDoc} */
397
	@Override
398
	public void dispose() {
399
		removeElements();
400
		super.dispose();
401
	}
402
	
403
	/**
404
	 * <p>getLayoutComposite</p>
405
	 *
406
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
407
	 */
408
	public Composite getLayoutComposite() {
409
		return (Composite) getClient();
410
	}
411
	
412
	/** {@inheritDoc} */
413
	public boolean containsFormElement(ICdmFormElement formElement){
414
		if(formElement == this){
415
			return true;
416
		}else{
417
			for(ICdmFormElement element : getElements()){				
418
				boolean contains = element.containsFormElement(formElement);
419
				if(contains == true){
420
					return true;
421
				}
422
			}
423
			return false;
424
		}
425
	}
426

    
427

    
428
	/**
429
	 * <p>Getter for the field <code>formFactory</code>.</p>
430
	 *
431
	 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
432
	 */
433
	public CdmFormFactory getFormFactory() {
434
		return formFactory;
435
	}
436
	
437
	/*
438
	 * (non-Javadoc)
439
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
440
	 */
441
	/**
442
	 * <p>refresh</p>
443
	 */
444
	public void refresh() {
445
		// empty default implementation
446
		
447
	}
448
	
449
	/**
450
	 * <p>getConversationHolder</p>
451
	 *
452
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
453
	 */
454
	public ConversationHolder getConversationHolder() {
455
		return conversation;
456
	}
457
	
458
	/** {@inheritDoc} */
459
	public void update(CdmDataChangeMap changeEvents) {}
460
}
(4-4/35)