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