Project

General

Profile

Download (14.4 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.model.AbstractUtility;
37
import eu.etaxonomy.taxeditor.model.MessagingUtils;
38

    
39
/**
40
 * <p>
41
 * Abstract super class for a {@link Section} GUI element that visualizes a CDM
42
 * entity, manages a conversation and listens to selections
43
 * </p>
44
 *
45
 * @param <ENTITY> A CDM entity which should be visualized by this section.
46
 *
47
 * @author n.hoffmann
48
 * @created Feb 22, 2010
49
 * @version 1.0
50
 * @param <T>
51
 */
52
//TODO shouldn't ENTITY be bound with super class ICdmBase for example (AbstractFormSection<ENTITY extends ICdmBase>)?
53
public abstract class AbstractFormSection<ENTITY> extends Section implements ISelectionChangedListener, IEntityElement<ENTITY>, IConversationEnabled {
54

    
55
	private ISelectionProvider selectionProvider;
56

    
57
	private ENTITY entity;
58

    
59
	private final Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
60

    
61
	protected CdmFormFactory formFactory;
62

    
63
	private List<IPropertyChangeListener> propertyChangeListeners;
64

    
65
	private ICdmFormElement parentElement;
66

    
67
	private Color persistentBackgroundColor;
68

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

    
90
		this.parentElement = parentElement;
91

    
92
		this.formFactory = formFactory;
93

    
94
		this.setLayoutData(LayoutConstants.FILL());
95

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

    
99
		TableWrapLayout layout = LayoutConstants.LAYOUT();
100
		layout.bottomMargin = 10;
101
		layout.rightMargin = 5;
102

    
103
		client.setLayout(layout);
104

    
105
		this.setClient(client);
106

    
107
	}
108

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

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

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

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

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

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

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

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

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

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

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

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

    
274
	/*
275
	 * (non-Javadoc)
276
	 *
277
	 * @see
278
	 * org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics
279
	 * .Color)
280
	 */
281
	/** {@inheritDoc} */
282
	@Override
283
	public void setBackground(Color color) {
284
		for (ICdmFormElement element : getElements()) {
285
			element.setBackground(color);
286
		}
287
		getLayoutComposite().setBackground(color);
288
		super.setBackground(color);
289
	}
290

    
291
	@Override
292
	public void setPersistentBackground(Color color) {
293
		persistentBackgroundColor = color;
294
		setBackground(color);
295
	}
296

    
297
	@Override
298
	public Color getPersistentBackground() {
299
		return persistentBackgroundColor;
300
	}
301

    
302

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

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

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

    
340
	/** {@inheritDoc} */
341
	@Override
342
    public void setSelected(boolean selected) {
343
		if (selected) {
344
			setBackground(Display.getCurrent().getSystemColor(
345
					SWT.COLOR_LIST_SELECTION));
346
		} else {
347
			setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
348
		}
349
	}
350

    
351
	/** {@inheritDoc} */
352
	@Override
353
    public void selectionChanged(SelectionChangedEvent event) {
354
		if (event.getSelection() == CdmFormFactory.EMPTY_SELECTION) {
355
			return;
356
		}
357

    
358
		IStructuredSelection selection = (IStructuredSelection) event
359
				.getSelection();
360
		setSelected(false);
361

    
362
		Object selectedObject = selection.getFirstElement();
363

    
364
		if (selectedObject != null && selectedObject.equals(getEntity())) {
365
			setSelected(true);
366
		}
367
	}
368

    
369
	/**
370
	 * <p>
371
	 * addSelectionListener
372
	 * </p>
373
	 *
374
	 * @param listener
375
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
376
	 */
377
	public void addSelectionListener(SelectionListener listener) {
378
		addListener(SWT.Selection, new TypedListener(listener));
379
	}
380

    
381
	/**
382
	 * <p>
383
	 * removeSelectionListener
384
	 * </p>
385
	 *
386
	 * @param listener
387
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
388
	 */
389
	public void removeSelectionListener(SelectionListener listener) {
390
		removeListener(SWT.Selection, listener);
391
	}
392

    
393
	/** {@inheritDoc} */
394
	@Override
395
    public void addElement(ICdmFormElement element) {
396
		elements.add(element);
397
	}
398

    
399
	/**
400
	 * <p>
401
	 * removeElement
402
	 * </p>
403
	 *
404
	 * @param element
405
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
406
	 *            object.
407
	 */
408
	protected void removeElement(ICdmFormElement element) {
409
		elements.remove(element);
410
	}
411

    
412
	/**
413
	 * <p>
414
	 * removeElements
415
	 * </p>
416
	 */
417
	@Override
418
    public void removeElements() {
419
		for (ICdmFormElement childElement : getElements()) {
420
			// recursion
421
			childElement.removeElements();
422

    
423
			// unregister selection arbitrator
424
			if (childElement instanceof ISelectableElement) {
425
				ISelectableElement selectableElement = (ISelectableElement) childElement;
426
				if (selectableElement.getSelectionArbitrator() != null) {
427
					formFactory.destroySelectionArbitrator(selectableElement
428
							.getSelectionArbitrator());
429
				}
430
			}
431

    
432
			// unregister propertyChangeListener
433
			formFactory.removePropertyChangeListener(childElement);
434

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

    
449
		elements.clear();
450
	}
451

    
452
	/**
453
	 * <p>
454
	 * Getter for the field <code>parentElement</code>.
455
	 * </p>
456
	 *
457
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
458
	 */
459
	@Override
460
    public ICdmFormElement getParentElement() {
461
		return parentElement;
462
	}
463

    
464
	/**
465
	 * <p>
466
	 * Getter for the field <code>elements</code>.
467
	 * </p>
468
	 *
469
	 * @return a {@link java.util.Set} object.
470
	 */
471
	@Override
472
    public Set<ICdmFormElement> getElements() {
473
		return elements;
474
	}
475

    
476
	/**
477
	 * <p>
478
	 * getControls
479
	 * </p>
480
	 *
481
	 * @return a {@link java.util.Set} object.
482
	 */
483
	@Override
484
    public Set<Control> getControls() {
485
		Set<Control> controls = new HashSet<Control>();
486

    
487
		for (Control control : getChildren()) {
488
			controls.add(control);
489
		}
490

    
491
		return controls;
492
	}
493

    
494
	/** {@inheritDoc} */
495
	@Override
496
	public void dispose() {
497
		removeElements();
498
		super.dispose();
499
	}
500

    
501
	/**
502
	 * <p>
503
	 * getLayoutComposite
504
	 * </p>
505
	 *
506
	 * @return a {@link org.eclipse.swt.widgets.Composite} object.
507
	 */
508
	@Override
509
    public Composite getLayoutComposite() {
510
		return (Composite) getClient();
511
	}
512

    
513
	/** {@inheritDoc} */
514
	@Override
515
    public boolean containsFormElement(ICdmFormElement formElement) {
516
		if (formElement == this) {
517
			return true;
518
		} else {
519
			for (ICdmFormElement element : getElements()) {
520
				boolean contains = element.containsFormElement(formElement);
521
				if (contains == true) {
522
					return true;
523
				}
524
			}
525
			return false;
526
		}
527
	}
528

    
529
	/**
530
	 * <p>
531
	 * Getter for the field <code>formFactory</code>.
532
	 * </p>
533
	 *
534
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
535
	 */
536
	@Override
537
    public CdmFormFactory getFormFactory() {
538
		return formFactory;
539
	}
540

    
541
	/*
542
	 * (non-Javadoc)
543
	 *
544
	 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
545
	 */
546
	/**
547
	 * <p>
548
	 * refresh
549
	 * </p>
550
	 */
551
	@Override
552
    public void refresh() {
553
		// empty default implementation
554

    
555
	}
556

    
557
	/**
558
	 * <p>
559
	 * getConversationHolder
560
	 * </p>
561
	 *
562
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
563
	 *         object.
564
	 */
565
	@Override
566
    public ConversationHolder getConversationHolder() {
567
		if(getParentElement() instanceof RootElement || getParentElement() == null){
568

    
569
			IEditorPart activeEditor = AbstractUtility.getActiveEditor();
570
			if(activeEditor instanceof IConversationEnabled){
571
				ConversationHolder conversation = ((IConversationEnabled) AbstractUtility.getActiveEditor()).getConversationHolder();
572
				return conversation;
573
			}
574
		}else if(getParentElement() instanceof IConversationEnabled){
575
			return ((IConversationEnabled) getParentElement()).getConversationHolder();
576
		}
577
		MessagingUtils.messageDialog("Could not get conversation for AbstractFormSection",
578
				getClass(), "There is an error in the implementation. There should have been an active editor but it wasn't",
579
				new IllegalArgumentException());
580
		return null;
581

    
582
	}
583

    
584
	/** {@inheritDoc} */
585

    
586
	@Override
587
    public void update(CdmDataChangeMap changeEvents) {
588

    
589
	}
590

    
591

    
592
}
(4-4/39)