View Javadoc
1   package org.argeo.connect.ui.widgets;
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 org.argeo.cms.util.CmsUtils;
11  import org.argeo.connect.ConnectConstants;
12  import org.argeo.connect.ui.ConnectImages;
13  import org.argeo.connect.ui.ConnectUiStyles;
14  import org.argeo.connect.ui.ConnectUiUtils;
15  import org.argeo.eclipse.ui.EclipseUiUtils;
16  import org.eclipse.swt.SWT;
17  import org.eclipse.swt.events.FocusEvent;
18  import org.eclipse.swt.events.FocusListener;
19  import org.eclipse.swt.events.MouseEvent;
20  import org.eclipse.swt.events.MouseListener;
21  import org.eclipse.swt.events.SelectionAdapter;
22  import org.eclipse.swt.events.SelectionEvent;
23  import org.eclipse.swt.events.ShellAdapter;
24  import org.eclipse.swt.events.ShellEvent;
25  import org.eclipse.swt.layout.GridData;
26  import org.eclipse.swt.layout.GridLayout;
27  import org.eclipse.swt.widgets.Button;
28  import org.eclipse.swt.widgets.Composite;
29  import org.eclipse.swt.widgets.Control;
30  import org.eclipse.swt.widgets.DateTime;
31  import org.eclipse.swt.widgets.Shell;
32  import org.eclipse.swt.widgets.Text;
33  
34  /**
35   * A text composite to request end user for a date using a text and a calendar
36   * popup
37   */
38  public class DateText extends Composite {
39  	private static final long serialVersionUID = 7651166365139278532L;
40  
41  	// Context
42  	private Calendar calendar;
43  
44  	// UI Objects
45  	private Text dateTxt;
46  	private Button openCalBtn;
47  
48  	private DateFormat dateFormat = new SimpleDateFormat(ConnectConstants.DEFAULT_SHORT_DATE_FORMAT);
49  
50  	/**
51  	 * 
52  	 * @param parent
53  	 * @param style
54  	 * @param node
55  	 * @param propName
56  	 */
57  	public DateText(Composite parent, int style) {
58  		super(parent, style);
59  		populate(this);
60  	}
61  
62  	/**
63  	 * Returns the user defined date as Calendar or null if none has been defined
64  	 */
65  	public Calendar getDate() {
66  		return calendar;
67  	}
68  
69  	/** @deprecated use {@link #getDate()} instead */
70  	@Deprecated
71  	public Calendar getCalendar() {
72  		return calendar;
73  	}
74  
75  	/** Enable setting a custom tooltip on the underlyting text */
76  	public void setToolTipText(String toolTipText) {
77  		dateTxt.setToolTipText(toolTipText);
78  	}
79  
80  	/** Enable setting a custom message on the underlying text */
81  	public void setMessage(String message) {
82  		dateTxt.setMessage(message);
83  	}
84  
85  	private void populate(Composite dateComposite) {
86  		GridLayout gl = ConnectUiUtils.noSpaceGridLayout(2);
87  		gl.horizontalSpacing = 5;
88  		dateComposite.setLayout(gl);
89  		dateTxt = new Text(dateComposite, SWT.BORDER);
90  		dateTxt.setMessage(ConnectConstants.DEFAULT_SHORT_DATE_FORMAT);
91  		CmsUtils.style(dateTxt, ConnectUiStyles.FORCE_BORDER);
92  		dateTxt.setLayoutData(new GridData(80, SWT.DEFAULT));
93  		dateTxt.setToolTipText(
94  				"Enter a date with form \"" + ConnectConstants.DEFAULT_SHORT_DATE_FORMAT + "\" or use the calendar");
95  		openCalBtn = new Button(dateComposite, SWT.FLAT);
96  		openCalBtn.setAlignment(SWT.CENTER);
97  		openCalBtn.setImage(ConnectImages.CALENDAR);
98  		// CmsUtils.style(openCalBtn, ConnectUiStyles.OPEN_CALENDAR_BTN);
99  		// openCalBtn.setLayoutData(new GridData(16, 16));
100 
101 		openCalBtn.addSelectionListener(new SelectionAdapter() {
102 			private static final long serialVersionUID = 1L;
103 
104 			public void widgetSelected(SelectionEvent event) {
105 				CalendarPopup popup = new CalendarPopup(dateTxt);
106 				popup.open();
107 			}
108 		});
109 
110 		dateTxt.addFocusListener(new FocusListener() {
111 			private static final long serialVersionUID = 1L;
112 
113 			@Override
114 			public void focusLost(FocusEvent event) {
115 				String newVal = dateTxt.getText();
116 				// Enable reset of the field
117 				if (EclipseUiUtils.isEmpty(newVal))
118 					calendar = null;
119 				else {
120 					try {
121 						Calendar newCal = parseDate(newVal);
122 						// DateText.this.setText(newCal);
123 						calendar = newCal;
124 					} catch (ParseException pe) {
125 						// Silent. Manage error popup?
126 						if (calendar != null)
127 							DateText.this.setDate(calendar);
128 					}
129 				}
130 			}
131 
132 			@Override
133 			public void focusGained(FocusEvent event) {
134 			}
135 		});
136 	}
137 
138 	/** @deprecated Use {@link #setDate(Calendar)} instead */
139 	@Deprecated
140 	public void setText(Calendar cal) {
141 		setDate(cal);
142 	}
143 
144 	public void setDate(Calendar calendar) {
145 		String newValueStr = "";
146 		if (calendar != null)
147 			newValueStr = dateFormat.format(calendar.getTime());
148 		if (!newValueStr.equals(dateTxt.getText()))
149 			dateTxt.setText(newValueStr);
150 		this.calendar = calendar;
151 	}
152 
153 	private Calendar parseDate(String newVal) throws ParseException {
154 		if (EclipseUiUtils.notEmpty(newVal)) {
155 			Date date = dateFormat.parse(newVal);
156 			Calendar cal = new GregorianCalendar();
157 			cal.setTime(date);
158 			return cal;
159 		}
160 		return null;
161 	}
162 
163 	private class CalendarPopup extends Shell {
164 		private static final long serialVersionUID = 1L;
165 		private DateTime dateTimeCtl;
166 
167 		public CalendarPopup(Control source) {
168 			super(source.getDisplay().getActiveShell(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
169 			populate();
170 			// Add border and shadow style
171 			CmsUtils.style(CalendarPopup.this, ConnectUiStyles.POPUP_SHELL);
172 			pack();
173 			layout();
174 			setLocation(source.toDisplay((source.getLocation().x - 2), (source.getSize().y) + 3));
175 
176 			addShellListener(new ShellAdapter() {
177 				private static final long serialVersionUID = 5178980294808435833L;
178 
179 				@Override
180 				public void shellDeactivated(ShellEvent e) {
181 					close();
182 					dispose();
183 				}
184 			});
185 			open();
186 		}
187 
188 		private void setProperty() {
189 			Calendar cal = new GregorianCalendar();
190 			cal.set(dateTimeCtl.getYear(), dateTimeCtl.getMonth(), dateTimeCtl.getDay(), 12, 0);
191 			dateTxt.setText(dateFormat.format(cal.getTime()));
192 			calendar = cal;
193 		}
194 
195 		protected void populate() {
196 			setLayout(EclipseUiUtils.noSpaceGridLayout());
197 
198 			dateTimeCtl = new DateTime(this, SWT.CALENDAR);
199 			dateTimeCtl.setLayoutData(EclipseUiUtils.fillAll());
200 			if (calendar != null)
201 				dateTimeCtl.setDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
202 						calendar.get(Calendar.DAY_OF_MONTH));
203 
204 			dateTimeCtl.addSelectionListener(new SelectionAdapter() {
205 				private static final long serialVersionUID = -8414377364434281112L;
206 
207 				@Override
208 				public void widgetSelected(SelectionEvent e) {
209 					setProperty();
210 				}
211 			});
212 
213 			dateTimeCtl.addMouseListener(new MouseListener() {
214 				private static final long serialVersionUID = 1L;
215 
216 				@Override
217 				public void mouseUp(MouseEvent e) {
218 				}
219 
220 				@Override
221 				public void mouseDown(MouseEvent e) {
222 				}
223 
224 				@Override
225 				public void mouseDoubleClick(MouseEvent e) {
226 					setProperty();
227 					close();
228 					dispose();
229 				}
230 			});
231 		}
232 	}
233 }