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