had to rename the packages to make them compliant with buckminster
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / forms / AbstractFormSection.java
1 /**
2 *
3 */
4 package eu.etaxonomy.taxeditor.ui.forms;
5
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Set;
9
10 import org.eclipse.core.runtime.Assert;
11 import org.eclipse.jface.util.IPropertyChangeListener;
12 import org.eclipse.jface.util.PropertyChangeEvent;
13 import org.eclipse.jface.viewers.ISelectionChangedListener;
14 import org.eclipse.jface.viewers.ISelectionProvider;
15 import org.eclipse.jface.viewers.IStructuredSelection;
16 import org.eclipse.jface.viewers.SelectionChangedEvent;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.SelectionEvent;
20 import org.eclipse.swt.events.SelectionListener;
21 import org.eclipse.swt.graphics.Color;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Display;
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
35 /**
36 * <p>Abstract AbstractFormSection class.</p>
37 *
38 * @author n.hoffmann
39 * @created Feb 22, 2010
40 * @version 1.0
41 * @param <T>
42 */
43 public abstract class AbstractFormSection<ENTITY> extends Section implements ISelectionChangedListener, IEntityElement<ENTITY>, IConversationEnabled{
44
45 private ISelectionProvider selectionProvider;
46
47 private ENTITY entity;
48
49 private Set<ICdmFormElement> elements = new HashSet<ICdmFormElement>();
50
51 protected CdmFormFactory formFactory;
52
53 private List<IPropertyChangeListener> propertyChangeListeners;
54
55 private ICdmFormElement parentElement;
56
57 private ConversationHolder conversation;
58
59 /**
60 * <p>Constructor for AbstractFormSection.</p>
61 *
62 * @param conversation TODO
63 * @param style a int.
64 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
65 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
66 * @param <ENTITY> a ENTITY object.
67 */
68 protected AbstractFormSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, int style) {
69 super(parentElement.getLayoutComposite(), style);
70
71 this.parentElement = parentElement;
72
73 this.formFactory = formFactory;
74
75 this.conversation = conversation;
76
77 this.setLayoutData(CdmFormFactory.FILL());
78
79 Composite client = formFactory.createComposite(this, SWT.WRAP);
80 client.setBackgroundMode(SWT.INHERIT_DEFAULT);
81
82 TableWrapLayout layout = CdmFormFactory.LAYOUT();
83 layout.bottomMargin = 10;
84 layout.rightMargin = 5;
85
86 client.setLayout(layout);
87
88 this.setClient(client);
89 }
90
91 /**
92 * <p>Constructor for AbstractFormSection.</p>
93 *
94 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
95 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
96 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
97 * @param selectionProvider a {@link org.eclipse.jface.viewers.ISelectionProvider} object.
98 * @param style a int.
99 */
100 protected AbstractFormSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, ISelectionProvider selectionProvider, int style){
101 this(formFactory, conversation, parentElement, style);
102 this.selectionProvider = selectionProvider;
103 }
104
105 /**
106 * <p>Getter for the field <code>propertyChangeListeners</code>.</p>
107 *
108 * @return a {@link java.util.Set} object.
109 */
110 public List<IPropertyChangeListener> getPropertyChangeListeners() {
111 return propertyChangeListeners;
112 }
113
114 /** {@inheritDoc} */
115 public void setPropertyChangeListeners(
116 List<IPropertyChangeListener> propertyChangeListeners) {
117 this.propertyChangeListeners = propertyChangeListeners;
118 }
119
120 /**
121 * <p>Setter for the field <code>entity</code>.</p>
122 *
123 * @param entity a ENTITY object.
124 */
125 public void setEntity(ENTITY entity){
126 this.entity = entity;
127 }
128
129 /*
130 * (non-Javadoc)
131 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
132 */
133 /**
134 * <p>Getter for the field <code>entity</code>.</p>
135 *
136 * @return a ENTITY object.
137 */
138 public ENTITY getEntity() {
139 return entity;
140 }
141
142 /**
143 * <p>getToggle</p>
144 *
145 * @return a {@link org.eclipse.ui.forms.widgets.ToggleHyperlink} object.
146 */
147 public ToggleHyperlink getToggle(){
148 return this.toggle;
149 }
150
151 /**
152 * <p>getSection</p>
153 *
154 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.AbstractFormSection} object.
155 */
156 public AbstractFormSection<ENTITY> getSection(){
157 return this;
158 }
159
160 /* (non-Javadoc)
161 * @see eu.etaxonomy.taxeditor.forms.IPropertyChangeEmitter#firePropertyChangeEvent()
162 */
163 /** {@inheritDoc} */
164 public void firePropertyChangeEvent(CdmPropertyChangeEvent event) {
165 Assert.isNotNull(propertyChangeListeners, "No property change listeners.");
166 for(Object listener : propertyChangeListeners){
167 ((IPropertyChangeListener) listener).propertyChange(event);
168 }
169 }
170
171 /* (non-Javadoc)
172 * @see org.eclipse.swt.widgets.Composite#setFocus()
173 */
174 /** {@inheritDoc} */
175 @Override
176 public boolean setFocus() {
177 return getClient().setFocus();
178 }
179
180 /* (non-Javadoc)
181 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
182 */
183 /** {@inheritDoc} */
184 public void propertyChange(PropertyChangeEvent event) {
185 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, event));
186 }
187
188 /* (non-Javadoc)
189 * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)
190 */
191 /** {@inheritDoc} */
192 @Override
193 public void setBackground(Color color) {
194 for(ICdmFormElement element : getElements()){
195 element.setBackground(color);
196 }
197 getLayoutComposite().setBackground(color);
198 super.setBackground(color);
199 }
200
201 /**
202 * <p>widgetSelected</p>
203 *
204 * @param e a {@link org.eclipse.swt.events.SelectionEvent} object.
205 */
206 public void widgetSelected(SelectionEvent e) {
207 Widget widget = e.widget;
208
209 if(widget instanceof Control){
210 Control control = (Control) widget;
211 if(checkControlAncestryForWidget(control)){
212 if(getEntity() != null){
213 IStructuredSelection selection = new StructuredSelection(getEntity());
214 if(selectionProvider != null){
215 selectionProvider.setSelection(selection);
216 }
217 }
218 }
219 }
220 }
221
222 private boolean checkControlAncestryForWidget(Control control){
223 if(control.equals(this)){
224 return true;
225 }else{
226 Control parent = control.getParent();
227 if(parent == null){
228 return false;
229 }else{
230 return checkControlAncestryForWidget(parent);
231 }
232 }
233 }
234
235 /** {@inheritDoc} */
236 public void setSelected(boolean selected) {
237 if(selected){
238 setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));
239 }else{
240 setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
241 }
242 }
243
244
245 /** {@inheritDoc} */
246 public void selectionChanged(SelectionChangedEvent event) {
247 if(event.getSelection() == CdmFormFactory.EMPTY_SELECTION){
248 return;
249 }
250
251 IStructuredSelection selection = (IStructuredSelection) event.getSelection();
252 setSelected(false);
253
254 Object selectedObject = selection.getFirstElement();
255
256 if(selectedObject != null && selectedObject.equals(getEntity())){
257 setSelected(true);
258 }
259 }
260
261 /**
262 * <p>addSelectionListener</p>
263 *
264 * @param listener a {@link org.eclipse.swt.events.SelectionListener} object.
265 */
266 public void addSelectionListener(SelectionListener listener) {
267 addListener(SWT.Selection, new TypedListener(listener));
268 }
269
270 /**
271 * <p>removeSelectionListener</p>
272 *
273 * @param listener a {@link org.eclipse.swt.events.SelectionListener} object.
274 */
275 public void removeSelectionListener(SelectionListener listener) {
276 removeListener(SWT.Selection, listener);
277 }
278
279 /** {@inheritDoc} */
280 public Color getColor(boolean selected) {
281 return selected ? SELECTED : NOT_SELECTED;
282 }
283
284 /** {@inheritDoc} */
285 public void addElement(ICdmFormElement element){
286 elements.add(element);
287 }
288
289 /**
290 * <p>removeElement</p>
291 *
292 * @param element a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
293 */
294 protected void removeElement(ICdmFormElement element){
295 elements.remove(element);
296 }
297
298 /**
299 * <p>removeElements</p>
300 */
301 public void removeElements() {
302 for(ICdmFormElement childElement : getElements()){
303 // recursion
304 childElement.removeElements();
305
306 // unregister selection arbitrator
307 if(childElement instanceof ISelectableElement){
308 ISelectableElement selectableElement = (ISelectableElement) childElement;
309 if (selectableElement != null && selectableElement.getSelectionArbitrator() != null) {
310 formFactory.destroySelectionArbitrator(selectableElement.getSelectionArbitrator());
311 }
312 }
313
314 // unregister propertyChangeListener
315 formFactory.removePropertyChangeListener(childElement);
316
317 // dispose of the controls
318 for(Control control : childElement.getControls()){
319 // we added the layoutComposite of the parental element as the layout composite to this formElement
320 // but we do not want to destroy it.
321 if(control.equals(childElement.getLayoutComposite())){
322 continue;
323 }else{
324 control.dispose();
325 control = null;
326 }
327 }
328 }
329
330 elements.clear();
331 }
332
333 /**
334 * <p>Getter for the field <code>parentElement</code>.</p>
335 *
336 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
337 */
338 public ICdmFormElement getParentElement() {
339 return parentElement;
340 }
341
342 /**
343 * <p>Getter for the field <code>elements</code>.</p>
344 *
345 * @return a {@link java.util.Set} object.
346 */
347 public Set<ICdmFormElement> getElements() {
348 return elements;
349 }
350
351 /**
352 * <p>getControls</p>
353 *
354 * @return a {@link java.util.Set} object.
355 */
356 public Set<Control> getControls() {
357 Set<Control> controls = new HashSet<Control>();
358
359 for (Control control : getChildren()){
360 controls.add(control);
361 }
362
363 return controls;
364 }
365
366 /** {@inheritDoc} */
367 @Override
368 public void dispose() {
369 removeElements();
370 super.dispose();
371 }
372
373 /**
374 * <p>getLayoutComposite</p>
375 *
376 * @return a {@link org.eclipse.swt.widgets.Composite} object.
377 */
378 public Composite getLayoutComposite() {
379 return (Composite) getClient();
380 }
381
382 /** {@inheritDoc} */
383 public boolean containsFormElement(ICdmFormElement formElement){
384 if(formElement == this){
385 return true;
386 }else{
387 for(ICdmFormElement element : getElements()){
388 boolean contains = element.containsFormElement(formElement);
389 if(contains == true){
390 return true;
391 }
392 }
393 return false;
394 }
395 }
396
397
398 /**
399 * <p>Getter for the field <code>formFactory</code>.</p>
400 *
401 * @return a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
402 */
403 public CdmFormFactory getFormFactory() {
404 return formFactory;
405 }
406
407 /*
408 * (non-Javadoc)
409 * @see eu.etaxonomy.taxeditor.forms.ICdmFormElement#refresh()
410 */
411 /**
412 * <p>refresh</p>
413 */
414 public void refresh() {
415 // empty default implementation
416
417 }
418
419 /**
420 * <p>getConversationHolder</p>
421 *
422 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
423 */
424 public ConversationHolder getConversationHolder() {
425 return conversation;
426 }
427
428 /** {@inheritDoc} */
429 public void update(CdmDataChangeMap changeEvents) {}
430 }