Project

General

Profile

Download (13.6 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.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.Display;
26
import org.eclipse.swt.widgets.TypedListener;
27
import org.eclipse.swt.widgets.Widget;
28
import org.eclipse.ui.IEditorPart;
29
import org.eclipse.ui.forms.widgets.Section;
30
import org.eclipse.ui.forms.widgets.TableWrapLayout;
31
import org.eclipse.ui.forms.widgets.ToggleHyperlink;
32

    
33
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
34
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
35
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
36
import eu.etaxonomy.taxeditor.store.StoreUtil;
37

    
38
/**
39
 * <p>
40
 * Abstract AbstractFormSection class.
41
 * </p>
42
 * 
43
 * @author n.hoffmann
44
 * @created Feb 22, 2010
45
 * @version 1.0
46
 * @param <T>
47
 */
48
public abstract class AbstractFormSection<ENTITY> extends Section implements
49
		ISelectionChangedListener, ICdmFormElement, IEntityElement<ENTITY>,
50
		IConversationEnabled {
51

    
52
	private ISelectionProvider selectionProvider;
53

    
54
	private ENTITY entity;
55

    
56
	private Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
57

    
58
	protected CdmFormFactory formFactory;
59

    
60
	private List<IPropertyChangeListener> propertyChangeListeners;
61

    
62
	private ICdmFormElement parentElement;
63

    
64
	private Color persistentBackgroundColor;
65

    
66
	/**
67
	 * <p>
68
	 * Constructor for AbstractFormSection.
69
	 * </p>
70
	 * 
71
	 * @param conversation
72
	 *            TODO
73
	 * @param style
74
	 *            a int.
75
	 * @param formFactory
76
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
77
	 *            object.
78
	 * @param parentElement
79
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
80
	 *            object.
81
	 * @param <ENTITY>
82
	 *            a ENTITY object.
83
	 */
84
	protected AbstractFormSection(CdmFormFactory formFactory, ICdmFormElement parentElement,
85
			int style) {
86
		super(parentElement.getLayoutComposite(), style);
87

    
88
		this.parentElement = parentElement;
89

    
90
		this.formFactory = formFactory;
91

    
92
		this.setLayoutData(CdmFormFactory.FILL());
93

    
94
		Composite client = formFactory.createComposite(this, SWT.WRAP);
95
		client.setBackgroundMode(SWT.INHERIT_DEFAULT);
96

    
97
		TableWrapLayout layout = CdmFormFactory.LAYOUT();
98
		layout.bottomMargin = 10;
99
		layout.rightMargin = 5;
100

    
101
		client.setLayout(layout);
102

    
103
		this.setClient(client);
104
	}
105

    
106
	/**
107
	 * <p>
108
	 * Constructor for AbstractFormSection.
109
	 * </p>
110
	 * 
111
	 * @param formFactory
112
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
113
	 *            object.
114
	 * @param conversation
115
	 *            a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
116
	 *            object.
117
	 * @param parentElement
118
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
119
	 *            object.
120
	 * @param selectionProvider
121
	 *            a {@link org.eclipse.jface.viewers.ISelectionProvider} object.
122
	 * @param style
123
	 *            a int.
124
	 */
125
	protected AbstractFormSection(CdmFormFactory formFactory,
126
			ICdmFormElement parentElement,
127
			ISelectionProvider selectionProvider, int style) {
128
		this(formFactory, parentElement, style);
129
		this.selectionProvider = selectionProvider;
130
	}
131

    
132
	/**
133
	 * <p>
134
	 * Getter for the field <code>propertyChangeListeners</code>.
135
	 * </p>
136
	 * 
137
	 * @return a {@link java.util.Set} object.
138
	 */
139
	public List<IPropertyChangeListener> getPropertyChangeListeners() {
140
		return propertyChangeListeners;
141
	}
142

    
143
	/** {@inheritDoc} */
144
	public void setPropertyChangeListeners(
145
			List<IPropertyChangeListener> propertyChangeListeners) {
146
		this.propertyChangeListeners = propertyChangeListeners;
147
	}
148

    
149
	/**
150
	 * <p>
151
	 * Setter for the field <code>entity</code>.
152
	 * </p>
153
	 * 
154
	 * @param entity
155
	 *            a ENTITY object.
156
	 */
157
	public void setEntity(ENTITY entity) {
158
		this.entity = entity;
159
	}
160

    
161
	/*
162
	 * (non-Javadoc)
163
	 * 
164
	 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
165
	 */
166
	/**
167
	 * <p>
168
	 * Getter for the field <code>entity</code>.
169
	 * </p>
170
	 * 
171
	 * @return a ENTITY object.
172
	 */
173
	public ENTITY getEntity() {
174
		return entity;
175
	}
176

    
177
	/**
178
	 * <p>
179
	 * getToggle
180
	 * </p>
181
	 * 
182
	 * @return a {@link org.eclipse.ui.forms.widgets.ToggleHyperlink} object.
183
	 */
184
	public ToggleHyperlink getToggle() {
185
		return this.toggle;
186
	}
187

    
188
	/**
189
	 * <p>
190
	 * getSection
191
	 * </p>
192
	 * 
193
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.AbstractFormSection}
194
	 *         object.
195
	 */
196
	public AbstractFormSection<ENTITY> getSection() {
197
		return this;
198
	}
199

    
200
	/*
201
	 * (non-Javadoc)
202
	 * 
203
	 * @see
204
	 * eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent
205
	 * ()
206
	 */
207
	/** {@inheritDoc} */
208
	public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
209
		Assert.isNotNull(propertyChangeListeners,
210
				"No property change listeners.");
211
		try {
212
			for (Object listener : propertyChangeListeners) {
213
				((IPropertyChangeListener) listener).propertyChange(event);
214
			}
215
		} catch (ConcurrentModificationException e) {
216
			StoreUtil.warn(getClass(),
217
					"ConcurrentModificationException while handling PropertyChangeEvents."
218
							+ " It seems like this is not critical");
219
		}
220
	}
221

    
222
	/**
223
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source.
224
	 * 
225
	 * @param object
226
	 *            the object on which the property changed
227
	 */
228
	public void firePropertyChangeEvent(Object object) {
229
		firePropertyChangeEvent(object, null);
230
	}
231

    
232
	/**
233
	 * Fires a {@link CdmPropertyChangeEvent} with the given object as source
234
	 * also containing the originating event
235
	 * 
236
	 * @param object
237
	 *            the object on which the property changed
238
	 * @param originatingEvent
239
	 *            the originating event
240
	 */
241
	public void firePropertyChangeEvent(Object object,
242
			PropertyChangeEvent originatingEvent) {
243
		firePropertyChangeEvent(new CdmPropertyChangeEvent(object,
244
				originatingEvent));
245
	}
246

    
247
	/*
248
	 * (non-Javadoc)
249
	 * 
250
	 * @see org.eclipse.swt.widgets.Composite#setFocus()
251
	 */
252
	/** {@inheritDoc} */
253
	@Override
254
	public boolean setFocus() {
255
		return getClient().setFocus();
256
	}
257

    
258
	/*
259
	 * (non-Javadoc)
260
	 * 
261
	 * @see
262
	 * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse
263
	 * .jface.util.PropertyChangeEvent)
264
	 */
265
	/** {@inheritDoc} */
266
	public void propertyChange(PropertyChangeEvent event) {
267
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, event));
268
	}
269

    
270
	/*
271
	 * (non-Javadoc)
272
	 * 
273
	 * @see
274
	 * org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics
275
	 * .Color)
276
	 */
277
	/** {@inheritDoc} */
278
	@Override
279
	public void setBackground(Color color) {
280
		for (ICdmFormElement element : getElements()) {
281
			element.setBackground(color);
282
		}
283
		getLayoutComposite().setBackground(color);
284
		super.setBackground(color);
285
	}
286
	
287
	@Override
288
	public void setPersistentBackground(Color color) {
289
		persistentBackgroundColor = color;
290
		setBackground(color);
291
	}
292
	
293
	@Override
294
	public Color getPersistentBackground() {
295
		return persistentBackgroundColor;
296
	}
297
	
298

    
299
	/**
300
	 * <p>
301
	 * widgetSelected
302
	 * </p>
303
	 * 
304
	 * @param e
305
	 *            a {@link org.eclipse.swt.events.SelectionEvent} object.
306
	 */
307
	public void widgetSelected(SelectionEvent e) {
308
		Widget widget = e.widget;
309

    
310
		if (widget instanceof Control) {
311
			Control control = (Control) widget;
312
			if (checkControlAncestryForWidget(control)) {
313
				if (getEntity() != null) {
314
					IStructuredSelection selection = new StructuredSelection(
315
							getEntity());
316
					if (selectionProvider != null) {
317
						selectionProvider.setSelection(selection);
318
					}
319
				}
320
			}
321
		}
322
	}
323

    
324
	private boolean checkControlAncestryForWidget(Control control) {
325
		if (control.equals(this)) {
326
			return true;
327
		} else {
328
			Control parent = control.getParent();
329
			if (parent == null) {
330
				return false;
331
			} else {
332
				return checkControlAncestryForWidget(parent);
333
			}
334
		}
335
	}
336

    
337
	/** {@inheritDoc} */
338
	public void setSelected(boolean selected) {
339
		if (selected) {
340
			setBackground(Display.getCurrent().getSystemColor(
341
					SWT.COLOR_LIST_SELECTION));
342
		} else {
343
			setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
344
		}
345
	}
346

    
347
	/** {@inheritDoc} */
348
	public void selectionChanged(SelectionChangedEvent event) {
349
		if (event.getSelection() == CdmFormFactory.EMPTY_SELECTION) {
350
			return;
351
		}
352

    
353
		IStructuredSelection selection = (IStructuredSelection) event
354
				.getSelection();
355
		setSelected(false);
356

    
357
		Object selectedObject = selection.getFirstElement();
358

    
359
		if (selectedObject != null && selectedObject.equals(getEntity())) {
360
			setSelected(true);
361
		}
362
	}
363

    
364
	/**
365
	 * <p>
366
	 * addSelectionListener
367
	 * </p>
368
	 * 
369
	 * @param listener
370
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
371
	 */
372
	public void addSelectionListener(SelectionListener listener) {
373
		addListener(SWT.Selection, new TypedListener(listener));
374
	}
375

    
376
	/**
377
	 * <p>
378
	 * removeSelectionListener
379
	 * </p>
380
	 * 
381
	 * @param listener
382
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
383
	 */
384
	public void removeSelectionListener(SelectionListener listener) {
385
		removeListener(SWT.Selection, listener);
386
	}
387

    
388
	/** {@inheritDoc} */
389
	public void addElement(ICdmFormElement element) {
390
		elements.add(element);
391
	}
392

    
393
	/**
394
	 * <p>
395
	 * removeElement
396
	 * </p>
397
	 * 
398
	 * @param element
399
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
400
	 *            object.
401
	 */
402
	protected void removeElement(ICdmFormElement element) {
403
		elements.remove(element);
404
	}
405

    
406
	/**
407
	 * <p>
408
	 * removeElements
409
	 * </p>
410
	 */
411
	public void removeElements() {
412
		for (ICdmFormElement childElement : getElements()) {
413
			// recursion
414
			childElement.removeElements();
415

    
416
			// unregister selection arbitrator
417
			if (childElement instanceof ISelectableElement) {
418
				ISelectableElement selectableElement = (ISelectableElement) childElement;
419
				if (selectableElement != null
420
						&& selectableElement.getSelectionArbitrator() != null) {
421
					formFactory.destroySelectionArbitrator(selectableElement
422
							.getSelectionArbitrator());
423
				}
424
			}
425

    
426
			// unregister propertyChangeListener
427
			formFactory.removePropertyChangeListener(childElement);
428

    
429
			// dispose of the controls
430
			for (Control control : childElement.getControls()) {
431
				// we added the layoutComposite of the parental element as the
432
				// layout composite to this formElement
433
				// but we do not want to destroy it.
434
				if (control.equals(childElement.getLayoutComposite())) {
435
					continue;
436
				} else {
437
					control.dispose();
438
					control = null;
439
				}
440
			}
441
		}
442

    
443
		elements.clear();
444
	}
445

    
446
	/**
447
	 * <p>
448
	 * Getter for the field <code>parentElement</code>.
449
	 * </p>
450
	 * 
451
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
452
	 */
453
	public ICdmFormElement getParentElement() {
454
		return parentElement;
455
	}
456

    
457
	/**
458
	 * <p>
459
	 * Getter for the field <code>elements</code>.
460
	 * </p>
461
	 * 
462
	 * @return a {@link java.util.Set} object.
463
	 */
464
	public Set<ICdmFormElement> getElements() {
465
		return elements;
466
	}
467

    
468
	/**
469
	 * <p>
470
	 * getControls
471
	 * </p>
472
	 * 
473
	 * @return a {@link java.util.Set} object.
474
	 */
475
	public Set<Control> getControls() {
476
		Set<Control> controls = new HashSet<Control>();
477

    
478
		for (Control control : getChildren()) {
479
			controls.add(control);
480
		}
481

    
482
		return controls;
483
	}
484

    
485
	/** {@inheritDoc} */
486
	@Override
487
	public void dispose() {
488
		removeElements();
489
		super.dispose();
490
	}
491

    
492
	/**
493
	 * <p>
494
	 * getLayoutComposite
495
	 * </p>
496
	 * 
497
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
498
	 */
499
	public Composite getLayoutComposite() {
500
		return (Composite) getClient();
501
	}
502

    
503
	/** {@inheritDoc} */
504
	public boolean containsFormElement(ICdmFormElement formElement) {
505
		if (formElement == this) {
506
			return true;
507
		} else {
508
			for (ICdmFormElement element : getElements()) {
509
				boolean contains = element.containsFormElement(formElement);
510
				if (contains == true) {
511
					return true;
512
				}
513
			}
514
			return false;
515
		}
516
	}
517

    
518
	/**
519
	 * <p>
520
	 * Getter for the field <code>formFactory</code>.
521
	 * </p>
522
	 * 
523
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
524
	 */
525
	public CdmFormFactory getFormFactory() {
526
		return formFactory;
527
	}
528

    
529
	/*
530
	 * (non-Javadoc)
531
	 * 
532
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
533
	 */
534
	/**
535
	 * <p>
536
	 * refresh
537
	 * </p>
538
	 */
539
	public void refresh() {
540
		// empty default implementation
541

    
542
	}
543

    
544
	/**
545
	 * <p>
546
	 * getConversationHolder
547
	 * </p>
548
	 * 
549
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
550
	 *         object.
551
	 */
552
	public ConversationHolder getConversationHolder() {
553
		if(getParentElement() instanceof RootElement || getParentElement() == null){
554
		
555
			IEditorPart activeEditor = StoreUtil.getActiveEditor();
556
			if(activeEditor instanceof IConversationEnabled){
557
				ConversationHolder conversation = ((IConversationEnabled) StoreUtil.getActiveEditor()).getConversationHolder();
558
				return conversation;
559
			}
560
		}else if(getParentElement() instanceof IConversationEnabled){
561
			return ((IConversationEnabled) getParentElement()).getConversationHolder();
562
		}
563
		StoreUtil.errorDialog("Could not get conversation for AbstractFormSection", 
564
				getClass(), "There is an error in the implementation. There should have been an active editor but it wasn't", 
565
				new IllegalArgumentException());
566
		return null;
567
	
568
	}
569

    
570
	/** {@inheritDoc} */
571
	public void update(CdmDataChangeMap changeEvents) {
572
	}
573

    
574

    
575
}
(4-4/35)