package org.vaadin.touchkit.gwt.client.vcom; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.vaadin.touchkit.gwt.client.ui.DatePicker; import com.google.gwt.core.shared.GWT; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.i18n.client.DateTimeFormat; import com.vaadin.client.DateTimeService; import com.vaadin.client.LocaleNotLoadedException; import com.vaadin.client.LocaleService; import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.v7.client.ui.AbstractFieldConnector; import com.vaadin.shared.ui.Connect; /** * Connector of DatePicker */ @SuppressWarnings("serial") @Connect(org.vaadin.touchkit.ui.DatePicker.class) public class DatePickerConnector extends AbstractFieldConnector implements ValueChangeHandler<Date>, DatePicker.DateParser { private DateTimeService dateTimeService; private final DatePickerServerRpc rpc = RpcProxy.create( DatePickerServerRpc.class, this); private String formatString; @Override public void init() { super.init(); getWidget().addValueChangeHandler(this); dateTimeService = new DateTimeService(); } @Override public DatePicker createWidget() { DatePicker picker = GWT.create(DatePicker.class); picker.setDateParser(this); return picker; } @Override public DatePicker getWidget() { return (DatePicker) super.getWidget(); } @Override public DatePickerState getState() { return (DatePickerState) super.getState(); } /** * Convert state resolution to widget resolution * * @param res * State resolution * @return Widget resolution */ private DatePicker.Resolution convertResolution( DatePickerState.Resolution res) { switch (res) { case DAY: return DatePicker.Resolution.DAY; case MONTH: return DatePicker.Resolution.MONTH; case TIME: default: return DatePicker.Resolution.TIME; } } @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); DatePicker.Resolution resolution = convertResolution(getState().resolution); try { dateTimeService.setLocale(getState().locale); } catch (LocaleNotLoadedException e) { Logger.getLogger(DatePickerConnector.class.getName()).log( Level.SEVERE, "Tried to use an unloaded locale \"" + getState().locale); } formatString = getFormatString(resolution, getState().locale); getWidget().setUseNative(getState().useNative); getWidget().setResolution(resolution); getWidget().setDate(parseDateInWireFormat(getState().date)); getWidget().setMin(parseDateInWireFormat(getState().min)); getWidget().setMax(parseDateInWireFormat(getState().max)); } private Date parseDateInWireFormat(String date) { return (date == null || date.isEmpty()) ? null : getWireFormat().parse( date); } /** * Date format used over the wire. * * @see <a href="http://tools.ietf.org/html/rfc3339">RFC3339</a> */ protected DateTimeFormat getWireFormat() { DatePicker.Resolution resolution = convertResolution(getState().resolution); return DatePicker.getFormat(resolution); } @Override public void onValueChange(ValueChangeEvent<Date> event) { if (event.getValue() != null) { rpc.valueChanged(getWireFormat().format((event.getValue()))); } else { rpc.valueChanged(null); } } /* * From VTextualDate */ private String getFormatString(DatePicker.Resolution resolution, String currentLocale) { switch (resolution) { case MONTH: case DAY: return createDateFormat(currentLocale, resolution); case TIME: String dateAndTimeFormat = createDateFormat(currentLocale, resolution); if (dateTimeService.isTwelveHourClock()) { dateAndTimeFormat += " hh"; } else { dateAndTimeFormat += " HH"; } dateAndTimeFormat += ":mm"; if (dateTimeService.isTwelveHourClock()) { dateAndTimeFormat += " aaa"; } return dateAndTimeFormat; default: throw new RuntimeException(); } } private String createDateFormat(String currentLocale, DatePicker.Resolution resolution) { try { String dateFormat = LocaleService.getDateFormat(currentLocale); return cleanFormat(dateFormat, resolution); } catch (LocaleNotLoadedException e) { throw new RuntimeException(e); } } /* * From VTextualDate */ private String cleanFormat(String format, DatePicker.Resolution resolution) { if (resolution == DatePicker.Resolution.MONTH) { format = format.replaceAll("d", ""); } // Remove unsupported patterns format = format.replaceAll("[GzZwWkK]", ""); // Remove extra delimiters ('/' and '.') while (format.startsWith("/") || format.startsWith(".") || format.startsWith("-")) { format = format.substring(1); } while (format.endsWith("/") || format.endsWith(".") || format.endsWith("-")) { format = format.substring(0, format.length() - 1); } // Remove duplicate delimiters format = format.replaceAll("//", "/"); format = format.replaceAll("\\.\\.", "."); format = format.replaceAll("--", "-"); return format.trim(); } @Override public String dateToString(Date date) { return dateTimeService.formatDate(date, formatString); } @Override public Date stringToDate(String string) { return dateTimeService.parseDate(string, formatString, false); } }