]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui/src/org/argeo/cms/forms/EditableMultiStringProperty.java
Better distinguish when admin login failed because there was no such JCR
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / forms / EditableMultiStringProperty.java
1 package org.argeo.cms.forms;
2
3 import java.util.List;
4
5 import javax.jcr.Node;
6 import javax.jcr.RepositoryException;
7
8 import org.argeo.cms.util.CmsUtils;
9 import org.argeo.cms.viewers.EditablePart;
10 import org.argeo.cms.widgets.StyledControl;
11 import org.argeo.eclipse.ui.EclipseUiUtils;
12 import org.eclipse.jface.dialogs.MessageDialog;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.events.SelectionListener;
15 import org.eclipse.swt.events.TraverseEvent;
16 import org.eclipse.swt.events.TraverseListener;
17 import org.eclipse.swt.layout.GridData;
18 import org.eclipse.swt.layout.GridLayout;
19 import org.eclipse.swt.layout.RowLayout;
20 import org.eclipse.swt.widgets.Button;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Control;
23 import org.eclipse.swt.widgets.Label;
24 import org.eclipse.swt.widgets.Text;
25
26 /** Display, add or remove values from a list in a CMS context */
27 public class EditableMultiStringProperty extends StyledControl implements EditablePart {
28 private static final long serialVersionUID = -7044614381252178595L;
29
30 private String propertyName;
31 private String message;
32 // TODO implement the ability to provide a list of possible values
33 private String[] possibleValues;
34 private boolean canEdit;
35 private SelectionListener removeValueSL;
36 private List<String> values;
37
38 // TODO manage within the CSS
39 private int rowSpacing = 5;
40 private int rowMarging = 0;
41 private int oneValueMargingRight = 5;
42 private int btnWidth = 16;
43 private int btnHeight = 16;
44 private int btnHorizontalIndent = 3;
45
46 public EditableMultiStringProperty(Composite parent, int style, Node node, String propertyName, List<String> values,
47 String[] possibleValues, String addValueMsg, SelectionListener removeValueSelectionListener)
48 throws RepositoryException {
49 super(parent, style, node, true);
50
51 this.propertyName = propertyName;
52 this.values = values;
53 this.possibleValues = new String[]{"Un", "Deux", "Trois"};
54 this.message = addValueMsg;
55 this.canEdit = removeValueSelectionListener != null;
56 this.removeValueSL = removeValueSelectionListener;
57 }
58
59 public List<String> getValues() {
60 return values;
61 }
62
63 public void setValues(List<String> values) {
64 this.values = values;
65 }
66
67 // Row layout items do not need explicit layout data
68 protected void setControlLayoutData(Control control) {
69 }
70
71 /** To be overridden */
72 protected void setContainerLayoutData(Composite composite) {
73 composite.setLayoutData(CmsUtils.fillWidth());
74 }
75
76 @Override
77 public Control getControl() {
78 return super.getControl();
79 }
80
81 @Override
82 protected Control createControl(Composite box, String style) {
83 Composite row = new Composite(box, SWT.NO_FOCUS);
84 row.setLayoutData(EclipseUiUtils.fillAll());
85
86 RowLayout rl = new RowLayout(SWT.HORIZONTAL);
87 rl.wrap = true;
88 rl.spacing = rowSpacing;
89 rl.marginRight = rl.marginLeft = rl.marginBottom = rl.marginTop = rowMarging;
90 row.setLayout(rl);
91
92 if (values != null) {
93 for (final String value : values) {
94 if (canEdit)
95 createRemovableValue(row, SWT.SINGLE, value);
96 else
97 createValueLabel(row, SWT.SINGLE, value);
98 }
99 }
100
101 if (!canEdit)
102 return row;
103 else if (isEditing())
104 return createText(row, style);
105 else
106 return createLabel(row, style);
107 }
108
109 /**
110 * Override to provide specific layout for the existing values, typically
111 * adding a pound (#) char for tags or anchor info for browsable links. We
112 * assume the parent composite already has a layout and it is the caller
113 * responsibility to apply corresponding layout data
114 */
115 protected Label createValueLabel(Composite parent, int style, String value) {
116 Label label = new Label(parent, style);
117 label.setText("#" + value);
118 CmsUtils.markup(label);
119 CmsUtils.style(label, FormStyle.propertyText.style());
120 return label;
121 }
122
123 private Composite createRemovableValue(Composite parent, int style, String value) {
124 Composite valCmp = new Composite(parent, SWT.NO_FOCUS);
125 GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
126 gl.marginRight = oneValueMargingRight;
127 valCmp.setLayout(gl);
128
129 createValueLabel(valCmp, SWT.WRAP, value);
130
131 Button deleteBtn = new Button(valCmp, SWT.FLAT);
132 deleteBtn.setData(FormConstants.LINKED_VALUE, value);
133 deleteBtn.addSelectionListener(removeValueSL);
134 CmsUtils.style(deleteBtn, FormStyle.delete.style() + FormStyle.BUTTON_SUFFIX);
135 GridData gd = new GridData();
136 gd.heightHint = btnHeight;
137 gd.widthHint = btnWidth;
138 gd.horizontalIndent = btnHorizontalIndent;
139 deleteBtn.setLayoutData(gd);
140
141 return valCmp;
142 }
143
144 protected Text createText(Composite box, String style) {
145 final Text text = new Text(box, getStyle());
146 // The "add new value" text is not meant to change, so we can set it on
147 // creation
148 text.setMessage(message);
149 CmsUtils.style(text, style);
150 text.setFocus();
151
152 text.addTraverseListener(new TraverseListener() {
153 private static final long serialVersionUID = 1L;
154
155 public void keyTraversed(TraverseEvent e) {
156 if (e.keyCode == SWT.CR) {
157 addValue(text);
158 e.doit = false;
159 }
160 }
161 });
162
163 // The OK button does not work with the focusOut listener
164 // because focus out is called before the OK button is pressed
165
166 // // we must call layout() now so that the row data can compute the
167 // height
168 // // of the other controls.
169 // text.getParent().layout();
170 // int height = text.getSize().y;
171 //
172 // Button okBtn = new Button(box, SWT.BORDER | SWT.PUSH | SWT.BOTTOM);
173 // okBtn.setText("OK");
174 // RowData rd = new RowData(SWT.DEFAULT, height - 2);
175 // okBtn.setLayoutData(rd);
176 //
177 // okBtn.addSelectionListener(new SelectionAdapter() {
178 // private static final long serialVersionUID = 2780819012423622369L;
179 //
180 // @Override
181 // public void widgetSelected(SelectionEvent e) {
182 // addValue(text);
183 // }
184 // });
185
186 return text;
187 }
188
189 /** Performs the real addition, overwrite to make further sanity checks */
190 protected void addValue(Text text) {
191 String value = text.getText();
192 String errMsg = null;
193
194 if (EclipseUiUtils.isEmpty(value))
195 return;
196
197 if (values.contains(value))
198 errMsg = "Dupplicated value: " + value + ", please correct and try again";
199 if (errMsg != null)
200 MessageDialog.openError(this.getShell(), "Addition not allowed", errMsg);
201 else {
202 values.add(value);
203 Composite newCmp = createRemovableValue(text.getParent(), SWT.SINGLE, value);
204 newCmp.moveAbove(text);
205 text.setText("");
206 newCmp.getParent().layout();
207 }
208 }
209
210 protected Label createLabel(Composite box, String style) {
211 if (canEdit) {
212 Label lbl = new Label(box, getStyle());
213 lbl.setText(message);
214 CmsUtils.style(lbl, style);
215 CmsUtils.markup(lbl);
216 if (mouseListener != null)
217 lbl.addMouseListener(mouseListener);
218 return lbl;
219 }
220 return null;
221 }
222
223 protected void clear(boolean deep) {
224 Control child = getControl();
225 if (deep)
226 super.clear(deep);
227 else {
228 child.getParent().dispose();
229 }
230 }
231
232 public void setText(String text) {
233 Control child = getControl();
234 if (child instanceof Label) {
235 Label lbl = (Label) child;
236 if (canEdit)
237 lbl.setText(text);
238 else
239 lbl.setText("");
240 } else if (child instanceof Text) {
241 Text txt = (Text) child;
242 txt.setText(text);
243 }
244 }
245
246 public synchronized void startEditing() {
247 getControl().setData(STYLE, FormStyle.propertyText.style());
248 super.startEditing();
249 }
250
251 public synchronized void stopEditing() {
252 getControl().setData(STYLE, FormStyle.propertyMessage.style());
253 super.stopEditing();
254 }
255
256 public String getPropertyName() {
257 return propertyName;
258 }
259 }