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