- increased version number
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / campanula / basicFields / EntitySelectionFieldController.java
1 // $Id$
2 /**
3 * Copyright (C) 2013 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.taxeditor.ui.campanula.basicFields;
11
12 import org.eclipse.core.runtime.IStatus;
13 import org.eclipse.jface.wizard.WizardDialog;
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.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.persistence.hibernate.CdmDataChangeMap;
31 import eu.etaxonomy.taxeditor.model.AbstractUtility;
32 import eu.etaxonomy.taxeditor.model.ImageResources;
33 import eu.etaxonomy.taxeditor.preference.Resources;
34 import eu.etaxonomy.taxeditor.ui.campanula.compatibility.ICdmFormElement;
35 import eu.etaxonomy.taxeditor.ui.dialog.selection.SelectionDialogFactory;
36 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
37 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
38 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
39 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
40 import eu.etaxonomy.taxeditor.ui.element.IEntityElement;
41 import eu.etaxonomy.taxeditor.ui.element.ILabeledElement;
42 import eu.etaxonomy.taxeditor.ui.element.ISelectableElement;
43 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
44 import eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator;
45 import eu.etaxonomy.taxeditor.ui.selection.EditFromSelectionWizard;
46 import eu.etaxonomy.taxeditor.ui.selection.EntitySelectionElement;
47
48 /**
49 * @author pplitzner
50 * @date 13.08.2013
51 *
52 */
53 public class EntitySelectionFieldController<T extends ICdmBase> extends AbstractCdmFormElement implements SelectionListener, IEnableableFormElement, ISelectableElement, IEntityElement<T>, ILabeledElement, IConversationEnabled {
54
55 /**
56 * Bitmask for configuring functionality of selection element
57 */
58 public static final int NOTHING = 0; // 000
59 public static final int EDITABLE = 1 << 0; // 001
60 public static final int DELETABLE = 1 << 1; // 010
61 public static final int SELECTABLE = 1 << 2; // 100
62 public static final int ALL = EDITABLE | DELETABLE | SELECTABLE; // 111
63
64 protected T entity;
65
66 //TODO also control "label" with this class?
67 // protected Label label;
68 protected Label text;
69 protected Button button_selection;
70
71 private SelectionArbitrator selectionArbitrator;
72
73 protected Button button_edit;
74
75 // private final String labelString;
76
77 private Composite selectableComposite;
78
79 private Button button_remove;
80
81 private final boolean isEditable;
82
83 private final boolean isDeletable;
84
85 private final ConversationHolder conversation;
86 private Class<T> clazz;
87
88 /**
89 * <p>
90 * Constructor for AbstractSelectionElement.
91 * </p>
92 *
93 * @param formFactory
94 * a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
95 * object.
96 * @param conversation
97 * TODO
98 * @param parentElement
99 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
100 * object.
101 * @param labelString
102 * a {@link java.lang.String} object.
103 * @param entity
104 * a T object.
105 * @param isEditable
106 * a boolean.
107 * @param isSelectable
108 * a boolean.
109 * @param isDeletable
110 * a boolean.
111 * @param style
112 * a int.
113 * @param <T>
114 * a T object.
115 */
116 public EntitySelectionFieldController(EntitySelectionField entitySelectionField, CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, T entity, int mode) {
117 super(formFactory, parentElement);
118
119 setPropertyChangeListeners(formFactory.getPropertyChangeListeners());
120 formFactory.addPropertyChangeListener(this);
121
122 this.isEditable = (mode & EDITABLE) == EDITABLE;
123 this.isDeletable = (mode & DELETABLE) == DELETABLE;
124 boolean isSelectable = (mode & SELECTABLE) == SELECTABLE;
125
126 // this.labelString = labelString;
127
128 this.conversation = conversation;
129
130 if (isSelectable && formFactory.getSelectionProvider() != null) {
131 selectionArbitrator = formFactory.createSelectionArbitrator(this);
132 }
133
134 createControls(entitySelectionField);
135
136 setEntity(entity);
137 }
138
139 public EntitySelectionFieldController(EntitySelectionField entitySelectionField, CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz, T entity, int mode) {
140 this(entitySelectionField, formFactory, conversation, parentElement, entity, mode);
141 this.clazz = clazz;
142 }
143
144 private void createControls(EntitySelectionField entitySelectionField) {
145
146 // label = formFactory.createLabel(getLayoutComposite(), labelString, SWT.NULL);
147 //
148 // addControl(label);
149
150 selectableComposite = entitySelectionField;
151
152 int columns = 2;
153 if (isEditable) {
154 columns += 1;
155 }
156 if (isDeletable) {
157 columns += 1;
158 }
159
160 selectableComposite.setLayout(LayoutConstants.LAYOUT(columns, false));
161 selectableComposite.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
162
163 addControl(selectableComposite);
164
165 text = entitySelectionField.getText();
166 addControl(text);
167
168 text.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
169 text.setBackground(AbstractUtility.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND));
170
171 button_selection = entitySelectionField.getButton_selection();
172 button_selection.setImage(ImageResources.getImage(ImageResources.BROWSE_ICON));
173 button_selection.setToolTipText("Browse existing");
174
175 addControl(button_selection);
176 button_selection.addSelectionListener(this);
177
178 button_edit = entitySelectionField.getButton_edit();
179 if (isEditable) {
180 addControl(button_edit);
181 //TODO: this worked with the extracted (but now reverted) interfaces done for campanula
182 // button_edit.addSelectionListener(new EditListener(this));
183 }
184 else{
185 button_edit.setVisible(false);
186 }
187
188 button_remove = entitySelectionField.getButton_remove();
189 if (isDeletable) {
190 addControl(button_remove);
191 button_remove.addSelectionListener(new DeleteListener(this));
192 }
193 else{
194 button_remove.setVisible(false);
195 }
196 }
197
198 @Override
199 public void widgetSelected(SelectionEvent e) {
200 T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getEntity());
201 setSelectionInternal(selection);
202 }
203
204 /**
205 * Return the selected object
206 *
207 * @return a T object.
208 */
209 public T getSelection() {
210 return entity;
211 }
212
213 /*
214 * (non-Javadoc)
215 *
216 * @see
217 * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
218 */
219 /** {@inheritDoc} */
220 @Override
221 public void setEnabled(boolean enabled) {
222 button_selection.setEnabled(enabled);
223 if (isEditable) {
224 button_edit.setEnabled(enabled && entity != null);
225 }
226 }
227
228 /**
229 * <p>
230 * setSelectionInternal
231 * </p>
232 *
233 * @param selection
234 * a T object.
235 */
236 protected void setSelectionInternal(T selection) {
237 if (selection != null && !selection.equals(this.entity)) {
238 setEntity(selection);
239 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
240 }
241 }
242
243 /**
244 * <p>
245 * Setter for the field <code>entity</code>.
246 * </p>
247 *
248 * @param selection
249 * a T object.
250 */
251 public void setEntity(T selection) {
252 this.entity = selection;
253 updateElement();
254 }
255
256 /**
257 * Updates this elements view
258 */
259 protected void updateElement() {
260 String title = CdmUtils.Nz(getTitle());
261 // we have to duplicate ampersands otherwise they are treated as
262 // mnenomic (see Label.setText() documentation)
263 title = title.replace("&", "&&");
264 text.setText(title); // title can be null
265 if (isEditable) {
266 button_edit.setEnabled(entity != null);
267 }
268 }
269
270 public void updateFromWizard() {
271 updateElement();
272 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
273 }
274
275 /**
276 * <p>
277 * getTitle
278 * </p>
279 *
280 * @return a {@link java.lang.String} object.
281 */
282 protected String getTitle() {
283 if (entity != null) {
284 if (entity instanceof IIdentifiableEntity) {
285 return ((IIdentifiableEntity) entity).getTitleCache();
286 } else if (entity instanceof Group) {
287 return ((Group) entity).getName();
288 } else if (entity instanceof GrantedAuthority) {
289 return ((GrantedAuthority) entity).getAuthority();
290 }
291 }
292 return "";
293 }
294
295 /** {@inheritDoc} */
296 @Override
297 public void setSelected(boolean selected) {
298 setBackground(selected ? SELECTED : getPersistentBackground());
299 }
300
301 /*
302 * (non-Javadoc)
303 *
304 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
305 */
306 /**
307 * <p>
308 * Getter for the field <code>entity</code>.
309 * </p>
310 *
311 * @return a T object.
312 */
313 @Override
314 public T getEntity() {
315 return entity;
316 }
317
318 /*
319 * (non-Javadoc)
320 *
321 * @see eu.etaxonomy.taxeditor.forms.section.cdmdetail.ISelectableElement#
322 * getSelectionArbitrator()
323 */
324 /**
325 * <p>
326 * Getter for the field <code>selectionArbitrator</code>.
327 * </p>
328 *
329 * @return a {@link eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator}
330 * object.
331 */
332 @Override
333 public SelectionArbitrator getSelectionArbitrator() {
334 return selectionArbitrator;
335 }
336
337 public Shell getShell() {
338 return getLayoutComposite().getShell();
339 }
340
341 /** {@inheritDoc} */
342 @Override
343 public void setIrrelevant(boolean irrelevant) {
344 String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT : Resources.COLOR_TEXT_DISABLED_BACKGROUND;
345
346 Color color = AbstractUtility.getColor(colorId);
347 text.setBackground(color);
348 }
349
350 private class DeleteListener extends SelectionAdapter {
351
352 private final EntitySelectionFieldController<T> selectionElement;
353
354 public DeleteListener(EntitySelectionFieldController<T> selectionElement) {
355 this.selectionElement = selectionElement;
356 }
357
358 @Override
359 public void widgetSelected(SelectionEvent e) {
360 setEntity(null);
361 firePropertyChangeEvent(new CdmPropertyChangeEvent(selectionElement, null));
362 }
363 }
364
365 private class EditListener extends SelectionAdapter {
366
367 private final EntitySelectionElement<T> selectionElement;
368
369 public EditListener(EntitySelectionElement<T> selectionElement) {
370 this.selectionElement = selectionElement;
371 }
372
373 /** {@inheritDoc} */
374 @Override
375 public void widgetSelected(SelectionEvent e) {
376 WizardDialog dialog = new WizardDialog(selectionElement.getShell(), new EditFromSelectionWizard(selectionElement));
377 if (dialog.open() == IStatus.OK) {
378 selectionElement.updateFromWizard();
379 }
380 }
381 }
382
383 // not used
384 /** {@inheritDoc} */
385 @Override
386 public void widgetDefaultSelected(SelectionEvent e) {
387 }
388
389 /**
390 * <p>
391 * getConversationHolder
392 * </p>
393 *
394 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
395 * object.
396 */
397 @Override
398 public ConversationHolder getConversationHolder() {
399 return conversation;
400 }
401
402 /** {@inheritDoc} */
403 @Override
404 public void setBackground(Color color) {
405 // label.setBackground(color);
406 }
407
408 /** {@inheritDoc} */
409 @Override
410 public void setLabel(String labelString) {
411 // if (label != null) {
412 // label.setText(labelString);
413 // }
414 }
415
416 /**
417 * <p>
418 * Getter for the field <code>label</code>.
419 * </p>
420 *
421 * @return a {@link java.lang.String} object.
422 */
423 @Override
424 public String getLabel() {
425 // if (label != null) {
426 // return label.getText();
427 // }
428 return null;
429 }
430
431 /** {@inheritDoc} */
432 @Override
433 public void update(CdmDataChangeMap changeEvents) {
434 }
435 }