-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Date;\r
-\r
-import com.google.gwt.event.dom.client.BlurEvent;\r
-import com.google.gwt.event.dom.client.BlurHandler;\r
-import com.google.gwt.event.dom.client.ChangeEvent;\r
-import com.google.gwt.event.dom.client.ChangeHandler;\r
-import com.google.gwt.event.dom.client.FocusEvent;\r
-import com.google.gwt.event.dom.client.FocusHandler;\r
-import com.google.gwt.i18n.client.DateTimeFormat;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.ui.TextBox;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.BrowserInfo;\r
-import com.vaadin.terminal.gwt.client.ClientExceptionHandler;\r
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;\r
-import com.vaadin.terminal.gwt.client.Focusable;\r
-import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;\r
-import com.vaadin.terminal.gwt.client.LocaleService;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-\r
-public class VTextualDate extends VDateField implements Paintable, Field,\r
- ChangeHandler, ContainerResizedListener, Focusable {\r
-\r
- private static final String PARSE_ERROR_CLASSNAME = CLASSNAME\r
- + "-parseerror";\r
-\r
- private final TextBox text;\r
-\r
- private String formatStr;\r
-\r
- private String width;\r
-\r
- private boolean needLayout;\r
-\r
- protected int fieldExtraWidth = -1;\r
-\r
- public VTextualDate() {\r
- super();\r
- text = new TextBox();\r
- // use normal textfield styles as a basis\r
- text.setStyleName(VTextField.CLASSNAME);\r
- // add datefield spesific style name also\r
- text.addStyleName(CLASSNAME + "-textfield");\r
- text.addChangeHandler(this);\r
- text.addFocusHandler(new FocusHandler() {\r
- public void onFocus(FocusEvent event) {\r
- text.addStyleName(VTextField.CLASSNAME + "-"\r
- + VTextField.CLASSNAME_FOCUS);\r
- }\r
- });\r
- text.addBlurHandler(new BlurHandler() {\r
- public void onBlur(BlurEvent event) {\r
- text.removeStyleName(VTextField.CLASSNAME + "-"\r
- + VTextField.CLASSNAME_FOCUS);\r
- }\r
- });\r
- add(text);\r
- }\r
-\r
- @Override\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-\r
- int origRes = currentResolution;\r
- super.updateFromUIDL(uidl, client);\r
- if (origRes != currentResolution) {\r
- // force recreating format string\r
- formatStr = null;\r
- }\r
- if (uidl.hasAttribute("format")) {\r
- formatStr = uidl.getStringAttribute("format");\r
- }\r
-\r
- buildDate();\r
- // not a FocusWidget -> needs own tabindex handling\r
- if (uidl.hasAttribute("tabindex")) {\r
- text.setTabIndex(uidl.getIntAttribute("tabindex"));\r
- }\r
-\r
- if (readonly) {\r
- text.addStyleDependentName("readonly");\r
- } else {\r
- text.removeStyleDependentName("readonly");\r
- }\r
- }\r
-\r
- protected String getFormatString() {\r
- if (formatStr == null) {\r
- if (currentResolution == RESOLUTION_YEAR) {\r
- formatStr = "yyyy"; // force full year\r
- } else {\r
-\r
- try {\r
- String frmString = LocaleService\r
- .getDateFormat(currentLocale);\r
- frmString = cleanFormat(frmString);\r
- String delim = LocaleService\r
- .getClockDelimiter(currentLocale);\r
-\r
- if (currentResolution >= RESOLUTION_HOUR) {\r
- if (dts.isTwelveHourClock()) {\r
- frmString += " hh";\r
- } else {\r
- frmString += " HH";\r
- }\r
- if (currentResolution >= RESOLUTION_MIN) {\r
- frmString += ":mm";\r
- if (currentResolution >= RESOLUTION_SEC) {\r
- frmString += ":ss";\r
- if (currentResolution >= RESOLUTION_MSEC) {\r
- frmString += ".SSS";\r
- }\r
- }\r
- }\r
- if (dts.isTwelveHourClock()) {\r
- frmString += " aaa";\r
- }\r
-\r
- }\r
-\r
- formatStr = frmString;\r
- } catch (LocaleNotLoadedException e) {\r
- ClientExceptionHandler.displayError(e);\r
- }\r
- }\r
- }\r
- return formatStr;\r
- }\r
-\r
- /**\r
- * \r
- */\r
- protected void buildDate() {\r
- removeStyleName(PARSE_ERROR_CLASSNAME);\r
- // Create the initial text for the textfield\r
- String dateText;\r
- if (date != null) {\r
- dateText = DateTimeFormat.getFormat(getFormatString()).format(date);\r
- } else {\r
- dateText = "";\r
- }\r
-\r
- text.setText(dateText);\r
- text.setEnabled(enabled);\r
- text.setReadOnly(readonly);\r
-\r
- if (readonly) {\r
- text.addStyleName("v-readonly");\r
- } else {\r
- text.removeStyleName("v-readonly");\r
- }\r
-\r
- }\r
-\r
- public void onChange(ChangeEvent event) {\r
- if (!text.getText().equals("")) {\r
- try {\r
- DateTimeFormat format = DateTimeFormat\r
- .getFormat(getFormatString());\r
- date = format.parse(text.getText());\r
- long stamp = date.getTime();\r
- if (stamp == 0) {\r
- // If date parsing fails in firefox the stamp will be 0\r
- date = null;\r
- addStyleName(PARSE_ERROR_CLASSNAME);\r
- } else {\r
- // remove possibly added invalid value indication\r
- removeStyleName(PARSE_ERROR_CLASSNAME);\r
- }\r
- } catch (final Exception e) {\r
- ClientExceptionHandler.displayError(e.getMessage());\r
-\r
- addStyleName(PARSE_ERROR_CLASSNAME);\r
- // this is a hack that may eventually be removed\r
- client.updateVariable(id, "lastInvalidDateString", text\r
- .getText(), false);\r
- date = null;\r
- }\r
- } else {\r
- date = null;\r
- // remove possibly added invalid value indication\r
- removeStyleName(PARSE_ERROR_CLASSNAME);\r
- }\r
- // always send the date string\r
- client.updateVariable(id, "dateString", text.getText(), false);\r
-\r
- if (date != null) {\r
- showingDate = new Date(date.getTime());\r
- }\r
-\r
- // Update variables\r
- // (only the smallest defining resolution needs to be\r
- // immediate)\r
- client.updateVariable(id, "year", date != null ? date.getYear() + 1900\r
- : -1, currentResolution == VDateField.RESOLUTION_YEAR\r
- && immediate);\r
- if (currentResolution >= VDateField.RESOLUTION_MONTH) {\r
- client.updateVariable(id, "month",\r
- date != null ? date.getMonth() + 1 : -1,\r
- currentResolution == VDateField.RESOLUTION_MONTH\r
- && immediate);\r
- }\r
- if (currentResolution >= VDateField.RESOLUTION_DAY) {\r
- client\r
- .updateVariable(id, "day", date != null ? date.getDate()\r
- : -1,\r
- currentResolution == VDateField.RESOLUTION_DAY\r
- && immediate);\r
- }\r
- if (currentResolution >= VDateField.RESOLUTION_HOUR) {\r
- client.updateVariable(id, "hour", date != null ? date.getHours()\r
- : -1, currentResolution == VDateField.RESOLUTION_HOUR\r
- && immediate);\r
- }\r
- if (currentResolution >= VDateField.RESOLUTION_MIN) {\r
- client.updateVariable(id, "min", date != null ? date.getMinutes()\r
- : -1, currentResolution == VDateField.RESOLUTION_MIN\r
- && immediate);\r
- }\r
- if (currentResolution >= VDateField.RESOLUTION_SEC) {\r
- client.updateVariable(id, "sec", date != null ? date.getSeconds()\r
- : -1, currentResolution == VDateField.RESOLUTION_SEC\r
- && immediate);\r
- }\r
- if (currentResolution == VDateField.RESOLUTION_MSEC) {\r
- client.updateVariable(id, "msec", date != null ? getMilliseconds()\r
- : -1, immediate);\r
- }\r
-\r
- }\r
-\r
- private String cleanFormat(String format) {\r
- // Remove unnecessary d & M if resolution is too low\r
- if (currentResolution < VDateField.RESOLUTION_DAY) {\r
- format = format.replaceAll("d", "");\r
- }\r
- if (currentResolution < VDateField.RESOLUTION_MONTH) {\r
- format = format.replaceAll("M", "");\r
- }\r
-\r
- // Remove unsupported patterns\r
- // TODO support for 'G', era designator (used at least in Japan)\r
- format = format.replaceAll("[GzZwWkK]", "");\r
-\r
- // Remove extra delimiters ('/' and '.')\r
- while (format.startsWith("/") || format.startsWith(".")\r
- || format.startsWith("-")) {\r
- format = format.substring(1);\r
- }\r
- while (format.endsWith("/") || format.endsWith(".")\r
- || format.endsWith("-")) {\r
- format = format.substring(0, format.length() - 1);\r
- }\r
-\r
- // Remove duplicate delimiters\r
- format = format.replaceAll("//", "/");\r
- format = format.replaceAll("\\.\\.", ".");\r
- format = format.replaceAll("--", "-");\r
-\r
- return format.trim();\r
- }\r
-\r
- @Override\r
- public void setWidth(String newWidth) {\r
- if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {\r
- if (BrowserInfo.get().isIE6()) {\r
- // in IE6 cols ~ min-width\r
- DOM.setElementProperty(text.getElement(), "size", "1");\r
- }\r
- needLayout = true;\r
- width = newWidth;\r
- super.setWidth(width);\r
- iLayout();\r
- if (newWidth.indexOf("%") < 0) {\r
- needLayout = false;\r
- }\r
- } else {\r
- if ("".equals(newWidth) && width != null && !"".equals(width)) {\r
- if (BrowserInfo.get().isIE6()) {\r
- // revert IE6 hack\r
- DOM.setElementProperty(text.getElement(), "size", "");\r
- }\r
- super.setWidth("");\r
- needLayout = true;\r
- iLayout();\r
- needLayout = false;\r
- width = null;\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Returns pixels in x-axis reserved for other than textfield content.\r
- * \r
- * @return extra width in pixels\r
- */\r
- protected int getFieldExtraWidth() {\r
- if (fieldExtraWidth < 0) {\r
- text.setWidth("0");\r
- fieldExtraWidth = text.getOffsetWidth();\r
- if (BrowserInfo.get().isFF3()) {\r
- // Firefox somehow always leaves the INPUT element 2px wide\r
- fieldExtraWidth -= 2;\r
- }\r
- }\r
- return fieldExtraWidth;\r
- }\r
-\r
- public void updateWidth() {\r
- needLayout = true;\r
- fieldExtraWidth = -1;\r
- iLayout();\r
- }\r
-\r
- public void iLayout() {\r
- if (needLayout) {\r
- text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");\r
- }\r
- }\r
-\r
- public void focus() {\r
- text.setFocus(true);\r
- }\r
-}\r
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.TextBox;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.ClientExceptionHandler;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.Focusable;
+import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
+import com.vaadin.terminal.gwt.client.LocaleService;
+import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VTextualDate extends VDateField implements Paintable, Field,
+ ChangeHandler, ContainerResizedListener, Focusable {
+
+ private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
+ + "-parseerror";
+
+ private final TextBox text;
+
+ private String formatStr;
+
+ private String width;
+
+ private boolean needLayout;
+
+ protected int fieldExtraWidth = -1;
+
+ private boolean lenient;
+
+ public VTextualDate() {
+
+ super();
+ text = new TextBox();
+ // use normal textfield styles as a basis
+ text.setStyleName(VTextField.CLASSNAME);
+ // add datefield spesific style name also
+ text.addStyleName(CLASSNAME + "-textfield");
+ text.addChangeHandler(this);
+ text.addFocusHandler(new FocusHandler() {
+ public void onFocus(FocusEvent event) {
+ text.addStyleName(VTextField.CLASSNAME + "-"
+ + VTextField.CLASSNAME_FOCUS);
+ }
+ });
+ text.addBlurHandler(new BlurHandler() {
+ public void onBlur(BlurEvent event) {
+ text.removeStyleName(VTextField.CLASSNAME + "-"
+ + VTextField.CLASSNAME_FOCUS);
+ }
+ });
+ add(text);
+ }
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ int origRes = currentResolution;
+ super.updateFromUIDL(uidl, client);
+ if (origRes != currentResolution) {
+ // force recreating format string
+ formatStr = null;
+ }
+ if (uidl.hasAttribute("format")) {
+ formatStr = uidl.getStringAttribute("format");
+ }
+
+ lenient = !uidl.getBooleanAttribute("strict");
+
+ buildDate();
+ // not a FocusWidget -> needs own tabindex handling
+ if (uidl.hasAttribute("tabindex")) {
+ text.setTabIndex(uidl.getIntAttribute("tabindex"));
+ }
+
+ if (readonly) {
+ text.addStyleDependentName("readonly");
+ } else {
+ text.removeStyleDependentName("readonly");
+ }
+ }
+
+ protected String getFormatString() {
+ if (formatStr == null) {
+ if (currentResolution == RESOLUTION_YEAR) {
+ formatStr = "yyyy"; // force full year
+ } else {
+
+ try {
+ String frmString = LocaleService
+ .getDateFormat(currentLocale);
+ frmString = cleanFormat(frmString);
+ String delim = LocaleService
+ .getClockDelimiter(currentLocale);
+
+ if (currentResolution >= RESOLUTION_HOUR) {
+ if (dts.isTwelveHourClock()) {
+ frmString += " hh";
+ } else {
+ frmString += " HH";
+ }
+ if (currentResolution >= RESOLUTION_MIN) {
+ frmString += ":mm";
+ if (currentResolution >= RESOLUTION_SEC) {
+ frmString += ":ss";
+ if (currentResolution >= RESOLUTION_MSEC) {
+ frmString += ".SSS";
+ }
+ }
+ }
+ if (dts.isTwelveHourClock()) {
+ frmString += " aaa";
+ }
+
+ }
+
+ formatStr = frmString;
+ } catch (LocaleNotLoadedException e) {
+ ClientExceptionHandler.displayError(e);
+ }
+ }
+ }
+ return formatStr;
+ }
+
+ /**
+ *
+ */
+ protected void buildDate() {
+ removeStyleName(PARSE_ERROR_CLASSNAME);
+ // Create the initial text for the textfield
+ String dateText;
+ if (date != null) {
+ dateText = DateTimeFormat.getFormat(getFormatString()).format(date);
+ } else {
+ dateText = "";
+ }
+
+ text.setText(dateText);
+ text.setEnabled(enabled);
+ text.setReadOnly(readonly);
+
+ if (readonly) {
+ text.addStyleName("v-readonly");
+ } else {
+ text.removeStyleName("v-readonly");
+ }
+
+ }
+
+ public void onChange(ChangeEvent event) {
+ if (!text.getText().equals("")) {
+ try {
+ DateTimeFormat format = DateTimeFormat
+ .getFormat(getFormatString());
+ if (lenient) {
+ date = format.parse(text.getText());
+ if (date != null) {
+ // if date value was leniently parsed, normalize text
+ // presentation
+ text.setValue(DateTimeFormat.getFormat(
+ getFormatString()).format(date), false);
+ }
+ } else {
+ date = format.parseStrict(text.getText());
+ }
+
+ long stamp = date.getTime();
+ if (stamp == 0) {
+ // If date parsing fails in firefox the stamp will be 0
+ date = null;
+ addStyleName(PARSE_ERROR_CLASSNAME);
+ } else {
+ // remove possibly added invalid value indication
+ removeStyleName(PARSE_ERROR_CLASSNAME);
+ }
+ } catch (final Exception e) {
+ ClientExceptionHandler.displayError(e.getMessage());
+
+ addStyleName(PARSE_ERROR_CLASSNAME);
+ // this is a hack that may eventually be removed
+ client.updateVariable(id, "lastInvalidDateString", text
+ .getText(), false);
+ date = null;
+ }
+ } else {
+ date = null;
+ // remove possibly added invalid value indication
+ removeStyleName(PARSE_ERROR_CLASSNAME);
+ }
+ // always send the date string
+ client.updateVariable(id, "dateString", text.getText(), false);
+
+ if (date != null) {
+ showingDate = new Date(date.getTime());
+ }
+
+ // Update variables
+ // (only the smallest defining resolution needs to be
+ // immediate)
+ client.updateVariable(id, "year", date != null ? date.getYear() + 1900
+ : -1, currentResolution == VDateField.RESOLUTION_YEAR
+ && immediate);
+ if (currentResolution >= VDateField.RESOLUTION_MONTH) {
+ client.updateVariable(id, "month",
+ date != null ? date.getMonth() + 1 : -1,
+ currentResolution == VDateField.RESOLUTION_MONTH
+ && immediate);
+ }
+ if (currentResolution >= VDateField.RESOLUTION_DAY) {
+ client
+ .updateVariable(id, "day", date != null ? date.getDate()
+ : -1,
+ currentResolution == VDateField.RESOLUTION_DAY
+ && immediate);
+ }
+ if (currentResolution >= VDateField.RESOLUTION_HOUR) {
+ client.updateVariable(id, "hour", date != null ? date.getHours()
+ : -1, currentResolution == VDateField.RESOLUTION_HOUR
+ && immediate);
+ }
+ if (currentResolution >= VDateField.RESOLUTION_MIN) {
+ client.updateVariable(id, "min", date != null ? date.getMinutes()
+ : -1, currentResolution == VDateField.RESOLUTION_MIN
+ && immediate);
+ }
+ if (currentResolution >= VDateField.RESOLUTION_SEC) {
+ client.updateVariable(id, "sec", date != null ? date.getSeconds()
+ : -1, currentResolution == VDateField.RESOLUTION_SEC
+ && immediate);
+ }
+ if (currentResolution == VDateField.RESOLUTION_MSEC) {
+ client.updateVariable(id, "msec", date != null ? getMilliseconds()
+ : -1, immediate);
+ }
+
+ }
+
+ private String cleanFormat(String format) {
+ // Remove unnecessary d & M if resolution is too low
+ if (currentResolution < VDateField.RESOLUTION_DAY) {
+ format = format.replaceAll("d", "");
+ }
+ if (currentResolution < VDateField.RESOLUTION_MONTH) {
+ format = format.replaceAll("M", "");
+ }
+
+ // Remove unsupported patterns
+ // TODO support for 'G', era designator (used at least in Japan)
+ 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 void setWidth(String newWidth) {
+ if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {
+ if (BrowserInfo.get().isIE6()) {
+ // in IE6 cols ~ min-width
+ DOM.setElementProperty(text.getElement(), "size", "1");
+ }
+ needLayout = true;
+ width = newWidth;
+ super.setWidth(width);
+ iLayout();
+ if (newWidth.indexOf("%") < 0) {
+ needLayout = false;
+ }
+ } else {
+ if ("".equals(newWidth) && width != null && !"".equals(width)) {
+ if (BrowserInfo.get().isIE6()) {
+ // revert IE6 hack
+ DOM.setElementProperty(text.getElement(), "size", "");
+ }
+ super.setWidth("");
+ needLayout = true;
+ iLayout();
+ needLayout = false;
+ width = null;
+ }
+ }
+ }
+
+ /**
+ * Returns pixels in x-axis reserved for other than textfield content.
+ *
+ * @return extra width in pixels
+ */
+ protected int getFieldExtraWidth() {
+ if (fieldExtraWidth < 0) {
+ text.setWidth("0");
+ fieldExtraWidth = text.getOffsetWidth();
+ if (BrowserInfo.get().isFF3()) {
+ // Firefox somehow always leaves the INPUT element 2px wide
+ fieldExtraWidth -= 2;
+ }
+ }
+ return fieldExtraWidth;
+ }
+
+ public void updateWidth() {
+ needLayout = true;
+ fieldExtraWidth = -1;
+ iLayout();
+ }
+
+ public void iLayout() {
+ if (needLayout) {
+ text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");
+ }
+ }
+
+ public void focus() {
+ text.setFocus(true);
+ }
+}