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