Merge branch 'develop' into LibrAlign
[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.api.service.IService;
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 * @author n.hoffmann
56 * @created Nov 17, 2009
57 * @version 1.0
58 * @param <T>
59 */
60 public class EntitySelectionElement<T extends CdmBase> extends
61 AbstractCdmFormElement implements SelectionListener, IEnableableFormElement, ISelectableElement, IEntityElement<T>, ILabeledElement, IConversationEnabled, Observer {
62
63 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
64 private static final EnumSet<CRUD> DELETE = EnumSet.of(CRUD.DELETE);
65 private static final EnumSet<CRUD> CREATE = EnumSet.of(CRUD.CREATE);
66
67 /**
68 * Bitmask for configuring functionality of selection element
69 */
70 public static final int NOTHING = 0; // 000
71 public static final int EDITABLE = 1 << 0; // 001
72 public static final int DELETABLE = 1 << 1; // 010
73 public static final int SELECTABLE = 1 << 2; // 100
74 public static final int ALL = EDITABLE | DELETABLE | SELECTABLE; // 111
75
76 protected T entity;
77 protected T filteredEntity;
78
79 protected Label label;
80 protected Text text;
81 protected Button button_selection;
82
83 private SelectionArbitrator selectionArbitrator;
84
85 protected Button button_edit;
86
87 private final String labelString;
88
89 private Composite selectableComposite;
90
91 private Button button_remove;
92
93 private final boolean isEditable;
94
95 private final boolean isDeletable;
96
97 private final ConversationHolder conversation;
98 private Class<T> clazz;
99
100 public EntitySelectionElement(CdmFormFactory formFactory,
101 ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz,
102 String labelString, T entity, int mode, int style, boolean filterElement) {
103 super(formFactory, parentElement);
104
105 this.clazz = clazz;
106 this.isEditable = (mode & EDITABLE) == EDITABLE;
107 this.isDeletable = (mode & DELETABLE) == DELETABLE;
108 boolean isSelectable = (mode & SELECTABLE) == SELECTABLE;
109
110 this.labelString = (labelString == null || labelString.equals("")) ? "" : labelString;
111
112 this.conversation = conversation;
113
114 if (isSelectable && formFactory.getSelectionProvider() != null) {
115 selectionArbitrator = formFactory.createSelectionArbitrator(this);
116 }
117
118 createControls(getLayoutComposite(), SWT.NULL);
119 if (filterElement){
120 setFilteredEntity(entity);
121 }else{
122 setEntity(entity);
123 }
124 }
125
126 private void setFilteredEntity(T filterEntity) {
127 this.filteredEntity =filterEntity;
128
129 }
130
131 public EntitySelectionElement(CdmFormFactory formFactory,
132 ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz,
133 String labelString, T entity, int mode, int style){
134 this(formFactory, conversation, parentElement, clazz, labelString, entity, mode, style, false);
135 }
136
137 private void createControls(Composite parent, int style) {
138
139 label = formFactory.createLabel(getLayoutComposite(), labelString,
140 SWT.NULL);
141
142 addControl(label);
143
144 selectableComposite = formFactory.createComposite(getLayoutComposite());
145
146 int columns = 2;
147 if (isEditable) {
148 columns += 1;
149 }
150 if (isDeletable) {
151 columns += 1;
152 }
153
154 selectableComposite.setLayout(LayoutConstants.LAYOUT(columns, false));
155 selectableComposite.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
156
157 addControl(selectableComposite);
158
159 text = formFactory.createText(selectableComposite, null, SWT.WRAP);
160 text.setEditable(false);
161 addControl(text);
162
163 text.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
164 text.setBackground(StoreUtil
165 .getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND));
166
167 button_selection = formFactory.createButton(selectableComposite, null,
168 SWT.PUSH);
169 button_selection.setImage(ImageResources
170 .getImage(ImageResources.BROWSE_ICON));
171 button_selection.setToolTipText("Browse existing");
172
173 addControl(button_selection);
174 button_selection.addSelectionListener(this);
175
176 if (isEditable) {
177 button_edit = formFactory.createButton(selectableComposite, null,
178 SWT.PUSH);
179 button_edit.setImage(ImageResources
180 .getImage(ImageResources.EDIT_ICON));
181 button_edit.setToolTipText("Edit");
182 addControl(button_edit);
183 button_edit.addSelectionListener(new EditListener(this));
184 }
185
186 if (isDeletable) {
187 button_remove = formFactory.createButton(selectableComposite, null,
188 SWT.PUSH);
189 button_remove.setImage(ImageResources
190 .getImage(ImageResources.TRASH_ICON));
191 button_remove.setToolTipText("Remove");
192 addControl(button_remove);
193 button_remove.addSelectionListener(new DeleteListener(this));
194 }
195 }
196
197 @Override
198 public void widgetSelected(SelectionEvent e) {
199 T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getFilteredEntity(), getParentElement());
200 setSelectionInternal(selection);
201 }
202
203 /**
204 * @return
205 */
206 public T getFilteredEntity() {
207
208 return this.filteredEntity;
209 }
210
211 /**
212 * Return the selected object
213 *
214 * @return a T object.
215 */
216 public T getSelection() {
217 return entity;
218 }
219
220 /*
221 * (non-Javadoc)
222 *
223 * @see
224 * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
225 */
226 /** {@inheritDoc} */
227 @Override
228 public void setEnabled(boolean enabled) {
229
230 button_selection.setEnabled(enabled);
231 if (isDeletable){
232 button_remove.setEnabled(enabled);
233 }
234 if (isEditable) {
235 updateButtonStates();
236 }
237
238 }
239
240 /* (non-Javadoc)
241 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
242 */
243 @Override
244 public boolean isEnabled() {
245 return button_selection.isEnabled();
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 text.setText(title); // title can be null
282 if (isEditable) {
283 updateButtonStates();
284 }
285 }
286
287 public void updateFromWizard() {
288 updateElement();
289 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
290 }
291
292 /**
293 * <p>
294 * getTitle
295 * </p>
296 *
297 * @return a {@link java.lang.String} object.
298 */
299 protected String getTitle() {
300 if (entity != null){
301 if(entity instanceof Group){
302 return ((Group) entity).getName();
303 } else if(entity instanceof GrantedAuthority){
304 return GrantedAuthorityLabelTextProvider.getText(((GrantedAuthority) entity));
305 } else if(entity instanceof User){
306 return ((User) entity).getUsername();
307 } else if (entity instanceof Primer){
308 return ((Primer) entity).getLabel();
309 } else if (entity instanceof Amplification){
310 return ((Amplification) entity).getLabelCache();
311 }
312 else if(entity instanceof IIdentifiableEntity) {
313 return ((IIdentifiableEntity) entity).getTitleCache();
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 //if the edited entity has already been persisted
413 //but the transient entity is still set in this
414 //EntitySelectionElement, re-load it and set it
415 IService<T> service = CdmStore.getService(entity);
416 if(entity.getId()==0){
417 T loadedEntity = service.load(entity.getUuid());
418 if(loadedEntity!=null){
419 setEntity(loadedEntity);
420 }
421 }
422 }
423 }
424 }
425
426 // not used
427 /** {@inheritDoc} */
428 @Override
429 public void widgetDefaultSelected(SelectionEvent e) {
430 }
431
432 /**
433 * <p>
434 * getConversationHolder
435 * </p>
436 *
437 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
438 * object.
439 */
440 @Override
441 public ConversationHolder getConversationHolder() {
442 return conversation;
443 }
444
445 /** {@inheritDoc} */
446 @Override
447 public void setBackground(Color color) {
448 if(!label.isDisposed()){
449 label.setBackground(color);
450 }
451 }
452
453 /** {@inheritDoc} */
454 @Override
455 public void setLabel(String labelString) {
456 if (label != null) {
457 label.setText(labelString);
458 }
459 }
460
461 /**
462 * <p>
463 * Getter for the field <code>label</code>.
464 * </p>
465 *
466 * @return a {@link java.lang.String} object.
467 */
468 @Override
469 public String getLabel() {
470 if (label != null) {
471 return label.getText() + " : ";
472 }
473 return null;
474 }
475
476 /** {@inheritDoc} */
477 @Override
478 public void update(CdmDataChangeMap changeEvents) {
479 }
480
481 /* (non-Javadoc)
482 * @see eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement#removeElements()
483 */
484 @Override
485 public void removeElements(){
486 super.removeElements();
487 LoginManager loginManager = CdmStore.getLoginManager();
488 loginManager.addObserver(this);
489 }
490
491 @Override
492 public void update(Observable o, Object arg) {
493 if(o instanceof LoginManager){
494 updateButtonStates();
495 }
496 }
497
498 private void updateButtonStates() {
499 if(button_edit != null && !button_selection.isDisposed()){
500 button_edit.setEnabled(isEditable && button_selection.isEnabled() && getEntity() != null && CdmStore.currentAuthentiationHasPermission(getEntity(), UPDATE));
501 }
502 }
503 }