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