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