Merge branch 'release/4.4.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / section / AbstractEntityCollectionElement.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.ui.section;
12
13 import org.eclipse.jface.util.PropertyChangeEvent;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.events.SelectionListener;
17 import org.eclipse.swt.graphics.Color;
18 import org.eclipse.swt.widgets.Button;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Event;
21 import org.eclipse.swt.widgets.Listener;
22 import org.eclipse.ui.forms.widgets.TableWrapLayout;
23
24 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
25 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
26 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
27 import eu.etaxonomy.taxeditor.model.ImageResources;
28 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
29 import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection;
30 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
31 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
32 import eu.etaxonomy.taxeditor.ui.element.IEntityElement;
33 import eu.etaxonomy.taxeditor.ui.element.ISelectable;
34 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
35
36 /**
37 * Visualizes an element of type ENTITY in an {@link AbstractEntityCollectionSection}
38 * and links listener functionalities to it.
39 *
40 * @param ENTITY the type of the element which is visualized by this class
41 *
42 * @author n.hoffmann
43 * @created Nov 16, 2009
44 */
45 public abstract class AbstractEntityCollectionElement<ENTITY> extends
46 AbstractCdmFormElement implements IEntityElement<ENTITY>,
47 SelectionListener, IConversationEnabled {
48
49 protected ENTITY entity;
50
51 private final Composite container;
52
53 /**
54 * Composite "around" the actual content. Is used for control action like e.g. remove button
55 */
56 private final Composite box;
57
58 private Button btnRemove;
59 protected Button btnChooseEntity;
60
61 private Color backgroundColor;
62
63 public AbstractEntityCollectionElement(CdmFormFactory formFactory,
64 AbstractFormSection section, ENTITY entity,
65 SelectionListener removeListener, Color backgroundColor, int style) {
66 this(formFactory, section, entity, removeListener, false, backgroundColor, style);
67 }
68 public AbstractEntityCollectionElement(CdmFormFactory formFactory,
69 AbstractFormSection section, ENTITY entity, SelectionListener removeListener,
70 boolean isChoosableEntity, Color backgroundColor, int style) {
71 super(formFactory, (ICdmFormElement) section);
72
73 init();
74
75 formFactory.addPropertyChangeListener(this);
76
77 box = formFactory.createComposite(section.getLayoutComposite());
78 box.setBackgroundMode(SWT.INHERIT_DEFAULT);
79 addControl(box);
80
81 TableWrapLayout boxLayout = LayoutConstants.LAYOUT(4, false);
82 boxLayout.topMargin = 4;
83 boxLayout.bottomMargin = 4;
84 box.setLayout(boxLayout);
85
86 box.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
87
88 container = formFactory.createComposite(box);
89 container.setBackgroundMode(SWT.INHERIT_DEFAULT);
90
91 setLayoutComposite(container);
92
93 addControl(container);
94 TableWrapLayout containerLayout = LayoutConstants.LAYOUT(2, false);
95 containerLayout.horizontalSpacing = 5;
96
97 container.setLayout(containerLayout);
98 container.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
99
100 if(isChoosableEntity){
101 btnChooseEntity = formFactory.createButton(box, null, SWT.PUSH);
102 addControl(btnChooseEntity);
103
104 btnChooseEntity.setLayoutData(LayoutConstants.RIGHT());
105 btnChooseEntity.setImage(ImageResources.getImage(ImageResources.BROWSE_ICON));
106 btnChooseEntity.setToolTipText("Browse");
107 btnChooseEntity.addListener(SWT.Selection, new Listener() {
108
109 @Override
110 public void handleEvent(Event event) {
111 ENTITY entity = selectFromDialog();
112 if(entity!=null){
113 if(getParentElement() instanceof AbstractEntityCollectionSection){
114 ((AbstractEntityCollectionSection)getParentElement()).removeElement(getEntity());
115 setEntity(entity);
116 ((AbstractEntityCollectionSection)getParentElement()).addElement(entity);
117 ((AbstractEntityCollectionSection)getParentElement()).firePropertyChangeEvent(getParentElement());
118 }
119
120 }
121 }
122 });
123 }
124
125 if (removeListener != null) {
126 btnRemove = formFactory.createButton(box, null, SWT.PUSH);
127 addControl(btnRemove);
128 btnRemove.setLayoutData(LayoutConstants.RIGHT());
129 btnRemove.setImage(ImageResources
130 .getImage(ImageResources.TRASH_ICON));
131 btnRemove.setToolTipText("Remove");
132
133 btnRemove.addSelectionListener(removeListener);
134 }
135
136 createControls(this, style);
137
138 setEntity(entity);
139 }
140
141 /**
142 * Init gets executed before any other setup of the section takes place
143 *
144 * Implement this if you want to configure the section
145 */
146 public void init() {
147 // default implementation is empty
148 }
149
150 public abstract void setEntity(ENTITY entity);
151
152 @Override
153 public ENTITY getEntity() {
154 return entity;
155 }
156
157 /**
158 * Sub classes should override to provide the functionality to choose the
159 * entity from existing ones from the data source.<br>
160 * <b>Note:</b> to enable this functionality sub classes have to set
161 * the corresponding flag in the super constructor
162 * @return an existing entity from the data source
163 */
164 protected ENTITY selectFromDialog(){
165 return null;
166 }
167
168 public abstract void createControls(ICdmFormElement element, int style);
169
170 /**
171 * Mark <code>this</code> element as selected.
172 */
173 @Override
174 public void setSelected(boolean selected) {
175
176 for (ICdmFormElement element : getElements()) {
177 if (element instanceof ISelectable) {
178 ((ISelectable) element).setSelected(selected);
179 }
180 }
181 setBackground(selected ? SELECTED : getPersistentBackground());
182 }
183
184 /** {@inheritDoc} */
185 @Override
186 public void propertyChange(PropertyChangeEvent event) {
187 if (event == null) {
188 return;
189 }
190 Object eventSource = event.getSource();
191 if (getElements().contains(eventSource) || getControls().contains(eventSource)) {
192 handleEvent(eventSource);
193 }
194 }
195
196 public abstract void handleEvent(Object eventSource);
197
198 /** {@inheritDoc} */
199 @Override
200 public void setBackground(Color color) {
201 if(box.isDisposed() || container.isDisposed()){
202 return;
203 }
204 backgroundColor = color;
205 super.setBackground(color);
206 box.setBackground(color);
207 container.setBackground(color);
208 }
209
210 /**
211 * {@inheritDoc}
212 *
213 * React when selection occurs
214 */
215 @Override
216 public void widgetSelected(SelectionEvent e) {
217
218 }
219
220 /** {@inheritDoc} */
221 @Override
222 public void widgetDefaultSelected(SelectionEvent e) {
223 }
224
225 /** {@inheritDoc} */
226 @Override
227 public Composite getLayoutComposite() {
228 return container;
229 }
230
231 public Color getBackgroundColor() {
232 return backgroundColor;
233 }
234
235 public Composite getBox() {
236 return box;
237 }
238
239 @Override
240 public ConversationHolder getConversationHolder() {
241 if (getParentElement() instanceof IConversationEnabled) {
242 return ((IConversationEnabled) getParentElement())
243 .getConversationHolder();
244 }
245 throw new IllegalArgumentException(
246 "Parent element should be IConversationEnabled");
247 }
248
249 /** {@inheritDoc} */
250 @Override
251 public void update(CdmDataChangeMap changeEvents) {
252 }
253 }