]> git.argeo.org Git - gpl/argeo-suite.git/blob - forms/EditablePropertyDate.java
Prepare next development cycle
[gpl/argeo-suite.git] / forms / EditablePropertyDate.java
1 package org.argeo.app.swt.forms;
2
3 import java.text.DateFormat;
4 import java.time.Instant;
5 import java.time.format.DateTimeFormatter;
6 import java.time.temporal.ChronoField;
7 import java.time.temporal.TemporalAccessor;
8 import java.util.Calendar;
9 import java.util.GregorianCalendar;
10 import java.util.Optional;
11
12 import javax.xml.namespace.QName;
13
14 import org.argeo.api.acr.Content;
15 import org.argeo.cms.swt.CmsSwtUtils;
16 import org.argeo.cms.swt.SwtEditablePart;
17 import org.argeo.cms.swt.acr.ContentStyledControl;
18 import org.argeo.eclipse.ui.EclipseUiUtils;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.MouseEvent;
21 import org.eclipse.swt.events.MouseListener;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.events.ShellAdapter;
25 import org.eclipse.swt.events.ShellEvent;
26 import org.eclipse.swt.layout.GridData;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Button;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.DateTime;
32 import org.eclipse.swt.widgets.Label;
33 import org.eclipse.swt.widgets.Shell;
34 import org.eclipse.swt.widgets.Text;
35
36 /** CMS form part to display and edit a date */
37 public class EditablePropertyDate extends ContentStyledControl implements SwtEditablePart {
38 private static final long serialVersionUID = 2500215515778162468L;
39
40 // Context
41 private QName propertyName;
42 private String message;
43 private DateTimeFormatter dateFormat;
44
45 // UI Objects
46 private Text dateTxt;
47 private Button openCalBtn;
48
49 // TODO manage within the CSS
50 private int fieldBtnSpacing = 5;
51
52 /**
53 *
54 * @param parent
55 * @param style
56 * @param node
57 * @param propertyName
58 * @param message
59 * @param dateFormat provide a {@link DateFormat} as contract to be able to
60 * read/write dates as strings
61 * @throws RepositoryException
62 */
63 public EditablePropertyDate(Composite parent, int style, Content node, QName propertyName, String message,
64 DateTimeFormatter dateFormat) {
65 super(parent, style, node);
66
67 this.propertyName = propertyName;
68 this.message = message;
69 this.dateFormat = dateFormat;
70
71 Optional<Instant> instant = node.get(propertyName, Instant.class);
72 if (instant.isPresent()) {
73 this.setStyle(FormStyle.propertyText.style());
74 this.setText(dateFormat.format(instant.get()));
75 } else {
76 this.setStyle(FormStyle.propertyMessage.style());
77 this.setText(message);
78 }
79 }
80
81 public void setText(String text) {
82 Control child = getControl();
83 if (child instanceof Label) {
84 Label lbl = (Label) child;
85 if (EclipseUiUtils.isEmpty(text))
86 lbl.setText(message);
87 else
88 lbl.setText(text);
89 } else if (child instanceof Text) {
90 Text txt = (Text) child;
91 if (EclipseUiUtils.isEmpty(text)) {
92 txt.setText("");
93 } else
94 txt.setText(text);
95 }
96 }
97
98 public synchronized void startEditing() {
99 // if (dateTxt != null && !dateTxt.isDisposed())
100 CmsSwtUtils.style(getControl(), FormStyle.propertyText);
101 // getControl().setData(STYLE, FormStyle.propertyText.style());
102 super.startEditing();
103 }
104
105 public synchronized void stopEditing() {
106 if (EclipseUiUtils.isEmpty(dateTxt.getText()))
107 CmsSwtUtils.style(getControl(), FormStyle.propertyMessage);
108 // getControl().setData(STYLE, FormStyle.propertyMessage.style());
109 else
110 CmsSwtUtils.style(getControl(), FormStyle.propertyText);
111 // getControl().setData(STYLE, FormStyle.propertyText.style());
112 super.stopEditing();
113 }
114
115 public QName getPropertyName() {
116 return propertyName;
117 }
118
119 @Override
120 protected Control createControl(Composite box, String style) {
121 if (isEditing()) {
122 return createCustomEditableControl(box, style);
123 } else
124 return createLabel(box, style);
125 }
126
127 protected Label createLabel(Composite box, String style) {
128 Label lbl = new Label(box, getStyle() | SWT.WRAP);
129 lbl.setLayoutData(CmsSwtUtils.fillWidth());
130 CmsSwtUtils.style(lbl, style);
131 CmsSwtUtils.markup(lbl);
132 if (mouseListener != null)
133 lbl.addMouseListener(mouseListener);
134 return lbl;
135 }
136
137 private Control createCustomEditableControl(Composite box, String style) {
138 box.setLayoutData(CmsSwtUtils.fillWidth());
139 Composite dateComposite = new Composite(box, SWT.NONE);
140 GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
141 gl.horizontalSpacing = fieldBtnSpacing;
142 dateComposite.setLayout(gl);
143 dateTxt = new Text(dateComposite, SWT.BORDER);
144 CmsSwtUtils.style(dateTxt, style);
145 dateTxt.setLayoutData(new GridData(120, SWT.DEFAULT));
146 dateTxt.setToolTipText(
147 "Enter a date with form \"" + FormUtils.DEFAULT_SHORT_DATE_FORMAT + "\" or use the calendar");
148 openCalBtn = new Button(dateComposite, SWT.FLAT);
149 CmsSwtUtils.style(openCalBtn, FormStyle.calendar.style() + FormStyle.BUTTON_SUFFIX);
150 GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
151 gd.heightHint = 17;
152 openCalBtn.setLayoutData(gd);
153 // openCalBtn.setImage(PeopleRapImages.CALENDAR_BTN);
154
155 openCalBtn.addSelectionListener(new SelectionAdapter() {
156 private static final long serialVersionUID = 1L;
157
158 public void widgetSelected(SelectionEvent event) {
159 CalendarPopup popup = new CalendarPopup(dateTxt);
160 popup.open();
161 }
162 });
163
164 // dateTxt.addFocusListener(new FocusListener() {
165 // private static final long serialVersionUID = 1L;
166 //
167 // @Override
168 // public void focusLost(FocusEvent event) {
169 // String newVal = dateTxt.getText();
170 // // Enable reset of the field
171 // if (FormUtils.notNull(newVal))
172 // calendar = null;
173 // else {
174 // try {
175 // Calendar newCal = parseDate(newVal);
176 // // DateText.this.setText(newCal);
177 // calendar = newCal;
178 // } catch (ParseException pe) {
179 // // Silent. Manage error popup?
180 // if (calendar != null)
181 // EditablePropertyDate.this.setText(calendar);
182 // }
183 // }
184 // }
185 //
186 // @Override
187 // public void focusGained(FocusEvent event) {
188 // }
189 // });
190 return dateTxt;
191 }
192
193 protected void clear(boolean deep) {
194 Control child = getControl();
195 if (deep || child instanceof Label)
196 super.clear(deep);
197 else {
198 child.getParent().dispose();
199 }
200 }
201
202 // /** Enable setting a custom tooltip on the underlying text */
203 // @Deprecated
204 // public void setToolTipText(String toolTipText) {
205 // dateTxt.setToolTipText(toolTipText);
206 // }
207 //
208 // @Deprecated
209 // /** Enable setting a custom message on the underlying text */
210 // public void setMessage(String message) {
211 // dateTxt.setMessage(message);
212 // }
213 //
214 // @Deprecated
215 // public void setText(Calendar cal) {
216 // String newValueStr = "";
217 // if (cal != null)
218 // newValueStr = dateFormat.format(cal.getTime());
219 // if (!newValueStr.equals(dateTxt.getText()))
220 // dateTxt.setText(newValueStr);
221 // }
222
223 // UTILITIES TO MANAGE THE CALENDAR POPUP
224 // TODO manage the popup shell in a cleaner way
225 private class CalendarPopup extends Shell {
226 private static final long serialVersionUID = 1L;
227 private DateTime dateTimeCtl;
228
229 public CalendarPopup(Control source) {
230 super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
231 populate();
232 // Add border and shadow style
233 CmsSwtUtils.markup(CalendarPopup.this);
234 CmsSwtUtils.style(CalendarPopup.this, FormStyle.popupCalendar.style());
235 pack();
236 layout();
237 setLocation(source.toDisplay((source.getLocation().x - 2), (source.getSize().y) + 3));
238
239 addShellListener(new ShellAdapter() {
240 private static final long serialVersionUID = 5178980294808435833L;
241
242 @Override
243 public void shellDeactivated(ShellEvent e) {
244 close();
245 dispose();
246 }
247 });
248 open();
249 }
250
251 private void setProperty() {
252 // Direct set does not seems to work. investigate
253 // cal.set(dateTimeCtl.getYear(), dateTimeCtl.getMonth(),
254 // dateTimeCtl.getDay(), 12, 0);
255 // TODO use modern time API
256 Calendar cal = new GregorianCalendar();
257 cal.set(Calendar.YEAR, dateTimeCtl.getYear());
258 cal.set(Calendar.MONTH, dateTimeCtl.getMonth());
259 cal.set(Calendar.DAY_OF_MONTH, dateTimeCtl.getDay());
260 String dateStr = dateFormat.format(cal.toInstant());
261 dateTxt.setText(dateStr);
262 }
263
264 protected void populate() {
265 setLayout(EclipseUiUtils.noSpaceGridLayout());
266
267 dateTimeCtl = new DateTime(this, SWT.CALENDAR);
268 dateTimeCtl.setLayoutData(EclipseUiUtils.fillAll());
269
270 TemporalAccessor calendar = FormUtils.parseDate(dateFormat, dateTxt.getText());
271
272 if (calendar != null)
273 dateTimeCtl.setDate(calendar.get(ChronoField.YEAR), calendar.get(ChronoField.MONTH_OF_YEAR),
274 calendar.get(ChronoField.DAY_OF_MONTH));
275
276 dateTimeCtl.addSelectionListener(new SelectionAdapter() {
277 private static final long serialVersionUID = -8414377364434281112L;
278
279 @Override
280 public void widgetSelected(SelectionEvent e) {
281 setProperty();
282 }
283 });
284
285 dateTimeCtl.addMouseListener(new MouseListener() {
286 private static final long serialVersionUID = 1L;
287
288 @Override
289 public void mouseUp(MouseEvent e) {
290 }
291
292 @Override
293 public void mouseDown(MouseEvent e) {
294 }
295
296 @Override
297 public void mouseDoubleClick(MouseEvent e) {
298 setProperty();
299 close();
300 dispose();
301 }
302 });
303 }
304 }
305 }