1 package org.argeo.connect.ui.parts;
2
3 import java.text.DateFormat;
4 import java.text.ParseException;
5 import java.text.SimpleDateFormat;
6 import java.util.Calendar;
7 import java.util.Date;
8 import java.util.GregorianCalendar;
9
10 import javax.jcr.Node;
11 import javax.jcr.PropertyType;
12 import javax.jcr.RepositoryException;
13
14 import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
15 import org.argeo.cms.util.CmsUtils;
16 import org.argeo.connect.ConnectConstants;
17 import org.argeo.connect.ConnectException;
18 import org.argeo.connect.ui.ConnectEditor;
19 import org.argeo.connect.ui.ConnectImages;
20 import org.argeo.connect.ui.ConnectUiStyles;
21 import org.argeo.connect.ui.ConnectUiUtils;
22 import org.argeo.connect.util.ConnectJcrUtils;
23 import org.argeo.eclipse.ui.EclipseUiUtils;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.events.FocusEvent;
26 import org.eclipse.swt.events.FocusListener;
27 import org.eclipse.swt.events.MouseEvent;
28 import org.eclipse.swt.events.MouseListener;
29 import org.eclipse.swt.events.SelectionAdapter;
30 import org.eclipse.swt.events.SelectionEvent;
31 import org.eclipse.swt.events.ShellAdapter;
32 import org.eclipse.swt.events.ShellEvent;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Button;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Control;
38 import org.eclipse.swt.widgets.DateTime;
39 import org.eclipse.swt.widgets.Shell;
40 import org.eclipse.swt.widgets.Text;
41
42
43 public class DateTextPart extends Composite {
44 private static final long serialVersionUID = 7651166365139278532L;
45
46
47 private Node node;
48 private String propName;
49
50
51 private final ConnectEditor editor;
52 private AbstractFormPart formPart;
53 private Text dateTxt;
54 private Button openCalBtn;
55
56 private DateFormat dateFormat = new SimpleDateFormat(ConnectConstants.DEFAULT_SHORT_DATE_FORMAT);
57
58
59
60
61
62
63
64
65
66
67
68
69 public DateTextPart(ConnectEditor editor, Composite parent, int style, AbstractFormPart formPart, Node node,
70 String propName) {
71 super(parent, style);
72 this.editor = editor;
73 this.formPart = formPart;
74 this.node = node;
75 this.propName = propName;
76 populate(this);
77 }
78
79
80
81
82
83 public void setFormPart(AbstractFormPart formPart) {
84 this.formPart = formPart;
85 }
86
87 public void setText(Calendar cal) {
88 String newValueStr = "";
89 if (cal != null)
90 newValueStr = dateFormat.format(cal.getTime());
91 if (!newValueStr.equals(dateTxt.getText()))
92 dateTxt.setText(newValueStr);
93 }
94
95 public void refresh() {
96 Calendar cal = null;
97 try {
98 if (node.hasProperty(propName))
99 cal = node.getProperty(propName).getDate();
100 dateTxt.setEnabled(editor.isEditing());
101 openCalBtn.setEnabled(editor.isEditing());
102 } catch (RepositoryException e) {
103 throw new ConnectException("Unable to refresh " + propName + " date property for " + node, e);
104 }
105 setText(cal);
106 }
107
108 private void populate(Composite dateComposite) {
109 GridLayout gl = ConnectUiUtils.noSpaceGridLayout(2);
110 gl.horizontalSpacing = 5;
111 dateComposite.setLayout(gl);
112 dateTxt = new Text(dateComposite, SWT.BORDER);
113 dateTxt.setMessage(ConnectConstants.DEFAULT_SHORT_DATE_FORMAT);
114 CmsUtils.style(dateTxt, ConnectUiStyles.FORCE_BORDER);
115 dateTxt.setLayoutData(new GridData(150, SWT.DEFAULT));
116 dateTxt.setToolTipText(
117 "Enter a date with form \"" + ConnectConstants.DEFAULT_SHORT_DATE_FORMAT + "\" or use the calendar");
118 openCalBtn = new Button(dateComposite, SWT.FLAT);
119 openCalBtn.setAlignment(SWT.CENTER);
120 openCalBtn.setImage(ConnectImages.CALENDAR);
121
122
123
124 openCalBtn.addSelectionListener(new SelectionAdapter() {
125 private static final long serialVersionUID = 1L;
126
127 public void widgetSelected(SelectionEvent event) {
128 CalendarPopup popup = new CalendarPopup(dateTxt);
129 popup.open();
130 }
131 });
132
133 dateTxt.addFocusListener(new FocusListener() {
134 private static final long serialVersionUID = 1L;
135
136 @Override
137 public void focusLost(FocusEvent event) {
138 try {
139 Calendar newVal = parseDate(false);
140 if (newVal != null) {
141 if (ConnectJcrUtils.setJcrProperty(node, propName, PropertyType.DATE, newVal))
142 formPart.markDirty();
143 } else if (node.hasProperty(propName)) {
144 node.getProperty(propName).remove();
145 formPart.markDirty();
146 }
147 } catch (RepositoryException e) {
148 throw new ConnectException("Unable to update " + propName + " date property for " + node, e);
149 }
150 }
151
152 @Override
153 public void focusGained(FocusEvent event) {
154 }
155 });
156 }
157
158 private Calendar parseDate(boolean openWrongFormatError) {
159 String dateStr = dateTxt.getText();
160
161 if (EclipseUiUtils.notEmpty(dateStr)) {
162 try {
163 Date date = dateFormat.parse(dateStr);
164 Calendar cal = new GregorianCalendar();
165 cal.setTime(date);
166 return cal;
167 } catch (ParseException pe) {
168
169 refresh();
170 try {
171 if (node.hasProperty(propName))
172 return node.getProperty(propName).getDate();
173 } catch (RepositoryException re) {
174 throw new ConnectException("Unable to reset text to old value after parsing of invalid value for "
175 + propName + " of " + node, re);
176 }
177 }
178 }
179 return null;
180 }
181
182 private class CalendarPopup extends Shell {
183 private static final long serialVersionUID = 1L;
184 private Calendar currCal = null;
185 private DateTime dateTimeCtl;
186
187 public CalendarPopup(Control source) {
188 super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
189 currCal = parseDate(false);
190
191 populate();
192
193
194 CmsUtils.style(CalendarPopup.this, ConnectUiStyles.POPUP_SHELL);
195
196 pack();
197 layout();
198 setLocation(source.toDisplay((source.getLocation().x - 2), (source.getSize().y) + 3));
199
200 addShellListener(new ShellAdapter() {
201 private static final long serialVersionUID = 5178980294808435833L;
202
203 @Override
204 public void shellDeactivated(ShellEvent e) {
205 close();
206 dispose();
207 }
208
209 });
210 open();
211 }
212
213 private void setProperty() {
214 Calendar cal = new GregorianCalendar();
215 cal.set(dateTimeCtl.getYear(), dateTimeCtl.getMonth(), dateTimeCtl.getDay(), 12, 0);
216 dateTxt.setText(dateFormat.format(cal.getTime()));
217 if (ConnectJcrUtils.setJcrProperty(node, propName, PropertyType.DATE, cal))
218 formPart.markDirty();
219 }
220
221 protected void populate() {
222 setLayout(EclipseUiUtils.noSpaceGridLayout());
223
224 dateTimeCtl = new DateTime(this, SWT.CALENDAR);
225 dateTimeCtl.setLayoutData(EclipseUiUtils.fillAll());
226 if (currCal != null)
227 dateTimeCtl.setDate(currCal.get(Calendar.YEAR), currCal.get(Calendar.MONTH),
228 currCal.get(Calendar.DAY_OF_MONTH));
229
230 dateTimeCtl.addSelectionListener(new SelectionAdapter() {
231 private static final long serialVersionUID = -8414377364434281112L;
232
233 @Override
234 public void widgetSelected(SelectionEvent e) {
235 setProperty();
236 }
237 });
238
239 dateTimeCtl.addMouseListener(new MouseListener() {
240 private static final long serialVersionUID = 1L;
241
242 @Override
243 public void mouseUp(MouseEvent e) {
244 }
245
246 @Override
247 public void mouseDown(MouseEvent e) {
248 }
249
250 @Override
251 public void mouseDoubleClick(MouseEvent e) {
252 setProperty();
253 close();
254 dispose();
255 }
256 });
257 }
258 }
259 }