Refactoring of selection elements. Additional minor refactoring. Fixed a bug with...
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / selection / EntitySelectionElement.java
1 /**
2 *
3 */
4 package eu.etaxonomy.taxeditor.ui.selection;
5
6 import org.eclipse.core.runtime.IStatus;
7 import org.eclipse.jface.wizard.WizardDialog;
8 import org.eclipse.swt.SWT;
9 import org.eclipse.swt.events.SelectionAdapter;
10 import org.eclipse.swt.events.SelectionEvent;
11 import org.eclipse.swt.events.SelectionListener;
12 import org.eclipse.swt.graphics.Color;
13 import org.eclipse.swt.widgets.Button;
14 import org.eclipse.swt.widgets.Composite;
15 import org.eclipse.swt.widgets.Label;
16 import org.eclipse.swt.widgets.Shell;
17
18 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
19 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
20 import eu.etaxonomy.cdm.common.CdmUtils;
21 import eu.etaxonomy.cdm.model.common.ICdmBase;
22 import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
23 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
24 import eu.etaxonomy.taxeditor.model.ImageResources;
25 import eu.etaxonomy.taxeditor.preference.Resources;
26 import eu.etaxonomy.taxeditor.store.StoreUtil;
27 import eu.etaxonomy.taxeditor.ui.dialog.selection.SelectionDialogFactory;
28 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
29 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
30 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
31 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
32 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
33 import eu.etaxonomy.taxeditor.ui.element.IEntityElement;
34 import eu.etaxonomy.taxeditor.ui.element.ILabeledElement;
35 import eu.etaxonomy.taxeditor.ui.element.ISelectable;
36 import eu.etaxonomy.taxeditor.ui.element.ISelectableElement;
37 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
38 import eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator;
39
40 /**
41 * <p>
42 * Abstract AbstractSelectionElement class.
43 * </p>
44 *
45 * @author n.hoffmann
46 * @created Nov 17, 2009
47 * @version 1.0
48 * @param <T>
49 */
50 public class EntitySelectionElement<T extends ICdmBase> extends
51 AbstractCdmFormElement implements SelectionListener,
52 IEnableableFormElement, ISelectableElement, IEntityElement<T>,
53 ILabeledElement, IConversationEnabled, ISelectable {
54
55 /**
56 * Bitmask for configuring functionality of selection element
57 */
58 public static final int NOTHING = 0; // 000
59 public static final int EDITABLE = 1 << 0; // 001
60 public static final int DELETABLE = 1 << 1; // 010
61 public static final int SELECTABLE = 1 << 2; // 100
62 public static final int ALL = EDITABLE | DELETABLE | SELECTABLE; // 111
63
64 protected T entity;
65
66 protected Label label;
67 protected Label text;
68 protected Button button_selection;
69
70 private SelectionArbitrator selectionArbitrator;
71
72 protected Button button_edit;
73
74 private final String labelString;
75
76 private Composite selectableComposite;
77
78 private Button button_remove;
79
80 private final boolean isEditable;
81
82 private final boolean isDeletable;
83
84 private final ConversationHolder conversation;
85 private Class<T> clazz;
86
87 /**
88 * <p>
89 * Constructor for AbstractSelectionElement.
90 * </p>
91 *
92 * @param formFactory
93 * a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
94 * object.
95 * @param conversation
96 * TODO
97 * @param parentElement
98 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
99 * object.
100 * @param labelString
101 * a {@link java.lang.String} object.
102 * @param entity
103 * a T object.
104 * @param isEditable
105 * a boolean.
106 * @param isSelectable
107 * a boolean.
108 * @param isDeletable
109 * a boolean.
110 * @param style
111 * a int.
112 * @param <T>
113 * a T object.
114 */
115 public EntitySelectionElement(CdmFormFactory formFactory,
116 ConversationHolder conversation, ICdmFormElement parentElement,
117 String labelString, T entity, int mode, int style) {
118 super(formFactory, parentElement);
119
120 this.isEditable = (mode & EDITABLE) == EDITABLE;
121 this.isDeletable = (mode & DELETABLE) == DELETABLE;
122 boolean isSelectable = (mode & SELECTABLE) == SELECTABLE;
123
124 this.labelString = labelString;
125
126 this.conversation = conversation;
127
128 if (isSelectable && formFactory.getSelectionProvider() != null) {
129 selectionArbitrator = formFactory.createSelectionArbitrator(this);
130 }
131
132 createControls(getLayoutComposite(), SWT.NULL);
133
134 setEntity(entity);
135 }
136
137 public EntitySelectionElement(CdmFormFactory formFactory,
138 ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz,
139 String labelString, T entity, int mode, int style) {
140 this(formFactory, conversation, parentElement, labelString, entity, mode, style);
141 this.clazz = clazz;
142 }
143
144 private void createControls(Composite parent, int style) {
145
146 label = formFactory.createLabel(getLayoutComposite(), labelString,
147 SWT.NULL);
148
149 addControl(label);
150
151 selectableComposite = formFactory.createComposite(getLayoutComposite());
152
153 int columns = 2;
154 if (isEditable) {
155 columns += 1;
156 }
157 if (isDeletable) {
158 columns += 1;
159 }
160
161 selectableComposite.setLayout(LayoutConstants.LAYOUT(columns, false));
162 selectableComposite.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
163
164 addControl(selectableComposite);
165
166 text = formFactory.createLabel(selectableComposite, null, SWT.WRAP);
167 addControl(text);
168
169 text.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
170 text.setBackground(StoreUtil
171 .getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND));
172
173 button_selection = formFactory.createButton(selectableComposite, null,
174 SWT.PUSH);
175 button_selection.setImage(ImageResources
176 .getImage(ImageResources.BROWSE_ICON));
177 button_selection.setToolTipText("Browse existing");
178
179 addControl(button_selection);
180 button_selection.addSelectionListener(this);
181
182 if (isEditable) {
183 button_edit = formFactory.createButton(selectableComposite, null,
184 SWT.PUSH);
185 button_edit.setImage(ImageResources
186 .getImage(ImageResources.EDIT_ICON));
187 button_edit.setToolTipText("Edit");
188 addControl(button_edit);
189 button_edit.addSelectionListener(new EditListener(this));
190 }
191
192 if (isDeletable) {
193 button_remove = formFactory.createButton(selectableComposite, null,
194 SWT.PUSH);
195 button_remove.setImage(ImageResources
196 .getImage(ImageResources.TRASH_ICON));
197 button_remove.setToolTipText("Remove");
198 addControl(button_remove);
199 button_remove.addSelectionListener(new DeleteListener(this));
200 }
201 }
202
203 public void widgetSelected(SelectionEvent e) {
204 T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getEntity());
205 setSelectionInternal(selection);
206 }
207
208 /**
209 * Return the selected object
210 *
211 * @return a T object.
212 */
213 public T getSelection() {
214 return entity;
215 }
216
217 /*
218 * (non-Javadoc)
219 *
220 * @see
221 * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
222 */
223 /** {@inheritDoc} */
224 @Override
225 public void setEnabled(boolean enabled) {
226 button_selection.setEnabled(enabled);
227 if (isEditable) {
228 button_edit.setEnabled(enabled && entity != null);
229 }
230 }
231
232 /**
233 * <p>
234 * setSelectionInternal
235 * </p>
236 *
237 * @param selection
238 * a T object.
239 */
240 protected void setSelectionInternal(T selection) {
241 if (selection != null && !selection.equals(this.entity)) {
242 setEntity(selection);
243 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
244 }
245 }
246
247 /**
248 * <p>
249 * Setter for the field <code>entity</code>.
250 * </p>
251 *
252 * @param selection
253 * a T object.
254 */
255 public void setEntity(T selection) {
256 this.entity = selection;
257 updateElement();
258 }
259
260 /**
261 * Updates this elements view
262 */
263 protected void updateElement() {
264 String title = CdmUtils.Nz(getTitle());
265 // we have to duplicate ampersands otherwise they are treated as
266 // mnenomic (see Label.setText() documentation)
267 title = title.replace("&", "&&");
268 text.setText(title); // title can be null
269 if (isEditable) {
270 button_edit.setEnabled(entity != null);
271 }
272 }
273
274 /**
275 * <p>
276 * updateFromWizard
277 * </p>
278 */
279 protected void updateFromWizard() {
280 updateElement();
281 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
282 }
283
284 /**
285 * <p>
286 * getTitle
287 * </p>
288 *
289 * @return a {@link java.lang.String} object.
290 */
291 protected String getTitle() {
292 if (entity != null && entity instanceof IIdentifiableEntity) {
293 return ((IIdentifiableEntity) entity).getTitleCache();
294 }
295 return "";
296 }
297
298 /** {@inheritDoc} */
299 @Override
300 public void setSelected(boolean selected) {
301 setBackground(selected ? SELECTED : getPersistentBackground());
302 }
303
304 /*
305 * (non-Javadoc)
306 *
307 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
308 */
309 /**
310 * <p>
311 * Getter for the field <code>entity</code>.
312 * </p>
313 *
314 * @return a T object.
315 */
316 @Override
317 public T getEntity() {
318 return entity;
319 }
320
321 /*
322 * (non-Javadoc)
323 *
324 * @see eu.etaxonomy.taxeditor.forms.section.cdmdetail.ISelectableElement#
325 * getSelectionArbitrator()
326 */
327 /**
328 * <p>
329 * Getter for the field <code>selectionArbitrator</code>.
330 * </p>
331 *
332 * @return a {@link eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator}
333 * object.
334 */
335 @Override
336 public SelectionArbitrator getSelectionArbitrator() {
337 return selectionArbitrator;
338 }
339
340 /**
341 * Convenient access to current shell
342 *
343 * @return a {@link org.eclipse.swt.widgets.Shell} object.
344 */
345 protected Shell getShell() {
346 return getLayoutComposite().getShell();
347 }
348
349 /** {@inheritDoc} */
350 @Override
351 public void setIrrelevant(boolean irrelevant) {
352 String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
353 : Resources.COLOR_TEXT_DISABLED_BACKGROUND;
354
355 Color color = StoreUtil.getColor(colorId);
356 text.setBackground(color);
357 }
358
359 private class DeleteListener extends SelectionAdapter {
360
361 private final EntitySelectionElement<T> selectionElement;
362
363 public DeleteListener(EntitySelectionElement<T> selectionElement) {
364 this.selectionElement = selectionElement;
365 }
366
367 @Override
368 public void widgetSelected(SelectionEvent e) {
369 setEntity(null);
370 firePropertyChangeEvent(new CdmPropertyChangeEvent(
371 selectionElement, null));
372 }
373 }
374
375 private class EditListener extends SelectionAdapter {
376
377 private final EntitySelectionElement<T> selectionElement;
378
379 public EditListener(EntitySelectionElement<T> selectionElement) {
380 this.selectionElement = selectionElement;
381 }
382
383 /** {@inheritDoc} */
384 @Override
385 public void widgetSelected(SelectionEvent e) {
386 WizardDialog dialog = new WizardDialog(selectionElement.getShell(),
387 new EditFromSelectionWizard(selectionElement));
388 if (dialog.open() == IStatus.OK) {
389 selectionElement.updateFromWizard();
390 }
391 }
392 }
393
394 // not used
395 /** {@inheritDoc} */
396 @Override
397 public void widgetDefaultSelected(SelectionEvent e) {
398 }
399
400 /**
401 * <p>
402 * getConversationHolder
403 * </p>
404 *
405 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
406 * object.
407 */
408 @Override
409 public ConversationHolder getConversationHolder() {
410 return conversation;
411 }
412
413 /** {@inheritDoc} */
414 @Override
415 public void setBackground(Color color) {
416 label.setBackground(color);
417 }
418
419 /** {@inheritDoc} */
420 @Override
421 public void setLabel(String labelString) {
422 if (label != null) {
423 label.setText(labelString);
424 }
425 }
426
427 /**
428 * <p>
429 * Getter for the field <code>label</code>.
430 * </p>
431 *
432 * @return a {@link java.lang.String} object.
433 */
434 @Override
435 public String getLabel() {
436 if (label != null) {
437 return label.getText();
438 }
439 return null;
440 }
441
442 /** {@inheritDoc} */
443 @Override
444 public void update(CdmDataChangeMap changeEvents) {
445 }
446 }