1 package org
.argeo
.cms
.forms
;
6 import javax
.jcr
.RepositoryException
;
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
;
26 /** Display, add or remove values from a list in a CMS context */
27 public class EditableMultiStringProperty
extends StyledControl
implements
29 private static final long serialVersionUID
= -7044614381252178595L;
31 private String propertyName
;
32 private String message
;
33 // TODO implement the ability to provide a list of legal values
34 private String
[] possibleValues
;
35 private boolean canEdit
;
36 private SelectionListener removeValueSL
;
37 private List
<String
> values
;
39 // TODO manage within the CSS
40 private int rowSpacing
= 5;
41 private int rowMarging
= 0;
42 private int oneValueMargingRight
= 5;
43 private int btnWidth
= 16;
44 private int btnHeight
= 16;
45 private int btnHorizontalIndent
= 3;
47 public EditableMultiStringProperty(Composite parent
, int style
, Node node
,
48 String propertyName
, List
<String
> values
, String
[] possibleValues
,
49 String addValueMsg
, SelectionListener removeValueSelectionListener
)
50 throws RepositoryException
{
51 super(parent
, style
, node
, true);
53 this.propertyName
= propertyName
;
55 this.possibleValues
= possibleValues
;
56 this.message
= addValueMsg
;
57 this.canEdit
= removeValueSelectionListener
!= null;
58 this.removeValueSL
= removeValueSelectionListener
;
61 public List
<String
> getValues() {
65 public void setValues(List
<String
> values
) {
69 // Row layout items do not need explicit layout data
70 protected void setControlLayoutData(Control control
) {
73 /** To be overridden */
74 protected void setContainerLayoutData(Composite composite
) {
75 composite
.setLayoutData(CmsUtils
.fillWidth());
79 public Control
getControl() {
80 return super.getControl();
84 protected Control
createControl(Composite box
, String style
) {
85 Composite row
= new Composite(box
, SWT
.NO_FOCUS
);
86 row
.setLayoutData(EclipseUiUtils
.fillAll());
88 RowLayout rl
= new RowLayout(SWT
.HORIZONTAL
);
90 rl
.spacing
= rowSpacing
;
91 rl
.marginRight
= rl
.marginLeft
= rl
.marginBottom
= rl
.marginTop
= rowMarging
;
95 for (final String value
: values
) {
97 createRemovableValue(row
, SWT
.SINGLE
, value
);
99 createValueLabel(row
, SWT
.SINGLE
, value
);
105 else if (isEditing())
106 return createText(row
, style
);
108 return createLabel(row
, style
);
112 * Override to provide specific layout for the existing values, typically
113 * adding a pound (#) char for tags or anchor info for browsable links. We
114 * assume the parent composite already has a layout and it is the caller
115 * responsibility to apply corresponding layout data
117 protected Label
createValueLabel(Composite parent
, int style
, String value
) {
118 Label label
= new Label(parent
, style
);
119 label
.setText("#" + value
);
120 CmsUtils
.markup(label
);
121 CmsUtils
.style(label
, FormStyle
.propertyText
.style());
125 private Composite
createRemovableValue(Composite parent
, int style
,
127 Composite valCmp
= new Composite(parent
, SWT
.NO_FOCUS
);
128 GridLayout gl
= EclipseUiUtils
.noSpaceGridLayout(new GridLayout(2,
130 gl
.marginRight
= oneValueMargingRight
;
131 valCmp
.setLayout(gl
);
133 createValueLabel(valCmp
, SWT
.WRAP
, value
);
135 Button deleteBtn
= new Button(valCmp
, SWT
.FLAT
);
136 deleteBtn
.setData(FormConstants
.LINKED_VALUE
, value
);
137 deleteBtn
.addSelectionListener(removeValueSL
);
138 CmsUtils
.style(deleteBtn
, FormStyle
.delete
.style()
139 + FormStyle
.BUTTON_SUFFIX
);
140 GridData gd
= new GridData();
141 gd
.heightHint
= btnHeight
;
142 gd
.widthHint
= btnWidth
;
143 gd
.horizontalIndent
= btnHorizontalIndent
;
144 deleteBtn
.setLayoutData(gd
);
149 protected Text
createText(Composite box
, String style
) {
150 final Text text
= new Text(box
, getStyle());
151 // The "add new value" text is not meant to change, so we can set it on
153 text
.setMessage(message
);
154 CmsUtils
.style(text
, style
);
157 text
.addTraverseListener(new TraverseListener() {
158 private static final long serialVersionUID
= 1L;
160 public void keyTraversed(TraverseEvent e
) {
161 if (e
.keyCode
== SWT
.CR
) {
168 // The OK button does not work with the focusOut listener
169 // because focus out is called before the OK button is pressed
171 // // we must call layout() now so that the row data can compute the
173 // // of the other controls.
174 // text.getParent().layout();
175 // int height = text.getSize().y;
177 // Button okBtn = new Button(box, SWT.BORDER | SWT.PUSH | SWT.BOTTOM);
178 // okBtn.setText("OK");
179 // RowData rd = new RowData(SWT.DEFAULT, height - 2);
180 // okBtn.setLayoutData(rd);
182 // okBtn.addSelectionListener(new SelectionAdapter() {
183 // private static final long serialVersionUID = 2780819012423622369L;
186 // public void widgetSelected(SelectionEvent e) {
194 /** Performs the real addition, overwrite to make further sanity checks */
195 protected void addValue(Text text
) {
196 String value
= text
.getText();
197 String errMsg
= null;
199 if (EclipseUiUtils
.isEmpty(value
))
202 if (values
.contains(value
))
203 errMsg
= "Dupplicated value: " + value
204 + ", please correct and try again";
206 MessageDialog
.openError(this.getShell(), "Addition not allowed",
210 Composite newCmp
= createRemovableValue(text
.getParent(),
212 newCmp
.moveAbove(text
);
214 newCmp
.getParent().layout();
218 protected Label
createLabel(Composite box
, String style
) {
220 Label lbl
= new Label(box
, getStyle());
221 lbl
.setText(message
);
222 CmsUtils
.style(lbl
, style
);
223 CmsUtils
.markup(lbl
);
224 if (mouseListener
!= null)
225 lbl
.addMouseListener(mouseListener
);
231 protected void clear(boolean deep
) {
232 Control child
= getControl();
236 child
.getParent().dispose();
240 public void setText(String text
) {
241 Control child
= getControl();
242 if (child
instanceof Label
) {
243 Label lbl
= (Label
) child
;
248 } else if (child
instanceof Text
) {
249 Text txt
= (Text
) child
;
254 public synchronized void startEditing() {
255 getControl().setData(STYLE
, FormStyle
.propertyText
.style());
256 super.startEditing();
259 public synchronized void stopEditing() {
260 getControl().setData(STYLE
, FormStyle
.propertyMessage
.style());
264 public String
getPropertyName() {