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