summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2012-02-07 10:49:54 +0200
committerHenri Sara <hesara@vaadin.com>2012-02-07 10:49:54 +0200
commitfc8d7eeaa573957d9a4c80caa1d4d21948e7057e (patch)
treee8f8bdb4d50d8a2b0d79259486deedb605b13c80 /src
parentdc0268c218c9de44df30f816d541de279e529ef4 (diff)
parentb77b4e6a2ed7253a48eb21fb5ac734f1c11fb6ff (diff)
downloadvaadin-framework-fc8d7eeaa573957d9a4c80caa1d4d21948e7057e.tar.gz
vaadin-framework-fc8d7eeaa573957d9a4c80caa1d4d21948e7057e.zip
Merge branch 'master' into rpc
Conflicts: src/com/vaadin/terminal/gwt/client/ApplicationConnection.java src/com/vaadin/terminal/gwt/client/VPaintableMap.java
Diffstat (limited to 'src')
-rw-r--r--src/com/google/gwt/dom/client/VaadinDOMImplSafari.java52
-rw-r--r--src/com/vaadin/data/fieldgroup/BeanFieldGroup.java312
-rw-r--r--src/com/vaadin/data/fieldgroup/Caption.java30
-rw-r--r--src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java312
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroup.java1954
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java62
-rw-r--r--src/com/vaadin/data/fieldgroup/PropertyId.java30
-rw-r--r--src/com/vaadin/data/util/TextFileProperty.java282
-rw-r--r--src/com/vaadin/data/util/TransactionalPropertyWrapper.java214
-rw-r--r--src/com/vaadin/data/util/converter/Converter.java318
-rw-r--r--src/com/vaadin/data/util/converter/ConverterFactory.java46
-rw-r--r--src/com/vaadin/data/util/converter/DateToLongConverter.java136
-rw-r--r--src/com/vaadin/data/util/converter/DefaultConverterFactory.java200
-rw-r--r--src/com/vaadin/data/util/converter/ReverseConverter.java160
-rw-r--r--src/com/vaadin/data/util/converter/StringToBooleanConverter.java208
-rw-r--r--src/com/vaadin/data/util/converter/StringToDateConverter.java216
-rw-r--r--src/com/vaadin/data/util/converter/StringToDoubleConverter.java206
-rw-r--r--src/com/vaadin/data/util/converter/StringToIntegerConverter.java168
-rw-r--r--src/com/vaadin/data/util/converter/StringToNumberConverter.java214
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java184
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheMap.java60
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/Reference.java112
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/RowId.java162
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java330
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java114
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java270
-rw-r--r--src/com/vaadin/data/validator/BeanValidator.java344
-rw-r--r--src/com/vaadin/data/validator/DateRangeValidator.java102
-rw-r--r--src/com/vaadin/data/validator/RangeValidator.java372
-rw-r--r--src/com/vaadin/event/FieldEvents.java500
-rw-r--r--src/com/vaadin/external/json/JSONException.java56
-rw-r--r--src/com/vaadin/external/json/JSONString.java42
-rw-r--r--src/com/vaadin/external/json/JSONStringer.java156
-rw-r--r--src/com/vaadin/external/json/JSONWriter.java710
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java12
-rw-r--r--src/com/vaadin/terminal/gwt/client/DateTimeService.java878
-rw-r--r--src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java26
-rw-r--r--src/com/vaadin/terminal/gwt/client/LocaleService.java296
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java14
-rw-r--r--src/com/vaadin/terminal/gwt/client/VBrowserDetails.java712
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintable.java154
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableMap.java808
-rw-r--r--src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java254
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java198
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/TreeImages.java58
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java171
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java206
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java34
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java3
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java283
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java139
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java77
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java3467
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java195
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java125
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java161
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java177
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java174
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java3
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java145
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VForm.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java81
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java349
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java389
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java37
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java29
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java104
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java221
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java322
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNotification.java834
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java511
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPanel.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java353
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java42
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java756
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupView.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java211
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java139
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java514
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSlider.java1030
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java159
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java195
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java167
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java428
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextArea.java126
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java459
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java46
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java202
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java37
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java27
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java79
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VView.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java669
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VWindow.java14
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java595
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java142
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java165
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java155
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java350
-rw-r--r--src/com/vaadin/ui/AbstractOrderedLayout.java8
-rw-r--r--src/com/vaadin/ui/ComboBox.java260
-rw-r--r--src/com/vaadin/ui/InlineDateField.java96
-rw-r--r--src/com/vaadin/ui/PopupDateField.java160
116 files changed, 14067 insertions, 13947 deletions
diff --git a/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java b/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
index 3975bf73d8..6e9cc81f43 100644
--- a/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
+++ b/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
@@ -1,26 +1,26 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.google.gwt.dom.client;
-
-/**
- * Overridden to workaround GWT issue #6194. Remove this when updating to a
- * newer GWT that fixes the problem (2.3.0 possibly). Must be in this package as
- * the whole DOMImpl hierarchy is package private and I really did not want to
- * copy all the parent classes into this one...
- */
-class VaadinDOMImplSafari extends DOMImplSafari {
- @Override
- public int getAbsoluteLeft(Element elem) {
- // Chrome returns a float in certain cases (at least when zoom != 100%).
- // The |0 ensures it is converted to an int.
- return super.getAbsoluteLeft(elem) | 0;
- }
-
- @Override
- public int getAbsoluteTop(Element elem) {
- // Chrome returns a float in certain cases (at least when zoom != 100%).
- // The |0 ensures it is converted to an int.
- return super.getAbsoluteTop(elem) | 0;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.google.gwt.dom.client;
+
+/**
+ * Overridden to workaround GWT issue #6194. Remove this when updating to a
+ * newer GWT that fixes the problem (2.3.0 possibly). Must be in this package as
+ * the whole DOMImpl hierarchy is package private and I really did not want to
+ * copy all the parent classes into this one...
+ */
+class VaadinDOMImplSafari extends DOMImplSafari {
+ @Override
+ public int getAbsoluteLeft(Element elem) {
+ // Chrome returns a float in certain cases (at least when zoom != 100%).
+ // The |0 ensures it is converted to an int.
+ return super.getAbsoluteLeft(elem) | 0;
+ }
+
+ @Override
+ public int getAbsoluteTop(Element elem) {
+ // Chrome returns a float in certain cases (at least when zoom != 100%).
+ // The |0 ensures it is converted to an int.
+ return super.getAbsoluteTop(elem) | 0;
+ }
+}
diff --git a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 8ca6c95069..2584a4770b 100644
--- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -1,157 +1,157 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.reflect.Method;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.util.BeanItem;
-import com.vaadin.data.validator.BeanValidator;
-import com.vaadin.ui.Field;
-
-public class BeanFieldGroup<T> extends FieldGroup {
-
- private Class<T> beanType;
-
- private static Boolean beanValidationImplementationAvailable = null;
-
- public BeanFieldGroup(Class<T> beanType) {
- this.beanType = beanType;
- }
-
- @Override
- protected Class<?> getPropertyType(Object propertyId) {
- if (getItemDataSource() != null) {
- return super.getPropertyType(propertyId);
- } else {
- // Data source not set so we need to figure out the type manually
- /*
- * toString should never really be needed as propertyId should be of
- * form "fieldName" or "fieldName.subField[.subField2]" but the
- * method declaration comes from parent.
- */
- java.lang.reflect.Field f;
- try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
- }
- }
- }
-
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldError e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
- /**
- * Helper method for setting the data source directly using a bean. This
- * method wraps the bean in a {@link BeanItem} and calls
- * {@link #setItemDataSource(Item)}.
- *
- * @param bean
- * The bean to use as data source.
- */
- public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
- }
-
- @Override
- public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
- throw new RuntimeException(getClass().getSimpleName()
- + " only supports BeanItems as item data source");
- }
- super.setItemDataSource(item);
- }
-
- @Override
- public BeanItem<T> getItemDataSource() {
- return (BeanItem<T>) super.getItemDataSource();
- }
-
- @Override
- public void bind(Field field, Object propertyId) {
- if (getItemDataSource() != null) {
- // The data source is set so the property must be found in the item.
- // If it is not we try to add it.
- try {
- getItemProperty(propertyId);
- } catch (BindException e) {
- // Not found, try to add a nested property;
- // BeanItem property ids are always strings so this is safe
- getItemDataSource().addNestedProperty((String) propertyId);
- }
- }
-
- super.bind(field, propertyId);
- }
-
- @Override
- protected void configureField(Field<?> field) {
- super.configureField(field);
- // Add Bean validators if there are annotations
- if (isBeanValidationImplementationAvailable()) {
- BeanValidator validator = new BeanValidator(
- beanType, getPropertyId(field).toString());
- field.addValidator(validator);
- if (field.getLocale() != null) {
- validator.setLocale(field.getLocale());
- }
- }
- }
-
- /**
- * Checks whether a bean validation implementation (e.g. Hibernate Validator
- * or Apache Bean Validation) is available.
- *
- * TODO move this method to some more generic location
- *
- * @return true if a JSR-303 bean validation implementation is available
- */
- protected static boolean isBeanValidationImplementationAvailable() {
- if (beanValidationImplementationAvailable != null) {
- return beanValidationImplementationAvailable;
- }
- try {
- Class<?> validationClass = Class
- .forName("javax.validation.Validation");
- Method buildFactoryMethod = validationClass
- .getMethod("buildDefaultValidatorFactory");
- Object factory = buildFactoryMethod.invoke(null);
- beanValidationImplementationAvailable = (factory != null);
- } catch (Exception e) {
- // no bean validation implementation available
- beanValidationImplementationAvailable = false;
- }
- return beanValidationImplementationAvailable;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.ui.Field;
+
+public class BeanFieldGroup<T> extends FieldGroup {
+
+ private Class<T> beanType;
+
+ private static Boolean beanValidationImplementationAvailable = null;
+
+ public BeanFieldGroup(Class<T> beanType) {
+ this.beanType = beanType;
+ }
+
+ @Override
+ protected Class<?> getPropertyType(Object propertyId) {
+ if (getItemDataSource() != null) {
+ return super.getPropertyType(propertyId);
+ } else {
+ // Data source not set so we need to figure out the type manually
+ /*
+ * toString should never really be needed as propertyId should be of
+ * form "fieldName" or "fieldName.subField[.subField2]" but the
+ * method declaration comes from parent.
+ */
+ java.lang.reflect.Field f;
+ try {
+ f = getField(beanType, propertyId.toString());
+ return f.getType();
+ } catch (SecurityException e) {
+ throw new BindException("Cannot determine type of propertyId '"
+ + propertyId + "'.", e);
+ } catch (NoSuchFieldException e) {
+ throw new BindException("Cannot determine type of propertyId '"
+ + propertyId + "'. The propertyId was not found in "
+ + beanType.getName(), e);
+ }
+ }
+ }
+
+ private static java.lang.reflect.Field getField(Class<?> cls,
+ String propertyId) throws SecurityException, NoSuchFieldException {
+ if (propertyId.contains(".")) {
+ String[] parts = propertyId.split("\\.", 2);
+ // Get the type of the field in the "cls" class
+ java.lang.reflect.Field field1 = getField(cls, parts[0]);
+ // Find the rest from the sub type
+ return getField(field1.getType(), parts[1]);
+ } else {
+ try {
+ // Try to find the field directly in the given class
+ java.lang.reflect.Field field1 = cls
+ .getDeclaredField(propertyId);
+ return field1;
+ } catch (NoSuchFieldError e) {
+ // Try super classes until we reach Object
+ Class<?> superClass = cls.getSuperclass();
+ if (superClass != Object.class) {
+ return getField(superClass, propertyId);
+ } else {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method for setting the data source directly using a bean. This
+ * method wraps the bean in a {@link BeanItem} and calls
+ * {@link #setItemDataSource(Item)}.
+ *
+ * @param bean
+ * The bean to use as data source.
+ */
+ public void setItemDataSource(T bean) {
+ setItemDataSource(new BeanItem(bean));
+ }
+
+ @Override
+ public void setItemDataSource(Item item) {
+ if (!(item instanceof BeanItem)) {
+ throw new RuntimeException(getClass().getSimpleName()
+ + " only supports BeanItems as item data source");
+ }
+ super.setItemDataSource(item);
+ }
+
+ @Override
+ public BeanItem<T> getItemDataSource() {
+ return (BeanItem<T>) super.getItemDataSource();
+ }
+
+ @Override
+ public void bind(Field field, Object propertyId) {
+ if (getItemDataSource() != null) {
+ // The data source is set so the property must be found in the item.
+ // If it is not we try to add it.
+ try {
+ getItemProperty(propertyId);
+ } catch (BindException e) {
+ // Not found, try to add a nested property;
+ // BeanItem property ids are always strings so this is safe
+ getItemDataSource().addNestedProperty((String) propertyId);
+ }
+ }
+
+ super.bind(field, propertyId);
+ }
+
+ @Override
+ protected void configureField(Field<?> field) {
+ super.configureField(field);
+ // Add Bean validators if there are annotations
+ if (isBeanValidationImplementationAvailable()) {
+ BeanValidator validator = new BeanValidator(
+ beanType, getPropertyId(field).toString());
+ field.addValidator(validator);
+ if (field.getLocale() != null) {
+ validator.setLocale(field.getLocale());
+ }
+ }
+ }
+
+ /**
+ * Checks whether a bean validation implementation (e.g. Hibernate Validator
+ * or Apache Bean Validation) is available.
+ *
+ * TODO move this method to some more generic location
+ *
+ * @return true if a JSR-303 bean validation implementation is available
+ */
+ protected static boolean isBeanValidationImplementationAvailable() {
+ if (beanValidationImplementationAvailable != null) {
+ return beanValidationImplementationAvailable;
+ }
+ try {
+ Class<?> validationClass = Class
+ .forName("javax.validation.Validation");
+ Method buildFactoryMethod = validationClass
+ .getMethod("buildDefaultValidatorFactory");
+ Object factory = buildFactoryMethod.invoke(null);
+ beanValidationImplementationAvailable = (factory != null);
+ } catch (Exception e) {
+ // no bean validation implementation available
+ beanValidationImplementationAvailable = false;
+ }
+ return beanValidationImplementationAvailable;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/Caption.java b/src/com/vaadin/data/fieldgroup/Caption.java
index e9ae01a2d2..b990b720cd 100644
--- a/src/com/vaadin/data/fieldgroup/Caption.java
+++ b/src/com/vaadin/data/fieldgroup/Caption.java
@@ -1,15 +1,15 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Caption {
- String value();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Caption {
+ String value();
+}
diff --git a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
index 2fc7bc6b7e..569f643998 100644
--- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
@@ -1,156 +1,156 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.util.EnumSet;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.fieldgroup.FieldGroup.BindException;
-import com.vaadin.ui.AbstractSelect;
-import com.vaadin.ui.AbstractTextField;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.OptionGroup;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.TextField;
-
-public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
-
- public static final Object CAPTION_PROPERTY_ID = "Caption";
-
- public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
- if (Enum.class.isAssignableFrom(type)) {
- return createEnumField(type, fieldType);
- } else if (Boolean.class.isAssignableFrom(type)
- || boolean.class.isAssignableFrom(type)) {
- return createBooleanField(fieldType);
- }
- if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return fieldType.cast(createAbstractTextField(fieldType
- .asSubclass(AbstractTextField.class)));
- } else if (fieldType == RichTextArea.class) {
- return fieldType.cast(createRichTextArea());
- }
- return createDefaultField(type, fieldType);
- }
-
- protected RichTextArea createRichTextArea() {
- RichTextArea rta = new RichTextArea();
- rta.setImmediate(true);
-
- return rta;
- }
-
- private <T extends Field> T createEnumField(Class<?> type,
- Class<T> fieldType) {
- if (AbstractSelect.class.isAssignableFrom(fieldType)) {
- AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
- populateWithEnumData(s, (Class<? extends Enum>) type);
- return (T) s;
- }
-
- return null;
- }
-
- protected AbstractSelect createCompatibleSelect(
- Class<? extends AbstractSelect> fieldType) {
- AbstractSelect select;
- if (fieldType.isAssignableFrom(ListSelect.class)) {
- select = new ListSelect();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
- select = new NativeSelect();
- } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
- select = new OptionGroup();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(Table.class)) {
- Table t = new Table();
- t.setSelectable(true);
- select = t;
- } else {
- select = new ComboBox(null);
- }
- select.setImmediate(true);
- select.setNullSelectionAllowed(false);
-
- return select;
- }
-
- protected <T extends Field> T createBooleanField(Class<T> fieldType) {
- if (fieldType.isAssignableFrom(CheckBox.class)) {
- CheckBox cb = new CheckBox(null);
- cb.setImmediate(true);
- return (T) cb;
- } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
- }
-
- return null;
- }
-
- protected <T extends AbstractTextField> T createAbstractTextField(
- Class<T> fieldType) {
- if (fieldType == AbstractTextField.class) {
- fieldType = (Class<T>) TextField.class;
- }
- try {
- T field = fieldType.newInstance();
- field.setImmediate(true);
- return field;
- } catch (Exception e) {
- throw new BindException("Could not create a field of type "
- + fieldType, e);
- }
- }
-
- /**
- * Fallback when no specific field has been created. Typically returns a
- * TextField.
- *
- * @param <T>
- * The type of field to create
- * @param type
- * The type of data that should be edited
- * @param fieldType
- * The type of field to create
- * @return A field capable of editing the data or null if no field could be
- * created
- */
- protected <T extends Field> T createDefaultField(Class<?> type,
- Class<T> fieldType) {
- if (fieldType.isAssignableFrom(TextField.class)) {
- return fieldType.cast(createAbstractTextField(TextField.class));
- }
- return null;
- }
-
- /**
- * Populates the given select with all the enums in the given {@link Enum}
- * class. Uses {@link Enum}.toString() for caption.
- *
- * @param select
- * The select to populate
- * @param enumClass
- * The Enum class to use
- */
- protected void populateWithEnumData(AbstractSelect select,
- Class<? extends Enum> enumClass) {
- select.removeAllItems();
- for (Object p : select.getContainerPropertyIds()) {
- select.removeContainerProperty(p);
- }
- select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
- select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
- @SuppressWarnings("unchecked")
- EnumSet<?> enumSet = EnumSet.allOf(enumClass);
- for (Object r : enumSet) {
- Item newItem = select.addItem(r);
- newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.util.EnumSet;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.fieldgroup.FieldGroup.BindException;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.AbstractTextField;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.RichTextArea;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextField;
+
+public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
+
+ public static final Object CAPTION_PROPERTY_ID = "Caption";
+
+ public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
+ if (Enum.class.isAssignableFrom(type)) {
+ return createEnumField(type, fieldType);
+ } else if (Boolean.class.isAssignableFrom(type)
+ || boolean.class.isAssignableFrom(type)) {
+ return createBooleanField(fieldType);
+ }
+ if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return fieldType.cast(createAbstractTextField(fieldType
+ .asSubclass(AbstractTextField.class)));
+ } else if (fieldType == RichTextArea.class) {
+ return fieldType.cast(createRichTextArea());
+ }
+ return createDefaultField(type, fieldType);
+ }
+
+ protected RichTextArea createRichTextArea() {
+ RichTextArea rta = new RichTextArea();
+ rta.setImmediate(true);
+
+ return rta;
+ }
+
+ private <T extends Field> T createEnumField(Class<?> type,
+ Class<T> fieldType) {
+ if (AbstractSelect.class.isAssignableFrom(fieldType)) {
+ AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
+ populateWithEnumData(s, (Class<? extends Enum>) type);
+ return (T) s;
+ }
+
+ return null;
+ }
+
+ protected AbstractSelect createCompatibleSelect(
+ Class<? extends AbstractSelect> fieldType) {
+ AbstractSelect select;
+ if (fieldType.isAssignableFrom(ListSelect.class)) {
+ select = new ListSelect();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
+ select = new NativeSelect();
+ } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
+ select = new OptionGroup();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(Table.class)) {
+ Table t = new Table();
+ t.setSelectable(true);
+ select = t;
+ } else {
+ select = new ComboBox(null);
+ }
+ select.setImmediate(true);
+ select.setNullSelectionAllowed(false);
+
+ return select;
+ }
+
+ protected <T extends Field> T createBooleanField(Class<T> fieldType) {
+ if (fieldType.isAssignableFrom(CheckBox.class)) {
+ CheckBox cb = new CheckBox(null);
+ cb.setImmediate(true);
+ return (T) cb;
+ } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
+ }
+
+ return null;
+ }
+
+ protected <T extends AbstractTextField> T createAbstractTextField(
+ Class<T> fieldType) {
+ if (fieldType == AbstractTextField.class) {
+ fieldType = (Class<T>) TextField.class;
+ }
+ try {
+ T field = fieldType.newInstance();
+ field.setImmediate(true);
+ return field;
+ } catch (Exception e) {
+ throw new BindException("Could not create a field of type "
+ + fieldType, e);
+ }
+ }
+
+ /**
+ * Fallback when no specific field has been created. Typically returns a
+ * TextField.
+ *
+ * @param <T>
+ * The type of field to create
+ * @param type
+ * The type of data that should be edited
+ * @param fieldType
+ * The type of field to create
+ * @return A field capable of editing the data or null if no field could be
+ * created
+ */
+ protected <T extends Field> T createDefaultField(Class<?> type,
+ Class<T> fieldType) {
+ if (fieldType.isAssignableFrom(TextField.class)) {
+ return fieldType.cast(createAbstractTextField(TextField.class));
+ }
+ return null;
+ }
+
+ /**
+ * Populates the given select with all the enums in the given {@link Enum}
+ * class. Uses {@link Enum}.toString() for caption.
+ *
+ * @param select
+ * The select to populate
+ * @param enumClass
+ * The Enum class to use
+ */
+ protected void populateWithEnumData(AbstractSelect select,
+ Class<? extends Enum> enumClass) {
+ select.removeAllItems();
+ for (Object p : select.getContainerPropertyIds()) {
+ select.removeContainerProperty(p);
+ }
+ select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
+ select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
+ @SuppressWarnings("unchecked")
+ EnumSet<?> enumSet = EnumSet.allOf(enumClass);
+ for (Object r : enumSet) {
+ Item newItem = select.addItem(r);
+ newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
+ }
+ }
+}
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroup.java b/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 381f4fef3f..3df19f5bc9 100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -1,978 +1,978 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.TransactionalPropertyWrapper;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.DefaultFieldFactory;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Form;
-
-/**
- * FieldGroup provides an easy way of binding fields to data and handling
- * commits of these fields.
- * <p>
- * The functionality of FieldGroup is similar to {@link Form} but
- * {@link FieldGroup} does not handle layouts in any way. The typical use case
- * is to create a layout outside the FieldGroup and then use FieldGroup to bind
- * the fields to a data source.
- * </p>
- * <p>
- * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
- * Using the buildAndBind methods {@link FieldGroup} can create fields for you
- * using a FieldGroupFieldFactory but you still have to add them to the correct
- * position in your layout.
- * </p>
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- */
-public class FieldGroup implements Serializable {
-
- private static final Logger logger = Logger.getLogger(FieldGroup.class
- .getName());
-
- private Item itemDataSource;
- private boolean buffered = true;
-
- private boolean enabled = true;
- private boolean readOnly = false;
-
- private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
- private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
- private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
-
- /**
- * The field factory used by builder methods.
- */
- private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
-
- /**
- * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
- * data source for the field binder.
- *
- */
- public FieldGroup() {
-
- }
-
- /**
- * Constructs a field binder that uses the given data source.
- *
- * @param itemDataSource
- * The data source to bind the fields to
- */
- public FieldGroup(Item itemDataSource) {
- setItemDataSource(itemDataSource);
- }
-
- /**
- * Updates the item that is used by this FieldBinder. Rebinds all fields to
- * the properties in the new item.
- *
- * @param itemDataSource
- * The new item to use
- */
- public void setItemDataSource(Item itemDataSource) {
- this.itemDataSource = itemDataSource;
-
- for (Field<?> f : fieldToPropertyId.keySet()) {
- bind(f, fieldToPropertyId.get(f));
- }
- }
-
- /**
- * Gets the item used by this FieldBinder. Note that you must call
- * {@link #commit()} for the item to be updated unless buffered mode has
- * been switched off.
- *
- * @see #setBuffered(boolean)
- * @see #commit()
- *
- * @return The item used by this FieldBinder
- */
- public Item getItemDataSource() {
- return itemDataSource;
- }
-
- /**
- * Checks the buffered mode for the bound fields.
- * <p>
- *
- * @see #setBuffered(boolean) for more details on buffered mode
- *
- * @see Field#isBuffered()
- * @return true if buffered mode is on, false otherwise
- *
- */
- public boolean isBuffered() {
- return buffered;
- }
-
- /**
- * Sets the buffered mode for the bound fields.
- * <p>
- * When buffered mode is on the item will not be updated until
- * {@link #commit()} is called. If buffered mode is off the item will be
- * updated once the fields are updated.
- * </p>
- * <p>
- * The default is to use buffered mode.
- * </p>
- *
- * @see Field#setBuffered(boolean)
- * @param buffered
- * true to turn on buffered mode, false otherwise
- */
- public void setBuffered(boolean buffered) {
- if (buffered == this.buffered) {
- return;
- }
-
- this.buffered = buffered;
- for (Field<?> field : getFields()) {
- field.setBuffered(buffered);
- }
- }
-
- /**
- * Returns the enabled status for the fields.
- * <p>
- * Note that this will not accurately represent the enabled status of all
- * fields if you change the enabled status of the fields through some other
- * method than {@link #setEnabled(boolean)}.
- *
- * @return true if the fields are enabled, false otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Updates the enabled state of all bound fields.
- *
- * @param fieldsEnabled
- * true to enable all bound fields, false to disable them
- */
- public void setEnabled(boolean fieldsEnabled) {
- enabled = fieldsEnabled;
- for (Field<?> field : getFields()) {
- field.setEnabled(fieldsEnabled);
- }
- }
-
- /**
- * Returns the read only status for the fields.
- * <p>
- * Note that this will not accurately represent the read only status of all
- * fields if you change the read only status of the fields through some
- * other method than {@link #setReadOnly(boolean)}.
- *
- * @return true if the fields are set to read only, false otherwise
- */
- public boolean isReadOnly() {
- return readOnly;
- }
-
- /**
- * Updates the read only state of all bound fields.
- *
- * @param fieldsReadOnly
- * true to set all bound fields to read only, false to set them
- * to read write
- */
- public void setReadOnly(boolean fieldsReadOnly) {
- readOnly = fieldsReadOnly;
- }
-
- /**
- * Returns a collection of all fields that have been bound.
- * <p>
- * The fields are not returned in any specific order.
- * </p>
- *
- * @return A collection with all bound Fields
- */
- public Collection<Field<?>> getFields() {
- return fieldToPropertyId.keySet();
- }
-
- /**
- * Binds the field with the given propertyId from the current item. If an
- * item has not been set then the binding is postponed until the item is set
- * using {@link #setItemDataSource(Item)}.
- * <p>
- * This method also adds validators when applicable.
- * </p>
- *
- * @param field
- * The field to bind
- * @param propertyId
- * The propertyId to bind to the field
- * @throws BindException
- * If the property id is already bound to another field by this
- * field binder
- */
- public void bind(Field<?> field, Object propertyId) throws BindException {
- if (propertyIdToField.containsKey(propertyId)
- && propertyIdToField.get(propertyId) != field) {
- throw new BindException("Property id " + propertyId
- + " is already bound to another field");
- }
- fieldToPropertyId.put(field, propertyId);
- propertyIdToField.put(propertyId, field);
- if (itemDataSource == null) {
- // Will be bound when data source is set
- return;
- }
-
- field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
- configureField(field);
- }
-
- private <T> Property.Transactional<T> wrapInTransactionalProperty(
- Property<T> itemProperty) {
- return new TransactionalPropertyWrapper<T>(itemProperty);
- }
-
- /**
- * Gets the property with the given property id from the item.
- *
- * @param propertyId
- * The id if the property to find
- * @return The property with the given id from the item
- * @throws BindException
- * If the property was not found in the item or no item has been
- * set
- */
- protected Property<?> getItemProperty(Object propertyId)
- throws BindException {
- Item item = getItemDataSource();
- if (item == null) {
- throw new BindException("Could not lookup property with id "
- + propertyId + " as no item has been set");
- }
- Property<?> p = item.getItemProperty(propertyId);
- if (p == null) {
- throw new BindException("A property with id " + propertyId
- + " was not found in the item");
- }
- return p;
- }
-
- /**
- * Detaches the field from its property id and removes it from this
- * FieldBinder.
- * <p>
- * Note that the field is not detached from its property data source if it
- * is no longer connected to the same property id it was bound to using this
- * FieldBinder.
- *
- * @param field
- * The field to detach
- * @throws BindException
- * If the field is not bound by this field binder or not bound
- * to the correct property id
- */
- public void unbind(Field<?> field) throws BindException {
- Object propertyId = fieldToPropertyId.get(field);
- if (propertyId == null) {
- throw new BindException(
- "The given field is not part of this FieldBinder");
- }
-
- Property fieldDataSource = field.getPropertyDataSource();
- if (fieldDataSource instanceof TransactionalPropertyWrapper) {
- fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
- .getWrappedProperty();
- }
- if (fieldDataSource == getItemProperty(propertyId)) {
- field.setPropertyDataSource(null);
- }
- fieldToPropertyId.remove(field);
- propertyIdToField.remove(propertyId);
- }
-
- /**
- * Configures a field with the settings set for this FieldBinder.
- * <p>
- * By default this updates the buffered, read only and enabled state of the
- * field. Also adds validators when applicable.
- *
- * @param field
- * The field to update
- */
- protected void configureField(Field<?> field) {
- field.setBuffered(isBuffered());
-
- field.setEnabled(isEnabled());
- field.setReadOnly(isReadOnly());
- }
-
- /**
- * Gets the type of the property with the given property id.
- *
- * @param propertyId
- * The propertyId. Must be find
- * @return The type of the property
- */
- protected Class<?> getPropertyType(Object propertyId) throws BindException {
- if (getItemDataSource() == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No item data source has been set.");
- }
- Property<?> p = getItemDataSource().getItemProperty(propertyId);
- if (p == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No property with that id was found.");
- }
-
- return p.getType();
- }
-
- /**
- * Returns a collection of all property ids that have been bound to fields.
- * <p>
- * Note that this will return property ids even before the item has been
- * set. In that case it returns the property ids that will be bound once the
- * item is set.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of bound property ids
- */
- public Collection<Object> getBoundPropertyIds() {
- return Collections.unmodifiableCollection(propertyIdToField.keySet());
- }
-
- /**
- * Returns a collection of all property ids that exist in the item set using
- * {@link #setItemDataSource(Item)} but have not been bound to fields.
- * <p>
- * Will always return an empty collection before an item has been set using
- * {@link #setItemDataSource(Item)}.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of property ids that have not been bound to fields
- */
- public Collection<Object> getUnboundPropertyIds() {
- if (getItemDataSource() == null) {
- return new ArrayList<Object>();
- }
- List<Object> unboundPropertyIds = new ArrayList<Object>();
- unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
- unboundPropertyIds.removeAll(propertyIdToField.keySet());
- return unboundPropertyIds;
- }
-
- /**
- * Commits all changes done to the bound fields.
- * <p>
- * Calls all {@link CommitHandler}s before and after committing the field
- * changes to the item data source. The whole commit is aborted and state is
- * restored to what it was before commit was called if any
- * {@link CommitHandler} throws a CommitException or there is a problem
- * committing the fields
- *
- * @throws CommitException
- * If the commit was aborted
- */
- public void commit() throws CommitException {
- if (!isBuffered()) {
- // Not using buffered mode, nothing to do
- return;
- }
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .startTransaction();
- }
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
-
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
-
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
- }
-
- throw new CommitException("Commit failed", e);
- }
-
- }
-
- /**
- * Sends a preCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePreCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.preCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Sends a postCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePostCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.postCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Discards all changes done to the bound fields.
- * <p>
- * Only has effect if buffered mode is used.
- *
- */
- public void discard() {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- f.discard();
- } catch (Exception e) {
- // TODO: handle exception
- // What can we do if discard fails other than try to discard all
- // other fields?
- }
- }
- }
-
- /**
- * Returns the field that is bound to the given property id
- *
- * @param propertyId
- * The property id to use to lookup the field
- * @return The field that is bound to the property id or null if no field is
- * bound to that property id
- */
- public Field<?> getField(Object propertyId) {
- return propertyIdToField.get(propertyId);
- }
-
- /**
- * Returns the property id that is bound to the given field
- *
- * @param field
- * The field to use to lookup the property id
- * @return The property id that is bound to the field or null if the field
- * is not bound to any property id by this FieldBinder
- */
- public Object getPropertyId(Field<?> field) {
- return fieldToPropertyId.get(field);
- }
-
- /**
- * Adds a commit handler.
- * <p>
- * The commit handler is called before the field values are committed to the
- * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
- * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
- * {@link CommitHandler} throws a CommitException the whole commit is
- * aborted and the fields retain their old values.
- *
- * @param commitHandler
- * The commit handler to add
- */
- public void addCommitHandler(CommitHandler commitHandler) {
- commitHandlers.add(commitHandler);
- }
-
- /**
- * Removes the given commit handler.
- *
- * @see #addCommitHandler(CommitHandler)
- *
- * @param commitHandler
- * The commit handler to remove
- */
- public void removeCommitHandler(CommitHandler commitHandler) {
- commitHandlers.remove(commitHandler);
- }
-
- /**
- * Returns a list of all commit handlers for this {@link FieldGroup}.
- * <p>
- * Use {@link #addCommitHandler(CommitHandler)} and
- * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
- * commit handler.
- *
- * @return A collection of commit handlers
- */
- protected Collection<CommitHandler> getCommitHandlers() {
- return Collections.unmodifiableCollection(commitHandlers);
- }
-
- /**
- * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
- * commit transactions. CommitHandlers can perform custom operations as part
- * of the commit and cause the commit to be aborted by throwing a
- * {@link CommitException}.
- */
- public interface CommitHandler extends Serializable {
- /**
- * Called before changes are committed to the field and the item is
- * updated.
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void preCommit(CommitEvent commitEvent) throws CommitException;
-
- /**
- * Called after changes are committed to the fields and the item is
- * updated..
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void postCommit(CommitEvent commitEvent) throws CommitException;
- }
-
- /**
- * FIXME javadoc
- *
- */
- public static class CommitEvent implements Serializable {
- private FieldGroup fieldBinder;
-
- private CommitEvent(FieldGroup fieldBinder) {
- this.fieldBinder = fieldBinder;
- }
-
- /**
- * Returns the field binder that this commit relates to
- *
- * @return The FieldBinder that is being committed.
- */
- public FieldGroup getFieldBinder() {
- return fieldBinder;
- }
-
- }
-
- /**
- * Checks the validity of the bound fields.
- * <p>
- * Call the {@link Field#validate()} for the fields to get the individual
- * error messages.
- *
- * @return true if all bound fields are valid, false otherwise.
- */
- public boolean isValid() {
- try {
- for (Field<?> field : getFields()) {
- field.validate();
- }
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks if any bound field has been modified.
- *
- * @return true if at least on field has been modified, false otherwise
- */
- public boolean isModified() {
- for (Field<?> field : getFields()) {
- if (field.isModified()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @return The field factory in use
- *
- */
- public FieldGroupFieldFactory getFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Sets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @param fieldFactory
- * The field factory to use
- */
- public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
- }
-
- /**
- * Binds member fields found in the given object.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age = new TextField("Age"); ... }
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.bindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and the age TextField to a "age"
- * property.
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to bind
- * @throws BindException
- * If there is a problem binding a field
- */
- public void bindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, false);
- }
-
- /**
- * Binds member fields found in the given object and builds member fields
- * that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age;
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.buildAndBindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * <p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and builds an age TextField using
- * the field factory and then binds it to the "age" property.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- public void buildAndBindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, true);
- }
-
- /**
- * Binds member fields found in the given object and optionally builds
- * member fields that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory is buildFields is true. All non-null fields for
- * which a property id can be determined are bound to the property id.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- protected void buildAndBindMemberFields(Object objectWithMemberFields,
- boolean buildFields) throws BindException {
- Class<?> objectClass = objectWithMemberFields.getClass();
-
- for (java.lang.reflect.Field memberField : objectClass
- .getDeclaredFields()) {
-
- if (!Field.class.isAssignableFrom(memberField.getType())) {
- // Process next field
- continue;
- }
-
- PropertyId propertyIdAnnotation = memberField
- .getAnnotation(PropertyId.class);
-
- Class<? extends Field> fieldType = (Class<? extends Field>) memberField
- .getType();
-
- Object propertyId = null;
- if (propertyIdAnnotation != null) {
- // @PropertyId(propertyId) always overrides property id
- propertyId = propertyIdAnnotation.value();
- } else {
- propertyId = memberField.getName();
- }
-
- // Ensure that the property id exists
- Class<?> propertyType;
-
- try {
- propertyType = getPropertyType(propertyId);
- } catch (BindException e) {
- // Property id was not found, skip this field
- continue;
- }
-
- Field<?> field;
- try {
- // Get the field from the object
- field = (Field<?>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField);
- } catch (Exception e) {
- // If we cannot determine the value, just skip the field and try
- // the next one
- continue;
- }
-
- if (field == null && buildFields) {
- Caption captionAnnotation = memberField
- .getAnnotation(Caption.class);
- String caption;
- if (captionAnnotation != null) {
- caption = captionAnnotation.value();
- } else {
- caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- }
-
- // Create the component (Field)
- field = build(caption, propertyType, fieldType);
-
- // Store it in the field
- try {
- ReflectTools.setJavaFieldValue(objectWithMemberFields,
- memberField, field);
- } catch (IllegalArgumentException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (IllegalAccessException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (InvocationTargetException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- }
- }
-
- if (field != null) {
- // Bind it to the property id
- bind(field, propertyId);
- }
- }
- }
-
- public static class CommitException extends Exception {
-
- public CommitException() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- }
-
- public static class BindException extends RuntimeException {
-
- public BindException(String message) {
- super(message);
- }
-
- public BindException(String message, Throwable t) {
- super(message, t);
- }
-
- }
-
- /**
- * Builds a field and binds it to the given property id using the field
- * binder.
- *
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field
- */
- public Field<?> buildAndBind(Object propertyId) throws BindException {
- String caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- return buildAndBind(caption, propertyId);
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field. Can be any type of {@link Field}.
- */
- public Field<?> buildAndBind(String caption, Object propertyId)
- throws BindException {
- Class<?> type = getPropertyType(propertyId);
- return buildAndBind(caption, propertyId, Field.class);
-
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder. Ensures the new field is of the given type.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If the field could not be created
- * @return The created and bound field. Can be any type of {@link Field}.
- */
-
- public <T extends Field> T buildAndBind(String caption, Object propertyId,
- Class<T> fieldType) throws BindException {
- Class<?> type = getPropertyType(propertyId);
-
- T field = build(caption, type, fieldType);
- bind(field, propertyId);
-
- return field;
- }
-
- /**
- * Creates a field based on the given data type.
- * <p>
- * The data type is the type that we want to edit using the field. The field
- * type is the type of field we want to create, can be {@link Field} if any
- * Field is good.
- * </p>
- *
- * @param caption
- * The caption for the new field
- * @param dataType
- * The data model type that we want to edit using the field
- * @param fieldType
- * The type of field that we want to create
- * @return A Field capable of editing the given type
- * @throws BindException
- * If the field could not be created
- */
- protected <T extends Field> T build(String caption, Class<?> dataType,
- Class<T> fieldType) throws BindException {
- T field = getFieldFactory().createField(dataType, fieldType);
- if (field == null) {
- throw new BindException("Unable to build a field of type "
- + fieldType.getName() + " for editing "
- + dataType.getName());
- }
-
- field.setCaption(caption);
- return field;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.TransactionalPropertyWrapper;
+import com.vaadin.tools.ReflectTools;
+import com.vaadin.ui.DefaultFieldFactory;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Form;
+
+/**
+ * FieldGroup provides an easy way of binding fields to data and handling
+ * commits of these fields.
+ * <p>
+ * The functionality of FieldGroup is similar to {@link Form} but
+ * {@link FieldGroup} does not handle layouts in any way. The typical use case
+ * is to create a layout outside the FieldGroup and then use FieldGroup to bind
+ * the fields to a data source.
+ * </p>
+ * <p>
+ * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
+ * Using the buildAndBind methods {@link FieldGroup} can create fields for you
+ * using a FieldGroupFieldFactory but you still have to add them to the correct
+ * position in your layout.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version @version@
+ * @since 7.0
+ */
+public class FieldGroup implements Serializable {
+
+ private static final Logger logger = Logger.getLogger(FieldGroup.class
+ .getName());
+
+ private Item itemDataSource;
+ private boolean buffered = true;
+
+ private boolean enabled = true;
+ private boolean readOnly = false;
+
+ private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
+ private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
+ private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
+
+ /**
+ * The field factory used by builder methods.
+ */
+ private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
+
+ /**
+ * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
+ * data source for the field binder.
+ *
+ */
+ public FieldGroup() {
+
+ }
+
+ /**
+ * Constructs a field binder that uses the given data source.
+ *
+ * @param itemDataSource
+ * The data source to bind the fields to
+ */
+ public FieldGroup(Item itemDataSource) {
+ setItemDataSource(itemDataSource);
+ }
+
+ /**
+ * Updates the item that is used by this FieldBinder. Rebinds all fields to
+ * the properties in the new item.
+ *
+ * @param itemDataSource
+ * The new item to use
+ */
+ public void setItemDataSource(Item itemDataSource) {
+ this.itemDataSource = itemDataSource;
+
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ bind(f, fieldToPropertyId.get(f));
+ }
+ }
+
+ /**
+ * Gets the item used by this FieldBinder. Note that you must call
+ * {@link #commit()} for the item to be updated unless buffered mode has
+ * been switched off.
+ *
+ * @see #setBuffered(boolean)
+ * @see #commit()
+ *
+ * @return The item used by this FieldBinder
+ */
+ public Item getItemDataSource() {
+ return itemDataSource;
+ }
+
+ /**
+ * Checks the buffered mode for the bound fields.
+ * <p>
+ *
+ * @see #setBuffered(boolean) for more details on buffered mode
+ *
+ * @see Field#isBuffered()
+ * @return true if buffered mode is on, false otherwise
+ *
+ */
+ public boolean isBuffered() {
+ return buffered;
+ }
+
+ /**
+ * Sets the buffered mode for the bound fields.
+ * <p>
+ * When buffered mode is on the item will not be updated until
+ * {@link #commit()} is called. If buffered mode is off the item will be
+ * updated once the fields are updated.
+ * </p>
+ * <p>
+ * The default is to use buffered mode.
+ * </p>
+ *
+ * @see Field#setBuffered(boolean)
+ * @param buffered
+ * true to turn on buffered mode, false otherwise
+ */
+ public void setBuffered(boolean buffered) {
+ if (buffered == this.buffered) {
+ return;
+ }
+
+ this.buffered = buffered;
+ for (Field<?> field : getFields()) {
+ field.setBuffered(buffered);
+ }
+ }
+
+ /**
+ * Returns the enabled status for the fields.
+ * <p>
+ * Note that this will not accurately represent the enabled status of all
+ * fields if you change the enabled status of the fields through some other
+ * method than {@link #setEnabled(boolean)}.
+ *
+ * @return true if the fields are enabled, false otherwise
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Updates the enabled state of all bound fields.
+ *
+ * @param fieldsEnabled
+ * true to enable all bound fields, false to disable them
+ */
+ public void setEnabled(boolean fieldsEnabled) {
+ enabled = fieldsEnabled;
+ for (Field<?> field : getFields()) {
+ field.setEnabled(fieldsEnabled);
+ }
+ }
+
+ /**
+ * Returns the read only status for the fields.
+ * <p>
+ * Note that this will not accurately represent the read only status of all
+ * fields if you change the read only status of the fields through some
+ * other method than {@link #setReadOnly(boolean)}.
+ *
+ * @return true if the fields are set to read only, false otherwise
+ */
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * Updates the read only state of all bound fields.
+ *
+ * @param fieldsReadOnly
+ * true to set all bound fields to read only, false to set them
+ * to read write
+ */
+ public void setReadOnly(boolean fieldsReadOnly) {
+ readOnly = fieldsReadOnly;
+ }
+
+ /**
+ * Returns a collection of all fields that have been bound.
+ * <p>
+ * The fields are not returned in any specific order.
+ * </p>
+ *
+ * @return A collection with all bound Fields
+ */
+ public Collection<Field<?>> getFields() {
+ return fieldToPropertyId.keySet();
+ }
+
+ /**
+ * Binds the field with the given propertyId from the current item. If an
+ * item has not been set then the binding is postponed until the item is set
+ * using {@link #setItemDataSource(Item)}.
+ * <p>
+ * This method also adds validators when applicable.
+ * </p>
+ *
+ * @param field
+ * The field to bind
+ * @param propertyId
+ * The propertyId to bind to the field
+ * @throws BindException
+ * If the property id is already bound to another field by this
+ * field binder
+ */
+ public void bind(Field<?> field, Object propertyId) throws BindException {
+ if (propertyIdToField.containsKey(propertyId)
+ && propertyIdToField.get(propertyId) != field) {
+ throw new BindException("Property id " + propertyId
+ + " is already bound to another field");
+ }
+ fieldToPropertyId.put(field, propertyId);
+ propertyIdToField.put(propertyId, field);
+ if (itemDataSource == null) {
+ // Will be bound when data source is set
+ return;
+ }
+
+ field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
+ configureField(field);
+ }
+
+ private <T> Property.Transactional<T> wrapInTransactionalProperty(
+ Property<T> itemProperty) {
+ return new TransactionalPropertyWrapper<T>(itemProperty);
+ }
+
+ /**
+ * Gets the property with the given property id from the item.
+ *
+ * @param propertyId
+ * The id if the property to find
+ * @return The property with the given id from the item
+ * @throws BindException
+ * If the property was not found in the item or no item has been
+ * set
+ */
+ protected Property<?> getItemProperty(Object propertyId)
+ throws BindException {
+ Item item = getItemDataSource();
+ if (item == null) {
+ throw new BindException("Could not lookup property with id "
+ + propertyId + " as no item has been set");
+ }
+ Property<?> p = item.getItemProperty(propertyId);
+ if (p == null) {
+ throw new BindException("A property with id " + propertyId
+ + " was not found in the item");
+ }
+ return p;
+ }
+
+ /**
+ * Detaches the field from its property id and removes it from this
+ * FieldBinder.
+ * <p>
+ * Note that the field is not detached from its property data source if it
+ * is no longer connected to the same property id it was bound to using this
+ * FieldBinder.
+ *
+ * @param field
+ * The field to detach
+ * @throws BindException
+ * If the field is not bound by this field binder or not bound
+ * to the correct property id
+ */
+ public void unbind(Field<?> field) throws BindException {
+ Object propertyId = fieldToPropertyId.get(field);
+ if (propertyId == null) {
+ throw new BindException(
+ "The given field is not part of this FieldBinder");
+ }
+
+ Property fieldDataSource = field.getPropertyDataSource();
+ if (fieldDataSource instanceof TransactionalPropertyWrapper) {
+ fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
+ .getWrappedProperty();
+ }
+ if (fieldDataSource == getItemProperty(propertyId)) {
+ field.setPropertyDataSource(null);
+ }
+ fieldToPropertyId.remove(field);
+ propertyIdToField.remove(propertyId);
+ }
+
+ /**
+ * Configures a field with the settings set for this FieldBinder.
+ * <p>
+ * By default this updates the buffered, read only and enabled state of the
+ * field. Also adds validators when applicable.
+ *
+ * @param field
+ * The field to update
+ */
+ protected void configureField(Field<?> field) {
+ field.setBuffered(isBuffered());
+
+ field.setEnabled(isEnabled());
+ field.setReadOnly(isReadOnly());
+ }
+
+ /**
+ * Gets the type of the property with the given property id.
+ *
+ * @param propertyId
+ * The propertyId. Must be find
+ * @return The type of the property
+ */
+ protected Class<?> getPropertyType(Object propertyId) throws BindException {
+ if (getItemDataSource() == null) {
+ throw new BindException(
+ "Property type for '"
+ + propertyId
+ + "' could not be determined. No item data source has been set.");
+ }
+ Property<?> p = getItemDataSource().getItemProperty(propertyId);
+ if (p == null) {
+ throw new BindException(
+ "Property type for '"
+ + propertyId
+ + "' could not be determined. No property with that id was found.");
+ }
+
+ return p.getType();
+ }
+
+ /**
+ * Returns a collection of all property ids that have been bound to fields.
+ * <p>
+ * Note that this will return property ids even before the item has been
+ * set. In that case it returns the property ids that will be bound once the
+ * item is set.
+ * </p>
+ * <p>
+ * No guarantee is given for the order of the property ids
+ * </p>
+ *
+ * @return A collection of bound property ids
+ */
+ public Collection<Object> getBoundPropertyIds() {
+ return Collections.unmodifiableCollection(propertyIdToField.keySet());
+ }
+
+ /**
+ * Returns a collection of all property ids that exist in the item set using
+ * {@link #setItemDataSource(Item)} but have not been bound to fields.
+ * <p>
+ * Will always return an empty collection before an item has been set using
+ * {@link #setItemDataSource(Item)}.
+ * </p>
+ * <p>
+ * No guarantee is given for the order of the property ids
+ * </p>
+ *
+ * @return A collection of property ids that have not been bound to fields
+ */
+ public Collection<Object> getUnboundPropertyIds() {
+ if (getItemDataSource() == null) {
+ return new ArrayList<Object>();
+ }
+ List<Object> unboundPropertyIds = new ArrayList<Object>();
+ unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
+ unboundPropertyIds.removeAll(propertyIdToField.keySet());
+ return unboundPropertyIds;
+ }
+
+ /**
+ * Commits all changes done to the bound fields.
+ * <p>
+ * Calls all {@link CommitHandler}s before and after committing the field
+ * changes to the item data source. The whole commit is aborted and state is
+ * restored to what it was before commit was called if any
+ * {@link CommitHandler} throws a CommitException or there is a problem
+ * committing the fields
+ *
+ * @throws CommitException
+ * If the commit was aborted
+ */
+ public void commit() throws CommitException {
+ if (!isBuffered()) {
+ // Not using buffered mode, nothing to do
+ return;
+ }
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .startTransaction();
+ }
+ try {
+ firePreCommitEvent();
+ // Commit the field values to the properties
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ f.commit();
+ }
+ firePostCommitEvent();
+
+ // Commit the properties
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .commit();
+ }
+
+ } catch (Exception e) {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .rollback();
+ } catch (Exception rollbackException) {
+ // FIXME: What to do ?
+ }
+ }
+
+ throw new CommitException("Commit failed", e);
+ }
+
+ }
+
+ /**
+ * Sends a preCommit event to all registered commit handlers
+ *
+ * @throws CommitException
+ * If the commit should be aborted
+ */
+ private void firePreCommitEvent() throws CommitException {
+ CommitHandler[] handlers = commitHandlers
+ .toArray(new CommitHandler[commitHandlers.size()]);
+
+ for (CommitHandler handler : handlers) {
+ handler.preCommit(new CommitEvent(this));
+ }
+ }
+
+ /**
+ * Sends a postCommit event to all registered commit handlers
+ *
+ * @throws CommitException
+ * If the commit should be aborted
+ */
+ private void firePostCommitEvent() throws CommitException {
+ CommitHandler[] handlers = commitHandlers
+ .toArray(new CommitHandler[commitHandlers.size()]);
+
+ for (CommitHandler handler : handlers) {
+ handler.postCommit(new CommitEvent(this));
+ }
+ }
+
+ /**
+ * Discards all changes done to the bound fields.
+ * <p>
+ * Only has effect if buffered mode is used.
+ *
+ */
+ public void discard() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ f.discard();
+ } catch (Exception e) {
+ // TODO: handle exception
+ // What can we do if discard fails other than try to discard all
+ // other fields?
+ }
+ }
+ }
+
+ /**
+ * Returns the field that is bound to the given property id
+ *
+ * @param propertyId
+ * The property id to use to lookup the field
+ * @return The field that is bound to the property id or null if no field is
+ * bound to that property id
+ */
+ public Field<?> getField(Object propertyId) {
+ return propertyIdToField.get(propertyId);
+ }
+
+ /**
+ * Returns the property id that is bound to the given field
+ *
+ * @param field
+ * The field to use to lookup the property id
+ * @return The property id that is bound to the field or null if the field
+ * is not bound to any property id by this FieldBinder
+ */
+ public Object getPropertyId(Field<?> field) {
+ return fieldToPropertyId.get(field);
+ }
+
+ /**
+ * Adds a commit handler.
+ * <p>
+ * The commit handler is called before the field values are committed to the
+ * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
+ * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
+ * {@link CommitHandler} throws a CommitException the whole commit is
+ * aborted and the fields retain their old values.
+ *
+ * @param commitHandler
+ * The commit handler to add
+ */
+ public void addCommitHandler(CommitHandler commitHandler) {
+ commitHandlers.add(commitHandler);
+ }
+
+ /**
+ * Removes the given commit handler.
+ *
+ * @see #addCommitHandler(CommitHandler)
+ *
+ * @param commitHandler
+ * The commit handler to remove
+ */
+ public void removeCommitHandler(CommitHandler commitHandler) {
+ commitHandlers.remove(commitHandler);
+ }
+
+ /**
+ * Returns a list of all commit handlers for this {@link FieldGroup}.
+ * <p>
+ * Use {@link #addCommitHandler(CommitHandler)} and
+ * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
+ * commit handler.
+ *
+ * @return A collection of commit handlers
+ */
+ protected Collection<CommitHandler> getCommitHandlers() {
+ return Collections.unmodifiableCollection(commitHandlers);
+ }
+
+ /**
+ * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
+ * commit transactions. CommitHandlers can perform custom operations as part
+ * of the commit and cause the commit to be aborted by throwing a
+ * {@link CommitException}.
+ */
+ public interface CommitHandler extends Serializable {
+ /**
+ * Called before changes are committed to the field and the item is
+ * updated.
+ * <p>
+ * Throw a {@link CommitException} to abort the commit.
+ *
+ * @param commitEvent
+ * An event containing information regarding the commit
+ * @throws CommitException
+ * if the commit should be aborted
+ */
+ public void preCommit(CommitEvent commitEvent) throws CommitException;
+
+ /**
+ * Called after changes are committed to the fields and the item is
+ * updated..
+ * <p>
+ * Throw a {@link CommitException} to abort the commit.
+ *
+ * @param commitEvent
+ * An event containing information regarding the commit
+ * @throws CommitException
+ * if the commit should be aborted
+ */
+ public void postCommit(CommitEvent commitEvent) throws CommitException;
+ }
+
+ /**
+ * FIXME javadoc
+ *
+ */
+ public static class CommitEvent implements Serializable {
+ private FieldGroup fieldBinder;
+
+ private CommitEvent(FieldGroup fieldBinder) {
+ this.fieldBinder = fieldBinder;
+ }
+
+ /**
+ * Returns the field binder that this commit relates to
+ *
+ * @return The FieldBinder that is being committed.
+ */
+ public FieldGroup getFieldBinder() {
+ return fieldBinder;
+ }
+
+ }
+
+ /**
+ * Checks the validity of the bound fields.
+ * <p>
+ * Call the {@link Field#validate()} for the fields to get the individual
+ * error messages.
+ *
+ * @return true if all bound fields are valid, false otherwise.
+ */
+ public boolean isValid() {
+ try {
+ for (Field<?> field : getFields()) {
+ field.validate();
+ }
+ return true;
+ } catch (InvalidValueException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if any bound field has been modified.
+ *
+ * @return true if at least on field has been modified, false otherwise
+ */
+ public boolean isModified() {
+ for (Field<?> field : getFields()) {
+ if (field.isModified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the field factory for the {@link FieldGroup}. The field factory is
+ * only used when {@link FieldGroup} creates a new field.
+ *
+ * @return The field factory in use
+ *
+ */
+ public FieldGroupFieldFactory getFieldFactory() {
+ return fieldFactory;
+ }
+
+ /**
+ * Sets the field factory for the {@link FieldGroup}. The field factory is
+ * only used when {@link FieldGroup} creates a new field.
+ *
+ * @param fieldFactory
+ * The field factory to use
+ */
+ public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
+ this.fieldFactory = fieldFactory;
+ }
+
+ /**
+ * Binds member fields found in the given object.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. All non-null fields for which a property id can
+ * be determined are bound to the property id.
+ * </p>
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class MyForm extends VerticalLayout {
+ * private TextField firstName = new TextField("First name");
+ * @PropertyId("last")
+ * private TextField lastName = new TextField("Last name");
+ * private TextField age = new TextField("Age"); ... }
+ *
+ * MyForm myForm = new MyForm();
+ * ...
+ * fieldGroup.bindMemberFields(myForm);
+ * </pre>
+ *
+ * </p>
+ * This binds the firstName TextField to a "firstName" property in the item,
+ * lastName TextField to a "last" property and the age TextField to a "age"
+ * property.
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to bind
+ * @throws BindException
+ * If there is a problem binding a field
+ */
+ public void bindMemberFields(Object objectWithMemberFields)
+ throws BindException {
+ buildAndBindMemberFields(objectWithMemberFields, false);
+ }
+
+ /**
+ * Binds member fields found in the given object and builds member fields
+ * that have not been initialized.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. Fields that are not initialized (null) are built
+ * using the field factory. All non-null fields for which a property id can
+ * be determined are bound to the property id.
+ * </p>
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class MyForm extends VerticalLayout {
+ * private TextField firstName = new TextField("First name");
+ * @PropertyId("last")
+ * private TextField lastName = new TextField("Last name");
+ * private TextField age;
+ *
+ * MyForm myForm = new MyForm();
+ * ...
+ * fieldGroup.buildAndBindMemberFields(myForm);
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * This binds the firstName TextField to a "firstName" property in the item,
+ * lastName TextField to a "last" property and builds an age TextField using
+ * the field factory and then binds it to the "age" property.
+ * </p>
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to build and
+ * bind
+ * @throws BindException
+ * If there is a problem binding or building a field
+ */
+ public void buildAndBindMemberFields(Object objectWithMemberFields)
+ throws BindException {
+ buildAndBindMemberFields(objectWithMemberFields, true);
+ }
+
+ /**
+ * Binds member fields found in the given object and optionally builds
+ * member fields that have not been initialized.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. Fields that are not initialized (null) are built
+ * using the field factory is buildFields is true. All non-null fields for
+ * which a property id can be determined are bound to the property id.
+ * </p>
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to build and
+ * bind
+ * @throws BindException
+ * If there is a problem binding or building a field
+ */
+ protected void buildAndBindMemberFields(Object objectWithMemberFields,
+ boolean buildFields) throws BindException {
+ Class<?> objectClass = objectWithMemberFields.getClass();
+
+ for (java.lang.reflect.Field memberField : objectClass
+ .getDeclaredFields()) {
+
+ if (!Field.class.isAssignableFrom(memberField.getType())) {
+ // Process next field
+ continue;
+ }
+
+ PropertyId propertyIdAnnotation = memberField
+ .getAnnotation(PropertyId.class);
+
+ Class<? extends Field> fieldType = (Class<? extends Field>) memberField
+ .getType();
+
+ Object propertyId = null;
+ if (propertyIdAnnotation != null) {
+ // @PropertyId(propertyId) always overrides property id
+ propertyId = propertyIdAnnotation.value();
+ } else {
+ propertyId = memberField.getName();
+ }
+
+ // Ensure that the property id exists
+ Class<?> propertyType;
+
+ try {
+ propertyType = getPropertyType(propertyId);
+ } catch (BindException e) {
+ // Property id was not found, skip this field
+ continue;
+ }
+
+ Field<?> field;
+ try {
+ // Get the field from the object
+ field = (Field<?>) ReflectTools.getJavaFieldValue(
+ objectWithMemberFields, memberField);
+ } catch (Exception e) {
+ // If we cannot determine the value, just skip the field and try
+ // the next one
+ continue;
+ }
+
+ if (field == null && buildFields) {
+ Caption captionAnnotation = memberField
+ .getAnnotation(Caption.class);
+ String caption;
+ if (captionAnnotation != null) {
+ caption = captionAnnotation.value();
+ } else {
+ caption = DefaultFieldFactory
+ .createCaptionByPropertyId(propertyId);
+ }
+
+ // Create the component (Field)
+ field = build(caption, propertyType, fieldType);
+
+ // Store it in the field
+ try {
+ ReflectTools.setJavaFieldValue(objectWithMemberFields,
+ memberField, field);
+ } catch (IllegalArgumentException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ } catch (IllegalAccessException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ } catch (InvocationTargetException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ }
+ }
+
+ if (field != null) {
+ // Bind it to the property id
+ bind(field, propertyId);
+ }
+ }
+ }
+
+ public static class CommitException extends Exception {
+
+ public CommitException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ }
+
+ public static class BindException extends RuntimeException {
+
+ public BindException(String message) {
+ super(message);
+ }
+
+ public BindException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ }
+
+ /**
+ * Builds a field and binds it to the given property id using the field
+ * binder.
+ *
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If there is a problem while building or binding
+ * @return The created and bound field
+ */
+ public Field<?> buildAndBind(Object propertyId) throws BindException {
+ String caption = DefaultFieldFactory
+ .createCaptionByPropertyId(propertyId);
+ return buildAndBind(caption, propertyId);
+ }
+
+ /**
+ * Builds a field using the given caption and binds it to the given property
+ * id using the field binder.
+ *
+ * @param caption
+ * The caption for the field
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If there is a problem while building or binding
+ * @return The created and bound field. Can be any type of {@link Field}.
+ */
+ public Field<?> buildAndBind(String caption, Object propertyId)
+ throws BindException {
+ Class<?> type = getPropertyType(propertyId);
+ return buildAndBind(caption, propertyId, Field.class);
+
+ }
+
+ /**
+ * Builds a field using the given caption and binds it to the given property
+ * id using the field binder. Ensures the new field is of the given type.
+ *
+ * @param caption
+ * The caption for the field
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If the field could not be created
+ * @return The created and bound field. Can be any type of {@link Field}.
+ */
+
+ public <T extends Field> T buildAndBind(String caption, Object propertyId,
+ Class<T> fieldType) throws BindException {
+ Class<?> type = getPropertyType(propertyId);
+
+ T field = build(caption, type, fieldType);
+ bind(field, propertyId);
+
+ return field;
+ }
+
+ /**
+ * Creates a field based on the given data type.
+ * <p>
+ * The data type is the type that we want to edit using the field. The field
+ * type is the type of field we want to create, can be {@link Field} if any
+ * Field is good.
+ * </p>
+ *
+ * @param caption
+ * The caption for the new field
+ * @param dataType
+ * The data model type that we want to edit using the field
+ * @param fieldType
+ * The type of field that we want to create
+ * @return A Field capable of editing the given type
+ * @throws BindException
+ * If the field could not be created
+ */
+ protected <T extends Field> T build(String caption, Class<?> dataType,
+ Class<T> fieldType) throws BindException {
+ T field = getFieldFactory().createField(dataType, fieldType);
+ if (field == null) {
+ throw new BindException("Unable to build a field of type "
+ + fieldType.getName() + " for editing "
+ + dataType.getName());
+ }
+
+ field.setCaption(caption);
+ return field;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
index 6945a492bd..80c012cbdc 100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
@@ -1,31 +1,31 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Field;
-
-/**
- * Factory interface for creating new Field-instances based on the data type
- * that should be edited.
- *
- * @author Vaadin Ltd.
- * @version @version@
- * @since 7.0
- */
-public interface FieldGroupFieldFactory extends Serializable {
- /**
- * Creates a field based on the data type that we want to edit
- *
- * @param dataType
- * The type that we want to edit using the field
- * @param fieldType
- * The type of field we want to create. If set to {@link Field}
- * then any type of field is accepted
- * @return A field that can be assigned to the given fieldType and that is
- * capable of editing the given type of data
- */
- <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.io.Serializable;
+
+import com.vaadin.ui.Field;
+
+/**
+ * Factory interface for creating new Field-instances based on the data type
+ * that should be edited.
+ *
+ * @author Vaadin Ltd.
+ * @version @version@
+ * @since 7.0
+ */
+public interface FieldGroupFieldFactory extends Serializable {
+ /**
+ * Creates a field based on the data type that we want to edit
+ *
+ * @param dataType
+ * The type that we want to edit using the field
+ * @param fieldType
+ * The type of field we want to create. If set to {@link Field}
+ * then any type of field is accepted
+ * @return A field that can be assigned to the given fieldType and that is
+ * capable of editing the given type of data
+ */
+ <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
+}
diff --git a/src/com/vaadin/data/fieldgroup/PropertyId.java b/src/com/vaadin/data/fieldgroup/PropertyId.java
index 588fdc3020..268047401d 100644
--- a/src/com/vaadin/data/fieldgroup/PropertyId.java
+++ b/src/com/vaadin/data/fieldgroup/PropertyId.java
@@ -1,15 +1,15 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface PropertyId {
- String value();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PropertyId {
+ String value();
+}
diff --git a/src/com/vaadin/data/util/TextFileProperty.java b/src/com/vaadin/data/util/TextFileProperty.java
index 77325e141d..5ebba98062 100644
--- a/src/com/vaadin/data/util/TextFileProperty.java
+++ b/src/com/vaadin/data/util/TextFileProperty.java
@@ -1,141 +1,141 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * Property implementation for wrapping a text file.
- *
- * Supports reading and writing of a File from/to String.
- *
- * {@link ValueChangeListener}s are supported, but only fire when
- * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
- * are supported but only fire when setReadOnly(boolean) is explicitly called.
- *
- */
-@SuppressWarnings("serial")
-public class TextFileProperty extends AbstractProperty<String> {
-
- private File file;
- private Charset charset = null;
-
- /**
- * Wrap given file with property interface.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- */
- public TextFileProperty(File file) {
- this.file = file;
- }
-
- /**
- * Wrap the given file with the property interface and specify character
- * set.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- * @param charset
- * Charset to be used for reading and writing the file.
- */
- public TextFileProperty(File file, Charset charset) {
- this.file = file;
- this.charset = charset;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getType()
- */
- public Class<String> getType() {
- return String.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getValue()
- */
- public String getValue() {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- InputStreamReader isr = charset == null ? new InputStreamReader(fis)
- : new InputStreamReader(fis, charset);
- BufferedReader r = new BufferedReader(isr);
- StringBuilder b = new StringBuilder();
- char buf[] = new char[8 * 1024];
- int len;
- while ((len = r.read(buf)) != -1) {
- b.append(buf, 0, len);
- }
- r.close();
- isr.close();
- fis.close();
- return b.toString();
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return file == null || super.isReadOnly() || !file.canWrite();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setValue(java.lang.Object)
- */
- public void setValue(Object newValue) throws ReadOnlyException {
- if (isReadOnly()) {
- throw new ReadOnlyException();
- }
- if (file == null) {
- return;
- }
-
- try {
- FileOutputStream fos = new FileOutputStream(file);
- OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
- fos) : new OutputStreamWriter(fos, charset);
- BufferedWriter w = new BufferedWriter(osw);
- w.append(newValue.toString());
- w.flush();
- w.close();
- osw.close();
- fos.close();
- fireValueChange();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+
+/**
+ * Property implementation for wrapping a text file.
+ *
+ * Supports reading and writing of a File from/to String.
+ *
+ * {@link ValueChangeListener}s are supported, but only fire when
+ * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
+ * are supported but only fire when setReadOnly(boolean) is explicitly called.
+ *
+ */
+@SuppressWarnings("serial")
+public class TextFileProperty extends AbstractProperty<String> {
+
+ private File file;
+ private Charset charset = null;
+
+ /**
+ * Wrap given file with property interface.
+ *
+ * Setting the file to null works, but getValue() will return null.
+ *
+ * @param file
+ * File to be wrapped.
+ */
+ public TextFileProperty(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Wrap the given file with the property interface and specify character
+ * set.
+ *
+ * Setting the file to null works, but getValue() will return null.
+ *
+ * @param file
+ * File to be wrapped.
+ * @param charset
+ * Charset to be used for reading and writing the file.
+ */
+ public TextFileProperty(File file, Charset charset) {
+ this.file = file;
+ this.charset = charset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#getType()
+ */
+ public Class<String> getType() {
+ return String.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#getValue()
+ */
+ public String getValue() {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ InputStreamReader isr = charset == null ? new InputStreamReader(fis)
+ : new InputStreamReader(fis, charset);
+ BufferedReader r = new BufferedReader(isr);
+ StringBuilder b = new StringBuilder();
+ char buf[] = new char[8 * 1024];
+ int len;
+ while ((len = r.read(buf)) != -1) {
+ b.append(buf, 0, len);
+ }
+ r.close();
+ isr.close();
+ fis.close();
+ return b.toString();
+ } catch (FileNotFoundException e) {
+ return null;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return file == null || super.isReadOnly() || !file.canWrite();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#setValue(java.lang.Object)
+ */
+ public void setValue(Object newValue) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ if (file == null) {
+ return;
+ }
+
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
+ fos) : new OutputStreamWriter(fos, charset);
+ BufferedWriter w = new BufferedWriter(osw);
+ w.append(newValue.toString());
+ w.flush();
+ w.close();
+ osw.close();
+ fos.close();
+ fireValueChange();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
index de44dbe544..06ec0935c3 100644
--- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
@@ -1,107 +1,107 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.Property.ValueChangeEvent;
-import com.vaadin.data.Property.ValueChangeNotifier;
-
-/**
- * Wrapper class that helps implement two-phase commit for a non-transactional
- * property.
- *
- * When accessing the property through the wrapper, getting and setting the
- * property value take place immediately. However, the wrapper keeps track of
- * the old value of the property so that it can be set for the property in case
- * of a roll-back. This can result in the underlying property value changing
- * multiple times (first based on modifications made by the application, then
- * back upon roll-back).
- *
- * Value change events on the {@link TransactionalPropertyWrapper} are only
- * fired at the end of a successful transaction, whereas listeners attached to
- * the underlying property may receive multiple value change events.
- *
- * @see com.vaadin.data.Property.Transactional
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- *
- * @param <T>
- */
-public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
- implements ValueChangeNotifier, Property.Transactional<T> {
-
- private Property<T> wrappedProperty;
- private boolean inTransaction = false;
- private boolean valueChangePending;
- private T valueBeforeTransaction;
-
- public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
- this.wrappedProperty = wrappedProperty;
- if (wrappedProperty instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) wrappedProperty)
- .addListener(new ValueChangeListener() {
-
- public void valueChange(ValueChangeEvent event) {
- fireValueChange();
- }
- });
- }
- }
-
- public Class getType() {
- return wrappedProperty.getType();
- }
-
- public T getValue() {
- return wrappedProperty.getValue();
- }
-
- public void setValue(Object newValue) throws ReadOnlyException {
- // Causes a value change to be sent to this listener which in turn fires
- // a new value change event for this property
- wrappedProperty.setValue(newValue);
- }
-
- public void startTransaction() {
- inTransaction = true;
- valueBeforeTransaction = getValue();
- }
-
- public void commit() {
- endTransaction();
- }
-
- public void rollback() {
- try {
- wrappedProperty.setValue(valueBeforeTransaction);
- } finally {
- valueChangePending = false;
- endTransaction();
- }
- }
-
- protected void endTransaction() {
- inTransaction = false;
- valueBeforeTransaction = null;
- if (valueChangePending) {
- fireValueChange();
- }
- }
-
- @Override
- protected void fireValueChange() {
- if (inTransaction) {
- valueChangePending = true;
- } else {
- super.fireValueChange();
- }
- }
-
- public Property<T> getWrappedProperty() {
- return wrappedProperty;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeNotifier;
+
+/**
+ * Wrapper class that helps implement two-phase commit for a non-transactional
+ * property.
+ *
+ * When accessing the property through the wrapper, getting and setting the
+ * property value take place immediately. However, the wrapper keeps track of
+ * the old value of the property so that it can be set for the property in case
+ * of a roll-back. This can result in the underlying property value changing
+ * multiple times (first based on modifications made by the application, then
+ * back upon roll-back).
+ *
+ * Value change events on the {@link TransactionalPropertyWrapper} are only
+ * fired at the end of a successful transaction, whereas listeners attached to
+ * the underlying property may receive multiple value change events.
+ *
+ * @see com.vaadin.data.Property.Transactional
+ *
+ * @author Vaadin Ltd
+ * @version @version@
+ * @since 7.0
+ *
+ * @param <T>
+ */
+public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
+ implements ValueChangeNotifier, Property.Transactional<T> {
+
+ private Property<T> wrappedProperty;
+ private boolean inTransaction = false;
+ private boolean valueChangePending;
+ private T valueBeforeTransaction;
+
+ public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
+ this.wrappedProperty = wrappedProperty;
+ if (wrappedProperty instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) wrappedProperty)
+ .addListener(new ValueChangeListener() {
+
+ public void valueChange(ValueChangeEvent event) {
+ fireValueChange();
+ }
+ });
+ }
+ }
+
+ public Class getType() {
+ return wrappedProperty.getType();
+ }
+
+ public T getValue() {
+ return wrappedProperty.getValue();
+ }
+
+ public void setValue(Object newValue) throws ReadOnlyException {
+ // Causes a value change to be sent to this listener which in turn fires
+ // a new value change event for this property
+ wrappedProperty.setValue(newValue);
+ }
+
+ public void startTransaction() {
+ inTransaction = true;
+ valueBeforeTransaction = getValue();
+ }
+
+ public void commit() {
+ endTransaction();
+ }
+
+ public void rollback() {
+ try {
+ wrappedProperty.setValue(valueBeforeTransaction);
+ } finally {
+ valueChangePending = false;
+ endTransaction();
+ }
+ }
+
+ protected void endTransaction() {
+ inTransaction = false;
+ valueBeforeTransaction = null;
+ if (valueChangePending) {
+ fireValueChange();
+ }
+ }
+
+ @Override
+ protected void fireValueChange() {
+ if (inTransaction) {
+ valueChangePending = true;
+ } else {
+ super.fireValueChange();
+ }
+ }
+
+ public Property<T> getWrappedProperty() {
+ return wrappedProperty;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/Converter.java b/src/com/vaadin/data/util/converter/Converter.java
index 065d06b071..b8c15e8cdc 100644
--- a/src/com/vaadin/data/util/converter/Converter.java
+++ b/src/com/vaadin/data/util/converter/Converter.java
@@ -1,159 +1,159 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-/**
- * Interface that implements conversion between a model and a presentation type.
- * <p>
- * Typically {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
- * these together returns the original result for all input but this is not a
- * requirement.
- * </p>
- * <p>
- * Converters must not have any side effects (never update UI from inside a
- * converter).
- * </p>
- * <p>
- * All Converters must be stateless and thread safe.
- * </p>
- * <p>
- * If conversion of a value fails, a {@link ConversionException} is thrown.
- * </p>
- *
- * @param <MODEL>
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
- * @param <PRESENTATION>
- * The presentation type. Must be compatible with what
- * {@link #getPresentationType()} returns.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public interface Converter<PRESENTATION, MODEL> extends Serializable {
-
- /**
- * Converts the given value from target type to source type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws ConversionException;
-
- /**
- * Converts the given value from source type to target type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws ConversionException;
-
- /**
- * The source type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToPresentation(Object, Locale)}.
- *
- * @return The source type
- */
- public Class<MODEL> getModelType();
-
- /**
- * The target type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToModel(Object, Locale)}.
- *
- * @return The target type
- */
- public Class<PRESENTATION> getPresentationType();
-
- /**
- * An exception that signals that the value passed to
- * {@link Converter#convertToPresentation(Object, Locale)} or
- * {@link Converter#convertToModel(Object, Locale)} could not be converted.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public static class ConversionException extends RuntimeException {
-
- /**
- * Constructs a new <code>ConversionException</code> without a detail
- * message.
- */
- public ConversionException() {
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public ConversionException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new {@code ConversionException} with the specified
- * cause.
- *
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message and cause.
- *
- * @param message
- * the detail message
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Interface that implements conversion between a model and a presentation type.
+ * <p>
+ * Typically {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
+ * these together returns the original result for all input but this is not a
+ * requirement.
+ * </p>
+ * <p>
+ * Converters must not have any side effects (never update UI from inside a
+ * converter).
+ * </p>
+ * <p>
+ * All Converters must be stateless and thread safe.
+ * </p>
+ * <p>
+ * If conversion of a value fails, a {@link ConversionException} is thrown.
+ * </p>
+ *
+ * @param <MODEL>
+ * The model type. Must be compatible with what
+ * {@link #getModelType()} returns.
+ * @param <PRESENTATION>
+ * The presentation type. Must be compatible with what
+ * {@link #getPresentationType()} returns.
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public interface Converter<PRESENTATION, MODEL> extends Serializable {
+
+ /**
+ * Converts the given value from target type to source type.
+ * <p>
+ * A converter can optionally use locale to do the conversion.
+ * </p>
+ * A converter should in most cases be symmetric so chaining
+ * {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should return the original value.
+ *
+ * @param value
+ * The value to convert, compatible with the target type. Can be
+ * null
+ * @param locale
+ * The locale to use for conversion. Can be null.
+ * @return The converted value compatible with the source type
+ * @throws ConversionException
+ * If the value could not be converted
+ */
+ public MODEL convertToModel(PRESENTATION value, Locale locale)
+ throws ConversionException;
+
+ /**
+ * Converts the given value from source type to target type.
+ * <p>
+ * A converter can optionally use locale to do the conversion.
+ * </p>
+ * A converter should in most cases be symmetric so chaining
+ * {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should return the original value.
+ *
+ * @param value
+ * The value to convert, compatible with the target type. Can be
+ * null
+ * @param locale
+ * The locale to use for conversion. Can be null.
+ * @return The converted value compatible with the source type
+ * @throws ConversionException
+ * If the value could not be converted
+ */
+ public PRESENTATION convertToPresentation(MODEL value, Locale locale)
+ throws ConversionException;
+
+ /**
+ * The source type of the converter.
+ *
+ * Values of this type can be passed to
+ * {@link #convertToPresentation(Object, Locale)}.
+ *
+ * @return The source type
+ */
+ public Class<MODEL> getModelType();
+
+ /**
+ * The target type of the converter.
+ *
+ * Values of this type can be passed to
+ * {@link #convertToModel(Object, Locale)}.
+ *
+ * @return The target type
+ */
+ public Class<PRESENTATION> getPresentationType();
+
+ /**
+ * An exception that signals that the value passed to
+ * {@link Converter#convertToPresentation(Object, Locale)} or
+ * {@link Converter#convertToModel(Object, Locale)} could not be converted.
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+ public static class ConversionException extends RuntimeException {
+
+ /**
+ * Constructs a new <code>ConversionException</code> without a detail
+ * message.
+ */
+ public ConversionException() {
+ }
+
+ /**
+ * Constructs a new <code>ConversionException</code> with the specified
+ * detail message.
+ *
+ * @param msg
+ * the detail message
+ */
+ public ConversionException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a new {@code ConversionException} with the specified
+ * cause.
+ *
+ * @param cause
+ * The cause of the the exception
+ */
+ public ConversionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new <code>ConversionException</code> with the specified
+ * detail message and cause.
+ *
+ * @param message
+ * the detail message
+ * @param cause
+ * The cause of the the exception
+ */
+ public ConversionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/ConverterFactory.java b/src/com/vaadin/data/util/converter/ConverterFactory.java
index 451f84185d..ed4ab41ac0 100644
--- a/src/com/vaadin/data/util/converter/ConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/ConverterFactory.java
@@ -1,23 +1,23 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-
-/**
- * Factory interface for providing Converters based on a presentation type and a
- * model type.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- *
- */
-public interface ConverterFactory extends Serializable {
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType);
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.io.Serializable;
+
+/**
+ * Factory interface for providing Converters based on a presentation type and a
+ * model type.
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ *
+ */
+public interface ConverterFactory extends Serializable {
+ public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType);
+
+}
diff --git a/src/com/vaadin/data/util/converter/DateToLongConverter.java b/src/com/vaadin/data/util/converter/DateToLongConverter.java
index d66adece06..537800f617 100644
--- a/src/com/vaadin/data/util/converter/DateToLongConverter.java
+++ b/src/com/vaadin/data/util/converter/DateToLongConverter.java
@@ -1,68 +1,68 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Long} to {@link Date} and back.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateToLongConverter implements Converter<Date, Long> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Long convertToModel(Date value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return value.getTime();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public Date convertToPresentation(Long value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return new Date(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Long> getModelType() {
- return Long.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<Date> getPresentationType() {
- return Date.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Long} to {@link Date} and back.
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DateToLongConverter implements Converter<Date, Long> {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Long convertToModel(Date value, Locale locale) {
+ if (value == null) {
+ return null;
+ }
+
+ return value.getTime();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public Date convertToPresentation(Long value, Locale locale) {
+ if (value == null) {
+ return null;
+ }
+
+ return new Date(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Long> getModelType() {
+ return Long.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<Date> getPresentationType() {
+ return Date.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 9233624819..3ad7b6a85b 100644
--- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@ -1,100 +1,100 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.logging.Logger;
-
-import com.vaadin.Application;
-
-/**
- * Default implementation of {@link ConverterFactory}. Provides converters for
- * standard types like {@link String}, {@link Double} and {@link Date}. </p>
- * <p>
- * Custom converters can be provided by extending this class and using
- * {@link Application#setConverterFactory(ConverterFactory)}.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DefaultConverterFactory implements ConverterFactory {
-
- private final static Logger log = Logger
- .getLogger(DefaultConverterFactory.class.getName());
-
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- Converter<PRESENTATION, MODEL> converter = findConverter(
- presentationType, modelType);
- if (converter != null) {
- log.finest(getClass().getName() + " created a "
- + converter.getClass());
- return converter;
- }
-
- // Try to find a reverse converter
- Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
- modelType, presentationType);
- if (reverseConverter != null) {
- log.finest(getClass().getName() + " created a reverse "
- + reverseConverter.getClass());
- return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
- }
-
- log.finest(getClass().getName() + " could not find a converter for "
- + presentationType.getName() + " to " + modelType.getName()
- + " conversion");
- return null;
-
- }
-
- protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- if (presentationType == String.class) {
- // TextField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
- if (converter != null) {
- return converter;
- }
- } else if (presentationType == Date.class) {
- // DateField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
- if (converter != null) {
- return converter;
- }
- }
-
- return null;
-
- }
-
- protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
- if (Long.class.isAssignableFrom(sourceType)) {
- return new DateToLongConverter();
- } else {
- return null;
- }
- }
-
- protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
- if (Double.class.isAssignableFrom(sourceType)) {
- return new StringToDoubleConverter();
- } else if (Integer.class.isAssignableFrom(sourceType)) {
- return new StringToIntegerConverter();
- } else if (Boolean.class.isAssignableFrom(sourceType)) {
- return new StringToBooleanConverter();
- } else if (Number.class.isAssignableFrom(sourceType)) {
- return new StringToNumberConverter();
- } else if (Date.class.isAssignableFrom(sourceType)) {
- return new StringToDateConverter();
- } else {
- return null;
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Date;
+import java.util.logging.Logger;
+
+import com.vaadin.Application;
+
+/**
+ * Default implementation of {@link ConverterFactory}. Provides converters for
+ * standard types like {@link String}, {@link Double} and {@link Date}. </p>
+ * <p>
+ * Custom converters can be provided by extending this class and using
+ * {@link Application#setConverterFactory(ConverterFactory)}.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DefaultConverterFactory implements ConverterFactory {
+
+ private final static Logger log = Logger
+ .getLogger(DefaultConverterFactory.class.getName());
+
+ public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
+ Converter<PRESENTATION, MODEL> converter = findConverter(
+ presentationType, modelType);
+ if (converter != null) {
+ log.finest(getClass().getName() + " created a "
+ + converter.getClass());
+ return converter;
+ }
+
+ // Try to find a reverse converter
+ Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
+ modelType, presentationType);
+ if (reverseConverter != null) {
+ log.finest(getClass().getName() + " created a reverse "
+ + reverseConverter.getClass());
+ return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
+ }
+
+ log.finest(getClass().getName() + " could not find a converter for "
+ + presentationType.getName() + " to " + modelType.getName()
+ + " conversion");
+ return null;
+
+ }
+
+ protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
+ if (presentationType == String.class) {
+ // TextField converters and more
+ Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
+ if (converter != null) {
+ return converter;
+ }
+ } else if (presentationType == Date.class) {
+ // DateField converters and more
+ Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
+ if (converter != null) {
+ return converter;
+ }
+ }
+
+ return null;
+
+ }
+
+ protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
+ if (Long.class.isAssignableFrom(sourceType)) {
+ return new DateToLongConverter();
+ } else {
+ return null;
+ }
+ }
+
+ protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
+ if (Double.class.isAssignableFrom(sourceType)) {
+ return new StringToDoubleConverter();
+ } else if (Integer.class.isAssignableFrom(sourceType)) {
+ return new StringToIntegerConverter();
+ } else if (Boolean.class.isAssignableFrom(sourceType)) {
+ return new StringToBooleanConverter();
+ } else if (Number.class.isAssignableFrom(sourceType)) {
+ return new StringToNumberConverter();
+ } else if (Date.class.isAssignableFrom(sourceType)) {
+ return new StringToDateConverter();
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/ReverseConverter.java b/src/com/vaadin/data/util/converter/ReverseConverter.java
index b191d1ca0b..1c561f29e8 100644
--- a/src/com/vaadin/data/util/converter/ReverseConverter.java
+++ b/src/com/vaadin/data/util/converter/ReverseConverter.java
@@ -1,80 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that wraps another {@link Converter} and reverses source and
- * target types.
- *
- * @param <MODEL>
- * The source type
- * @param <PRESENTATION>
- * The target type
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class ReverseConverter<PRESENTATION, MODEL> implements
- Converter<PRESENTATION, MODEL> {
-
- private Converter<MODEL, PRESENTATION> realConverter;
-
- /**
- * Creates a converter from source to target based on a converter that
- * converts from target to source.
- *
- * @param converter
- * The converter to use in a reverse fashion
- */
- public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
- this.realConverter = converter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#convertToModel(java
- * .lang.Object, java.util.Locale)
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToPresentation(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToModel(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getSourceType()
- */
- public Class<MODEL> getModelType() {
- return realConverter.getPresentationType();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getTargetType()
- */
- public Class<PRESENTATION> getPresentationType() {
- return realConverter.getModelType();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Locale;
+
+/**
+ * A converter that wraps another {@link Converter} and reverses source and
+ * target types.
+ *
+ * @param <MODEL>
+ * The source type
+ * @param <PRESENTATION>
+ * The target type
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class ReverseConverter<PRESENTATION, MODEL> implements
+ Converter<PRESENTATION, MODEL> {
+
+ private Converter<MODEL, PRESENTATION> realConverter;
+
+ /**
+ * Creates a converter from source to target based on a converter that
+ * converts from target to source.
+ *
+ * @param converter
+ * The converter to use in a reverse fashion
+ */
+ public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
+ this.realConverter = converter;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#convertToModel(java
+ * .lang.Object, java.util.Locale)
+ */
+ public MODEL convertToModel(PRESENTATION value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return realConverter.convertToPresentation(value, locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public PRESENTATION convertToPresentation(MODEL value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return realConverter.convertToModel(value, locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getSourceType()
+ */
+ public Class<MODEL> getModelType() {
+ return realConverter.getPresentationType();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getTargetType()
+ */
+ public Class<PRESENTATION> getPresentationType() {
+ return realConverter.getModelType();
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
index 3b2034a361..96a3a3d071 100644
--- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
@@ -1,104 +1,104 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Boolean} and back.
- * The String representation is given by Boolean.toString().
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToBooleanConverter implements Converter<String, Boolean> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Boolean convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- if (getTrueString().equals(value)) {
- return true;
- } else if (getFalseString().equals(value)) {
- return false;
- } else {
- throw new ConversionException("Cannot convert " + value + " to "
- + getModelType().getName());
- }
- }
-
- /**
- * Gets the string representation for true. Default is "true".
- *
- * @return the string representation for true
- */
- protected String getTrueString() {
- return Boolean.TRUE.toString();
- }
-
- /**
- * Gets the string representation for false. Default is "false".
- *
- * @return the string representation for false
- */
- protected String getFalseString() {
- return Boolean.FALSE.toString();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Boolean value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
- if (value) {
- return getTrueString();
- } else {
- return getFalseString();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Boolean> getModelType() {
- return Boolean.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Boolean} and back.
+ * The String representation is given by Boolean.toString().
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToBooleanConverter implements Converter<String, Boolean> {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Boolean convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ if (getTrueString().equals(value)) {
+ return true;
+ } else if (getFalseString().equals(value)) {
+ return false;
+ } else {
+ throw new ConversionException("Cannot convert " + value + " to "
+ + getModelType().getName());
+ }
+ }
+
+ /**
+ * Gets the string representation for true. Default is "true".
+ *
+ * @return the string representation for true
+ */
+ protected String getTrueString() {
+ return Boolean.TRUE.toString();
+ }
+
+ /**
+ * Gets the string representation for false. Default is "false".
+ *
+ * @return the string representation for false
+ */
+ protected String getFalseString() {
+ return Boolean.FALSE.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Boolean value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+ if (value) {
+ return getTrueString();
+ } else {
+ return getFalseString();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Boolean> getModelType() {
+ return Boolean.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToDateConverter.java b/src/com/vaadin/data/util/converter/StringToDateConverter.java
index 2aa9395532..6f3c2e47f6 100644
--- a/src/com/vaadin/data/util/converter/StringToDateConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDateConverter.java
@@ -1,108 +1,108 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.DateFormat;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Date} to {@link String} and back. Uses
- * the given locale and {@link DateFormat} for formatting and parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDateConverter implements Converter<String, Date> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Date, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A DateFormat instance
- */
- protected DateFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
- DateFormat.MEDIUM, locale);
- f.setLenient(false);
- return f;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Date convertToModel(String value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Date parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Date value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Date> getModelType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Date} to {@link String} and back. Uses
+ * the given locale and {@link DateFormat} for formatting and parsing.
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToDateConverter implements Converter<String, Date> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Date, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A DateFormat instance
+ */
+ protected DateFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
+ DateFormat.MEDIUM, locale);
+ f.setLenient(false);
+ return f;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Date convertToModel(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ ParsePosition parsePosition = new ParsePosition(0);
+ Date parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ return parsedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Date value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Date> getModelType() {
+ return Date.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
index 29c6329451..60a38f4127 100644
--- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
@@ -1,103 +1,103 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Double} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDoubleConverter implements Converter<String, Double> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Double, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Double convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- return parsedValue.doubleValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Double value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Double> getModelType() {
- return Double.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Double} and back.
+ * Uses the given locale and a {@link NumberFormat} instance for formatting and
+ * parsing.
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToDoubleConverter implements Converter<String, Double> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Double, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ return NumberFormat.getNumberInstance(locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Double convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+ return parsedValue.doubleValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Double value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Double> getModelType() {
+ return Double.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+}
diff --git a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
index 7fa4458c51..e55feec3b6 100644
--- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
@@ -1,84 +1,84 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Integer} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToIntegerConverter implements Converter<String, Integer> {
-
- /**
- * Returns the format used by
- * {@link #convertToPresentation(Integer, Locale)} and
- * {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
- return NumberFormat.getIntegerInstance(locale);
- }
-
- public Integer convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue.intValue();
- }
-
- public String convertToPresentation(Integer value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- public Class<Integer> getModelType() {
- return Integer.class;
- }
-
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Integer} and back.
+ * Uses the given locale and a {@link NumberFormat} instance for formatting and
+ * parsing.
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToIntegerConverter implements Converter<String, Integer> {
+
+ /**
+ * Returns the format used by
+ * {@link #convertToPresentation(Integer, Locale)} and
+ * {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+ return NumberFormat.getIntegerInstance(locale);
+ }
+
+ public Integer convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ // Parse and detect errors. If the full string was not used, it is
+ // an error.
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ if (parsedValue == null) {
+ // Convert "" to null
+ return null;
+ }
+ return parsedValue.intValue();
+ }
+
+ public String convertToPresentation(Integer value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ public Class<Integer> getModelType() {
+ return Integer.class;
+ }
+
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
index 64944a434c..d1816007e7 100644
--- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
@@ -1,107 +1,107 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Number} to {@link String} and back.
- * Uses the given locale and {@link NumberFormat} for formatting and parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToNumberConverter implements Converter<String, Number> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Number, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Number convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Number value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Number> getModelType() {
- return Number.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Number} to {@link String} and back.
+ * Uses the given locale and {@link NumberFormat} for formatting and parsing.
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToNumberConverter implements Converter<String, Number> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Number, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ return NumberFormat.getNumberInstance(locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Number convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ // Parse and detect errors. If the full string was not used, it is
+ // an error.
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ if (parsedValue == null) {
+ // Convert "" to null
+ return null;
+ }
+ return parsedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Number value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Number> getModelType() {
+ return Number.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
index ac6efaa49b..788966048d 100644
--- a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
+++ b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
@@ -1,92 +1,92 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-
-/**
- * CacheFlushNotifier is a simple static notification mechanism to inform other
- * SQLContainers that the contents of their caches may have become stale.
- */
-class CacheFlushNotifier implements Serializable {
- /*
- * SQLContainer instance reference list and dead reference queue. Used for
- * the cache flush notification feature.
- */
- private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
- private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
-
- /**
- * Adds the given SQLContainer to the cache flush notification receiver list
- *
- * @param c
- * Container to add
- */
- public static void addInstance(SQLContainer c) {
- removeDeadReferences();
- if (c != null) {
- allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
- }
- }
-
- /**
- * Removes dead references from instance list
- */
- private static void removeDeadReferences() {
- java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
- .poll();
- while (dead != null) {
- allInstances.remove(dead);
- dead = deadInstances.poll();
- }
- }
-
- /**
- * Iterates through the instances and notifies containers which are
- * connected to the same table or are using the same query string.
- *
- * @param c
- * SQLContainer that issued the cache flush notification
- */
- public static void notifyOfCacheFlush(SQLContainer c) {
- removeDeadReferences();
- for (WeakReference<SQLContainer> wr : allInstances) {
- if (wr.get() != null) {
- SQLContainer wrc = wr.get();
- if (wrc == null) {
- continue;
- }
- /*
- * If the reference points to the container sending the
- * notification, do nothing.
- */
- if (wrc.equals(c)) {
- continue;
- }
- /* Compare QueryDelegate types and tableName/queryString */
- QueryDelegate wrQd = wrc.getQueryDelegate();
- QueryDelegate qd = c.getQueryDelegate();
- if (wrQd instanceof TableQuery
- && qd instanceof TableQuery
- && ((TableQuery) wrQd).getTableName().equals(
- ((TableQuery) qd).getTableName())) {
- wrc.refresh();
- } else if (wrQd instanceof FreeformQuery
- && qd instanceof FreeformQuery
- && ((FreeformQuery) wrQd).getQueryString().equals(
- ((FreeformQuery) qd).getQueryString())) {
- wrc.refresh();
- }
- }
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+
+/**
+ * CacheFlushNotifier is a simple static notification mechanism to inform other
+ * SQLContainers that the contents of their caches may have become stale.
+ */
+class CacheFlushNotifier implements Serializable {
+ /*
+ * SQLContainer instance reference list and dead reference queue. Used for
+ * the cache flush notification feature.
+ */
+ private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
+ private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
+
+ /**
+ * Adds the given SQLContainer to the cache flush notification receiver list
+ *
+ * @param c
+ * Container to add
+ */
+ public static void addInstance(SQLContainer c) {
+ removeDeadReferences();
+ if (c != null) {
+ allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
+ }
+ }
+
+ /**
+ * Removes dead references from instance list
+ */
+ private static void removeDeadReferences() {
+ java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
+ .poll();
+ while (dead != null) {
+ allInstances.remove(dead);
+ dead = deadInstances.poll();
+ }
+ }
+
+ /**
+ * Iterates through the instances and notifies containers which are
+ * connected to the same table or are using the same query string.
+ *
+ * @param c
+ * SQLContainer that issued the cache flush notification
+ */
+ public static void notifyOfCacheFlush(SQLContainer c) {
+ removeDeadReferences();
+ for (WeakReference<SQLContainer> wr : allInstances) {
+ if (wr.get() != null) {
+ SQLContainer wrc = wr.get();
+ if (wrc == null) {
+ continue;
+ }
+ /*
+ * If the reference points to the container sending the
+ * notification, do nothing.
+ */
+ if (wrc.equals(c)) {
+ continue;
+ }
+ /* Compare QueryDelegate types and tableName/queryString */
+ QueryDelegate wrQd = wrc.getQueryDelegate();
+ QueryDelegate qd = c.getQueryDelegate();
+ if (wrQd instanceof TableQuery
+ && qd instanceof TableQuery
+ && ((TableQuery) wrQd).getTableName().equals(
+ ((TableQuery) qd).getTableName())) {
+ wrc.refresh();
+ } else if (wrQd instanceof FreeformQuery
+ && qd instanceof FreeformQuery
+ && ((FreeformQuery) wrQd).getQueryString().equals(
+ ((FreeformQuery) qd).getQueryString())) {
+ wrc.refresh();
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
index 44921dd12d..839fceb3c2 100644
--- a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
+++ b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
@@ -1,31 +1,31 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
- * number of items. In SQLContainer this is used for RowItem -cache. Cache size
- * will be two times the page length parameter of the container.
- */
-class CacheMap<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = 679999766473555231L;
- private int cacheLimit = SQLContainer.CACHE_RATIO
- * SQLContainer.DEFAULT_PAGE_LENGTH;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
- return size() > cacheLimit;
- }
-
- void setCacheLimit(int limit) {
- cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
- }
-
- int getCacheLimit() {
- return cacheLimit;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
+ * number of items. In SQLContainer this is used for RowItem -cache. Cache size
+ * will be two times the page length parameter of the container.
+ */
+class CacheMap<K, V> extends LinkedHashMap<K, V> {
+ private static final long serialVersionUID = 679999766473555231L;
+ private int cacheLimit = SQLContainer.CACHE_RATIO
+ * SQLContainer.DEFAULT_PAGE_LENGTH;
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+ return size() > cacheLimit;
+ }
+
+ void setCacheLimit(int limit) {
+ cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
+ }
+
+ int getCacheLimit() {
+ return cacheLimit;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/Reference.java b/src/com/vaadin/data/util/sqlcontainer/Reference.java
index 6e863fa040..dea1aa87c0 100644
--- a/src/com/vaadin/data/util/sqlcontainer/Reference.java
+++ b/src/com/vaadin/data/util/sqlcontainer/Reference.java
@@ -1,56 +1,56 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * The reference class represents a simple [usually foreign key] reference to
- * another SQLContainer. Actual foreign key reference in the database is not
- * required, but it is recommended to make sure that certain constraints are
- * followed.
- */
-@SuppressWarnings("serial")
-class Reference implements Serializable {
-
- /**
- * The SQLContainer that this reference points to.
- */
- private SQLContainer referencedContainer;
-
- /**
- * The column ID/name in the referencing SQLContainer that contains the key
- * used for the reference.
- */
- private String referencingColumn;
-
- /**
- * The column ID/name in the referenced SQLContainer that contains the key
- * used for the reference.
- */
- private String referencedColumn;
-
- /**
- * Constructs a new reference to be used within the SQLContainer to
- * reference another SQLContainer.
- */
- Reference(SQLContainer referencedContainer, String referencingColumn,
- String referencedColumn) {
- this.referencedContainer = referencedContainer;
- this.referencingColumn = referencingColumn;
- this.referencedColumn = referencedColumn;
- }
-
- SQLContainer getReferencedContainer() {
- return referencedContainer;
- }
-
- String getReferencingColumn() {
- return referencingColumn;
- }
-
- String getReferencedColumn() {
- return referencedColumn;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+
+/**
+ * The reference class represents a simple [usually foreign key] reference to
+ * another SQLContainer. Actual foreign key reference in the database is not
+ * required, but it is recommended to make sure that certain constraints are
+ * followed.
+ */
+@SuppressWarnings("serial")
+class Reference implements Serializable {
+
+ /**
+ * The SQLContainer that this reference points to.
+ */
+ private SQLContainer referencedContainer;
+
+ /**
+ * The column ID/name in the referencing SQLContainer that contains the key
+ * used for the reference.
+ */
+ private String referencingColumn;
+
+ /**
+ * The column ID/name in the referenced SQLContainer that contains the key
+ * used for the reference.
+ */
+ private String referencedColumn;
+
+ /**
+ * Constructs a new reference to be used within the SQLContainer to
+ * reference another SQLContainer.
+ */
+ Reference(SQLContainer referencedContainer, String referencingColumn,
+ String referencedColumn) {
+ this.referencedContainer = referencedContainer;
+ this.referencingColumn = referencingColumn;
+ this.referencedColumn = referencedColumn;
+ }
+
+ SQLContainer getReferencedContainer() {
+ return referencedContainer;
+ }
+
+ String getReferencingColumn() {
+ return referencingColumn;
+ }
+
+ String getReferencedColumn() {
+ return referencedColumn;
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/RowId.java b/src/com/vaadin/data/util/sqlcontainer/RowId.java
index ed01b72e06..925325134a 100644
--- a/src/com/vaadin/data/util/sqlcontainer/RowId.java
+++ b/src/com/vaadin/data/util/sqlcontainer/RowId.java
@@ -1,81 +1,81 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * RowId represents identifiers of a single database result set row.
- *
- * The data structure of a RowId is an Object array which contains the values of
- * the primary key columns of the identified row. This allows easy equals()
- * -comparison of RowItems.
- */
-public class RowId implements Serializable {
- private static final long serialVersionUID = -3161778404698901258L;
- protected Object[] id;
-
- /**
- * Prevent instantiation without required parameters.
- */
- protected RowId() {
- }
-
- public RowId(Object[] id) {
- if (id == null) {
- throw new IllegalArgumentException("id parameter must not be null!");
- }
- this.id = id;
- }
-
- public Object[] getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- int result = 31;
- if (id != null) {
- for (Object o : id) {
- if (o != null) {
- result += o.hashCode();
- }
- }
- }
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RowId)) {
- return false;
- }
- Object[] compId = ((RowId) obj).getId();
- if (id == null && compId == null) {
- return true;
- }
- if (id.length != compId.length) {
- return false;
- }
- for (int i = 0; i < id.length; i++) {
- if ((id[i] == null && compId[i] != null)
- || (id[i] != null && !id[i].equals(compId[i]))) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- StringBuffer s = new StringBuffer();
- for (int i = 0; i < id.length; i++) {
- s.append(id[i]);
- if (i < id.length - 1) {
- s.append("/");
- }
- }
- return s.toString();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+
+/**
+ * RowId represents identifiers of a single database result set row.
+ *
+ * The data structure of a RowId is an Object array which contains the values of
+ * the primary key columns of the identified row. This allows easy equals()
+ * -comparison of RowItems.
+ */
+public class RowId implements Serializable {
+ private static final long serialVersionUID = -3161778404698901258L;
+ protected Object[] id;
+
+ /**
+ * Prevent instantiation without required parameters.
+ */
+ protected RowId() {
+ }
+
+ public RowId(Object[] id) {
+ if (id == null) {
+ throw new IllegalArgumentException("id parameter must not be null!");
+ }
+ this.id = id;
+ }
+
+ public Object[] getId() {
+ return id;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 31;
+ if (id != null) {
+ for (Object o : id) {
+ if (o != null) {
+ result += o.hashCode();
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof RowId)) {
+ return false;
+ }
+ Object[] compId = ((RowId) obj).getId();
+ if (id == null && compId == null) {
+ return true;
+ }
+ if (id.length != compId.length) {
+ return false;
+ }
+ for (int i = 0; i < id.length; i++) {
+ if ((id[i] == null && compId[i] != null)
+ || (id[i] != null && !id[i].equals(compId[i]))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ for (int i = 0; i < id.length; i++) {
+ s.append(id[i]);
+ if (i < id.length - 1) {
+ s.append("/");
+ }
+ }
+ return s.toString();
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
index c1a7c61eab..2a1068e786 100644
--- a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
+++ b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
@@ -1,165 +1,165 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Simple implementation of the JDBCConnectionPool interface. Handles loading
- * the JDBC driver, setting up the connections and ensuring they are still
- * usable upon release.
- */
-@SuppressWarnings("serial")
-public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
-
- private int initialConnections = 5;
- private int maxConnections = 20;
-
- private String driverName;
- private String connectionUri;
- private String userName;
- private String password;
-
- private transient Set<Connection> availableConnections;
- private transient Set<Connection> reservedConnections;
-
- private boolean initialized;
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password) throws SQLException {
- if (driverName == null) {
- throw new IllegalArgumentException(
- "JDBC driver class name must be given.");
- }
- if (connectionUri == null) {
- throw new IllegalArgumentException(
- "Database connection URI must be given.");
- }
- if (userName == null) {
- throw new IllegalArgumentException(
- "Database username must be given.");
- }
- if (password == null) {
- throw new IllegalArgumentException(
- "Database password must be given.");
- }
- this.driverName = driverName;
- this.connectionUri = connectionUri;
- this.userName = userName;
- this.password = password;
-
- /* Initialize JDBC driver */
- try {
- Class.forName(driverName).newInstance();
- } catch (Exception ex) {
- throw new RuntimeException("Specified JDBC Driver: " + driverName
- + " - initialization failed.", ex);
- }
- }
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password, int initialConnections,
- int maxConnections) throws SQLException {
- this(driverName, connectionUri, userName, password);
- this.initialConnections = initialConnections;
- this.maxConnections = maxConnections;
- }
-
- private void initializeConnections() throws SQLException {
- availableConnections = new HashSet<Connection>(initialConnections);
- reservedConnections = new HashSet<Connection>(initialConnections);
- for (int i = 0; i < initialConnections; i++) {
- availableConnections.add(createConnection());
- }
- initialized = true;
- }
-
- public synchronized Connection reserveConnection() throws SQLException {
- if (!initialized) {
- initializeConnections();
- }
- if (availableConnections.isEmpty()) {
- if (reservedConnections.size() < maxConnections) {
- availableConnections.add(createConnection());
- } else {
- throw new SQLException("Connection limit has been reached.");
- }
- }
-
- Connection c = availableConnections.iterator().next();
- availableConnections.remove(c);
- reservedConnections.add(c);
-
- return c;
- }
-
- public synchronized void releaseConnection(Connection conn) {
- if (conn == null || !initialized) {
- return;
- }
- /* Try to roll back if necessary */
- try {
- if (!conn.getAutoCommit()) {
- conn.rollback();
- }
- } catch (SQLException e) {
- /* Roll back failed, close and discard connection */
- try {
- conn.close();
- } catch (SQLException e1) {
- /* Nothing needs to be done */
- }
- reservedConnections.remove(conn);
- return;
- }
- reservedConnections.remove(conn);
- availableConnections.add(conn);
- }
-
- private Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(connectionUri, userName,
- password);
- c.setAutoCommit(false);
- if (driverName.toLowerCase().contains("mysql")) {
- try {
- Statement s = c.createStatement();
- s.execute("SET SESSION sql_mode = 'ANSI'");
- s.close();
- } catch (Exception e) {
- // Failed to set ansi mode; continue
- }
- }
- return c;
- }
-
- public void destroy() {
- for (Connection c : availableConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
- for (Connection c : reservedConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
-
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- initialized = false;
- out.defaultWriteObject();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple implementation of the JDBCConnectionPool interface. Handles loading
+ * the JDBC driver, setting up the connections and ensuring they are still
+ * usable upon release.
+ */
+@SuppressWarnings("serial")
+public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
+
+ private int initialConnections = 5;
+ private int maxConnections = 20;
+
+ private String driverName;
+ private String connectionUri;
+ private String userName;
+ private String password;
+
+ private transient Set<Connection> availableConnections;
+ private transient Set<Connection> reservedConnections;
+
+ private boolean initialized;
+
+ public SimpleJDBCConnectionPool(String driverName, String connectionUri,
+ String userName, String password) throws SQLException {
+ if (driverName == null) {
+ throw new IllegalArgumentException(
+ "JDBC driver class name must be given.");
+ }
+ if (connectionUri == null) {
+ throw new IllegalArgumentException(
+ "Database connection URI must be given.");
+ }
+ if (userName == null) {
+ throw new IllegalArgumentException(
+ "Database username must be given.");
+ }
+ if (password == null) {
+ throw new IllegalArgumentException(
+ "Database password must be given.");
+ }
+ this.driverName = driverName;
+ this.connectionUri = connectionUri;
+ this.userName = userName;
+ this.password = password;
+
+ /* Initialize JDBC driver */
+ try {
+ Class.forName(driverName).newInstance();
+ } catch (Exception ex) {
+ throw new RuntimeException("Specified JDBC Driver: " + driverName
+ + " - initialization failed.", ex);
+ }
+ }
+
+ public SimpleJDBCConnectionPool(String driverName, String connectionUri,
+ String userName, String password, int initialConnections,
+ int maxConnections) throws SQLException {
+ this(driverName, connectionUri, userName, password);
+ this.initialConnections = initialConnections;
+ this.maxConnections = maxConnections;
+ }
+
+ private void initializeConnections() throws SQLException {
+ availableConnections = new HashSet<Connection>(initialConnections);
+ reservedConnections = new HashSet<Connection>(initialConnections);
+ for (int i = 0; i < initialConnections; i++) {
+ availableConnections.add(createConnection());
+ }
+ initialized = true;
+ }
+
+ public synchronized Connection reserveConnection() throws SQLException {
+ if (!initialized) {
+ initializeConnections();
+ }
+ if (availableConnections.isEmpty()) {
+ if (reservedConnections.size() < maxConnections) {
+ availableConnections.add(createConnection());
+ } else {
+ throw new SQLException("Connection limit has been reached.");
+ }
+ }
+
+ Connection c = availableConnections.iterator().next();
+ availableConnections.remove(c);
+ reservedConnections.add(c);
+
+ return c;
+ }
+
+ public synchronized void releaseConnection(Connection conn) {
+ if (conn == null || !initialized) {
+ return;
+ }
+ /* Try to roll back if necessary */
+ try {
+ if (!conn.getAutoCommit()) {
+ conn.rollback();
+ }
+ } catch (SQLException e) {
+ /* Roll back failed, close and discard connection */
+ try {
+ conn.close();
+ } catch (SQLException e1) {
+ /* Nothing needs to be done */
+ }
+ reservedConnections.remove(conn);
+ return;
+ }
+ reservedConnections.remove(conn);
+ availableConnections.add(conn);
+ }
+
+ private Connection createConnection() throws SQLException {
+ Connection c = DriverManager.getConnection(connectionUri, userName,
+ password);
+ c.setAutoCommit(false);
+ if (driverName.toLowerCase().contains("mysql")) {
+ try {
+ Statement s = c.createStatement();
+ s.execute("SET SESSION sql_mode = 'ANSI'");
+ s.close();
+ } catch (Exception e) {
+ // Failed to set ansi mode; continue
+ }
+ }
+ return c;
+ }
+
+ public void destroy() {
+ for (Connection c : availableConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) {
+ // No need to do anything
+ }
+ }
+ for (Connection c : reservedConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) {
+ // No need to do anything
+ }
+ }
+
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ initialized = false;
+ out.defaultWriteObject();
+ }
+
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
index 2ea151c578..95521c5019 100644
--- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
+++ b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
@@ -1,57 +1,57 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-/**
- * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
- * provides definitions for methods that produce StatementHelper objects instead
- * of basic query strings. This allows the FreeformQuery query delegate to use
- * PreparedStatements instead of regular Statement when accessing the database.
- *
- * Due to the injection protection and other benefits of prepared statements, it
- * is advisable to implement this interface instead of the FreeformQueryDelegate
- * whenever possible.
- */
-public interface FreeformStatementDelegate extends FreeformQueryDelegate {
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement. This
- * method is responsible for gluing together the select query from the
- * filters and the order by conditions if these are supported.
- *
- * @param offset
- * the first record (row) to fetch.
- * @param pagelength
- * the number of records (rows) to fetch. 0 means all records
- * starting from offset.
- */
- public StatementHelper getQueryStatement(int offset, int limit)
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement that
- * will fetch the row count from the DB. Row count should be fetched using
- * filters that are currently set to the QueryDelegate.
- */
- public StatementHelper getCountStatement()
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement used
- * by the FreeformQuery.containsRowWithKeys() method. This is useful for
- * cases when the default logic in said method is not enough to support more
- * complex free form queries.
- *
- * @param keys
- * the values of the primary keys
- * @throws UnsupportedOperationException
- * to use the default logic in FreeformQuery
- */
- public StatementHelper getContainsRowQueryStatement(Object... keys)
- throws UnsupportedOperationException;
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.query;
+
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+
+/**
+ * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
+ * provides definitions for methods that produce StatementHelper objects instead
+ * of basic query strings. This allows the FreeformQuery query delegate to use
+ * PreparedStatements instead of regular Statement when accessing the database.
+ *
+ * Due to the injection protection and other benefits of prepared statements, it
+ * is advisable to implement this interface instead of the FreeformQueryDelegate
+ * whenever possible.
+ */
+public interface FreeformStatementDelegate extends FreeformQueryDelegate {
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement. This
+ * method is responsible for gluing together the select query from the
+ * filters and the order by conditions if these are supported.
+ *
+ * @param offset
+ * the first record (row) to fetch.
+ * @param pagelength
+ * the number of records (rows) to fetch. 0 means all records
+ * starting from offset.
+ */
+ public StatementHelper getQueryStatement(int offset, int limit)
+ throws UnsupportedOperationException;
+
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement that
+ * will fetch the row count from the DB. Row count should be fetched using
+ * filters that are currently set to the QueryDelegate.
+ */
+ public StatementHelper getCountStatement()
+ throws UnsupportedOperationException;
+
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement used
+ * by the FreeformQuery.containsRowWithKeys() method. This is useful for
+ * cases when the default logic in said method is not enough to support more
+ * complex free form queries.
+ *
+ * @param keys
+ * the values of the primary keys
+ * @throws UnsupportedOperationException
+ * to use the default logic in FreeformQuery
+ */
+ public StatementHelper getContainsRowQueryStatement(Object... keys)
+ throws UnsupportedOperationException;
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
index 888f1ec501..3fd92e920d 100644
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
+++ b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
@@ -1,135 +1,135 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * StatementHelper is a simple helper class that assists TableQuery and the
- * query generators in filling a PreparedStatement. The actual statement is
- * generated by the query generator methods, but the resulting statement and all
- * the parameter values are stored in an instance of StatementHelper.
- *
- * This class will also fill the values with correct setters into the
- * PreparedStatement on request.
- */
-public class StatementHelper implements Serializable {
-
- private String queryString;
-
- private List<Object> parameters = new ArrayList<Object>();
- private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
-
- public StatementHelper() {
- }
-
- public void setQueryString(String queryString) {
- this.queryString = queryString;
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public void addParameterValue(Object parameter) {
- if (parameter != null) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, parameter.getClass());
- }
- }
-
- public void addParameterValue(Object parameter, Class<?> type) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, type);
- }
-
- public void setParameterValuesToStatement(PreparedStatement pstmt)
- throws SQLException {
- for (int i = 0; i < parameters.size(); i++) {
- if (parameters.get(i) == null) {
- handleNullValue(i, pstmt);
- } else {
- pstmt.setObject(i + 1, parameters.get(i));
- }
- }
-
- /*
- * The following list contains the data types supported by
- * PreparedStatement but not supported by SQLContainer:
- *
- * [The list is provided as PreparedStatement method signatures]
- *
- * setNCharacterStream(int parameterIndex, Reader value)
- *
- * setNClob(int parameterIndex, NClob value)
- *
- * setNString(int parameterIndex, String value)
- *
- * setRef(int parameterIndex, Ref x)
- *
- * setRowId(int parameterIndex, RowId x)
- *
- * setSQLXML(int parameterIndex, SQLXML xmlObject)
- *
- * setBytes(int parameterIndex, byte[] x)
- *
- * setCharacterStream(int parameterIndex, Reader reader)
- *
- * setClob(int parameterIndex, Clob x)
- *
- * setURL(int parameterIndex, URL x)
- *
- * setArray(int parameterIndex, Array x)
- *
- * setAsciiStream(int parameterIndex, InputStream x)
- *
- * setBinaryStream(int parameterIndex, InputStream x)
- *
- * setBlob(int parameterIndex, Blob x)
- */
- }
-
- private void handleNullValue(int i, PreparedStatement pstmt)
- throws SQLException {
- if (BigDecimal.class.equals(dataTypes.get(i))) {
- pstmt.setBigDecimal(i + 1, null);
- } else if (Boolean.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BOOLEAN);
- } else if (Byte.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (Date.class.equals(dataTypes.get(i))) {
- pstmt.setDate(i + 1, null);
- } else if (Double.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.DOUBLE);
- } else if (Float.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.FLOAT);
- } else if (Integer.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.INTEGER);
- } else if (Long.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BIGINT);
- } else if (Short.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (String.class.equals(dataTypes.get(i))) {
- pstmt.setString(i + 1, null);
- } else if (Time.class.equals(dataTypes.get(i))) {
- pstmt.setTime(i + 1, null);
- } else if (Timestamp.class.equals(dataTypes.get(i))) {
- pstmt.setTimestamp(i + 1, null);
- } else {
- throw new SQLException("Data type not supported by SQLContainer: "
- + parameters.get(i).getClass().toString());
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.query.generator;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * StatementHelper is a simple helper class that assists TableQuery and the
+ * query generators in filling a PreparedStatement. The actual statement is
+ * generated by the query generator methods, but the resulting statement and all
+ * the parameter values are stored in an instance of StatementHelper.
+ *
+ * This class will also fill the values with correct setters into the
+ * PreparedStatement on request.
+ */
+public class StatementHelper implements Serializable {
+
+ private String queryString;
+
+ private List<Object> parameters = new ArrayList<Object>();
+ private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
+
+ public StatementHelper() {
+ }
+
+ public void setQueryString(String queryString) {
+ this.queryString = queryString;
+ }
+
+ public String getQueryString() {
+ return queryString;
+ }
+
+ public void addParameterValue(Object parameter) {
+ if (parameter != null) {
+ parameters.add(parameter);
+ dataTypes.put(parameters.size() - 1, parameter.getClass());
+ }
+ }
+
+ public void addParameterValue(Object parameter, Class<?> type) {
+ parameters.add(parameter);
+ dataTypes.put(parameters.size() - 1, type);
+ }
+
+ public void setParameterValuesToStatement(PreparedStatement pstmt)
+ throws SQLException {
+ for (int i = 0; i < parameters.size(); i++) {
+ if (parameters.get(i) == null) {
+ handleNullValue(i, pstmt);
+ } else {
+ pstmt.setObject(i + 1, parameters.get(i));
+ }
+ }
+
+ /*
+ * The following list contains the data types supported by
+ * PreparedStatement but not supported by SQLContainer:
+ *
+ * [The list is provided as PreparedStatement method signatures]
+ *
+ * setNCharacterStream(int parameterIndex, Reader value)
+ *
+ * setNClob(int parameterIndex, NClob value)
+ *
+ * setNString(int parameterIndex, String value)
+ *
+ * setRef(int parameterIndex, Ref x)
+ *
+ * setRowId(int parameterIndex, RowId x)
+ *
+ * setSQLXML(int parameterIndex, SQLXML xmlObject)
+ *
+ * setBytes(int parameterIndex, byte[] x)
+ *
+ * setCharacterStream(int parameterIndex, Reader reader)
+ *
+ * setClob(int parameterIndex, Clob x)
+ *
+ * setURL(int parameterIndex, URL x)
+ *
+ * setArray(int parameterIndex, Array x)
+ *
+ * setAsciiStream(int parameterIndex, InputStream x)
+ *
+ * setBinaryStream(int parameterIndex, InputStream x)
+ *
+ * setBlob(int parameterIndex, Blob x)
+ */
+ }
+
+ private void handleNullValue(int i, PreparedStatement pstmt)
+ throws SQLException {
+ if (BigDecimal.class.equals(dataTypes.get(i))) {
+ pstmt.setBigDecimal(i + 1, null);
+ } else if (Boolean.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.BOOLEAN);
+ } else if (Byte.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.SMALLINT);
+ } else if (Date.class.equals(dataTypes.get(i))) {
+ pstmt.setDate(i + 1, null);
+ } else if (Double.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.DOUBLE);
+ } else if (Float.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.FLOAT);
+ } else if (Integer.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.INTEGER);
+ } else if (Long.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.BIGINT);
+ } else if (Short.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.SMALLINT);
+ } else if (String.class.equals(dataTypes.get(i))) {
+ pstmt.setString(i + 1, null);
+ } else if (Time.class.equals(dataTypes.get(i))) {
+ pstmt.setTime(i + 1, null);
+ } else if (Timestamp.class.equals(dataTypes.get(i))) {
+ pstmt.setTimestamp(i + 1, null);
+ } else {
+ throw new SQLException("Data type not supported by SQLContainer: "
+ + parameters.get(i).getClass().toString());
+ }
+ }
+}
diff --git a/src/com/vaadin/data/validator/BeanValidator.java b/src/com/vaadin/data/validator/BeanValidator.java
index 939fd2e9c4..817df85248 100644
--- a/src/com/vaadin/data/validator/BeanValidator.java
+++ b/src/com/vaadin/data/validator/BeanValidator.java
@@ -1,173 +1,173 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.MessageInterpolator.Context;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.metadata.ConstraintDescriptor;
-
-import com.vaadin.data.Validator;
-
-/**
- * Vaadin {@link Validator} using the JSR-303 (javax.validation)
- * annotation-based bean validation.
- *
- * The annotations of the fields of the beans are used to determine the
- * validation to perform.
- *
- * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
- * Validation - formerly agimatec validation) must be present on the project
- * classpath when using bean validation.
- *
- * @since 7.0
- *
- * @author Petri Hakala
- * @author Henri Sara
- */
-public class BeanValidator implements Validator {
-
- private static final long serialVersionUID = 1L;
- private static ValidatorFactory factory;
-
- private transient javax.validation.Validator javaxBeanValidator;
- private String propertyName;
- private Class<?> beanClass;
- private Locale locale;
-
- /**
- * Simple implementation of a message interpolator context that returns
- * fixed values.
- */
- protected static class SimpleContext implements Context, Serializable {
-
- private final Object value;
- private final ConstraintDescriptor<?> descriptor;
-
- /**
- * Create a simple immutable message interpolator context.
- *
- * @param value
- * value being validated
- * @param descriptor
- * ConstraintDescriptor corresponding to the constraint being
- * validated
- */
- public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
- this.value = value;
- this.descriptor = descriptor;
- }
-
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return descriptor;
- }
-
- public Object getValidatedValue() {
- return value;
- }
-
- }
-
- /**
- * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
- *
- * @param beanClass
- * bean class based on which the validation should be performed
- * @param propertyName
- * property to validate
- */
- public BeanValidator(Class<?> beanClass, String propertyName) {
- this.beanClass = beanClass;
- this.propertyName = propertyName;
- locale = Locale.getDefault();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Validator#validate(java.lang.Object)
- */
- public void validate(final Object value) throws InvalidValueException {
- Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
- propertyName, value);
- if (violations.size() > 0) {
- List<String> exceptions = new ArrayList<String>();
- for (Object v : violations) {
- final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
- String msg = getJavaxBeanValidatorFactory()
- .getMessageInterpolator().interpolate(
- violation.getMessageTemplate(),
- new SimpleContext(value, violation
- .getConstraintDescriptor()), locale);
- exceptions.add(msg);
- }
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < exceptions.size(); i++) {
- if (i != 0) {
- b.append("<br/>");
- }
- b.append(exceptions.get(i));
- }
- throw new InvalidValueException(b.toString());
- }
- }
-
- /**
- * Sets the locale used for validation error messages.
- *
- * Revalidation is not automatically triggered by setting the locale.
- *
- * @param locale
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Gets the locale used for validation error messages.
- *
- * @return locale used for validation
- */
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Returns the underlying JSR-303 bean validator factory used. A factory is
- * created using {@link Validation} if necessary.
- *
- * @return {@link ValidatorFactory} to use
- */
- protected static ValidatorFactory getJavaxBeanValidatorFactory() {
- if (factory == null) {
- factory = Validation.buildDefaultValidatorFactory();
- }
-
- return factory;
- }
-
- /**
- * Returns a shared Validator instance to use. An instance is created using
- * the validator factory if necessary and thereafter reused by the
- * {@link BeanValidator} instance.
- *
- * @return the JSR-303 {@link javax.validation.Validator} to use
- */
- protected javax.validation.Validator getJavaxBeanValidator() {
- if (javaxBeanValidator == null) {
- javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
- }
-
- return javaxBeanValidator;
- }
-
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.validator;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.MessageInterpolator.Context;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.metadata.ConstraintDescriptor;
+
+import com.vaadin.data.Validator;
+
+/**
+ * Vaadin {@link Validator} using the JSR-303 (javax.validation)
+ * annotation-based bean validation.
+ *
+ * The annotations of the fields of the beans are used to determine the
+ * validation to perform.
+ *
+ * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
+ * Validation - formerly agimatec validation) must be present on the project
+ * classpath when using bean validation.
+ *
+ * @since 7.0
+ *
+ * @author Petri Hakala
+ * @author Henri Sara
+ */
+public class BeanValidator implements Validator {
+
+ private static final long serialVersionUID = 1L;
+ private static ValidatorFactory factory;
+
+ private transient javax.validation.Validator javaxBeanValidator;
+ private String propertyName;
+ private Class<?> beanClass;
+ private Locale locale;
+
+ /**
+ * Simple implementation of a message interpolator context that returns
+ * fixed values.
+ */
+ protected static class SimpleContext implements Context, Serializable {
+
+ private final Object value;
+ private final ConstraintDescriptor<?> descriptor;
+
+ /**
+ * Create a simple immutable message interpolator context.
+ *
+ * @param value
+ * value being validated
+ * @param descriptor
+ * ConstraintDescriptor corresponding to the constraint being
+ * validated
+ */
+ public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
+ this.value = value;
+ this.descriptor = descriptor;
+ }
+
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return descriptor;
+ }
+
+ public Object getValidatedValue() {
+ return value;
+ }
+
+ }
+
+ /**
+ * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
+ *
+ * @param beanClass
+ * bean class based on which the validation should be performed
+ * @param propertyName
+ * property to validate
+ */
+ public BeanValidator(Class<?> beanClass, String propertyName) {
+ this.beanClass = beanClass;
+ this.propertyName = propertyName;
+ locale = Locale.getDefault();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Validator#validate(java.lang.Object)
+ */
+ public void validate(final Object value) throws InvalidValueException {
+ Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
+ propertyName, value);
+ if (violations.size() > 0) {
+ List<String> exceptions = new ArrayList<String>();
+ for (Object v : violations) {
+ final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
+ String msg = getJavaxBeanValidatorFactory()
+ .getMessageInterpolator().interpolate(
+ violation.getMessageTemplate(),
+ new SimpleContext(value, violation
+ .getConstraintDescriptor()), locale);
+ exceptions.add(msg);
+ }
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < exceptions.size(); i++) {
+ if (i != 0) {
+ b.append("<br/>");
+ }
+ b.append(exceptions.get(i));
+ }
+ throw new InvalidValueException(b.toString());
+ }
+ }
+
+ /**
+ * Sets the locale used for validation error messages.
+ *
+ * Revalidation is not automatically triggered by setting the locale.
+ *
+ * @param locale
+ */
+ public void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * Gets the locale used for validation error messages.
+ *
+ * @return locale used for validation
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Returns the underlying JSR-303 bean validator factory used. A factory is
+ * created using {@link Validation} if necessary.
+ *
+ * @return {@link ValidatorFactory} to use
+ */
+ protected static ValidatorFactory getJavaxBeanValidatorFactory() {
+ if (factory == null) {
+ factory = Validation.buildDefaultValidatorFactory();
+ }
+
+ return factory;
+ }
+
+ /**
+ * Returns a shared Validator instance to use. An instance is created using
+ * the validator factory if necessary and thereafter reused by the
+ * {@link BeanValidator} instance.
+ *
+ * @return the JSR-303 {@link javax.validation.Validator} to use
+ */
+ protected javax.validation.Validator getJavaxBeanValidator() {
+ if (javaxBeanValidator == null) {
+ javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
+ }
+
+ return javaxBeanValidator;
+ }
+
} \ No newline at end of file
diff --git a/src/com/vaadin/data/validator/DateRangeValidator.java b/src/com/vaadin/data/validator/DateRangeValidator.java
index 42f5a224ed..24f3d3ce10 100644
--- a/src/com/vaadin/data/validator/DateRangeValidator.java
+++ b/src/com/vaadin/data/validator/DateRangeValidator.java
@@ -1,51 +1,51 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import java.util.Date;
-
-import com.vaadin.ui.DateField.Resolution;
-
-/**
- * Validator for validating that a Date is inside a given range.
- *
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateRangeValidator extends RangeValidator<Date> {
-
- /**
- * Creates a validator for checking that an Date is within a given range.
- * <p>
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- * </p>
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public DateRangeValidator(String errorMessage, Date minValue,
- Date maxValue, Resolution resolution) {
- super(errorMessage, Date.class, minValue, maxValue);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.validator;
+
+import java.util.Date;
+
+import com.vaadin.ui.DateField.Resolution;
+
+/**
+ * Validator for validating that a Date is inside a given range.
+ *
+ * <p>
+ * Note that the comparison is done directly on the Date object so take care
+ * that the hours/minutes/seconds/milliseconds of the min/max values are
+ * properly set.
+ * </p>
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DateRangeValidator extends RangeValidator<Date> {
+
+ /**
+ * Creates a validator for checking that an Date is within a given range.
+ * <p>
+ * By default the range is inclusive i.e. both minValue and maxValue are
+ * valid values. Use {@link #setMinValueIncluded(boolean)} or
+ * {@link #setMaxValueIncluded(boolean)} to change it.
+ * </p>
+ * <p>
+ * Note that the comparison is done directly on the Date object so take care
+ * that the hours/minutes/seconds/milliseconds of the min/max values are
+ * properly set.
+ * </p>
+ *
+ * @param errorMessage
+ * the message to display in case the value does not validate.
+ * @param minValue
+ * The minimum value to accept or null for no limit
+ * @param maxValue
+ * The maximum value to accept or null for no limit
+ */
+ public DateRangeValidator(String errorMessage, Date minValue,
+ Date maxValue, Resolution resolution) {
+ super(errorMessage, Date.class, minValue, maxValue);
+ }
+
+}
diff --git a/src/com/vaadin/data/validator/RangeValidator.java b/src/com/vaadin/data/validator/RangeValidator.java
index 457f046360..433271274f 100644
--- a/src/com/vaadin/data/validator/RangeValidator.java
+++ b/src/com/vaadin/data/validator/RangeValidator.java
@@ -1,186 +1,186 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * An base implementation for validating any objects that implement
- * {@link Comparable}.
- *
- * Verifies that the value is of the given type and within the (optionally)
- * given limits. Typically you want to use a sub class of this like
- * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
- * {@link DateRangeValidator} in applications.
- * <p>
- * Note that {@link RangeValidator} always accept null values. Make a field
- * required to ensure that no empty values are accepted or override
- * {@link #isValidValue(Comparable)}.
- * </p>
- *
- * @param <T>
- * The type of Number to validate. Must implement Comparable so that
- * minimum and maximum checks work.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
-
- private T minValue = null;
- private boolean minValueIncluded = true;
- private T maxValue = null;
- private boolean maxValueIncluded = true;
- private Class<T> type;
-
- /**
- * Creates a new range validator of the given type.
- *
- * @param errorMessage
- * The error message to use if validation fails
- * @param type
- * The type of object the validator can validate.
- * @param minValue
- * The minimum value that should be accepted or null for no limit
- * @param maxValue
- * The maximum value that should be accepted or null for no limit
- */
- public RangeValidator(String errorMessage, Class<T> type, T minValue,
- T maxValue) {
- super(errorMessage);
- this.type = type;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-
- /**
- * Checks if the minimum value is part of the accepted range
- *
- * @return true if the minimum value is part of the range, false otherwise
- */
- public boolean isMinValueIncluded() {
- return minValueIncluded;
- }
-
- /**
- * Sets if the minimum value is part of the accepted range
- *
- * @param minValueIncluded
- * true if the minimum value should be part of the range, false
- * otherwise
- */
- public void setMinValueIncluded(boolean minValueIncluded) {
- this.minValueIncluded = minValueIncluded;
- }
-
- /**
- * Checks if the maximum value is part of the accepted range
- *
- * @return true if the maximum value is part of the range, false otherwise
- */
- public boolean isMaxValueIncluded() {
- return maxValueIncluded;
- }
-
- /**
- * Sets if the maximum value is part of the accepted range
- *
- * @param maxValueIncluded
- * true if the maximum value should be part of the range, false
- * otherwise
- */
- public void setMaxValueIncluded(boolean maxValueIncluded) {
- this.maxValueIncluded = maxValueIncluded;
- }
-
- /**
- * Gets the minimum value of the range
- *
- * @return the minimum value
- */
- public T getMinValue() {
- return minValue;
- }
-
- /**
- * Sets the minimum value of the range. Use
- * {@link #setMinValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param minValue
- * the minimum value
- */
- public void setMinValue(T minValue) {
- this.minValue = minValue;
- }
-
- /**
- * Gets the maximum value of the range
- *
- * @return the maximum value
- */
- public T getMaxValue() {
- return maxValue;
- }
-
- /**
- * Sets the maximum value of the range. Use
- * {@link #setMaxValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param maxValue
- * the maximum value
- */
- public void setMaxValue(T maxValue) {
- this.maxValue = maxValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
- * )
- */
- @Override
- protected boolean isValidValue(T value) {
- if (value == null) {
- return true;
- }
-
- if (getMinValue() != null) {
- // Ensure that the min limit is ok
- int result = value.compareTo(getMinValue());
- if (result < 0) {
- // value less than min value
- return false;
- } else if (result == 0 && !isMinValueIncluded()) {
- // values equal and min value not included
- return false;
- }
- }
- if (getMaxValue() != null) {
- // Ensure that the Max limit is ok
- int result = value.compareTo(getMaxValue());
- if (result > 0) {
- // value greater than max value
- return false;
- } else if (result == 0 && !isMaxValueIncluded()) {
- // values equal and max value not included
- return false;
- }
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.validator.AbstractValidator#getType()
- */
- @Override
- public Class<T> getType() {
- return type;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.validator;
+
+/**
+ * An base implementation for validating any objects that implement
+ * {@link Comparable}.
+ *
+ * Verifies that the value is of the given type and within the (optionally)
+ * given limits. Typically you want to use a sub class of this like
+ * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
+ * {@link DateRangeValidator} in applications.
+ * <p>
+ * Note that {@link RangeValidator} always accept null values. Make a field
+ * required to ensure that no empty values are accepted or override
+ * {@link #isValidValue(Comparable)}.
+ * </p>
+ *
+ * @param <T>
+ * The type of Number to validate. Must implement Comparable so that
+ * minimum and maximum checks work.
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
+
+ private T minValue = null;
+ private boolean minValueIncluded = true;
+ private T maxValue = null;
+ private boolean maxValueIncluded = true;
+ private Class<T> type;
+
+ /**
+ * Creates a new range validator of the given type.
+ *
+ * @param errorMessage
+ * The error message to use if validation fails
+ * @param type
+ * The type of object the validator can validate.
+ * @param minValue
+ * The minimum value that should be accepted or null for no limit
+ * @param maxValue
+ * The maximum value that should be accepted or null for no limit
+ */
+ public RangeValidator(String errorMessage, Class<T> type, T minValue,
+ T maxValue) {
+ super(errorMessage);
+ this.type = type;
+ this.minValue = minValue;
+ this.maxValue = maxValue;
+ }
+
+ /**
+ * Checks if the minimum value is part of the accepted range
+ *
+ * @return true if the minimum value is part of the range, false otherwise
+ */
+ public boolean isMinValueIncluded() {
+ return minValueIncluded;
+ }
+
+ /**
+ * Sets if the minimum value is part of the accepted range
+ *
+ * @param minValueIncluded
+ * true if the minimum value should be part of the range, false
+ * otherwise
+ */
+ public void setMinValueIncluded(boolean minValueIncluded) {
+ this.minValueIncluded = minValueIncluded;
+ }
+
+ /**
+ * Checks if the maximum value is part of the accepted range
+ *
+ * @return true if the maximum value is part of the range, false otherwise
+ */
+ public boolean isMaxValueIncluded() {
+ return maxValueIncluded;
+ }
+
+ /**
+ * Sets if the maximum value is part of the accepted range
+ *
+ * @param maxValueIncluded
+ * true if the maximum value should be part of the range, false
+ * otherwise
+ */
+ public void setMaxValueIncluded(boolean maxValueIncluded) {
+ this.maxValueIncluded = maxValueIncluded;
+ }
+
+ /**
+ * Gets the minimum value of the range
+ *
+ * @return the minimum value
+ */
+ public T getMinValue() {
+ return minValue;
+ }
+
+ /**
+ * Sets the minimum value of the range. Use
+ * {@link #setMinValueIncluded(boolean)} to control whether this value is
+ * part of the range or not.
+ *
+ * @param minValue
+ * the minimum value
+ */
+ public void setMinValue(T minValue) {
+ this.minValue = minValue;
+ }
+
+ /**
+ * Gets the maximum value of the range
+ *
+ * @return the maximum value
+ */
+ public T getMaxValue() {
+ return maxValue;
+ }
+
+ /**
+ * Sets the maximum value of the range. Use
+ * {@link #setMaxValueIncluded(boolean)} to control whether this value is
+ * part of the range or not.
+ *
+ * @param maxValue
+ * the maximum value
+ */
+ public void setMaxValue(T maxValue) {
+ this.maxValue = maxValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
+ * )
+ */
+ @Override
+ protected boolean isValidValue(T value) {
+ if (value == null) {
+ return true;
+ }
+
+ if (getMinValue() != null) {
+ // Ensure that the min limit is ok
+ int result = value.compareTo(getMinValue());
+ if (result < 0) {
+ // value less than min value
+ return false;
+ } else if (result == 0 && !isMinValueIncluded()) {
+ // values equal and min value not included
+ return false;
+ }
+ }
+ if (getMaxValue() != null) {
+ // Ensure that the Max limit is ok
+ int result = value.compareTo(getMaxValue());
+ if (result > 0) {
+ // value greater than max value
+ return false;
+ } else if (result == 0 && !isMaxValueIncluded()) {
+ // values equal and max value not included
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.validator.AbstractValidator#getType()
+ */
+ @Override
+ public Class<T> getType() {
+ return type;
+ }
+
+}
diff --git a/src/com/vaadin/event/FieldEvents.java b/src/com/vaadin/event/FieldEvents.java
index 202abba078..28fd6bb4f7 100644
--- a/src/com/vaadin/event/FieldEvents.java
+++ b/src/com/vaadin/event/FieldEvents.java
@@ -1,250 +1,250 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Field.ValueChangeEvent;
-import com.vaadin.ui.TextField;
-
-/**
- * Interface that serves as a wrapper for {@link Field} related events.
- */
-public interface FieldEvents {
-
- /**
- * The interface for adding and removing <code>FocusEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>FocusEvent</code> when it receives keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see FocusListener
- * @see FocusEvent
- */
- public interface FocusNotifier extends Serializable {
- /**
- * Adds a <code>FocusListener</code> to the Component which gets fired
- * when a <code>Field</code> receives keyboard focus.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void addListener(FocusListener listener);
-
- /**
- * Removes a <code>FocusListener</code> from the Component.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void removeListener(FocusListener listener);
- }
-
- /**
- * The interface for adding and removing <code>BlurEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>BlurEvent</code> when it loses keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see BlurListener
- * @see BlurEvent
- */
- public interface BlurNotifier extends Serializable {
- /**
- * Adds a <code>BlurListener</code> to the Component which gets fired
- * when a <code>Field</code> loses keyboard focus.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void addListener(BlurListener listener);
-
- /**
- * Removes a <code>BlurListener</code> from the Component.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void removeListener(BlurListener listener);
- }
-
- /**
- * <code>FocusEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> receives keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class FocusEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.FOCUS;
-
- public FocusEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>FocusListener</code> interface for listening for
- * <code>FocusEvent</code> fired by a <code>Field</code>.
- *
- * @see FocusEvent
- * @since 6.2
- */
- public interface FocusListener extends ComponentEventListener {
-
- public static final Method focusMethod = ReflectTools.findMethod(
- FocusListener.class, "focus", FocusEvent.class);
-
- /**
- * Component has been focused
- *
- * @param event
- * Component focus event.
- */
- public void focus(FocusEvent event);
- }
-
- /**
- * <code>BlurEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> loses keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class BlurEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.BLUR;
-
- public BlurEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>BlurListener</code> interface for listening for
- * <code>BlurEvent</code> fired by a <code>Field</code>.
- *
- * @see BlurEvent
- * @since 6.2
- */
- public interface BlurListener extends ComponentEventListener {
-
- public static final Method blurMethod = ReflectTools.findMethod(
- BlurListener.class, "blur", BlurEvent.class);
-
- /**
- * Component has been blurred
- *
- * @param event
- * Component blur event.
- */
- public void blur(BlurEvent event);
- }
-
- /**
- * TextChangeEvents are fired when the user is editing the text content of a
- * field. Most commonly text change events are triggered by typing text with
- * keyboard, but e.g. pasting content from clip board to a text field also
- * triggers an event.
- * <p>
- * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are
- * triggered repeatedly while the end user is filling the field.
- * ValueChangeEvents are not fired until the user for example hits enter or
- * focuses another field. Also note the difference that TextChangeEvents are
- * only fired if the change is triggered from the user, while
- * ValueChangeEvents are also fired if the field value is set by the
- * application code.
- * <p>
- * The {@link TextChangeNotifier}s implementation may decide when exactly
- * TextChangeEvents are fired. TextChangeEvents are not necessary fire for
- * example on each key press, but buffered with a small delay. The
- * {@link TextField} component supports different modes for triggering
- * TextChangeEvents.
- *
- * @see TextChangeListener
- * @see TextChangeNotifier
- * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode)
- * @since 6.5
- */
- public static abstract class TextChangeEvent extends Component.Event {
- public TextChangeEvent(Component source) {
- super(source);
- }
-
- /**
- * @return the text content of the field after the
- * {@link TextChangeEvent}
- */
- public abstract String getText();
-
- /**
- * @return the cursor position during after the {@link TextChangeEvent}
- */
- public abstract int getCursorPosition();
- }
-
- /**
- * A listener for {@link TextChangeEvent}s.
- *
- * @since 6.5
- */
- public interface TextChangeListener extends ComponentEventListener {
-
- public static String EVENT_ID = "ie";
- public static Method EVENT_METHOD = ReflectTools.findMethod(
- TextChangeListener.class, "textChange", TextChangeEvent.class);
-
- /**
- * This method is called repeatedly while the text is edited by a user.
- *
- * @param event
- * the event providing details of the text change
- */
- public void textChange(TextChangeEvent event);
- }
-
- /**
- * An interface implemented by a {@link Field} supporting
- * {@link TextChangeEvent}s. An example a {@link TextField} supports
- * {@link TextChangeListener}s.
- */
- public interface TextChangeNotifier extends Serializable {
- public void addListener(TextChangeListener listener);
-
- public void removeListener(TextChangeListener listener);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.event;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.tools.ReflectTools;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Field.ValueChangeEvent;
+import com.vaadin.ui.TextField;
+
+/**
+ * Interface that serves as a wrapper for {@link Field} related events.
+ */
+public interface FieldEvents {
+
+ /**
+ * The interface for adding and removing <code>FocusEvent</code> listeners.
+ * By implementing this interface a class explicitly announces that it will
+ * generate a <code>FocusEvent</code> when it receives keyboard focus.
+ * <p>
+ * Note: The general Java convention is not to explicitly declare that a
+ * class generates events, but to directly define the
+ * <code>addListener</code> and <code>removeListener</code> methods. That
+ * way the caller of these methods has no real way of finding out if the
+ * class really will send the events, or if it just defines the methods to
+ * be able to implement an interface.
+ * </p>
+ *
+ * @since 6.2
+ * @see FocusListener
+ * @see FocusEvent
+ */
+ public interface FocusNotifier extends Serializable {
+ /**
+ * Adds a <code>FocusListener</code> to the Component which gets fired
+ * when a <code>Field</code> receives keyboard focus.
+ *
+ * @param listener
+ * @see FocusListener
+ * @since 6.2
+ */
+ public void addListener(FocusListener listener);
+
+ /**
+ * Removes a <code>FocusListener</code> from the Component.
+ *
+ * @param listener
+ * @see FocusListener
+ * @since 6.2
+ */
+ public void removeListener(FocusListener listener);
+ }
+
+ /**
+ * The interface for adding and removing <code>BlurEvent</code> listeners.
+ * By implementing this interface a class explicitly announces that it will
+ * generate a <code>BlurEvent</code> when it loses keyboard focus.
+ * <p>
+ * Note: The general Java convention is not to explicitly declare that a
+ * class generates events, but to directly define the
+ * <code>addListener</code> and <code>removeListener</code> methods. That
+ * way the caller of these methods has no real way of finding out if the
+ * class really will send the events, or if it just defines the methods to
+ * be able to implement an interface.
+ * </p>
+ *
+ * @since 6.2
+ * @see BlurListener
+ * @see BlurEvent
+ */
+ public interface BlurNotifier extends Serializable {
+ /**
+ * Adds a <code>BlurListener</code> to the Component which gets fired
+ * when a <code>Field</code> loses keyboard focus.
+ *
+ * @param listener
+ * @see BlurListener
+ * @since 6.2
+ */
+ public void addListener(BlurListener listener);
+
+ /**
+ * Removes a <code>BlurListener</code> from the Component.
+ *
+ * @param listener
+ * @see BlurListener
+ * @since 6.2
+ */
+ public void removeListener(BlurListener listener);
+ }
+
+ /**
+ * <code>FocusEvent</code> class for holding additional event information.
+ * Fired when a <code>Field</code> receives keyboard focus.
+ *
+ * @since 6.2
+ */
+ @SuppressWarnings("serial")
+ public class FocusEvent extends Component.Event {
+
+ /**
+ * Identifier for event that can be used in {@link EventRouter}
+ */
+ public static final String EVENT_ID = EventId.FOCUS;
+
+ public FocusEvent(Component source) {
+ super(source);
+ }
+ }
+
+ /**
+ * <code>FocusListener</code> interface for listening for
+ * <code>FocusEvent</code> fired by a <code>Field</code>.
+ *
+ * @see FocusEvent
+ * @since 6.2
+ */
+ public interface FocusListener extends ComponentEventListener {
+
+ public static final Method focusMethod = ReflectTools.findMethod(
+ FocusListener.class, "focus", FocusEvent.class);
+
+ /**
+ * Component has been focused
+ *
+ * @param event
+ * Component focus event.
+ */
+ public void focus(FocusEvent event);
+ }
+
+ /**
+ * <code>BlurEvent</code> class for holding additional event information.
+ * Fired when a <code>Field</code> loses keyboard focus.
+ *
+ * @since 6.2
+ */
+ @SuppressWarnings("serial")
+ public class BlurEvent extends Component.Event {
+
+ /**
+ * Identifier for event that can be used in {@link EventRouter}
+ */
+ public static final String EVENT_ID = EventId.BLUR;
+
+ public BlurEvent(Component source) {
+ super(source);
+ }
+ }
+
+ /**
+ * <code>BlurListener</code> interface for listening for
+ * <code>BlurEvent</code> fired by a <code>Field</code>.
+ *
+ * @see BlurEvent
+ * @since 6.2
+ */
+ public interface BlurListener extends ComponentEventListener {
+
+ public static final Method blurMethod = ReflectTools.findMethod(
+ BlurListener.class, "blur", BlurEvent.class);
+
+ /**
+ * Component has been blurred
+ *
+ * @param event
+ * Component blur event.
+ */
+ public void blur(BlurEvent event);
+ }
+
+ /**
+ * TextChangeEvents are fired when the user is editing the text content of a
+ * field. Most commonly text change events are triggered by typing text with
+ * keyboard, but e.g. pasting content from clip board to a text field also
+ * triggers an event.
+ * <p>
+ * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are
+ * triggered repeatedly while the end user is filling the field.
+ * ValueChangeEvents are not fired until the user for example hits enter or
+ * focuses another field. Also note the difference that TextChangeEvents are
+ * only fired if the change is triggered from the user, while
+ * ValueChangeEvents are also fired if the field value is set by the
+ * application code.
+ * <p>
+ * The {@link TextChangeNotifier}s implementation may decide when exactly
+ * TextChangeEvents are fired. TextChangeEvents are not necessary fire for
+ * example on each key press, but buffered with a small delay. The
+ * {@link TextField} component supports different modes for triggering
+ * TextChangeEvents.
+ *
+ * @see TextChangeListener
+ * @see TextChangeNotifier
+ * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode)
+ * @since 6.5
+ */
+ public static abstract class TextChangeEvent extends Component.Event {
+ public TextChangeEvent(Component source) {
+ super(source);
+ }
+
+ /**
+ * @return the text content of the field after the
+ * {@link TextChangeEvent}
+ */
+ public abstract String getText();
+
+ /**
+ * @return the cursor position during after the {@link TextChangeEvent}
+ */
+ public abstract int getCursorPosition();
+ }
+
+ /**
+ * A listener for {@link TextChangeEvent}s.
+ *
+ * @since 6.5
+ */
+ public interface TextChangeListener extends ComponentEventListener {
+
+ public static String EVENT_ID = "ie";
+ public static Method EVENT_METHOD = ReflectTools.findMethod(
+ TextChangeListener.class, "textChange", TextChangeEvent.class);
+
+ /**
+ * This method is called repeatedly while the text is edited by a user.
+ *
+ * @param event
+ * the event providing details of the text change
+ */
+ public void textChange(TextChangeEvent event);
+ }
+
+ /**
+ * An interface implemented by a {@link Field} supporting
+ * {@link TextChangeEvent}s. An example a {@link TextField} supports
+ * {@link TextChangeListener}s.
+ */
+ public interface TextChangeNotifier extends Serializable {
+ public void addListener(TextChangeListener listener);
+
+ public void removeListener(TextChangeListener listener);
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONException.java b/src/com/vaadin/external/json/JSONException.java
index 9d97a32d7d..d799021506 100644
--- a/src/com/vaadin/external/json/JSONException.java
+++ b/src/com/vaadin/external/json/JSONException.java
@@ -1,28 +1,28 @@
-package com.vaadin.external.json;
-
-/**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
- * @author JSON.org
- * @version 2010-12-24
- */
-public class JSONException extends Exception {
- private static final long serialVersionUID = 0;
- private Throwable cause;
-
- /**
- * Constructs a JSONException with an explanatory message.
- * @param message Detail about the reason for the exception.
- */
- public JSONException(String message) {
- super(message);
- }
-
- public JSONException(Throwable cause) {
- super(cause.getMessage());
- this.cause = cause;
- }
-
- public Throwable getCause() {
- return this.cause;
- }
-}
+package com.vaadin.external.json;
+
+/**
+ * The JSONException is thrown by the JSON.org classes when things are amiss.
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class JSONException extends Exception {
+ private static final long serialVersionUID = 0;
+ private Throwable cause;
+
+ /**
+ * Constructs a JSONException with an explanatory message.
+ * @param message Detail about the reason for the exception.
+ */
+ public JSONException(String message) {
+ super(message);
+ }
+
+ public JSONException(Throwable cause) {
+ super(cause.getMessage());
+ this.cause = cause;
+ }
+
+ public Throwable getCause() {
+ return this.cause;
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONString.java b/src/com/vaadin/external/json/JSONString.java
index 7b574d1915..cc7e4d8c07 100644
--- a/src/com/vaadin/external/json/JSONString.java
+++ b/src/com/vaadin/external/json/JSONString.java
@@ -1,21 +1,21 @@
-package com.vaadin.external.json;
-
-import java.io.Serializable;
-
-/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
- * method so that a class can change the behavior of
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
- * <code>JSONWriter.value(</code>Object<code>)</code>. The
- * <code>toJSONString</code> method will be used instead of the default behavior
- * of using the Object's <code>toString()</code> method and quoting the result.
- */
-public interface JSONString extends Serializable {
- /**
- * The <code>toJSONString</code> method allows a class to produce its own
- * JSON serialization.
- *
- * @return A strictly syntactically correct JSON text.
- */
- public String toJSONString();
-}
+package com.vaadin.external.json;
+
+import java.io.Serializable;
+
+/**
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
+ * method so that a class can change the behavior of
+ * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
+ * <code>JSONWriter.value(</code>Object<code>)</code>. The
+ * <code>toJSONString</code> method will be used instead of the default behavior
+ * of using the Object's <code>toString()</code> method and quoting the result.
+ */
+public interface JSONString extends Serializable {
+ /**
+ * The <code>toJSONString</code> method allows a class to produce its own
+ * JSON serialization.
+ *
+ * @return A strictly syntactically correct JSON text.
+ */
+ public String toJSONString();
+}
diff --git a/src/com/vaadin/external/json/JSONStringer.java b/src/com/vaadin/external/json/JSONStringer.java
index c4a1af600a..465f27aaab 100644
--- a/src/com/vaadin/external/json/JSONStringer.java
+++ b/src/com/vaadin/external/json/JSONStringer.java
@@ -1,78 +1,78 @@
-package com.vaadin.external.json;
-
-/*
-Copyright (c) 2006 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.io.StringWriter;
-
-/**
- * JSONStringer provides a quick and convenient way of producing JSON text.
- * The texts produced strictly conform to JSON syntax rules. No whitespace is
- * added, so the results are ready for transmission or storage. Each instance of
- * JSONStringer can produce one JSON text.
- * <p>
- * A JSONStringer instance provides a <code>value</code> method for appending
- * values to the
- * text, and a <code>key</code>
- * method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound
- * object values. All of these methods return the JSONWriter instance,
- * permitting cascade style. For example, <pre>
- * myString = new JSONStringer()
- * .object()
- * .key("JSON")
- * .value("Hello, World!")
- * .endObject()
- * .toString();</pre> which produces the string <pre>
- * {"JSON":"Hello, World!"}</pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONStringer adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * @author JSON.org
- * @version 2008-09-18
- */
-public class JSONStringer extends JSONWriter {
- /**
- * Make a fresh JSONStringer. It can be used to build one JSON text.
- */
- public JSONStringer() {
- super(new StringWriter());
- }
-
- /**
- * Return the JSON text. This method is used to obtain the product of the
- * JSONStringer instance. It will return <code>null</code> if there was a
- * problem in the construction of the JSON text (such as the calls to
- * <code>array</code> were not properly balanced with calls to
- * <code>endArray</code>).
- * @return The JSON text.
- */
- public String toString() {
- return this.mode == 'd' ? this.writer.toString() : null;
- }
-}
+package com.vaadin.external.json;
+
+/*
+Copyright (c) 2006 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+import java.io.StringWriter;
+
+/**
+ * JSONStringer provides a quick and convenient way of producing JSON text.
+ * The texts produced strictly conform to JSON syntax rules. No whitespace is
+ * added, so the results are ready for transmission or storage. Each instance of
+ * JSONStringer can produce one JSON text.
+ * <p>
+ * A JSONStringer instance provides a <code>value</code> method for appending
+ * values to the
+ * text, and a <code>key</code>
+ * method for adding keys before values in objects. There are <code>array</code>
+ * and <code>endArray</code> methods that make and bound array values, and
+ * <code>object</code> and <code>endObject</code> methods which make and bound
+ * object values. All of these methods return the JSONWriter instance,
+ * permitting cascade style. For example, <pre>
+ * myString = new JSONStringer()
+ * .object()
+ * .key("JSON")
+ * .value("Hello, World!")
+ * .endObject()
+ * .toString();</pre> which produces the string <pre>
+ * {"JSON":"Hello, World!"}</pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONStringer adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ * @author JSON.org
+ * @version 2008-09-18
+ */
+public class JSONStringer extends JSONWriter {
+ /**
+ * Make a fresh JSONStringer. It can be used to build one JSON text.
+ */
+ public JSONStringer() {
+ super(new StringWriter());
+ }
+
+ /**
+ * Return the JSON text. This method is used to obtain the product of the
+ * JSONStringer instance. It will return <code>null</code> if there was a
+ * problem in the construction of the JSON text (such as the calls to
+ * <code>array</code> were not properly balanced with calls to
+ * <code>endArray</code>).
+ * @return The JSON text.
+ */
+ public String toString() {
+ return this.mode == 'd' ? this.writer.toString() : null;
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONWriter.java b/src/com/vaadin/external/json/JSONWriter.java
index 438721b7b2..5f9ddeeae2 100644
--- a/src/com/vaadin/external/json/JSONWriter.java
+++ b/src/com/vaadin/external/json/JSONWriter.java
@@ -1,355 +1,355 @@
-package com.vaadin.external.json;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-
-/*
- Copyright (c) 2006 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONWriter provides a quick and convenient way of producing JSON text. The
- * texts produced strictly conform to JSON syntax rules. No whitespace is added,
- * so the results are ready for transmission or storage. Each instance of
- * JSONWriter can produce one JSON text.
- * <p>
- * A JSONWriter instance provides a <code>value</code> method for appending
- * values to the text, and a <code>key</code> method for adding keys before
- * values in objects. There are <code>array</code> and <code>endArray</code>
- * methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting a cascade style. For
- * example,
- *
- * <pre>
- * new JSONWriter(myWriter).object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
- * .endObject();
- * </pre>
- *
- * which writes
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONWriter adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- *
- * @author JSON.org
- * @version 2011-11-14
- */
-public class JSONWriter implements Serializable {
- private static final int maxdepth = 200;
-
- /**
- * The comma flag determines if a comma should be output before the next
- * value.
- */
- private boolean comma;
-
- /**
- * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k'
- * (key), 'o' (object).
- */
- protected char mode;
-
- /**
- * The object/array stack.
- */
- private final JSONObject stack[];
-
- /**
- * The stack top index. A value of 0 indicates that the stack is empty.
- */
- private int top;
-
- /**
- * The writer that will receive the output.
- */
- protected Writer writer;
-
- /**
- * Make a fresh JSONWriter. It can be used to build one JSON text.
- */
- public JSONWriter(Writer w) {
- comma = false;
- mode = 'i';
- stack = new JSONObject[maxdepth];
- top = 0;
- writer = w;
- }
-
- /**
- * Append a value.
- *
- * @param string
- * A string value.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- private JSONWriter append(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null pointer");
- }
- if (mode == 'o' || mode == 'a') {
- try {
- if (comma && mode == 'a') {
- writer.write(',');
- }
- writer.write(string);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- if (mode == 'o') {
- mode = 'k';
- }
- comma = true;
- return this;
- }
- throw new JSONException("Value out of sequence.");
- }
-
- /**
- * Begin appending a new array. All values until the balancing
- * <code>endArray</code> will be appended to this array. The
- * <code>endArray</code> method must be called to mark the array's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter array() throws JSONException {
- if (mode == 'i' || mode == 'o' || mode == 'a') {
- push(null);
- append("[");
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced array.");
- }
-
- /**
- * End something.
- *
- * @param mode
- * Mode
- * @param c
- * Closing character
- * @return this
- * @throws JSONException
- * If unbalanced.
- */
- private JSONWriter end(char mode, char c) throws JSONException {
- if (this.mode != mode) {
- throw new JSONException(mode == 'a' ? "Misplaced endArray."
- : "Misplaced endObject.");
- }
- pop(mode);
- try {
- writer.write(c);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- comma = true;
- return this;
- }
-
- /**
- * End an array. This method most be called to balance calls to
- * <code>array</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endArray() throws JSONException {
- return end('a', ']');
- }
-
- /**
- * End an object. This method most be called to balance calls to
- * <code>object</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endObject() throws JSONException {
- return end('k', '}');
- }
-
- /**
- * Append a key. The key will be associated with the next value. In an
- * object, every value must be preceded by a key.
- *
- * @param string
- * A key string.
- * @return this
- * @throws JSONException
- * If the key is out of place. For example, keys do not belong
- * in arrays or if the key is null.
- */
- public JSONWriter key(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null key.");
- }
- if (mode == 'k') {
- try {
- stack[top - 1].putOnce(string, Boolean.TRUE);
- if (comma) {
- writer.write(',');
- }
- writer.write(JSONObject.quote(string));
- writer.write(':');
- comma = false;
- mode = 'o';
- return this;
- } catch (IOException e) {
- throw new JSONException(e);
- }
- }
- throw new JSONException("Misplaced key.");
- }
-
- /**
- * Begin appending a new object. All keys and values until the balancing
- * <code>endObject</code> will be appended to this object. The
- * <code>endObject</code> method must be called to mark the object's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter object() throws JSONException {
- if (mode == 'i') {
- mode = 'o';
- }
- if (mode == 'o' || mode == 'a') {
- append("{");
- push(new JSONObject());
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced object.");
-
- }
-
- /**
- * Pop an array or object scope.
- *
- * @param c
- * The scope to close.
- * @throws JSONException
- * If nesting is wrong.
- */
- private void pop(char c) throws JSONException {
- if (top <= 0) {
- throw new JSONException("Nesting error.");
- }
- char m = stack[top - 1] == null ? 'a' : 'k';
- if (m != c) {
- throw new JSONException("Nesting error.");
- }
- top -= 1;
- mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
- }
-
- /**
- * Push an array or object scope.
- *
- * @param c
- * The scope to open.
- * @throws JSONException
- * If nesting is too deep.
- */
- private void push(JSONObject jo) throws JSONException {
- if (top >= maxdepth) {
- throw new JSONException("Nesting too deep.");
- }
- stack[top] = jo;
- mode = jo == null ? 'a' : 'k';
- top += 1;
- }
-
- /**
- * Append either the value <code>true</code> or the value <code>false</code>
- * .
- *
- * @param b
- * A boolean.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(boolean b) throws JSONException {
- return append(b ? "true" : "false");
- }
-
- /**
- * Append a double value.
- *
- * @param d
- * A double.
- * @return this
- * @throws JSONException
- * If the number is not finite.
- */
- public JSONWriter value(double d) throws JSONException {
- return this.value(new Double(d));
- }
-
- /**
- * Append a long value.
- *
- * @param l
- * A long.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(long l) throws JSONException {
- return append(Long.toString(l));
- }
-
- /**
- * Append an object value.
- *
- * @param object
- * The object to append. It can be null, or a Boolean, Number,
- * String, JSONObject, or JSONArray, or an object that implements
- * JSONString.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- public JSONWriter value(Object object) throws JSONException {
- return append(JSONObject.valueToString(object));
- }
-}
+package com.vaadin.external.json;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+
+/*
+ Copyright (c) 2006 JSON.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ The Software shall be used for Good, not Evil.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+
+/**
+ * JSONWriter provides a quick and convenient way of producing JSON text. The
+ * texts produced strictly conform to JSON syntax rules. No whitespace is added,
+ * so the results are ready for transmission or storage. Each instance of
+ * JSONWriter can produce one JSON text.
+ * <p>
+ * A JSONWriter instance provides a <code>value</code> method for appending
+ * values to the text, and a <code>key</code> method for adding keys before
+ * values in objects. There are <code>array</code> and <code>endArray</code>
+ * methods that make and bound array values, and <code>object</code> and
+ * <code>endObject</code> methods which make and bound object values. All of
+ * these methods return the JSONWriter instance, permitting a cascade style. For
+ * example,
+ *
+ * <pre>
+ * new JSONWriter(myWriter).object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
+ * .endObject();
+ * </pre>
+ *
+ * which writes
+ *
+ * <pre>
+ * {"JSON":"Hello, World!"}
+ * </pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONWriter adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ *
+ * @author JSON.org
+ * @version 2011-11-14
+ */
+public class JSONWriter implements Serializable {
+ private static final int maxdepth = 200;
+
+ /**
+ * The comma flag determines if a comma should be output before the next
+ * value.
+ */
+ private boolean comma;
+
+ /**
+ * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k'
+ * (key), 'o' (object).
+ */
+ protected char mode;
+
+ /**
+ * The object/array stack.
+ */
+ private final JSONObject stack[];
+
+ /**
+ * The stack top index. A value of 0 indicates that the stack is empty.
+ */
+ private int top;
+
+ /**
+ * The writer that will receive the output.
+ */
+ protected Writer writer;
+
+ /**
+ * Make a fresh JSONWriter. It can be used to build one JSON text.
+ */
+ public JSONWriter(Writer w) {
+ comma = false;
+ mode = 'i';
+ stack = new JSONObject[maxdepth];
+ top = 0;
+ writer = w;
+ }
+
+ /**
+ * Append a value.
+ *
+ * @param string
+ * A string value.
+ * @return this
+ * @throws JSONException
+ * If the value is out of sequence.
+ */
+ private JSONWriter append(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null pointer");
+ }
+ if (mode == 'o' || mode == 'a') {
+ try {
+ if (comma && mode == 'a') {
+ writer.write(',');
+ }
+ writer.write(string);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ if (mode == 'o') {
+ mode = 'k';
+ }
+ comma = true;
+ return this;
+ }
+ throw new JSONException("Value out of sequence.");
+ }
+
+ /**
+ * Begin appending a new array. All values until the balancing
+ * <code>endArray</code> will be appended to this array. The
+ * <code>endArray</code> method must be called to mark the array's end.
+ *
+ * @return this
+ * @throws JSONException
+ * If the nesting is too deep, or if the object is started in
+ * the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter array() throws JSONException {
+ if (mode == 'i' || mode == 'o' || mode == 'a') {
+ push(null);
+ append("[");
+ comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced array.");
+ }
+
+ /**
+ * End something.
+ *
+ * @param mode
+ * Mode
+ * @param c
+ * Closing character
+ * @return this
+ * @throws JSONException
+ * If unbalanced.
+ */
+ private JSONWriter end(char mode, char c) throws JSONException {
+ if (this.mode != mode) {
+ throw new JSONException(mode == 'a' ? "Misplaced endArray."
+ : "Misplaced endObject.");
+ }
+ pop(mode);
+ try {
+ writer.write(c);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ comma = true;
+ return this;
+ }
+
+ /**
+ * End an array. This method most be called to balance calls to
+ * <code>array</code>.
+ *
+ * @return this
+ * @throws JSONException
+ * If incorrectly nested.
+ */
+ public JSONWriter endArray() throws JSONException {
+ return end('a', ']');
+ }
+
+ /**
+ * End an object. This method most be called to balance calls to
+ * <code>object</code>.
+ *
+ * @return this
+ * @throws JSONException
+ * If incorrectly nested.
+ */
+ public JSONWriter endObject() throws JSONException {
+ return end('k', '}');
+ }
+
+ /**
+ * Append a key. The key will be associated with the next value. In an
+ * object, every value must be preceded by a key.
+ *
+ * @param string
+ * A key string.
+ * @return this
+ * @throws JSONException
+ * If the key is out of place. For example, keys do not belong
+ * in arrays or if the key is null.
+ */
+ public JSONWriter key(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null key.");
+ }
+ if (mode == 'k') {
+ try {
+ stack[top - 1].putOnce(string, Boolean.TRUE);
+ if (comma) {
+ writer.write(',');
+ }
+ writer.write(JSONObject.quote(string));
+ writer.write(':');
+ comma = false;
+ mode = 'o';
+ return this;
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ }
+ throw new JSONException("Misplaced key.");
+ }
+
+ /**
+ * Begin appending a new object. All keys and values until the balancing
+ * <code>endObject</code> will be appended to this object. The
+ * <code>endObject</code> method must be called to mark the object's end.
+ *
+ * @return this
+ * @throws JSONException
+ * If the nesting is too deep, or if the object is started in
+ * the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter object() throws JSONException {
+ if (mode == 'i') {
+ mode = 'o';
+ }
+ if (mode == 'o' || mode == 'a') {
+ append("{");
+ push(new JSONObject());
+ comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced object.");
+
+ }
+
+ /**
+ * Pop an array or object scope.
+ *
+ * @param c
+ * The scope to close.
+ * @throws JSONException
+ * If nesting is wrong.
+ */
+ private void pop(char c) throws JSONException {
+ if (top <= 0) {
+ throw new JSONException("Nesting error.");
+ }
+ char m = stack[top - 1] == null ? 'a' : 'k';
+ if (m != c) {
+ throw new JSONException("Nesting error.");
+ }
+ top -= 1;
+ mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
+ }
+
+ /**
+ * Push an array or object scope.
+ *
+ * @param c
+ * The scope to open.
+ * @throws JSONException
+ * If nesting is too deep.
+ */
+ private void push(JSONObject jo) throws JSONException {
+ if (top >= maxdepth) {
+ throw new JSONException("Nesting too deep.");
+ }
+ stack[top] = jo;
+ mode = jo == null ? 'a' : 'k';
+ top += 1;
+ }
+
+ /**
+ * Append either the value <code>true</code> or the value <code>false</code>
+ * .
+ *
+ * @param b
+ * A boolean.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(boolean b) throws JSONException {
+ return append(b ? "true" : "false");
+ }
+
+ /**
+ * Append a double value.
+ *
+ * @param d
+ * A double.
+ * @return this
+ * @throws JSONException
+ * If the number is not finite.
+ */
+ public JSONWriter value(double d) throws JSONException {
+ return this.value(new Double(d));
+ }
+
+ /**
+ * Append a long value.
+ *
+ * @param l
+ * A long.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(long l) throws JSONException {
+ return append(Long.toString(l));
+ }
+
+ /**
+ * Append an object value.
+ *
+ * @param object
+ * The object to append. It can be null, or a Boolean, Number,
+ * String, JSONObject, or JSONArray, or an object that implements
+ * JSONString.
+ * @return this
+ * @throws JSONException
+ * If the value is out of sequence.
+ */
+ public JSONWriter value(Object object) throws JSONException {
+ return append(JSONObject.valueToString(object));
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 630f9bf99b..88d6009a29 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -45,11 +45,9 @@ import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
import com.vaadin.terminal.gwt.client.communication.SharedState;
import com.vaadin.terminal.gwt.client.ui.Field;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.VContextMenu;
import com.vaadin.terminal.gwt.client.ui.VNotification;
import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent;
-import com.vaadin.terminal.gwt.client.ui.VView;
import com.vaadin.terminal.gwt.client.ui.VViewPaintable;
import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager;
import com.vaadin.terminal.gwt.server.AbstractCommunicationManager;
@@ -177,7 +175,8 @@ public class ApplicationConnection {
private Set<VPaintableWidget> zeroHeightComponents = null;
public ApplicationConnection() {
- view = GWT.create(VView.class);
+ view = GWT.create(VViewPaintable.class);
+ view.setConnection(this);
}
public void init(WidgetSet widgetSet, ApplicationConfiguration cnf) {
@@ -2079,10 +2078,9 @@ public class ApplicationConnection {
if (!paintableMap.hasPaintable(pid)) {
// Create and register a new paintable if no old was found
VPaintableWidget p = widgetSet.createWidget(uidl, configuration);
- if (p instanceof VAbstractPaintableWidget) {
- ((VAbstractPaintableWidget) p).setConnection(this);
- ((VAbstractPaintableWidget) p).init();
- }
+ p.setConnection(this);
+ p.setId(pid);
+ p.init();
paintableMap.registerPaintable(pid, p);
}
return (VPaintableWidget) paintableMap.getPaintable(pid);
diff --git a/src/com/vaadin/terminal/gwt/client/DateTimeService.java b/src/com/vaadin/terminal/gwt/client/DateTimeService.java
index d368d655af..c0151d2819 100644
--- a/src/com/vaadin/terminal/gwt/client/DateTimeService.java
+++ b/src/com/vaadin/terminal/gwt/client/DateTimeService.java
@@ -1,439 +1,439 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.Date;
-
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.i18n.client.LocaleInfo;
-import com.vaadin.terminal.gwt.client.ui.VDateField;
-
-/**
- * This class provides date/time parsing services to all components on the
- * client side.
- *
- * @author Vaadin Ltd.
- *
- */
-@SuppressWarnings("deprecation")
-public class DateTimeService {
-
- private String currentLocale;
-
- private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
- 31, 30, 31 };
-
- /**
- * Creates a new date time service with the application default locale.
- */
- public DateTimeService() {
- currentLocale = LocaleService.getDefaultLocale();
- }
-
- /**
- * Creates a new date time service with a given locale.
- *
- * @param locale
- * e.g. fi, en etc.
- * @throws LocaleNotLoadedException
- */
- public DateTimeService(String locale) throws LocaleNotLoadedException {
- setLocale(locale);
- }
-
- public void setLocale(String locale) throws LocaleNotLoadedException {
- if (LocaleService.getAvailableLocales().contains(locale)) {
- currentLocale = locale;
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public String getLocale() {
- return currentLocale;
- }
-
- public String getMonth(int month) {
- try {
- return LocaleService.getMonthNames(currentLocale)[month];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getShortMonth(int month) {
- try {
- return LocaleService.getShortMonthNames(currentLocale)[month];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getDay(int day) {
- try {
- return LocaleService.getDayNames(currentLocale)[day];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getShortDay(int day) {
- try {
- return LocaleService.getShortDayNames(currentLocale)[day];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public int getFirstDayOfWeek() {
- try {
- return LocaleService.getFirstDayOfWeek(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return 0;
- }
- }
-
- public boolean isTwelveHourClock() {
- try {
- return LocaleService.isTwelveHourClock(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return false;
- }
- }
-
- public String getClockDelimeter() {
- try {
- return LocaleService.getClockDelimiter(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return ":";
- }
- }
-
- private static final String[] DEFAULT_AMPM_STRINGS = { "AM", "PM" };
-
- public String[] getAmPmStrings() {
- try {
- return LocaleService.getAmPmStrings(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- // TODO can this practically even happen? Should die instead?
- VConsole.error("Locale not loaded, using fallback : AM/PM");
- VConsole.error(e);
- return DEFAULT_AMPM_STRINGS;
- }
- }
-
- public int getStartWeekDay(Date date) {
- final Date dateForFirstOfThisMonth = new Date(date.getYear(),
- date.getMonth(), 1);
- int firstDay;
- try {
- firstDay = LocaleService.getFirstDayOfWeek(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error("Locale not loaded, using fallback 0");
- VConsole.error(e);
- firstDay = 0;
- }
- int start = dateForFirstOfThisMonth.getDay() - firstDay;
- if (start < 0) {
- start = 6;
- }
- return start;
- }
-
- public static void setMilliseconds(Date date, int ms) {
- date.setTime(date.getTime() / 1000 * 1000 + ms);
- }
-
- public static int getMilliseconds(Date date) {
- if (date == null) {
- return 0;
- }
-
- return (int) (date.getTime() - date.getTime() / 1000 * 1000);
- }
-
- public static int getNumberOfDaysInMonth(Date date) {
- final int month = date.getMonth();
- if (month == 1 && true == isLeapYear(date)) {
- return 29;
- }
- return maxDaysInMonth[month];
- }
-
- public static boolean isLeapYear(Date date) {
- // Instantiate the date for 1st March of that year
- final Date firstMarch = new Date(date.getYear(), 2, 1);
-
- // Go back 1 day
- final long firstMarchTime = firstMarch.getTime();
- final long lastDayTimeFeb = firstMarchTime - (24 * 60 * 60 * 1000); // NUM_MILLISECS_A_DAY
-
- // Instantiate new Date with this time
- final Date febLastDay = new Date(lastDayTimeFeb);
-
- // Check for date in this new instance
- return (29 == febLastDay.getDate()) ? true : false;
- }
-
- public static boolean isSameDay(Date d1, Date d2) {
- return (getDayInt(d1) == getDayInt(d2));
- }
-
- public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,
- int resolution) {
- Date s;
- Date e;
- if (rangeStart.after(rangeEnd)) {
- s = rangeEnd;
- e = rangeStart;
- } else {
- e = rangeEnd;
- s = rangeStart;
- }
- long start = s.getYear() * 10000000000l;
- long end = e.getYear() * 10000000000l;
- long target = date.getYear() * 10000000000l;
-
- if (resolution == VDateField.RESOLUTION_YEAR) {
- return (start <= target && end >= target);
- }
- start += s.getMonth() * 100000000l;
- end += e.getMonth() * 100000000l;
- target += date.getMonth() * 100000000l;
- if (resolution == VDateField.RESOLUTION_MONTH) {
- return (start <= target && end >= target);
- }
- start += s.getDate() * 1000000l;
- end += e.getDate() * 1000000l;
- target += date.getDate() * 1000000l;
- if (resolution == VDateField.RESOLUTION_DAY) {
- return (start <= target && end >= target);
- }
- start += s.getHours() * 10000l;
- end += e.getHours() * 10000l;
- target += date.getHours() * 10000l;
- if (resolution == VDateField.RESOLUTION_HOUR) {
- return (start <= target && end >= target);
- }
- start += s.getMinutes() * 100l;
- end += e.getMinutes() * 100l;
- target += date.getMinutes() * 100l;
- if (resolution == VDateField.RESOLUTION_MIN) {
- return (start <= target && end >= target);
- }
- start += s.getSeconds();
- end += e.getSeconds();
- target += date.getSeconds();
- return (start <= target && end >= target);
-
- }
-
- private static int getDayInt(Date date) {
- final int y = date.getYear();
- final int m = date.getMonth();
- final int d = date.getDate();
-
- return ((y + 1900) * 10000 + m * 100 + d) * 1000000000;
- }
-
- /**
- * Returns the ISO-8601 week number of the given date.
- *
- * @param date
- * The date for which the week number should be resolved
- * @return The ISO-8601 week number for {@literal date}
- */
- public static int getISOWeekNumber(Date date) {
- final long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
- int dayOfWeek = date.getDay(); // 0 == sunday
-
- // ISO 8601 use weeks that start on monday so we use
- // mon=1,tue=2,...sun=7;
- if (dayOfWeek == 0) {
- dayOfWeek = 7;
- }
- // Find nearest thursday (defines the week in ISO 8601). The week number
- // for the nearest thursday is the same as for the target date.
- int nearestThursdayDiff = 4 - dayOfWeek; // 4 is thursday
- Date nearestThursday = new Date(date.getTime() + nearestThursdayDiff
- * MILLISECONDS_PER_DAY);
-
- Date firstOfJanuary = new Date(nearestThursday.getYear(), 0, 1);
- long timeDiff = nearestThursday.getTime() - firstOfJanuary.getTime();
- int daysSinceFirstOfJanuary = (int) (timeDiff / MILLISECONDS_PER_DAY);
-
- int weekNumber = (daysSinceFirstOfJanuary) / 7 + 1;
-
- return weekNumber;
- }
-
- /**
- * Check if format contains the month name. If it does we manually convert
- * it to the month name since DateTimeFormat.format always uses the current
- * locale and will replace the month name wrong if current locale is
- * different from the locale set for the DateField.
- *
- * MMMM is converted into long month name, MMM is converted into short month
- * name. '' are added around the name to avoid that DateTimeFormat parses
- * the month name as a pattern.
- *
- * @param date
- * The date to convert
- * @param formatStr
- * The format string that might contain MMM or MMMM
- * @param dateTimeService
- * Reference to the Vaadin DateTimeService
- * @return
- */
- public String formatDate(Date date, String formatStr) {
- /*
- * Format month names separately when locale for the DateTimeService is
- * not the same as the browser locale
- */
- formatStr = formatMonthNames(date, formatStr);
-
- // Format uses the browser locale
- DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
-
- String result = format.format(date);
-
- return result;
- }
-
- private String formatMonthNames(Date date, String formatStr) {
- if (formatStr.contains("MMMM")) {
- String monthName = getMonth(date.getMonth());
-
- if (monthName != null) {
- /*
- * Replace 4 or more M:s with the quoted month name. Also
- * concatenate generated string with any other string prepending
- * or following the MMMM pattern, i.e. 'MMMM'ta ' becomes
- * 'MONTHta ' and not 'MONTH''ta ', 'ab'MMMM becomes 'abMONTH',
- * 'x'MMMM'y' becomes 'xMONTHy'.
- */
- formatStr = formatStr.replaceAll("'([M]{4,})'", monthName);
- formatStr = formatStr.replaceAll("([M]{4,})'", "'" + monthName);
- formatStr = formatStr.replaceAll("'([M]{4,})", monthName + "'");
- formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName
- + "'");
- }
- }
-
- if (formatStr.contains("MMM")) {
-
- String monthName = getShortMonth(date.getMonth());
-
- if (monthName != null) {
- /*
- * Replace 3 or more M:s with the quoted month name. Also
- * concatenate generated string with any other string prepending
- * or following the MMM pattern, i.e. 'MMM'ta ' becomes 'MONTHta
- * ' and not 'MONTH''ta ', 'ab'MMM becomes 'abMONTH', 'x'MMM'y'
- * becomes 'xMONTHy'.
- */
- formatStr = formatStr.replaceAll("'([M]{3,})'", monthName);
- formatStr = formatStr.replaceAll("([M]{3,})'", "'" + monthName);
- formatStr = formatStr.replaceAll("'([M]{3,})", monthName + "'");
- formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName
- + "'");
- }
- }
-
- return formatStr;
- }
-
- /**
- * Replaces month names in the entered date with the name in the current
- * browser locale.
- *
- * @param enteredDate
- * Date string e.g. "5 May 2010"
- * @param formatString
- * Format string e.g. "d M yyyy"
- * @return The date string where the month names have been replaced by the
- * browser locale version
- */
- private String parseMonthName(String enteredDate, String formatString) {
- LocaleInfo browserLocale = LocaleInfo.getCurrentLocale();
- if (browserLocale.getLocaleName().equals(getLocale())) {
- // No conversion needs to be done when locales match
- return enteredDate;
- }
- String[] browserMonthNames = browserLocale.getDateTimeConstants()
- .months();
- String[] browserShortMonthNames = browserLocale.getDateTimeConstants()
- .shortMonths();
-
- if (formatString.contains("MMMM")) {
- // Full month name
- for (int i = 0; i < 12; i++) {
- enteredDate = enteredDate.replaceAll(getMonth(i),
- browserMonthNames[i]);
- }
- }
- if (formatString.contains("MMM")) {
- // Short month name
- for (int i = 0; i < 12; i++) {
- enteredDate = enteredDate.replaceAll(getShortMonth(i),
- browserShortMonthNames[i]);
- }
- }
-
- return enteredDate;
- }
-
- /**
- * Parses the given date string using the given format string and the locale
- * set in this DateTimeService instance.
- *
- * @param dateString
- * Date string e.g. "1 February 2010"
- * @param formatString
- * Format string e.g. "d MMMM yyyy"
- * @param lenient
- * true to use lenient parsing, false to use strict parsing
- * @return A Date object representing the dateString. Never returns null.
- * @throws IllegalArgumentException
- * if the parsing fails
- *
- */
- public Date parseDate(String dateString, String formatString,
- boolean lenient) throws IllegalArgumentException {
- /* DateTimeFormat uses the browser's locale */
- DateTimeFormat format = DateTimeFormat.getFormat(formatString);
-
- /*
- * Parse month names separately when locale for the DateTimeService is
- * not the same as the browser locale
- */
- dateString = parseMonthName(dateString, formatString);
-
- Date date;
-
- if (lenient) {
- date = format.parse(dateString);
- } else {
- date = format.parseStrict(dateString);
- }
-
- // Some version of Firefox sets the timestamp to 0 if parsing fails.
- if (date != null && date.getTime() == 0) {
- throw new IllegalArgumentException("Parsing of '" + dateString
- + "' failed");
- }
-
- return date;
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.Date;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.LocaleInfo;
+import com.vaadin.terminal.gwt.client.ui.VDateField;
+
+/**
+ * This class provides date/time parsing services to all components on the
+ * client side.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+@SuppressWarnings("deprecation")
+public class DateTimeService {
+
+ private String currentLocale;
+
+ private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
+ 31, 30, 31 };
+
+ /**
+ * Creates a new date time service with the application default locale.
+ */
+ public DateTimeService() {
+ currentLocale = LocaleService.getDefaultLocale();
+ }
+
+ /**
+ * Creates a new date time service with a given locale.
+ *
+ * @param locale
+ * e.g. fi, en etc.
+ * @throws LocaleNotLoadedException
+ */
+ public DateTimeService(String locale) throws LocaleNotLoadedException {
+ setLocale(locale);
+ }
+
+ public void setLocale(String locale) throws LocaleNotLoadedException {
+ if (LocaleService.getAvailableLocales().contains(locale)) {
+ currentLocale = locale;
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public String getLocale() {
+ return currentLocale;
+ }
+
+ public String getMonth(int month) {
+ try {
+ return LocaleService.getMonthNames(currentLocale)[month];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getShortMonth(int month) {
+ try {
+ return LocaleService.getShortMonthNames(currentLocale)[month];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getDay(int day) {
+ try {
+ return LocaleService.getDayNames(currentLocale)[day];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getShortDay(int day) {
+ try {
+ return LocaleService.getShortDayNames(currentLocale)[day];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public int getFirstDayOfWeek() {
+ try {
+ return LocaleService.getFirstDayOfWeek(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return 0;
+ }
+ }
+
+ public boolean isTwelveHourClock() {
+ try {
+ return LocaleService.isTwelveHourClock(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return false;
+ }
+ }
+
+ public String getClockDelimeter() {
+ try {
+ return LocaleService.getClockDelimiter(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return ":";
+ }
+ }
+
+ private static final String[] DEFAULT_AMPM_STRINGS = { "AM", "PM" };
+
+ public String[] getAmPmStrings() {
+ try {
+ return LocaleService.getAmPmStrings(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ // TODO can this practically even happen? Should die instead?
+ VConsole.error("Locale not loaded, using fallback : AM/PM");
+ VConsole.error(e);
+ return DEFAULT_AMPM_STRINGS;
+ }
+ }
+
+ public int getStartWeekDay(Date date) {
+ final Date dateForFirstOfThisMonth = new Date(date.getYear(),
+ date.getMonth(), 1);
+ int firstDay;
+ try {
+ firstDay = LocaleService.getFirstDayOfWeek(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error("Locale not loaded, using fallback 0");
+ VConsole.error(e);
+ firstDay = 0;
+ }
+ int start = dateForFirstOfThisMonth.getDay() - firstDay;
+ if (start < 0) {
+ start = 6;
+ }
+ return start;
+ }
+
+ public static void setMilliseconds(Date date, int ms) {
+ date.setTime(date.getTime() / 1000 * 1000 + ms);
+ }
+
+ public static int getMilliseconds(Date date) {
+ if (date == null) {
+ return 0;
+ }
+
+ return (int) (date.getTime() - date.getTime() / 1000 * 1000);
+ }
+
+ public static int getNumberOfDaysInMonth(Date date) {
+ final int month = date.getMonth();
+ if (month == 1 && true == isLeapYear(date)) {
+ return 29;
+ }
+ return maxDaysInMonth[month];
+ }
+
+ public static boolean isLeapYear(Date date) {
+ // Instantiate the date for 1st March of that year
+ final Date firstMarch = new Date(date.getYear(), 2, 1);
+
+ // Go back 1 day
+ final long firstMarchTime = firstMarch.getTime();
+ final long lastDayTimeFeb = firstMarchTime - (24 * 60 * 60 * 1000); // NUM_MILLISECS_A_DAY
+
+ // Instantiate new Date with this time
+ final Date febLastDay = new Date(lastDayTimeFeb);
+
+ // Check for date in this new instance
+ return (29 == febLastDay.getDate()) ? true : false;
+ }
+
+ public static boolean isSameDay(Date d1, Date d2) {
+ return (getDayInt(d1) == getDayInt(d2));
+ }
+
+ public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,
+ int resolution) {
+ Date s;
+ Date e;
+ if (rangeStart.after(rangeEnd)) {
+ s = rangeEnd;
+ e = rangeStart;
+ } else {
+ e = rangeEnd;
+ s = rangeStart;
+ }
+ long start = s.getYear() * 10000000000l;
+ long end = e.getYear() * 10000000000l;
+ long target = date.getYear() * 10000000000l;
+
+ if (resolution == VDateField.RESOLUTION_YEAR) {
+ return (start <= target && end >= target);
+ }
+ start += s.getMonth() * 100000000l;
+ end += e.getMonth() * 100000000l;
+ target += date.getMonth() * 100000000l;
+ if (resolution == VDateField.RESOLUTION_MONTH) {
+ return (start <= target && end >= target);
+ }
+ start += s.getDate() * 1000000l;
+ end += e.getDate() * 1000000l;
+ target += date.getDate() * 1000000l;
+ if (resolution == VDateField.RESOLUTION_DAY) {
+ return (start <= target && end >= target);
+ }
+ start += s.getHours() * 10000l;
+ end += e.getHours() * 10000l;
+ target += date.getHours() * 10000l;
+ if (resolution == VDateField.RESOLUTION_HOUR) {
+ return (start <= target && end >= target);
+ }
+ start += s.getMinutes() * 100l;
+ end += e.getMinutes() * 100l;
+ target += date.getMinutes() * 100l;
+ if (resolution == VDateField.RESOLUTION_MIN) {
+ return (start <= target && end >= target);
+ }
+ start += s.getSeconds();
+ end += e.getSeconds();
+ target += date.getSeconds();
+ return (start <= target && end >= target);
+
+ }
+
+ private static int getDayInt(Date date) {
+ final int y = date.getYear();
+ final int m = date.getMonth();
+ final int d = date.getDate();
+
+ return ((y + 1900) * 10000 + m * 100 + d) * 1000000000;
+ }
+
+ /**
+ * Returns the ISO-8601 week number of the given date.
+ *
+ * @param date
+ * The date for which the week number should be resolved
+ * @return The ISO-8601 week number for {@literal date}
+ */
+ public static int getISOWeekNumber(Date date) {
+ final long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
+ int dayOfWeek = date.getDay(); // 0 == sunday
+
+ // ISO 8601 use weeks that start on monday so we use
+ // mon=1,tue=2,...sun=7;
+ if (dayOfWeek == 0) {
+ dayOfWeek = 7;
+ }
+ // Find nearest thursday (defines the week in ISO 8601). The week number
+ // for the nearest thursday is the same as for the target date.
+ int nearestThursdayDiff = 4 - dayOfWeek; // 4 is thursday
+ Date nearestThursday = new Date(date.getTime() + nearestThursdayDiff
+ * MILLISECONDS_PER_DAY);
+
+ Date firstOfJanuary = new Date(nearestThursday.getYear(), 0, 1);
+ long timeDiff = nearestThursday.getTime() - firstOfJanuary.getTime();
+ int daysSinceFirstOfJanuary = (int) (timeDiff / MILLISECONDS_PER_DAY);
+
+ int weekNumber = (daysSinceFirstOfJanuary) / 7 + 1;
+
+ return weekNumber;
+ }
+
+ /**
+ * Check if format contains the month name. If it does we manually convert
+ * it to the month name since DateTimeFormat.format always uses the current
+ * locale and will replace the month name wrong if current locale is
+ * different from the locale set for the DateField.
+ *
+ * MMMM is converted into long month name, MMM is converted into short month
+ * name. '' are added around the name to avoid that DateTimeFormat parses
+ * the month name as a pattern.
+ *
+ * @param date
+ * The date to convert
+ * @param formatStr
+ * The format string that might contain MMM or MMMM
+ * @param dateTimeService
+ * Reference to the Vaadin DateTimeService
+ * @return
+ */
+ public String formatDate(Date date, String formatStr) {
+ /*
+ * Format month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ formatStr = formatMonthNames(date, formatStr);
+
+ // Format uses the browser locale
+ DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
+
+ String result = format.format(date);
+
+ return result;
+ }
+
+ private String formatMonthNames(Date date, String formatStr) {
+ if (formatStr.contains("MMMM")) {
+ String monthName = getMonth(date.getMonth());
+
+ if (monthName != null) {
+ /*
+ * Replace 4 or more M:s with the quoted month name. Also
+ * concatenate generated string with any other string prepending
+ * or following the MMMM pattern, i.e. 'MMMM'ta ' becomes
+ * 'MONTHta ' and not 'MONTH''ta ', 'ab'MMMM becomes 'abMONTH',
+ * 'x'MMMM'y' becomes 'xMONTHy'.
+ */
+ formatStr = formatStr.replaceAll("'([M]{4,})'", monthName);
+ formatStr = formatStr.replaceAll("([M]{4,})'", "'" + monthName);
+ formatStr = formatStr.replaceAll("'([M]{4,})", monthName + "'");
+ formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ if (formatStr.contains("MMM")) {
+
+ String monthName = getShortMonth(date.getMonth());
+
+ if (monthName != null) {
+ /*
+ * Replace 3 or more M:s with the quoted month name. Also
+ * concatenate generated string with any other string prepending
+ * or following the MMM pattern, i.e. 'MMM'ta ' becomes 'MONTHta
+ * ' and not 'MONTH''ta ', 'ab'MMM becomes 'abMONTH', 'x'MMM'y'
+ * becomes 'xMONTHy'.
+ */
+ formatStr = formatStr.replaceAll("'([M]{3,})'", monthName);
+ formatStr = formatStr.replaceAll("([M]{3,})'", "'" + monthName);
+ formatStr = formatStr.replaceAll("'([M]{3,})", monthName + "'");
+ formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ return formatStr;
+ }
+
+ /**
+ * Replaces month names in the entered date with the name in the current
+ * browser locale.
+ *
+ * @param enteredDate
+ * Date string e.g. "5 May 2010"
+ * @param formatString
+ * Format string e.g. "d M yyyy"
+ * @return The date string where the month names have been replaced by the
+ * browser locale version
+ */
+ private String parseMonthName(String enteredDate, String formatString) {
+ LocaleInfo browserLocale = LocaleInfo.getCurrentLocale();
+ if (browserLocale.getLocaleName().equals(getLocale())) {
+ // No conversion needs to be done when locales match
+ return enteredDate;
+ }
+ String[] browserMonthNames = browserLocale.getDateTimeConstants()
+ .months();
+ String[] browserShortMonthNames = browserLocale.getDateTimeConstants()
+ .shortMonths();
+
+ if (formatString.contains("MMMM")) {
+ // Full month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getMonth(i),
+ browserMonthNames[i]);
+ }
+ }
+ if (formatString.contains("MMM")) {
+ // Short month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getShortMonth(i),
+ browserShortMonthNames[i]);
+ }
+ }
+
+ return enteredDate;
+ }
+
+ /**
+ * Parses the given date string using the given format string and the locale
+ * set in this DateTimeService instance.
+ *
+ * @param dateString
+ * Date string e.g. "1 February 2010"
+ * @param formatString
+ * Format string e.g. "d MMMM yyyy"
+ * @param lenient
+ * true to use lenient parsing, false to use strict parsing
+ * @return A Date object representing the dateString. Never returns null.
+ * @throws IllegalArgumentException
+ * if the parsing fails
+ *
+ */
+ public Date parseDate(String dateString, String formatString,
+ boolean lenient) throws IllegalArgumentException {
+ /* DateTimeFormat uses the browser's locale */
+ DateTimeFormat format = DateTimeFormat.getFormat(formatString);
+
+ /*
+ * Parse month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ dateString = parseMonthName(dateString, formatString);
+
+ Date date;
+
+ if (lenient) {
+ date = format.parse(dateString);
+ } else {
+ date = format.parseStrict(dateString);
+ }
+
+ // Some version of Firefox sets the timestamp to 0 if parsing fails.
+ if (date != null && date.getTime() == 0) {
+ throw new IllegalArgumentException("Parsing of '" + dateString
+ + "' failed");
+ }
+
+ return date;
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java b/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
index 4d0a9faf97..871495c79e 100644
--- a/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
+++ b/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
@@ -1,13 +1,13 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-@SuppressWarnings("serial")
-public class LocaleNotLoadedException extends Exception {
-
- public LocaleNotLoadedException(String locale) {
- super(locale);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+@SuppressWarnings("serial")
+public class LocaleNotLoadedException extends Exception {
+
+ public LocaleNotLoadedException(String locale) {
+ super(locale);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/LocaleService.java b/src/com/vaadin/terminal/gwt/client/LocaleService.java
index 9ae1b04118..0f22ae705b 100644
--- a/src/com/vaadin/terminal/gwt/client/LocaleService.java
+++ b/src/com/vaadin/terminal/gwt/client/LocaleService.java
@@ -1,148 +1,148 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import com.google.gwt.core.client.JsArray;
-
-/**
- * Date / time etc. localisation service for all widgets. Caches all loaded
- * locales as JSONObjects.
- *
- * @author Vaadin Ltd.
- *
- */
-public class LocaleService {
-
- private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
- private static String defaultLocale;
-
- public static void addLocale(ValueMap valueMap) {
-
- final String key = valueMap.getString("name");
- if (cache.containsKey(key)) {
- cache.remove(key);
- }
- cache.put(key, valueMap);
- if (cache.size() == 1) {
- setDefaultLocale(key);
- }
- }
-
- public static void setDefaultLocale(String locale) {
- defaultLocale = locale;
- }
-
- public static String getDefaultLocale() {
- return defaultLocale;
- }
-
- public static Set<String> getAvailableLocales() {
- return cache.keySet();
- }
-
- public static String[] getMonthNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("mn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getShortMonthNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("smn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getDayNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("dn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getShortDayNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("sdn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static int getFirstDayOfWeek(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getInt("fdow");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String getDateFormat(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("df");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static boolean isTwelveHourClock(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getBoolean("thc");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String getClockDelimiter(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("hmd");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getAmPmStrings(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("ampm");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
-
- }
-
- public static void addLocales(JsArray<ValueMap> valueMapArray) {
- for (int i = 0; i < valueMapArray.length(); i++) {
- addLocale(valueMapArray.get(i));
-
- }
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.client.JsArray;
+
+/**
+ * Date / time etc. localisation service for all widgets. Caches all loaded
+ * locales as JSONObjects.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class LocaleService {
+
+ private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
+ private static String defaultLocale;
+
+ public static void addLocale(ValueMap valueMap) {
+
+ final String key = valueMap.getString("name");
+ if (cache.containsKey(key)) {
+ cache.remove(key);
+ }
+ cache.put(key, valueMap);
+ if (cache.size() == 1) {
+ setDefaultLocale(key);
+ }
+ }
+
+ public static void setDefaultLocale(String locale) {
+ defaultLocale = locale;
+ }
+
+ public static String getDefaultLocale() {
+ return defaultLocale;
+ }
+
+ public static Set<String> getAvailableLocales() {
+ return cache.keySet();
+ }
+
+ public static String[] getMonthNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("mn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getShortMonthNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("smn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getDayNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("dn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getShortDayNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("sdn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static int getFirstDayOfWeek(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getInt("fdow");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String getDateFormat(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getString("df");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static boolean isTwelveHourClock(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getBoolean("thc");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String getClockDelimiter(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getString("hmd");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getAmPmStrings(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("ampm");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+
+ }
+
+ public static void addLocales(JsArray<ValueMap> valueMapArray) {
+ for (int i = 0; i < valueMapArray.length(); i++) {
+ addLocale(valueMapArray.get(i));
+
+ }
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index a3b1074fc4..6a3e663103 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -1221,4 +1221,18 @@ public class Util {
cur = cur.parentNode;
}
}-*/;
+
+ /**
+ * Checks if the given event is either a touch event or caused by the left
+ * mouse button
+ *
+ * @param event
+ * @return true if the event is a touch event or caused by the left mouse
+ * button, false otherwise
+ */
+ public static boolean isTouchEventOrLeftMouseButton(Event event) {
+ int eventType = event.getTypeInt();
+ boolean touchEvent = Util.isTouchEvent(event);
+ return touchEvent || event.getButton() == Event.BUTTON_LEFT;
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
index d9ca56be05..89e106f063 100644
--- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
+++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
@@ -1,356 +1,356 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.gwt.server.WebBrowser;
-
-/**
- * Class that parses the user agent string from the browser and provides
- * information about the browser. Used internally by {@link BrowserInfo} and
- * {@link WebBrowser}. Should not be used directly.
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- * @since 6.3
- */
-public class VBrowserDetails implements Serializable {
-
- private boolean isGecko = false;
- private boolean isWebKit = false;
- private boolean isPresto = false;
-
- private boolean isChromeFrameCapable = false;
- private boolean isChromeFrame = false;
-
- private boolean isSafari = false;
- private boolean isChrome = false;
- private boolean isFirefox = false;
- private boolean isOpera = false;
- private boolean isIE = false;
-
- private boolean isWindows = false;
- private boolean isMacOSX = false;
- private boolean isLinux = false;
-
- private float browserEngineVersion = -1;
- private int browserMajorVersion = -1;
- private int browserMinorVersion = -1;
-
- /**
- * Create an instance based on the given user agent.
- *
- * @param userAgent
- * User agent as provided by the browser.
- */
- public VBrowserDetails(String userAgent) {
- userAgent = userAgent.toLowerCase();
-
- // browser engine name
- isGecko = userAgent.indexOf("gecko") != -1
- && userAgent.indexOf("webkit") == -1;
- isWebKit = userAgent.indexOf("applewebkit") != -1;
- isPresto = userAgent.indexOf(" presto/") != -1;
-
- // browser name
- isChrome = userAgent.indexOf(" chrome/") != -1;
- isSafari = !isChrome && userAgent.indexOf("safari") != -1;
- isOpera = userAgent.indexOf("opera") != -1;
- isIE = userAgent.indexOf("msie") != -1 && !isOpera
- && (userAgent.indexOf("webtv") == -1);
- isFirefox = userAgent.indexOf(" firefox/") != -1;
-
- // chromeframe
- isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
- isChromeFrame = isChromeFrameCapable && !isChrome;
-
- // Rendering engine version
- try {
- if (isGecko) {
- int rvPos = userAgent.indexOf("rv:");
- if (rvPos >= 0) {
- String tmp = userAgent.substring(rvPos + 3);
- tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
- browserEngineVersion = Float.parseFloat(tmp);
- }
- } else if (isWebKit) {
- String tmp = userAgent
- .substring(userAgent.indexOf("webkit/") + 7);
- tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1");
- browserEngineVersion = Float.parseFloat(tmp);
- }
- } catch (Exception e) {
- // Browser engine version parsing failed
- System.err.println("Browser engine version parsing failed for: "
- + userAgent);
- }
-
- // Browser version
- try {
- if (isIE) {
- String ieVersionString = userAgent.substring(userAgent
- .indexOf("msie ") + 5);
- ieVersionString = safeSubstring(ieVersionString, 0,
- ieVersionString.indexOf(";"));
- parseVersionString(ieVersionString);
- } else if (isFirefox) {
- int i = userAgent.indexOf(" firefox/") + 9;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isChrome) {
- int i = userAgent.indexOf(" chrome/") + 8;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isSafari) {
- int i = userAgent.indexOf(" version/") + 9;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isOpera) {
- int i = userAgent.indexOf(" version/");
- if (i != -1) {
- // Version present in Opera 10 and newer
- i += 9; // " version/".length
- } else {
- i = userAgent.indexOf("opera/") + 6;
- }
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- }
- } catch (Exception e) {
- // Browser version parsing failed
- System.err.println("Browser version parsing failed for: "
- + userAgent);
- }
-
- // Operating system
- if (userAgent.contains("windows ")) {
- isWindows = true;
- } else if (userAgent.contains("linux")) {
- isLinux = true;
- } else if (userAgent.contains("macintosh")
- || userAgent.contains("mac osx")
- || userAgent.contains("mac os x")) {
- isMacOSX = true;
- }
- }
-
- private void parseVersionString(String versionString) {
- int idx = versionString.indexOf('.');
- if (idx < 0) {
- idx = versionString.length();
- }
- browserMajorVersion = Integer.parseInt(safeSubstring(versionString, 0,
- idx));
-
- int idx2 = versionString.indexOf('.', idx + 1);
- if (idx2 < 0) {
- idx2 = versionString.length();
- }
- try {
- browserMinorVersion = Integer.parseInt(safeSubstring(versionString,
- idx + 1, idx2).replaceAll("[^0-9].*", ""));
- } catch (NumberFormatException e) {
- // leave the minor version unmodified (-1 = unknown)
- }
- }
-
- private String safeSubstring(String string, int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- beginIndex = 0;
- }
- if (endIndex < 0 || endIndex > string.length()) {
- endIndex = string.length();
- }
- return string.substring(beginIndex, endIndex);
- }
-
- /**
- * Tests if the browser is Firefox.
- *
- * @return true if it is Firefox, false otherwise
- */
- public boolean isFirefox() {
- return isFirefox;
- }
-
- /**
- * Tests if the browser is using the Gecko engine
- *
- * @return true if it is Gecko, false otherwise
- */
- public boolean isGecko() {
- return isGecko;
- }
-
- /**
- * Tests if the browser is using the WebKit engine
- *
- * @return true if it is WebKit, false otherwise
- */
- public boolean isWebKit() {
- return isWebKit;
- }
-
- /**
- * Tests if the browser is using the Presto engine
- *
- * @return true if it is Presto, false otherwise
- */
- public boolean isPresto() {
- return isPresto;
- }
-
- /**
- * Tests if the browser is Safari.
- *
- * @return true if it is Safari, false otherwise
- */
- public boolean isSafari() {
- return isSafari;
- }
-
- /**
- * Tests if the browser is Chrome.
- *
- * @return true if it is Chrome, false otherwise
- */
- public boolean isChrome() {
- return isChrome;
- }
-
- /**
- * Tests if the browser is capable of running ChromeFrame.
- *
- * @return true if it has ChromeFrame, false otherwise
- */
- public boolean isChromeFrameCapable() {
- return isChromeFrameCapable;
- }
-
- /**
- * Tests if the browser is running ChromeFrame.
- *
- * @return true if it is ChromeFrame, false otherwise
- */
- public boolean isChromeFrame() {
- return isChromeFrame;
- }
-
- /**
- * Tests if the browser is Opera.
- *
- * @return true if it is Opera, false otherwise
- */
- public boolean isOpera() {
- return isOpera;
- }
-
- /**
- * Tests if the browser is Internet Explorer.
- *
- * @return true if it is Internet Explorer, false otherwise
- */
- public boolean isIE() {
- return isIE;
- }
-
- /**
- * Returns the version of the browser engine. For WebKit this is an integer
- * e.g., 532.0. For gecko it is a float e.g., 1.8 or 1.9.
- *
- * @return The version of the browser engine
- */
- public float getBrowserEngineVersion() {
- return browserEngineVersion;
- }
-
- /**
- * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
- * 4, 8 for Internet Explorer 8.
- * <p>
- * Note that Internet Explorer 8 and newer will return the document mode so
- * IE8 rendering as IE7 will return 7.
- * </p>
- *
- * @return The major version of the browser.
- */
- public final int getBrowserMajorVersion() {
- return browserMajorVersion;
- }
-
- /**
- * Returns the browser minor version e.g., 5 for Firefox 3.5.
- *
- * @see #getBrowserMajorVersion()
- *
- * @return The minor version of the browser, or -1 if not known/parsed.
- */
- public final int getBrowserMinorVersion() {
- return browserMinorVersion;
- }
-
- /**
- * Sets the version for IE based on the documentMode. This is used to return
- * the correct the correct IE version when the version from the user agent
- * string and the value of the documentMode property do not match.
- *
- * @param documentMode
- * The current document mode
- */
- public void setIEMode(int documentMode) {
- browserMajorVersion = documentMode;
- browserMinorVersion = 0;
- }
-
- /**
- * Tests if the browser is run on Windows.
- *
- * @return true if run on Windows, false otherwise
- */
- public boolean isWindows() {
- return isWindows;
- }
-
- /**
- * Tests if the browser is run on Mac OSX.
- *
- * @return true if run on Mac OSX, false otherwise
- */
- public boolean isMacOSX() {
- return isMacOSX;
- }
-
- /**
- * Tests if the browser is run on Linux.
- *
- * @return true if run on Linux, false otherwise
- */
- public boolean isLinux() {
- return isLinux;
- }
-
- /**
- * Checks if the browser is so old that it simply won't work with a Vaadin
- * application. NOTE that the browser might still be capable of running
- * Crome Frame, so you might still want to check
- * {@link #isChromeFrameCapable()} if this returns true.
- *
- * @return true if the browser won't work, false if not the browser is
- * supported or might work
- */
- public boolean isTooOldToFunctionProperly() {
- if (isIE() && getBrowserMajorVersion() < 8) {
- return true;
- }
- if (isSafari() && getBrowserMajorVersion() < 5) {
- return true;
- }
- if (isFirefox() && getBrowserMajorVersion() < 4) {
- return true;
- }
- if (isOpera() && getBrowserMajorVersion() < 11) {
- return true;
- }
-
- return false;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import java.io.Serializable;
+
+import com.vaadin.terminal.gwt.server.WebBrowser;
+
+/**
+ * Class that parses the user agent string from the browser and provides
+ * information about the browser. Used internally by {@link BrowserInfo} and
+ * {@link WebBrowser}. Should not be used directly.
+ *
+ * @author Vaadin Ltd.
+ * @version @VERSION@
+ * @since 6.3
+ */
+public class VBrowserDetails implements Serializable {
+
+ private boolean isGecko = false;
+ private boolean isWebKit = false;
+ private boolean isPresto = false;
+
+ private boolean isChromeFrameCapable = false;
+ private boolean isChromeFrame = false;
+
+ private boolean isSafari = false;
+ private boolean isChrome = false;
+ private boolean isFirefox = false;
+ private boolean isOpera = false;
+ private boolean isIE = false;
+
+ private boolean isWindows = false;
+ private boolean isMacOSX = false;
+ private boolean isLinux = false;
+
+ private float browserEngineVersion = -1;
+ private int browserMajorVersion = -1;
+ private int browserMinorVersion = -1;
+
+ /**
+ * Create an instance based on the given user agent.
+ *
+ * @param userAgent
+ * User agent as provided by the browser.
+ */
+ public VBrowserDetails(String userAgent) {
+ userAgent = userAgent.toLowerCase();
+
+ // browser engine name
+ isGecko = userAgent.indexOf("gecko") != -1
+ && userAgent.indexOf("webkit") == -1;
+ isWebKit = userAgent.indexOf("applewebkit") != -1;
+ isPresto = userAgent.indexOf(" presto/") != -1;
+
+ // browser name
+ isChrome = userAgent.indexOf(" chrome/") != -1;
+ isSafari = !isChrome && userAgent.indexOf("safari") != -1;
+ isOpera = userAgent.indexOf("opera") != -1;
+ isIE = userAgent.indexOf("msie") != -1 && !isOpera
+ && (userAgent.indexOf("webtv") == -1);
+ isFirefox = userAgent.indexOf(" firefox/") != -1;
+
+ // chromeframe
+ isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
+ isChromeFrame = isChromeFrameCapable && !isChrome;
+
+ // Rendering engine version
+ try {
+ if (isGecko) {
+ int rvPos = userAgent.indexOf("rv:");
+ if (rvPos >= 0) {
+ String tmp = userAgent.substring(rvPos + 3);
+ tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
+ browserEngineVersion = Float.parseFloat(tmp);
+ }
+ } else if (isWebKit) {
+ String tmp = userAgent
+ .substring(userAgent.indexOf("webkit/") + 7);
+ tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1");
+ browserEngineVersion = Float.parseFloat(tmp);
+ }
+ } catch (Exception e) {
+ // Browser engine version parsing failed
+ System.err.println("Browser engine version parsing failed for: "
+ + userAgent);
+ }
+
+ // Browser version
+ try {
+ if (isIE) {
+ String ieVersionString = userAgent.substring(userAgent
+ .indexOf("msie ") + 5);
+ ieVersionString = safeSubstring(ieVersionString, 0,
+ ieVersionString.indexOf(";"));
+ parseVersionString(ieVersionString);
+ } else if (isFirefox) {
+ int i = userAgent.indexOf(" firefox/") + 9;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isChrome) {
+ int i = userAgent.indexOf(" chrome/") + 8;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isSafari) {
+ int i = userAgent.indexOf(" version/") + 9;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isOpera) {
+ int i = userAgent.indexOf(" version/");
+ if (i != -1) {
+ // Version present in Opera 10 and newer
+ i += 9; // " version/".length
+ } else {
+ i = userAgent.indexOf("opera/") + 6;
+ }
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ }
+ } catch (Exception e) {
+ // Browser version parsing failed
+ System.err.println("Browser version parsing failed for: "
+ + userAgent);
+ }
+
+ // Operating system
+ if (userAgent.contains("windows ")) {
+ isWindows = true;
+ } else if (userAgent.contains("linux")) {
+ isLinux = true;
+ } else if (userAgent.contains("macintosh")
+ || userAgent.contains("mac osx")
+ || userAgent.contains("mac os x")) {
+ isMacOSX = true;
+ }
+ }
+
+ private void parseVersionString(String versionString) {
+ int idx = versionString.indexOf('.');
+ if (idx < 0) {
+ idx = versionString.length();
+ }
+ browserMajorVersion = Integer.parseInt(safeSubstring(versionString, 0,
+ idx));
+
+ int idx2 = versionString.indexOf('.', idx + 1);
+ if (idx2 < 0) {
+ idx2 = versionString.length();
+ }
+ try {
+ browserMinorVersion = Integer.parseInt(safeSubstring(versionString,
+ idx + 1, idx2).replaceAll("[^0-9].*", ""));
+ } catch (NumberFormatException e) {
+ // leave the minor version unmodified (-1 = unknown)
+ }
+ }
+
+ private String safeSubstring(String string, int beginIndex, int endIndex) {
+ if (beginIndex < 0) {
+ beginIndex = 0;
+ }
+ if (endIndex < 0 || endIndex > string.length()) {
+ endIndex = string.length();
+ }
+ return string.substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Tests if the browser is Firefox.
+ *
+ * @return true if it is Firefox, false otherwise
+ */
+ public boolean isFirefox() {
+ return isFirefox;
+ }
+
+ /**
+ * Tests if the browser is using the Gecko engine
+ *
+ * @return true if it is Gecko, false otherwise
+ */
+ public boolean isGecko() {
+ return isGecko;
+ }
+
+ /**
+ * Tests if the browser is using the WebKit engine
+ *
+ * @return true if it is WebKit, false otherwise
+ */
+ public boolean isWebKit() {
+ return isWebKit;
+ }
+
+ /**
+ * Tests if the browser is using the Presto engine
+ *
+ * @return true if it is Presto, false otherwise
+ */
+ public boolean isPresto() {
+ return isPresto;
+ }
+
+ /**
+ * Tests if the browser is Safari.
+ *
+ * @return true if it is Safari, false otherwise
+ */
+ public boolean isSafari() {
+ return isSafari;
+ }
+
+ /**
+ * Tests if the browser is Chrome.
+ *
+ * @return true if it is Chrome, false otherwise
+ */
+ public boolean isChrome() {
+ return isChrome;
+ }
+
+ /**
+ * Tests if the browser is capable of running ChromeFrame.
+ *
+ * @return true if it has ChromeFrame, false otherwise
+ */
+ public boolean isChromeFrameCapable() {
+ return isChromeFrameCapable;
+ }
+
+ /**
+ * Tests if the browser is running ChromeFrame.
+ *
+ * @return true if it is ChromeFrame, false otherwise
+ */
+ public boolean isChromeFrame() {
+ return isChromeFrame;
+ }
+
+ /**
+ * Tests if the browser is Opera.
+ *
+ * @return true if it is Opera, false otherwise
+ */
+ public boolean isOpera() {
+ return isOpera;
+ }
+
+ /**
+ * Tests if the browser is Internet Explorer.
+ *
+ * @return true if it is Internet Explorer, false otherwise
+ */
+ public boolean isIE() {
+ return isIE;
+ }
+
+ /**
+ * Returns the version of the browser engine. For WebKit this is an integer
+ * e.g., 532.0. For gecko it is a float e.g., 1.8 or 1.9.
+ *
+ * @return The version of the browser engine
+ */
+ public float getBrowserEngineVersion() {
+ return browserEngineVersion;
+ }
+
+ /**
+ * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
+ * 4, 8 for Internet Explorer 8.
+ * <p>
+ * Note that Internet Explorer 8 and newer will return the document mode so
+ * IE8 rendering as IE7 will return 7.
+ * </p>
+ *
+ * @return The major version of the browser.
+ */
+ public final int getBrowserMajorVersion() {
+ return browserMajorVersion;
+ }
+
+ /**
+ * Returns the browser minor version e.g., 5 for Firefox 3.5.
+ *
+ * @see #getBrowserMajorVersion()
+ *
+ * @return The minor version of the browser, or -1 if not known/parsed.
+ */
+ public final int getBrowserMinorVersion() {
+ return browserMinorVersion;
+ }
+
+ /**
+ * Sets the version for IE based on the documentMode. This is used to return
+ * the correct the correct IE version when the version from the user agent
+ * string and the value of the documentMode property do not match.
+ *
+ * @param documentMode
+ * The current document mode
+ */
+ public void setIEMode(int documentMode) {
+ browserMajorVersion = documentMode;
+ browserMinorVersion = 0;
+ }
+
+ /**
+ * Tests if the browser is run on Windows.
+ *
+ * @return true if run on Windows, false otherwise
+ */
+ public boolean isWindows() {
+ return isWindows;
+ }
+
+ /**
+ * Tests if the browser is run on Mac OSX.
+ *
+ * @return true if run on Mac OSX, false otherwise
+ */
+ public boolean isMacOSX() {
+ return isMacOSX;
+ }
+
+ /**
+ * Tests if the browser is run on Linux.
+ *
+ * @return true if run on Linux, false otherwise
+ */
+ public boolean isLinux() {
+ return isLinux;
+ }
+
+ /**
+ * Checks if the browser is so old that it simply won't work with a Vaadin
+ * application. NOTE that the browser might still be capable of running
+ * Crome Frame, so you might still want to check
+ * {@link #isChromeFrameCapable()} if this returns true.
+ *
+ * @return true if the browser won't work, false if not the browser is
+ * supported or might work
+ */
+ public boolean isTooOldToFunctionProperly() {
+ if (isIE() && getBrowserMajorVersion() < 8) {
+ return true;
+ }
+ if (isSafari() && getBrowserMajorVersion() < 5) {
+ return true;
+ }
+ if (isFirefox() && getBrowserMajorVersion() < 4) {
+ return true;
+ }
+ if (isOpera() && getBrowserMajorVersion() < 11) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintable.java b/src/com/vaadin/terminal/gwt/client/VPaintable.java
index d85c6d33e2..032058b8d5 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintable.java
@@ -1,74 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-/**
- * Interface implemented by all client side classes that can be communicate with
- * the server. Classes implementing this interface are initialized by the
- * framework when needed and have the ability to communicate with the server.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public interface VPaintable {
- /**
- * TODO
- *
- * @param uidl
- * @param client
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
-
- // /**
- // * Returns the id for this VPaintable. This must always be what has been
- // set
- // * using {@link #setId(String)}.
- // *
- // * @return The id for the VPaintable.
- // */
- // public String getId();
- //
- // /**
- // * Sets the id for the VPaintable. This method is called once by the
- // * framework when the VPaintable is initialized and should never be called
- // * otherwise.
- // * <p>
- // * The VPaintable id is used to map the server and the client paintables
- // * together. It is unique in this root and assigned by the framework.
- // * </p>
- // *
- // * @param id
- // * The id of the paintable.
- // */
- // public void setId(String id);
-
- /**
- * Gets ApplicationConnection instance that created this VPaintable.
- *
- * @return The ApplicationConnection as set by
- * {@link #setConnection(ApplicationConnection)}
- */
- // public ApplicationConnection getConnection();
-
- /**
- * Sets the reference to ApplicationConnection. This method is called by the
- * framework when the VPaintable is created and should never be called
- * otherwise.
- *
- * @param connection
- * The ApplicationConnection that created this VPaintable
- */
- // public void setConnection(ApplicationConnection connection);
-
- /**
- * Tests whether the component is enabled or not. A user can not interact
- * with disabled components. Disabled components are rendered in a style
- * that indicates the status, usually in gray color. Children of a disabled
- * component are also disabled.
- *
- * @return true if the component is enabled, false otherwise
- */
- // public boolean isEnabled();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+/**
+ * Interface implemented by all client side classes that can be communicate with
+ * the server. Classes implementing this interface are initialized by the
+ * framework when needed and have the ability to communicate with the server.
+ *
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.0
+ */
+public interface VPaintable {
+ /**
+ * TODO
+ *
+ * @param uidl
+ * @param client
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
+
+ /**
+ * Returns the id for this VPaintable. This must always be what has been set
+ * using {@link #setId(String)}.
+ *
+ * @return The id for the VPaintable.
+ */
+ public String getId();
+
+ /**
+ * Sets the id for the VPaintable. This method is called once by the
+ * framework when the VPaintable is initialized and should never be called
+ * otherwise.
+ * <p>
+ * The VPaintable id is used to map the server and the client paintables
+ * together. It is unique in this root and assigned by the framework.
+ * </p>
+ *
+ * @param id
+ * The id of the paintable.
+ */
+ public void setId(String id);
+
+ /**
+ * Gets ApplicationConnection instance that created this VPaintable.
+ *
+ * @return The ApplicationConnection as set by
+ * {@link #setConnection(ApplicationConnection)}
+ */
+ public ApplicationConnection getConnection();
+
+ /**
+ * Sets the reference to ApplicationConnection. This method is called by the
+ * framework when the VPaintable is created and should never be called
+ * otherwise.
+ *
+ * @param connection
+ * The ApplicationConnection that created this VPaintable
+ */
+ public void setConnection(ApplicationConnection connection);
+
+ /**
+ * Tests whether the component is enabled or not. A user can not interact
+ * with disabled components. Disabled components are rendered in a style
+ * that indicates the status, usually in gray color. Children of a disabled
+ * component are also disabled.
+ *
+ * @return true if the component is enabled, false otherwise
+ */
+ // public boolean isEnabled();
+
+ /**
+ *
+ * Called once when the connection and id has been set
+ */
+ public void init();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
index f9d05e592d..e36d02bb2b 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
@@ -1,404 +1,404 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.HasWidgets;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.Paintable;
-import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
-import com.vaadin.terminal.gwt.client.RenderInformation.Size;
-
-public class VPaintableMap {
-
- private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();
- private Map<VPaintable, String> paintableToId = new HashMap<VPaintable, String>();
-
- public static VPaintableMap get(ApplicationConnection applicationConnection) {
- return applicationConnection.getPaintableMap();
- }
-
- @Deprecated
- private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
- .create();
-
- private Set<String> unregistryBag = new HashSet<String>();
-
- /**
- * Returns a Paintable by its paintable id
- *
- * @param id
- * The Paintable id
- */
- public VPaintable getPaintable(String pid) {
- return idToPaintable.get(pid);
- }
-
- /**
- * Returns a Paintable element by its root element
- *
- * @param element
- * Root element of the paintable
- */
- public VPaintableWidget getPaintable(Element element) {
- return (VPaintableWidget) getPaintable(getPid(element));
- }
-
- /**
- * FIXME: What does this even do and why?
- *
- * @param pid
- * @return
- */
- public boolean isDragAndDropPaintable(String pid) {
- return (pid.startsWith("DD"));
- }
-
- /**
- * Checks if a paintable with the given paintable id has been registered.
- *
- * @param pid
- * The paintable id to check for
- * @return true if a paintable has been registered with the given paintable
- * id, false otherwise
- */
- public boolean hasPaintable(String pid) {
- return idToPaintable.containsKey(pid);
- }
-
- /**
- * Removes all registered paintable ids
- */
- public void clear() {
- idToPaintable.clear();
- paintableToId.clear();
- idToComponentDetail.clear();
- }
-
- @Deprecated
- public Widget getWidget(VPaintableWidget paintable) {
- return paintable.getWidgetForPaintable();
- }
-
- @Deprecated
- public VPaintableWidget getPaintable(Widget widget) {
- return getPaintable(widget.getElement());
- }
-
- public void registerPaintable(String pid, VPaintable paintable) {
- ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
- idToComponentDetail.put(pid, componentDetail);
- idToPaintable.put(pid, paintable);
- paintableToId.put(paintable, pid);
- if (paintable instanceof VPaintableWidget) {
- VPaintableWidget pw = (VPaintableWidget) paintable;
- setPid(pw.getWidgetForPaintable().getElement(), pid);
- }
- }
-
- private native void setPid(Element el, String pid)
- /*-{
- el.tkPid = pid;
- }-*/;
-
- /**
- * Gets the paintableId for a specific paintable.
- * <p>
- * The paintableId is used in the UIDL to identify a specific widget
- * instance, effectively linking the widget with it's server side Component.
- * </p>
- *
- * @param paintable
- * the paintable who's id is needed
- * @return the id for the given paintable or null if the paintable could not
- * be found
- */
- public String getPid(VPaintable paintable) {
- if (paintable == null) {
- return null;
- }
- return paintableToId.get(paintable);
- }
-
- @Deprecated
- public String getPid(Widget widget) {
- return getPid(widget.getElement());
- }
-
- /**
- * Gets the paintableId using a DOM element - the element should be the main
- * element for a paintable otherwise no id will be found. Use
- * {@link #getPid(Paintable)} instead whenever possible.
- *
- * @see #getPid(Paintable)
- * @param el
- * element of the paintable whose pid is desired
- * @return the pid of the element's paintable, if it's a paintable
- */
- native String getPid(Element el)
- /*-{
- return el.tkPid;
- }-*/;
-
- /**
- * Gets the main element for the paintable with the given id. The revers of
- * {@link #getPid(Element)}.
- *
- * @param pid
- * the pid of the widget whose element is desired
- * @return the element for the paintable corresponding to the pid
- */
- public Element getElement(String pid) {
- VPaintable p = getPaintable(pid);
- if (p instanceof VPaintableWidget) {
- return ((VPaintableWidget) p).getWidgetForPaintable().getElement();
- }
-
- return null;
- }
-
- /**
- * Unregisters the given paintable; always use after removing a paintable.
- * This method does not remove the paintable from the DOM, but marks the
- * paintable so that ApplicationConnection may clean up its references to
- * it. Removing the widget from DOM is component containers responsibility.
- *
- * @param p
- * the paintable to remove
- */
- public void unregisterPaintable(VPaintable p) {
-
- // add to unregistry que
-
- if (p == null) {
- VConsole.error("WARN: Trying to unregister null paintable");
- return;
- }
- String id = getPid(p);
- Widget widget = null;
- if (p instanceof VPaintableWidget) {
- widget = ((VPaintableWidget) p).getWidgetForPaintable();
- }
-
- if (id == null) {
- /*
- * Uncomment the following to debug unregistring components. No
- * paintables with null id should end here. At least one exception
- * is our VScrollTableRow, that is hacked to fake it self as a
- * Paintable to build support for sizing easier.
- */
- // if (!(p instanceof VScrollTableRow)) {
- // VConsole.log("Trying to unregister Paintable not created by Application Connection.");
- // }
- } else {
- unregistryBag.add(id);
- }
- if (widget != null && widget instanceof HasWidgets) {
- unregisterChildPaintables((HasWidgets) widget);
- }
-
- }
-
- void purgeUnregistryBag(boolean unregisterPaintables) {
- if (unregisterPaintables) {
- for (String pid : unregistryBag) {
- VPaintable paintable = getPaintable(pid);
- if (paintable == null) {
- /*
- * this should never happen, but it does :-( See e.g.
- * com.vaadin.tests.components.accordion.RemoveTabs (with
- * test script)
- */
- VConsole.error("Tried to unregister component (id="
- + pid
- + ") that is never registered (or already unregistered)");
- continue;
- }
- Widget widget = null;
- if (paintable instanceof VPaintableWidget) {
- widget = ((VPaintableWidget) paintable)
- .getWidgetForPaintable();
- }
-
- // check if can be cleaned
- if (widget == null || !widget.isAttached()) {
- // clean reference to paintable
- idToComponentDetail.remove(pid);
- idToPaintable.remove(pid);
- paintableToId.remove(paintable);
- // TODO purge shared state for pid
- }
- /*
- * else NOP : same component has been reattached to another
- * parent or replaced by another component implementation.
- */
- }
- }
-
- unregistryBag.clear();
- }
-
- /**
- * Unregisters a paintable and all it's child paintables recursively. Use
- * when after removing a paintable that contains other paintables. Does not
- * unregister the given container itself. Does not actually remove the
- * paintable from the DOM.
- *
- * @see #unregisterPaintable(Paintable)
- * @param container
- */
- public void unregisterChildPaintables(HasWidgets container) {
- // FIXME: This should be based on the paintable hierarchy
- final Iterator<Widget> it = container.iterator();
- while (it.hasNext()) {
- final Widget w = it.next();
- VPaintableWidget p = getPaintable(w);
- if (p != null) {
- // This will unregister the paintable and all its children
- unregisterPaintable(p);
- } else if (w instanceof HasWidgets) {
- // For normal widget containers, unregister the children
- unregisterChildPaintables((HasWidgets) w);
- }
- }
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param pid
- * @param uidl
- */
- @Deprecated
- public void registerEventListenersFromUIDL(String pid, UIDL uidl) {
- ComponentDetail cd = idToComponentDetail.get(pid);
- if (cd == null) {
- throw new IllegalArgumentException("Pid must not be null");
- }
-
- cd.registerEventListenersFromUIDL(uidl);
-
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public Size getOffsetSize(VPaintableWidget paintable) {
- return getComponentDetail(paintable).getOffsetSize();
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public FloatSize getRelativeSize(VPaintableWidget paintable) {
- return getComponentDetail(paintable).getRelativeSize();
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public void setOffsetSize(VPaintableWidget paintable, Size newSize) {
- getComponentDetail(paintable).setOffsetSize(newSize);
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public void setRelativeSize(VPaintableWidget paintable,
- FloatSize relativeSize) {
- getComponentDetail(paintable).setRelativeSize(relativeSize);
-
- }
-
- private ComponentDetail getComponentDetail(VPaintableWidget paintable) {
- return idToComponentDetail.get(getPid(paintable));
- }
-
- public int size() {
- return idToPaintable.size();
- }
-
- /**
- * FIXME: Should be moved to VAbstractPaintableWidget
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public TooltipInfo getTooltipInfo(VPaintableWidget paintable, Object key) {
- return getComponentDetail(paintable).getTooltipInfo(key);
- }
-
- @Deprecated
- public TooltipInfo getWidgetTooltipInfo(Widget widget, Object key) {
- return getTooltipInfo(getPaintable(widget), key);
- }
-
- public Collection<? extends VPaintable> getPaintables() {
- return Collections.unmodifiableCollection(paintableToId.keySet());
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public void registerTooltip(VPaintableWidget paintable, Object key,
- TooltipInfo tooltip) {
- getComponentDetail(paintable).putAdditionalTooltip(key, tooltip);
-
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public boolean hasEventListeners(VPaintableWidget paintable,
- String eventIdentifier) {
- return getComponentDetail(paintable).hasEventListeners(eventIdentifier);
- }
-
- /**
- * Tests if the widget is the root widget of a VPaintableWidget.
- *
- * @param widget
- * The widget to test
- * @return true if the widget is the root widget of a VPaintableWidget,
- * false otherwise
- */
- public boolean isPaintable(Widget w) {
- return getPid(w) != null;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.HasWidgets;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.Paintable;
+import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
+import com.vaadin.terminal.gwt.client.RenderInformation.Size;
+
+public class VPaintableMap {
+
+ private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();
+ private Map<VPaintable, String> paintableToId = new HashMap<VPaintable, String>();
+
+ public static VPaintableMap get(ApplicationConnection applicationConnection) {
+ return applicationConnection.getPaintableMap();
+ }
+
+ @Deprecated
+ private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
+ .create();
+
+ private Set<String> unregistryBag = new HashSet<String>();
+
+ /**
+ * Returns a Paintable by its paintable id
+ *
+ * @param id
+ * The Paintable id
+ */
+ public VPaintable getPaintable(String pid) {
+ return idToPaintable.get(pid);
+ }
+
+ /**
+ * Returns a Paintable element by its root element
+ *
+ * @param element
+ * Root element of the paintable
+ */
+ public VPaintableWidget getPaintable(Element element) {
+ return (VPaintableWidget) getPaintable(getPid(element));
+ }
+
+ /**
+ * FIXME: What does this even do and why?
+ *
+ * @param pid
+ * @return
+ */
+ public boolean isDragAndDropPaintable(String pid) {
+ return (pid.startsWith("DD"));
+ }
+
+ /**
+ * Checks if a paintable with the given paintable id has been registered.
+ *
+ * @param pid
+ * The paintable id to check for
+ * @return true if a paintable has been registered with the given paintable
+ * id, false otherwise
+ */
+ public boolean hasPaintable(String pid) {
+ return idToPaintable.containsKey(pid);
+ }
+
+ /**
+ * Removes all registered paintable ids
+ */
+ public void clear() {
+ idToPaintable.clear();
+ paintableToId.clear();
+ idToComponentDetail.clear();
+ }
+
+ @Deprecated
+ public Widget getWidget(VPaintableWidget paintable) {
+ return paintable.getWidgetForPaintable();
+ }
+
+ @Deprecated
+ public VPaintableWidget getPaintable(Widget widget) {
+ return getPaintable(widget.getElement());
+ }
+
+ public void registerPaintable(String pid, VPaintable paintable) {
+ ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
+ idToComponentDetail.put(pid, componentDetail);
+ idToPaintable.put(pid, paintable);
+ paintableToId.put(paintable, pid);
+ if (paintable instanceof VPaintableWidget) {
+ VPaintableWidget pw = (VPaintableWidget) paintable;
+ setPid(pw.getWidgetForPaintable().getElement(), pid);
+ }
+ }
+
+ private native void setPid(Element el, String pid)
+ /*-{
+ el.tkPid = pid;
+ }-*/;
+
+ /**
+ * Gets the paintableId for a specific paintable.
+ * <p>
+ * The paintableId is used in the UIDL to identify a specific widget
+ * instance, effectively linking the widget with it's server side Component.
+ * </p>
+ *
+ * @param paintable
+ * the paintable who's id is needed
+ * @return the id for the given paintable or null if the paintable could not
+ * be found
+ */
+ public String getPid(VPaintable paintable) {
+ if (paintable == null) {
+ return null;
+ }
+ return paintableToId.get(paintable);
+ }
+
+ @Deprecated
+ public String getPid(Widget widget) {
+ return getPid(widget.getElement());
+ }
+
+ /**
+ * Gets the paintableId using a DOM element - the element should be the main
+ * element for a paintable otherwise no id will be found. Use
+ * {@link #getPid(Paintable)} instead whenever possible.
+ *
+ * @see #getPid(Paintable)
+ * @param el
+ * element of the paintable whose pid is desired
+ * @return the pid of the element's paintable, if it's a paintable
+ */
+ native String getPid(Element el)
+ /*-{
+ return el.tkPid;
+ }-*/;
+
+ /**
+ * Gets the main element for the paintable with the given id. The revers of
+ * {@link #getPid(Element)}.
+ *
+ * @param pid
+ * the pid of the widget whose element is desired
+ * @return the element for the paintable corresponding to the pid
+ */
+ public Element getElement(String pid) {
+ VPaintable p = getPaintable(pid);
+ if (p instanceof VPaintableWidget) {
+ return ((VPaintableWidget) p).getWidgetForPaintable().getElement();
+ }
+
+ return null;
+ }
+
+ /**
+ * Unregisters the given paintable; always use after removing a paintable.
+ * This method does not remove the paintable from the DOM, but marks the
+ * paintable so that ApplicationConnection may clean up its references to
+ * it. Removing the widget from DOM is component containers responsibility.
+ *
+ * @param p
+ * the paintable to remove
+ */
+ public void unregisterPaintable(VPaintable p) {
+
+ // add to unregistry que
+
+ if (p == null) {
+ VConsole.error("WARN: Trying to unregister null paintable");
+ return;
+ }
+ String id = getPid(p);
+ Widget widget = null;
+ if (p instanceof VPaintableWidget) {
+ widget = ((VPaintableWidget) p).getWidgetForPaintable();
+ }
+
+ if (id == null) {
+ /*
+ * Uncomment the following to debug unregistring components. No
+ * paintables with null id should end here. At least one exception
+ * is our VScrollTableRow, that is hacked to fake it self as a
+ * Paintable to build support for sizing easier.
+ */
+ // if (!(p instanceof VScrollTableRow)) {
+ // VConsole.log("Trying to unregister Paintable not created by Application Connection.");
+ // }
+ } else {
+ unregistryBag.add(id);
+ }
+ if (widget != null && widget instanceof HasWidgets) {
+ unregisterChildPaintables((HasWidgets) widget);
+ }
+
+ }
+
+ void purgeUnregistryBag(boolean unregisterPaintables) {
+ if (unregisterPaintables) {
+ for (String pid : unregistryBag) {
+ // TODO purge shared state for pid
+ VPaintable paintable = getPaintable(pid);
+ if (paintable == null) {
+ /*
+ * this should never happen, but it does :-( See e.g.
+ * com.vaadin.tests.components.accordion.RemoveTabs (with
+ * test script)
+ */
+ VConsole.error("Tried to unregister component (id="
+ + pid
+ + ") that is never registered (or already unregistered)");
+ continue;
+ }
+ Widget widget = null;
+ if (paintable instanceof VPaintableWidget) {
+ widget = ((VPaintableWidget) paintable)
+ .getWidgetForPaintable();
+ }
+
+ // check if can be cleaned
+ if (widget == null || !widget.isAttached()) {
+ // clean reference to paintable
+ idToComponentDetail.remove(pid);
+ idToPaintable.remove(pid);
+ paintableToId.remove(paintable);
+ }
+ /*
+ * else NOP : same component has been reattached to another
+ * parent or replaced by another component implementation.
+ */
+ }
+ }
+
+ unregistryBag.clear();
+ }
+
+ /**
+ * Unregisters a paintable and all it's child paintables recursively. Use
+ * when after removing a paintable that contains other paintables. Does not
+ * unregister the given container itself. Does not actually remove the
+ * paintable from the DOM.
+ *
+ * @see #unregisterPaintable(Paintable)
+ * @param container
+ */
+ public void unregisterChildPaintables(HasWidgets container) {
+ // FIXME: This should be based on the paintable hierarchy
+ final Iterator<Widget> it = container.iterator();
+ while (it.hasNext()) {
+ final Widget w = it.next();
+ VPaintableWidget p = getPaintable(w);
+ if (p != null) {
+ // This will unregister the paintable and all its children
+ unregisterPaintable(p);
+ } else if (w instanceof HasWidgets) {
+ // For normal widget containers, unregister the children
+ unregisterChildPaintables((HasWidgets) w);
+ }
+ }
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param pid
+ * @param uidl
+ */
+ @Deprecated
+ public void registerEventListenersFromUIDL(String pid, UIDL uidl) {
+ ComponentDetail cd = idToComponentDetail.get(pid);
+ if (cd == null) {
+ throw new IllegalArgumentException("Pid must not be null");
+ }
+
+ cd.registerEventListenersFromUIDL(uidl);
+
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public Size getOffsetSize(VPaintableWidget paintable) {
+ return getComponentDetail(paintable).getOffsetSize();
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public FloatSize getRelativeSize(VPaintableWidget paintable) {
+ return getComponentDetail(paintable).getRelativeSize();
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public void setOffsetSize(VPaintableWidget paintable, Size newSize) {
+ getComponentDetail(paintable).setOffsetSize(newSize);
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public void setRelativeSize(VPaintableWidget paintable,
+ FloatSize relativeSize) {
+ getComponentDetail(paintable).setRelativeSize(relativeSize);
+
+ }
+
+ private ComponentDetail getComponentDetail(VPaintableWidget paintable) {
+ return idToComponentDetail.get(getPid(paintable));
+ }
+
+ public int size() {
+ return idToPaintable.size();
+ }
+
+ /**
+ * FIXME: Should be moved to VAbstractPaintableWidget
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public TooltipInfo getTooltipInfo(VPaintableWidget paintable, Object key) {
+ return getComponentDetail(paintable).getTooltipInfo(key);
+ }
+
+ @Deprecated
+ public TooltipInfo getWidgetTooltipInfo(Widget widget, Object key) {
+ return getTooltipInfo(getPaintable(widget), key);
+ }
+
+ public Collection<? extends VPaintable> getPaintables() {
+ return Collections.unmodifiableCollection(paintableToId.keySet());
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public void registerTooltip(VPaintableWidget paintable, Object key,
+ TooltipInfo tooltip) {
+ getComponentDetail(paintable).putAdditionalTooltip(key, tooltip);
+
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public boolean hasEventListeners(VPaintableWidget paintable,
+ String eventIdentifier) {
+ return getComponentDetail(paintable).hasEventListeners(eventIdentifier);
+ }
+
+ /**
+ * Tests if the widget is the root widget of a VPaintableWidget.
+ *
+ * @param widget
+ * The widget to test
+ * @return true if the widget is the root widget of a VPaintableWidget,
+ * false otherwise
+ */
+ public boolean isPaintable(Widget w) {
+ return getPid(w) != null;
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java b/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
index 6bef0c409c..65d5d6a9a2 100644
--- a/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
+++ b/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
@@ -1,32 +1,32 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import com.google.gwt.core.client.impl.SchedulerImpl;
-
-public class VSchedulerImpl extends SchedulerImpl {
-
- /**
- * Keeps track of if there are deferred commands that are being executed. 0
- * == no deferred commands currently in progress, > 0 otherwise.
- */
- private int deferredCommandTrackers = 0;
-
- @Override
- public void scheduleDeferred(ScheduledCommand cmd) {
- deferredCommandTrackers++;
- super.scheduleDeferred(cmd);
- super.scheduleDeferred(new ScheduledCommand() {
-
- public void execute() {
- deferredCommandTrackers--;
- }
- });
- }
-
- public boolean hasWorkQueued() {
- boolean hasWorkQueued = (deferredCommandTrackers != 0);
- return hasWorkQueued;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.core.client.impl.SchedulerImpl;
+
+public class VSchedulerImpl extends SchedulerImpl {
+
+ /**
+ * Keeps track of if there are deferred commands that are being executed. 0
+ * == no deferred commands currently in progress, > 0 otherwise.
+ */
+ private int deferredCommandTrackers = 0;
+
+ @Override
+ public void scheduleDeferred(ScheduledCommand cmd) {
+ deferredCommandTrackers++;
+ super.scheduleDeferred(cmd);
+ super.scheduleDeferred(new ScheduledCommand() {
+
+ public void execute() {
+ deferredCommandTrackers--;
+ }
+ });
+ }
+
+ public boolean hasWorkQueued() {
+ boolean hasWorkQueued = (deferredCommandTrackers != 0);
+ return hasWorkQueued;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java b/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
index cf18c693c6..1577d60ab7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
@@ -1,128 +1,128 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.vaadin.terminal.gwt.client.DateTimeService;
-
-public class CalendarEntry {
- private final String styleName;
- private Date start;
- private Date end;
- private String title;
- private String description;
- private boolean notime;
-
- @SuppressWarnings("deprecation")
- public CalendarEntry(String styleName, Date start, Date end, String title,
- String description, boolean notime) {
- this.styleName = styleName;
- if (notime) {
- Date d = new Date(start.getTime());
- d.setSeconds(0);
- d.setMinutes(0);
- this.start = d;
- if (end != null) {
- d = new Date(end.getTime());
- d.setSeconds(0);
- d.setMinutes(0);
- this.end = d;
- } else {
- end = start;
- }
- } else {
- this.start = start;
- this.end = end;
- }
- this.title = title;
- this.description = description;
- this.notime = notime;
- }
-
- public CalendarEntry(String styleName, Date start, Date end, String title,
- String description) {
- this(styleName, start, end, title, description, false);
- }
-
- public String getStyleName() {
- return styleName;
- }
-
- public Date getStart() {
- return start;
- }
-
- public void setStart(Date start) {
- this.start = start;
- }
-
- public Date getEnd() {
- return end;
- }
-
- public void setEnd(Date end) {
- this.end = end;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public boolean isNotime() {
- return notime;
- }
-
- public void setNotime(boolean notime) {
- this.notime = notime;
- }
-
- @SuppressWarnings("deprecation")
- public String getStringForDate(Date d) {
- // TODO format from DateTimeService
- String s = "";
- if (!notime) {
- if (!DateTimeService.isSameDay(d, start)) {
- s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)
- + "." + start.getDate() + " ";
- }
- int i = start.getHours();
- s += (i < 10 ? "0" : "") + i;
- s += ":";
- i = start.getMinutes();
- s += (i < 10 ? "0" : "") + i;
- if (!start.equals(end)) {
- s += " - ";
- if (!DateTimeService.isSameDay(start, end)) {
- s += (end.getYear() + 1900) + "." + (end.getMonth() + 1)
- + "." + end.getDate() + " ";
- }
- i = end.getHours();
- s += (i < 10 ? "0" : "") + i;
- s += ":";
- i = end.getMinutes();
- s += (i < 10 ? "0" : "") + i;
- }
- s += " ";
- }
- if (title != null) {
- s += title;
- }
- return s;
- }
-
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.vaadin.terminal.gwt.client.DateTimeService;
+
+public class CalendarEntry {
+ private final String styleName;
+ private Date start;
+ private Date end;
+ private String title;
+ private String description;
+ private boolean notime;
+
+ @SuppressWarnings("deprecation")
+ public CalendarEntry(String styleName, Date start, Date end, String title,
+ String description, boolean notime) {
+ this.styleName = styleName;
+ if (notime) {
+ Date d = new Date(start.getTime());
+ d.setSeconds(0);
+ d.setMinutes(0);
+ this.start = d;
+ if (end != null) {
+ d = new Date(end.getTime());
+ d.setSeconds(0);
+ d.setMinutes(0);
+ this.end = d;
+ } else {
+ end = start;
+ }
+ } else {
+ this.start = start;
+ this.end = end;
+ }
+ this.title = title;
+ this.description = description;
+ this.notime = notime;
+ }
+
+ public CalendarEntry(String styleName, Date start, Date end, String title,
+ String description) {
+ this(styleName, start, end, title, description, false);
+ }
+
+ public String getStyleName() {
+ return styleName;
+ }
+
+ public Date getStart() {
+ return start;
+ }
+
+ public void setStart(Date start) {
+ this.start = start;
+ }
+
+ public Date getEnd() {
+ return end;
+ }
+
+ public void setEnd(Date end) {
+ this.end = end;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public boolean isNotime() {
+ return notime;
+ }
+
+ public void setNotime(boolean notime) {
+ this.notime = notime;
+ }
+
+ @SuppressWarnings("deprecation")
+ public String getStringForDate(Date d) {
+ // TODO format from DateTimeService
+ String s = "";
+ if (!notime) {
+ if (!DateTimeService.isSameDay(d, start)) {
+ s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)
+ + "." + start.getDate() + " ";
+ }
+ int i = start.getHours();
+ s += (i < 10 ? "0" : "") + i;
+ s += ":";
+ i = start.getMinutes();
+ s += (i < 10 ? "0" : "") + i;
+ if (!start.equals(end)) {
+ s += " - ";
+ if (!DateTimeService.isSameDay(start, end)) {
+ s += (end.getYear() + 1900) + "." + (end.getMonth() + 1)
+ + "." + end.getDate() + " ";
+ }
+ i = end.getHours();
+ s += (i < 10 ? "0" : "") + i;
+ s += ":";
+ i = end.getMinutes();
+ s += (i < 10 ? "0" : "") + i;
+ }
+ s += " ";
+ }
+ if (title != null) {
+ s += title;
+ }
+ return s;
+ }
+
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
index 0ca97d2bf8..831add049b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
@@ -1,100 +1,100 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.HasBlurHandlers;
-import com.google.gwt.event.dom.client.HasFocusHandlers;
-import com.google.gwt.event.dom.client.HasKeyDownHandlers;
-import com.google.gwt.event.dom.client.HasKeyPressHandlers;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.impl.FocusImpl;
-import com.vaadin.terminal.gwt.client.Focusable;
-
-public class FocusableFlowPanel extends FlowPanel implements HasFocusHandlers,
- HasBlurHandlers, HasKeyDownHandlers, HasKeyPressHandlers, Focusable {
-
- /**
- * Constructor
- */
- public FocusableFlowPanel() {
- // make focusable, as we don't need access key magic we don't need to
- // use FocusImpl.createFocusable
- getElement().setTabIndex(0);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.
- * google.gwt.event.dom.client.FocusHandler)
- */
- public HandlerRegistration addFocusHandler(FocusHandler handler) {
- return addDomHandler(handler, FocusEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasBlurHandlers#addBlurHandler(com.google
- * .gwt.event.dom.client.BlurHandler)
- */
- public HandlerRegistration addBlurHandler(BlurHandler handler) {
- return addDomHandler(handler, BlurEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasKeyDownHandlers#addKeyDownHandler(
- * com.google.gwt.event.dom.client.KeyDownHandler)
- */
- public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
- return addDomHandler(handler, KeyDownEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasKeyPressHandlers#addKeyPressHandler
- * (com.google.gwt.event.dom.client.KeyPressHandler)
- */
- public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
- return addDomHandler(handler, KeyPressEvent.getType());
- }
-
- /**
- * Sets/Removes the keyboard focus to the panel.
- *
- * @param focus
- * If set to true then the focus is moved to the panel, if set to
- * false the focus is removed
- */
- public void setFocus(boolean focus) {
- if (focus) {
- FocusImpl.getFocusImplForPanel().focus(getElement());
- } else {
- FocusImpl.getFocusImplForPanel().blur(getElement());
- }
- }
-
- /**
- * Focus the panel
- */
- public void focus() {
- setFocus(true);
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.HasBlurHandlers;
+import com.google.gwt.event.dom.client.HasFocusHandlers;
+import com.google.gwt.event.dom.client.HasKeyDownHandlers;
+import com.google.gwt.event.dom.client.HasKeyPressHandlers;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.impl.FocusImpl;
+import com.vaadin.terminal.gwt.client.Focusable;
+
+public class FocusableFlowPanel extends FlowPanel implements HasFocusHandlers,
+ HasBlurHandlers, HasKeyDownHandlers, HasKeyPressHandlers, Focusable {
+
+ /**
+ * Constructor
+ */
+ public FocusableFlowPanel() {
+ // make focusable, as we don't need access key magic we don't need to
+ // use FocusImpl.createFocusable
+ getElement().setTabIndex(0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.
+ * google.gwt.event.dom.client.FocusHandler)
+ */
+ public HandlerRegistration addFocusHandler(FocusHandler handler) {
+ return addDomHandler(handler, FocusEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasBlurHandlers#addBlurHandler(com.google
+ * .gwt.event.dom.client.BlurHandler)
+ */
+ public HandlerRegistration addBlurHandler(BlurHandler handler) {
+ return addDomHandler(handler, BlurEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasKeyDownHandlers#addKeyDownHandler(
+ * com.google.gwt.event.dom.client.KeyDownHandler)
+ */
+ public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
+ return addDomHandler(handler, KeyDownEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasKeyPressHandlers#addKeyPressHandler
+ * (com.google.gwt.event.dom.client.KeyPressHandler)
+ */
+ public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
+ return addDomHandler(handler, KeyPressEvent.getType());
+ }
+
+ /**
+ * Sets/Removes the keyboard focus to the panel.
+ *
+ * @param focus
+ * If set to true then the focus is moved to the panel, if set to
+ * false the focus is removed
+ */
+ public void setFocus(boolean focus) {
+ if (focus) {
+ FocusImpl.getFocusImplForPanel().focus(getElement());
+ } else {
+ FocusImpl.getFocusImplForPanel().blur(getElement());
+ }
+ }
+
+ /**
+ * Focus the panel
+ */
+ public void focus() {
+ setFocus(true);
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java b/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
index 8a153da98c..37f8889463 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
@@ -1,29 +1,29 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.ui.AbstractImagePrototype;
-
-public interface TreeImages extends com.google.gwt.user.client.ui.TreeImages {
-
- /**
- * An image indicating an open branch.
- *
- * @return a prototype of this image
- * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/expanded
- * .png
- */
- AbstractImagePrototype treeOpen();
-
- /**
- * An image indicating a closed branch.
- *
- * @return a prototype of this image
- * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/collapsed
- * .png
- */
- AbstractImagePrototype treeClosed();
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+
+public interface TreeImages extends com.google.gwt.user.client.ui.TreeImages {
+
+ /**
+ * An image indicating an open branch.
+ *
+ * @return a prototype of this image
+ * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/expanded
+ * .png
+ */
+ AbstractImagePrototype treeOpen();
+
+ /**
+ * An image indicating a closed branch.
+ *
+ * @return a prototype of this image
+ * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/collapsed
+ * .png
+ */
+ AbstractImagePrototype treeClosed();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
index f95acfc43c..7ac44bc4b7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
@@ -309,8 +309,4 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
return Util.getPaintableForElement(client, this, element);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
index 27535806c1..9d73e75b09 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
@@ -1,84 +1,87 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashSet;
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout.AbsoluteWrapper;
-
-public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer {
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getWidgetForPaintable().getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- getWidgetForPaintable().client = client;
- // TODO margin handling
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- HashSet<String> unrenderedPids = new HashSet<String>(
- getWidgetForPaintable().pidToComponentWrappper.keySet());
-
- for (Iterator<Object> childIterator = uidl.getChildIterator(); childIterator
- .hasNext();) {
- UIDL cc = (UIDL) childIterator.next();
- if (cc.getTag().equals("cc")) {
- UIDL componentUIDL = cc.getChildUIDL(0);
- unrenderedPids.remove(componentUIDL.getId());
- getWidgetForPaintable().getWrapper(client, componentUIDL)
- .updateFromUIDL(cc);
- }
- }
-
- for (String pid : unrenderedPids) {
- AbsoluteWrapper absoluteWrapper = getWidgetForPaintable().pidToComponentWrappper
- .get(pid);
- getWidgetForPaintable().pidToComponentWrappper.remove(pid);
- absoluteWrapper.destroy();
- }
- getWidgetForPaintable().rendering = false;
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- AbsoluteWrapper parent2 = (AbsoluteWrapper) (component
- .getWidgetForPaintable()).getParent();
- parent2.updateCaption(uidl);
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VAbsoluteLayout.class);
- }
-
- @Override
- public VAbsoluteLayout getWidgetForPaintable() {
- return (VAbsoluteLayout) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout.AbsoluteWrapper;
+
+public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+ // TODO margin handling
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ HashSet<String> unrenderedPids = new HashSet<String>(
+ getWidgetForPaintable().pidToComponentWrappper.keySet());
+
+ for (Iterator<Object> childIterator = uidl.getChildIterator(); childIterator
+ .hasNext();) {
+ UIDL cc = (UIDL) childIterator.next();
+ if (cc.getTag().equals("cc")) {
+ UIDL componentUIDL = cc.getChildUIDL(0);
+ unrenderedPids.remove(componentUIDL.getId());
+ getWidgetForPaintable().getWrapper(client, componentUIDL)
+ .updateFromUIDL(cc);
+ }
+ }
+
+ for (String pid : unrenderedPids) {
+ AbsoluteWrapper absoluteWrapper = getWidgetForPaintable().pidToComponentWrappper
+ .get(pid);
+ getWidgetForPaintable().pidToComponentWrappper.remove(pid);
+ absoluteWrapper.destroy();
+ }
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ AbsoluteWrapper parent2 = (AbsoluteWrapper) (component
+ .getWidgetForPaintable()).getParent();
+ parent2.updateCaption(uidl);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAbsoluteLayout.class);
+ }
+
+ @Override
+ public VAbsoluteLayout getWidgetForPaintable() {
+ return (VAbsoluteLayout) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
index 90da0ef4ac..09bf02ec43 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
@@ -1,103 +1,103 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.VPaintableWidgetContainer;
-
-public abstract class VAbstractPaintableWidget implements VPaintableWidget {
-
- private Widget widget;
- private ApplicationConnection connection;
- private String id;
-
- /* State variables */
- private boolean enabled = true;
-
- /**
- * Default constructor
- */
- public VAbstractPaintableWidget() {
- }
-
- /**
- * Called after the application connection reference has been set up
- */
- public void init() {
- }
-
- /**
- * Creates and returns the widget for this VPaintableWidget. This method
- * should only be called once when initializing the paintable.
- *
- * @return
- */
- protected abstract Widget createWidget();
-
- /**
- * Returns the widget associated with this paintable. The widget returned by
- * this method must not changed during the life time of the paintable.
- *
- * @return The widget associated with this paintable
- */
- public Widget getWidgetForPaintable() {
- if (widget == null) {
- widget = createWidget();
- }
-
- return widget;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.VPaintable#getConnection()
- */
- public final ApplicationConnection getConnection() {
- return connection;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.VPaintable#setConnection(com.vaadin.terminal
- * .gwt.client.ApplicationConnection)
- */
- public final void setConnection(ApplicationConnection connection) {
- this.connection = connection;
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public VPaintableWidgetContainer getParentPaintable() {
- // FIXME: Return VPaintableWidgetContainer
- // FIXME: Store hierarchy instead of doing lookup every time
-
- VPaintableMap paintableMap = VPaintableMap.get(getConnection());
-
- Widget w = getWidgetForPaintable();
- while (w != null) {
- w = w.getParent();
- if (paintableMap.isPaintable(w)) {
- return (VPaintableWidgetContainer) paintableMap.getPaintable(w);
- }
- }
-
- return null;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.VPaintableWidgetContainer;
+
+public abstract class VAbstractPaintableWidget implements VPaintableWidget {
+
+ private Widget widget;
+ private ApplicationConnection connection;
+ private String id;
+
+ /* State variables */
+ private boolean enabled = true;
+
+ /**
+ * Default constructor
+ */
+ public VAbstractPaintableWidget() {
+ }
+
+ /**
+ * Called after the application connection reference has been set up
+ */
+ public void init() {
+ }
+
+ /**
+ * Creates and returns the widget for this VPaintableWidget. This method
+ * should only be called once when initializing the paintable.
+ *
+ * @return
+ */
+ protected abstract Widget createWidget();
+
+ /**
+ * Returns the widget associated with this paintable. The widget returned by
+ * this method must not changed during the life time of the paintable.
+ *
+ * @return The widget associated with this paintable
+ */
+ public Widget getWidgetForPaintable() {
+ if (widget == null) {
+ widget = createWidget();
+ }
+
+ return widget;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.VPaintable#getConnection()
+ */
+ public final ApplicationConnection getConnection() {
+ return connection;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.VPaintable#setConnection(com.vaadin.terminal
+ * .gwt.client.ApplicationConnection)
+ */
+ public final void setConnection(ApplicationConnection connection) {
+ this.connection = connection;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public VPaintableWidgetContainer getParentPaintable() {
+ // FIXME: Return VPaintableWidgetContainer
+ // FIXME: Store hierarchy instead of doing lookup every time
+
+ VPaintableMap paintableMap = VPaintableMap.get(getConnection());
+
+ Widget w = getWidgetForPaintable();
+ while (w != null) {
+ w = w.getParent();
+ if (paintableMap.isPaintable(w)) {
+ return (VPaintableWidgetContainer) paintableMap.getPaintable(w);
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
index b3e19f037a..1f78c02f58 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
@@ -1,17 +1,17 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.vaadin.terminal.gwt.client.VPaintableWidgetContainer;
-
-public abstract class VAbstractPaintableWidgetContainer extends
- VAbstractPaintableWidget implements VPaintableWidgetContainer {
-
- /**
- * Default constructor
- */
- public VAbstractPaintableWidgetContainer() {
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.vaadin.terminal.gwt.client.VPaintableWidgetContainer;
+
+public abstract class VAbstractPaintableWidgetContainer extends
+ VAbstractPaintableWidget implements VPaintableWidgetContainer {
+
+ /**
+ * Default constructor
+ */
+ public VAbstractPaintableWidgetContainer() {
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
index 1aa9d92770..f1a932b3a3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
@@ -730,7 +730,4 @@ public class VAbstractSplitPanel extends ComplexPanel implements Container,
return enabled;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
index 1ff066d004..9c7e5f04f9 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
@@ -1,140 +1,143 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public abstract class VAbstractSplitPanelPaintable extends
- VAbstractPaintableWidgetContainer {
-
- public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // TODO Implement caption handling
- }
-
- ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- SPLITTER_CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- if ((Event.getEventsSunk(getWidgetForPaintable().splitter) & Event
- .getTypeInt(type.getName())) != 0) {
- // If we are already sinking the event for the splitter we do
- // not want to additionally sink it for the root element
- return getWidgetForPaintable().addHandler(handler, type);
- } else {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- }
-
- @Override
- public void onContextMenu(
- com.google.gwt.event.dom.client.ContextMenuEvent event) {
- Element target = event.getNativeEvent().getEventTarget().cast();
- if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
- super.onContextMenu(event);
- }
- };
-
- @Override
- protected void fireClick(NativeEvent event) {
- Element target = event.getEventTarget().cast();
- if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
- super.fireClick(event);
- }
- }
-
- @Override
- protected Element getRelativeToElement() {
- return null;
- }
-
- };
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
- getWidgetForPaintable().rendering = true;
-
- getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
- getWidgetForPaintable().setEnabled(
- !uidl.getBooleanAttribute("disabled"));
-
- clickEventHandler.handleEventHandlerRegistration(client);
- if (uidl.hasAttribute("style")) {
- getWidgetForPaintable().componentStyleNames = uidl
- .getStringAttribute("style").split(" ");
- } else {
- getWidgetForPaintable().componentStyleNames = new String[0];
- }
-
- getWidgetForPaintable().setLocked(uidl.getBooleanAttribute("locked"));
-
- getWidgetForPaintable().setPositionReversed(
- uidl.getBooleanAttribute("reversed"));
-
- getWidgetForPaintable().setStylenames();
-
- getWidgetForPaintable().position = uidl.getStringAttribute("position");
- getWidgetForPaintable().setSplitPosition(
- getWidgetForPaintable().position);
-
- final VPaintableWidget newFirstChildPaintable = client
- .getPaintable(uidl.getChildUIDL(0));
- final VPaintableWidget newSecondChildPaintable = client
- .getPaintable(uidl.getChildUIDL(1));
- Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();
- Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();
-
- if (getWidgetForPaintable().firstChild != newFirstChild) {
- if (getWidgetForPaintable().firstChild != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(getWidgetForPaintable().firstChild));
- }
- getWidgetForPaintable().setFirstWidget(newFirstChild);
- }
- if (getWidgetForPaintable().secondChild != newSecondChild) {
- if (getWidgetForPaintable().secondChild != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(getWidgetForPaintable().secondChild));
- }
- getWidgetForPaintable().setSecondWidget(newSecondChild);
- }
- newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
- newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
-
- getWidgetForPaintable().renderInformation
- .updateSize(getWidgetForPaintable().getElement());
-
- // This is needed at least for cases like #3458 to take
- // appearing/disappearing scrollbars into account.
- client.runDescendentsLayout(getWidgetForPaintable());
-
- getWidgetForPaintable().rendering = false;
-
- }
-
- @Override
- public VAbstractSplitPanel getWidgetForPaintable() {
- return (VAbstractSplitPanel) super.getWidgetForPaintable();
- }
-
- @Override
- protected abstract VAbstractSplitPanel createWidget();
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public abstract class VAbstractSplitPanelPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // TODO Implement caption handling
+ }
+
+ ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ SPLITTER_CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ if ((Event.getEventsSunk(getWidgetForPaintable().splitter) & Event
+ .getTypeInt(type.getName())) != 0) {
+ // If we are already sinking the event for the splitter we do
+ // not want to additionally sink it for the root element
+ return getWidgetForPaintable().addHandler(handler, type);
+ } else {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ }
+
+ @Override
+ public void onContextMenu(
+ com.google.gwt.event.dom.client.ContextMenuEvent event) {
+ Element target = event.getNativeEvent().getEventTarget().cast();
+ if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
+ super.onContextMenu(event);
+ }
+ };
+
+ @Override
+ protected void fireClick(NativeEvent event) {
+ Element target = event.getEventTarget().cast();
+ if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
+ super.fireClick(event);
+ }
+ }
+
+ @Override
+ protected Element getRelativeToElement() {
+ return null;
+ }
+
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ getWidgetForPaintable().setEnabled(
+ !uidl.getBooleanAttribute("disabled"));
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+ if (uidl.hasAttribute("style")) {
+ getWidgetForPaintable().componentStyleNames = uidl
+ .getStringAttribute("style").split(" ");
+ } else {
+ getWidgetForPaintable().componentStyleNames = new String[0];
+ }
+
+ getWidgetForPaintable().setLocked(uidl.getBooleanAttribute("locked"));
+
+ getWidgetForPaintable().setPositionReversed(
+ uidl.getBooleanAttribute("reversed"));
+
+ getWidgetForPaintable().setStylenames();
+
+ getWidgetForPaintable().position = uidl.getStringAttribute("position");
+ getWidgetForPaintable().setSplitPosition(
+ getWidgetForPaintable().position);
+
+ final VPaintableWidget newFirstChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(0));
+ final VPaintableWidget newSecondChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(1));
+ Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();
+ Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();
+
+ if (getWidgetForPaintable().firstChild != newFirstChild) {
+ if (getWidgetForPaintable().firstChild != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().firstChild));
+ }
+ getWidgetForPaintable().setFirstWidget(newFirstChild);
+ }
+ if (getWidgetForPaintable().secondChild != newSecondChild) {
+ if (getWidgetForPaintable().secondChild != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().secondChild));
+ }
+ getWidgetForPaintable().setSecondWidget(newSecondChild);
+ }
+ newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
+ newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ // This is needed at least for cases like #3458 to take
+ // appearing/disappearing scrollbars into account.
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ @Override
+ public VAbstractSplitPanel getWidgetForPaintable() {
+ return (VAbstractSplitPanel) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected abstract VAbstractSplitPanel createWidget();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
index 3f28818073..6b03300a09 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
@@ -1,68 +1,71 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.VAccordion.StackItem;
-
-public class VAccordionPaintable extends VTabsheetBasePaintable {
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- getWidgetForPaintable().selectedUIDLItemIndex = -1;
- super.updateFromUIDL(uidl, client);
- /*
- * Render content after all tabs have been created and we know how large
- * the content area is
- */
- if (getWidgetForPaintable().selectedUIDLItemIndex >= 0) {
- StackItem selectedItem = getWidgetForPaintable().getStackItem(
- getWidgetForPaintable().selectedUIDLItemIndex);
- UIDL selectedTabUIDL = getWidgetForPaintable().lazyUpdateMap
- .remove(selectedItem);
- getWidgetForPaintable().open(
- getWidgetForPaintable().selectedUIDLItemIndex);
-
- selectedItem.setContent(selectedTabUIDL);
- } else if (!uidl.getBooleanAttribute("cached")
- && getWidgetForPaintable().openTab != null) {
- getWidgetForPaintable().close(getWidgetForPaintable().openTab);
- }
-
- getWidgetForPaintable().iLayout();
- // finally render possible hidden tabs
- if (getWidgetForPaintable().lazyUpdateMap.size() > 0) {
- for (Iterator iterator = getWidgetForPaintable().lazyUpdateMap
- .keySet().iterator(); iterator.hasNext();) {
- StackItem item = (StackItem) iterator.next();
- item.setContent(getWidgetForPaintable().lazyUpdateMap.get(item));
- }
- getWidgetForPaintable().lazyUpdateMap.clear();
- }
-
- getWidgetForPaintable().renderInformation
- .updateSize(getWidgetForPaintable().getElement());
-
- getWidgetForPaintable().rendering = false;
- }
-
- @Override
- public VAccordion getWidgetForPaintable() {
- return (VAccordion) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VAccordion.class);
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- /* Accordion does not render its children's captions */
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VAccordion.StackItem;
+
+public class VAccordionPaintable extends VTabsheetBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().selectedUIDLItemIndex = -1;
+ super.updateFromUIDL(uidl, client);
+ /*
+ * Render content after all tabs have been created and we know how large
+ * the content area is
+ */
+ if (getWidgetForPaintable().selectedUIDLItemIndex >= 0) {
+ StackItem selectedItem = getWidgetForPaintable().getStackItem(
+ getWidgetForPaintable().selectedUIDLItemIndex);
+ UIDL selectedTabUIDL = getWidgetForPaintable().lazyUpdateMap
+ .remove(selectedItem);
+ getWidgetForPaintable().open(
+ getWidgetForPaintable().selectedUIDLItemIndex);
+
+ selectedItem.setContent(selectedTabUIDL);
+ } else if (!uidl.getBooleanAttribute("cached")
+ && getWidgetForPaintable().openTab != null) {
+ getWidgetForPaintable().close(getWidgetForPaintable().openTab);
+ }
+
+ getWidgetForPaintable().iLayout();
+ // finally render possible hidden tabs
+ if (getWidgetForPaintable().lazyUpdateMap.size() > 0) {
+ for (Iterator iterator = getWidgetForPaintable().lazyUpdateMap
+ .keySet().iterator(); iterator.hasNext();) {
+ StackItem item = (StackItem) iterator.next();
+ item.setContent(getWidgetForPaintable().lazyUpdateMap.get(item));
+ }
+ getWidgetForPaintable().lazyUpdateMap.clear();
+ }
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ public VAccordion getWidgetForPaintable() {
+ return (VAccordion) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAccordion.class);
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ /* Accordion does not render its children's captions */
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
index e949d95104..a10c81861b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
@@ -1,37 +1,40 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Style;
-import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VAudioPaintable extends VMediaBasePaintable {
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- super.updateFromUIDL(uidl, client);
- Style style = getWidgetForPaintable().getElement().getStyle();
-
- // Make sure that the controls are not clipped if visible.
- if (shouldShowControls(uidl)
- && (style.getHeight() == null || "".equals(style.getHeight()))) {
- if (BrowserInfo.get().isChrome()) {
- style.setHeight(32, Unit.PX);
- } else {
- style.setHeight(25, Unit.PX);
- }
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VAudio.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VAudioPaintable extends VMediaBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+ super.updateFromUIDL(uidl, client);
+ Style style = getWidgetForPaintable().getElement().getStyle();
+
+ // Make sure that the controls are not clipped if visible.
+ if (shouldShowControls(uidl)
+ && (style.getHeight() == null || "".equals(style.getHeight()))) {
+ if (BrowserInfo.get().isChrome()) {
+ style.setHeight(32, Unit.PX);
+ } else {
+ style.setHeight(25, Unit.PX);
+ }
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAudio.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
index b318fe0af3..2968e132c6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
@@ -1,1730 +1,1737 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-import java.util.Iterator;
-
-import com.google.gwt.dom.client.Node;
-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.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.dom.client.MouseDownEvent;
-import com.google.gwt.event.dom.client.MouseDownHandler;
-import com.google.gwt.event.dom.client.MouseOutEvent;
-import com.google.gwt.event.dom.client.MouseOutHandler;
-import com.google.gwt.event.dom.client.MouseUpEvent;
-import com.google.gwt.event.dom.client.MouseUpHandler;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.InlineHTML;
-import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.ui.label.VLabel;
-
-@SuppressWarnings("deprecation")
-public class VCalendarPanel extends FocusableFlexTable implements
- KeyDownHandler, KeyPressHandler, MouseOutHandler, MouseDownHandler,
- MouseUpHandler, BlurHandler, FocusHandler, SubPartAware {
-
- public interface SubmitListener {
-
- /**
- * Called when calendar user triggers a submitting operation in calendar
- * panel. Eg. clicking on day or hitting enter.
- */
- void onSubmit();
-
- /**
- * On eg. ESC key.
- */
- void onCancel();
- }
-
- /**
- * Blur listener that listens to blur event from the panel
- */
- public interface FocusOutListener {
- /**
- * @return true if the calendar panel is not used after focus moves out
- */
- boolean onFocusOut(DomEvent<?> event);
- }
-
- /**
- * FocusChangeListener is notified when the panel changes its _focused_
- * value. It can be set with
- */
- public interface FocusChangeListener {
- void focusChanged(Date focusedDate);
- }
-
- /**
- * Dispatches an event when the panel when time is changed
- */
- public interface TimeChangeListener {
-
- void changed(int hour, int min, int sec, int msec);
- }
-
- /**
- * Represents a Date button in the calendar
- */
- private class VEventButton extends Button {
- public VEventButton() {
- addMouseDownHandler(VCalendarPanel.this);
- addMouseOutHandler(VCalendarPanel.this);
- addMouseUpHandler(VCalendarPanel.this);
- }
- }
-
- private static final String CN_FOCUSED = "focused";
-
- private static final String CN_TODAY = "today";
-
- private static final String CN_SELECTED = "selected";
-
- private static final String CN_OFFMONTH = "offmonth";
-
- /**
- * Represents a click handler for when a user selects a value by using the
- * mouse
- */
- private ClickHandler dayClickHandler = new ClickHandler() {
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
- * .event.dom.client.ClickEvent)
- */
- public void onClick(ClickEvent event) {
- Day day = (Day) event.getSource();
- focusDay(day.getDate());
- selectFocused();
- onSubmit();
- }
- };
-
- private VEventButton prevYear;
-
- private VEventButton nextYear;
-
- private VEventButton prevMonth;
-
- private VEventButton nextMonth;
-
- private VTime time;
-
- private FlexTable days = new FlexTable();
-
- private int resolution = VDateField.RESOLUTION_YEAR;
-
- private int focusedRow;
-
- private Timer mouseTimer;
-
- private Date value;
-
- private boolean enabled = true;
-
- private boolean readonly = false;
-
- private DateTimeService dateTimeService;
-
- private boolean showISOWeekNumbers;
-
- private Date displayedMonth;
-
- private Date focusedDate;
-
- private Day selectedDay;
-
- private Day focusedDay;
-
- private FocusOutListener focusOutListener;
-
- private SubmitListener submitListener;
-
- private FocusChangeListener focusChangeListener;
-
- private TimeChangeListener timeChangeListener;
-
- private boolean hasFocus = false;
-
- public VCalendarPanel() {
-
- setStyleName(VDateField.CLASSNAME + "-calendarpanel");
-
- /*
- * Firefox auto-repeat works correctly only if we use a key press
- * handler, other browsers handle it correctly when using a key down
- * handler
- */
- if (BrowserInfo.get().isGecko()) {
- addKeyPressHandler(this);
- } else {
- addKeyDownHandler(this);
- }
- addFocusHandler(this);
- addBlurHandler(this);
-
- }
-
- /**
- * Sets the focus to given day of current time. Used when moving in the
- * calender with the keyboard.
- *
- * @param date
- * The day number from by Date.getDate()
- */
- private void focusDay(Date day) {
- // Only used when calender body is present
- if (resolution > VDateField.RESOLUTION_MONTH) {
- if (focusedDay != null) {
- focusedDay.removeStyleDependentName(CN_FOCUSED);
- }
-
- if (day != null && focusedDate != null) {
- focusedDate.setTime(day.getTime());
- int rowCount = days.getRowCount();
- for (int i = 0; i < rowCount; i++) {
- int cellCount = days.getCellCount(i);
- for (int j = 0; j < cellCount; j++) {
- Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
- Day curday = (Day) widget;
- if (curday.getDate().equals(day)) {
- curday.addStyleDependentName(CN_FOCUSED);
- focusedDay = curday;
- focusedRow = i;
- return;
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Sets the selection hightlight to a given date of current time
- *
- * @param date
- */
- private void selectDate(Date date) {
- if (selectedDay != null) {
- selectedDay.removeStyleDependentName(CN_SELECTED);
- }
-
- int rowCount = days.getRowCount();
- for (int i = 0; i < rowCount; i++) {
- int cellCount = days.getCellCount(i);
- for (int j = 0; j < cellCount; j++) {
- Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
- Day curday = (Day) widget;
- if (curday.getDate().equals(date)) {
- curday.addStyleDependentName(CN_SELECTED);
- selectedDay = curday;
- return;
- }
- }
- }
- }
- }
-
- /**
- * Updates year, month, day from focusedDate to value
- */
- private void selectFocused() {
- if (focusedDate != null) {
- if (value == null) {
- // No previously selected value (set to null on server side).
- // Create a new date using current date and time
- value = new Date();
- }
- /*
- * #5594 set Date (day) to 1 in order to prevent any kind of
- * wrapping of months when later setting the month. (e.g. 31 ->
- * month with 30 days -> wraps to the 1st of the following month,
- * e.g. 31st of May -> 31st of April = 1st of May)
- */
- value.setDate(1);
- if (value.getYear() != focusedDate.getYear()) {
- value.setYear(focusedDate.getYear());
- }
- if (value.getMonth() != focusedDate.getMonth()) {
- value.setMonth(focusedDate.getMonth());
- }
- if (value.getDate() != focusedDate.getDate()) {
- }
- // We always need to set the date, even if it hasn't changed, since
- // it was forced to 1 above.
- value.setDate(focusedDate.getDate());
-
- selectDate(focusedDate);
- } else {
- VConsole.log("Trying to select a the focused date which is NULL!");
- }
- }
-
- protected boolean onValueChange() {
- return false;
- }
-
- public int getResolution() {
- return resolution;
- }
-
- public void setResolution(int resolution) {
- this.resolution = resolution;
- if (time != null) {
- time.removeFromParent();
- time = null;
- }
- }
-
- private boolean isReadonly() {
- return readonly;
- }
-
- private boolean isEnabled() {
- return enabled;
- }
-
- private void clearCalendarBody(boolean remove) {
- if (!remove) {
- // Leave the cells in place but clear their contents
-
- // This has the side effect of ensuring that the calendar always
- // contain 7 rows.
- for (int row = 1; row < 7; row++) {
- for (int col = 0; col < 8; col++) {
- days.setHTML(row, col, "&nbsp;");
- }
- }
- } else if (getRowCount() > 1) {
- removeRow(1);
- days.clear();
- }
- }
-
- /**
- * Builds the top buttons and current month and year header.
- *
- * @param needsMonth
- * Should the month buttons be visible?
- */
- private void buildCalendarHeader(boolean needsMonth) {
-
- getRowFormatter().addStyleName(0,
- VDateField.CLASSNAME + "-calendarpanel-header");
-
- if (prevMonth == null && needsMonth) {
- prevMonth = new VEventButton();
- prevMonth.setHTML("&lsaquo;");
- prevMonth.setStyleName("v-button-prevmonth");
- prevMonth.setTabIndex(-1);
- nextMonth = new VEventButton();
- nextMonth.setHTML("&rsaquo;");
- nextMonth.setStyleName("v-button-nextmonth");
- nextMonth.setTabIndex(-1);
- getFlexCellFormatter().setStyleName(0, 3,
- VDateField.CLASSNAME + "-calendarpanel-nextmonth");
- getFlexCellFormatter().setStyleName(0, 1,
- VDateField.CLASSNAME + "-calendarpanel-prevmonth");
-
- setWidget(0, 3, nextMonth);
- setWidget(0, 1, prevMonth);
- } else if (prevMonth != null && !needsMonth) {
- // Remove month traverse buttons
- remove(prevMonth);
- remove(nextMonth);
- prevMonth = null;
- nextMonth = null;
- }
-
- if (prevYear == null) {
- prevYear = new VEventButton();
- prevYear.setHTML("&laquo;");
- prevYear.setStyleName("v-button-prevyear");
- prevYear.setTabIndex(-1);
- nextYear = new VEventButton();
- nextYear.setHTML("&raquo;");
- nextYear.setStyleName("v-button-nextyear");
- nextYear.setTabIndex(-1);
- setWidget(0, 0, prevYear);
- setWidget(0, 4, nextYear);
- getFlexCellFormatter().setStyleName(0, 0,
- VDateField.CLASSNAME + "-calendarpanel-prevyear");
- getFlexCellFormatter().setStyleName(0, 4,
- VDateField.CLASSNAME + "-calendarpanel-nextyear");
- }
-
- final String monthName = needsMonth ? getDateTimeService().getMonth(
- focusedDate.getMonth()) : "";
- final int year = focusedDate.getYear() + 1900;
- getFlexCellFormatter().setStyleName(0, 2,
- VDateField.CLASSNAME + "-calendarpanel-month");
- setHTML(0, 2, "<span class=\"" + VDateField.CLASSNAME
- + "-calendarpanel-month\">" + monthName + " " + year
- + "</span>");
- }
-
- private DateTimeService getDateTimeService() {
- return dateTimeService;
- }
-
- public void setDateTimeService(DateTimeService dateTimeService) {
- this.dateTimeService = dateTimeService;
- }
-
- /**
- * Returns whether ISO 8601 week numbers should be shown in the value
- * selector or not. ISO 8601 defines that a week always starts with a Monday
- * so the week numbers are only shown if this is the case.
- *
- * @return true if week number should be shown, false otherwise
- */
- public boolean isShowISOWeekNumbers() {
- return showISOWeekNumbers;
- }
-
- public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
- this.showISOWeekNumbers = showISOWeekNumbers;
- }
-
- /**
- * Builds the day and time selectors of the calendar.
- */
- private void buildCalendarBody() {
-
- final int weekColumn = 0;
- final int firstWeekdayColumn = 1;
- final int headerRow = 0;
-
- setWidget(1, 0, days);
- setCellPadding(0);
- setCellSpacing(0);
- getFlexCellFormatter().setColSpan(1, 0, 5);
- getFlexCellFormatter().setStyleName(1, 0,
- VDateField.CLASSNAME + "-calendarpanel-body");
-
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
- "v-week");
- days.setHTML(headerRow, weekColumn, "<strong></strong>");
- // Hide the week column if week numbers are not to be displayed.
- days.getFlexCellFormatter().setVisible(headerRow, weekColumn,
- isShowISOWeekNumbers());
-
- days.getRowFormatter().setStyleName(headerRow,
- VDateField.CLASSNAME + "-calendarpanel-weekdays");
-
- if (isShowISOWeekNumbers()) {
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
- "v-first");
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn, "");
- days.getRowFormatter().addStyleName(headerRow,
- VDateField.CLASSNAME + "-calendarpanel-weeknumbers");
- } else {
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "");
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn, "v-first");
- }
-
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn + 6, "v-last");
-
- // Print weekday names
- final int firstDay = getDateTimeService().getFirstDayOfWeek();
- for (int i = 0; i < 7; i++) {
- int day = i + firstDay;
- if (day > 6) {
- day = 0;
- }
- if (getResolution() > VDateField.RESOLUTION_MONTH) {
- days.setHTML(headerRow, firstWeekdayColumn + i, "<strong>"
- + getDateTimeService().getShortDay(day) + "</strong>");
- } else {
- days.setHTML(headerRow, firstWeekdayColumn + i, "");
- }
- }
-
- // today must have zeroed hours, minutes, seconds, and milliseconds
- final Date tmp = new Date();
- final Date today = new Date(tmp.getYear(), tmp.getMonth(),
- tmp.getDate());
-
- final int startWeekDay = getDateTimeService().getStartWeekDay(
- focusedDate);
- final Date curr = (Date) focusedDate.clone();
- // Start from the first day of the week that at least partially belongs
- // to the current month
- curr.setDate(-startWeekDay);
-
- // No month has more than 6 weeks so 6 is a safe maximum for rows.
- for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {
- for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
-
- // Actually write the day of month
- Day day = new Day((Date) curr.clone());
-
- if (curr.equals(value)) {
- day.addStyleDependentName(CN_SELECTED);
- selectedDay = day;
- }
- if (curr.equals(today)) {
- day.addStyleDependentName(CN_TODAY);
- }
- if (curr.equals(focusedDate)) {
- focusedDay = day;
- focusedRow = weekOfMonth;
- if (hasFocus) {
- day.addStyleDependentName(CN_FOCUSED);
- }
- }
- if (curr.getMonth() != focusedDate.getMonth()) {
- day.addStyleDependentName(CN_OFFMONTH);
- }
-
- days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);
-
- // ISO week numbers if requested
- days.getCellFormatter().setVisible(weekOfMonth, weekColumn,
- isShowISOWeekNumbers());
- if (isShowISOWeekNumbers()) {
- final String baseCssClass = VDateField.CLASSNAME
- + "-calendarpanel-weeknumber";
- String weekCssClass = baseCssClass;
-
- int weekNumber = DateTimeService.getISOWeekNumber(curr);
-
- days.setHTML(weekOfMonth, 0, "<span class=\""
- + weekCssClass + "\"" + ">" + weekNumber
- + "</span>");
- }
- curr.setDate(curr.getDate() + 1);
- }
- }
- }
-
- /**
- * Do we need the time selector
- *
- * @return True if it is required
- */
- private boolean isTimeSelectorNeeded() {
- return getResolution() > VDateField.RESOLUTION_DAY;
- }
-
- /**
- * Updates the calendar and text field with the selected dates.
- */
- public void renderCalendar() {
- if (focusedDate == null) {
- focusedDate = new Date();
- }
-
- if (getResolution() <= VDateField.RESOLUTION_MONTH
- && focusChangeListener != null) {
- focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
- }
-
- final boolean needsMonth = getResolution() > VDateField.RESOLUTION_YEAR;
- boolean needsBody = getResolution() >= VDateField.RESOLUTION_DAY;
- buildCalendarHeader(needsMonth);
- clearCalendarBody(!needsBody);
- if (needsBody) {
- buildCalendarBody();
- }
-
- if (isTimeSelectorNeeded() && time == null) {
- time = new VTime();
- setWidget(2, 0, time);
- getFlexCellFormatter().setColSpan(2, 0, 5);
- getFlexCellFormatter().setStyleName(2, 0,
- VDateField.CLASSNAME + "-calendarpanel-time");
- } else if (isTimeSelectorNeeded()) {
- time.updateTimes();
- } else if (time != null) {
- remove(time);
- }
-
- }
-
- /**
- * Selects the next month
- */
- private void focusNextMonth() {
-
- int currentMonth = focusedDate.getMonth();
- focusedDate.setMonth(currentMonth + 1);
- int requestedMonth = (currentMonth + 1) % 12;
-
- /*
- * If the selected value was e.g. 31.3 the new value would be 31.4 but
- * this value is invalid so the new value will be 1.5. This is taken
- * care of by decreasing the value until we have the correct month.
- */
- while (focusedDate.getMonth() != requestedMonth) {
- focusedDate.setDate(focusedDate.getDate() - 1);
- }
- displayedMonth.setMonth(displayedMonth.getMonth() + 1);
-
- renderCalendar();
- }
-
- /**
- * Selects the previous month
- */
- private void focusPreviousMonth() {
- int currentMonth = focusedDate.getMonth();
- focusedDate.setMonth(currentMonth - 1);
-
- /*
- * If the selected value was e.g. 31.12 the new value would be 31.11 but
- * this value is invalid so the new value will be 1.12. This is taken
- * care of by decreasing the value until we have the correct month.
- */
- while (focusedDate.getMonth() == currentMonth) {
- focusedDate.setDate(focusedDate.getDate() - 1);
- }
- displayedMonth.setMonth(displayedMonth.getMonth() - 1);
-
- renderCalendar();
- }
-
- /**
- * Selects the previous year
- */
- private void focusPreviousYear(int years) {
- focusedDate.setYear(focusedDate.getYear() - years);
- displayedMonth.setYear(displayedMonth.getYear() - years);
- renderCalendar();
- }
-
- /**
- * Selects the next year
- */
- private void focusNextYear(int years) {
- focusedDate.setYear(focusedDate.getYear() + years);
- displayedMonth.setYear(displayedMonth.getYear() + years);
- renderCalendar();
- }
-
- /**
- * Handles a user click on the component
- *
- * @param sender
- * The component that was clicked
- * @param updateVariable
- * Should the value field be updated
- *
- */
- private void processClickEvent(Widget sender) {
- if (!isEnabled() || isReadonly()) {
- return;
- }
- if (sender == prevYear) {
- focusPreviousYear(1);
- } else if (sender == nextYear) {
- focusNextYear(1);
- } else if (sender == prevMonth) {
- focusPreviousMonth();
- } else if (sender == nextMonth) {
- focusNextMonth();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
- * .event.dom.client.KeyDownEvent)
- */
- public void onKeyDown(KeyDownEvent event) {
- handleKeyPress(event);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google
- * .gwt.event.dom.client.KeyPressEvent)
- */
- public void onKeyPress(KeyPressEvent event) {
- handleKeyPress(event);
- }
-
- /**
- * Handles the keypress from both the onKeyPress event and the onKeyDown
- * event
- *
- * @param event
- * The keydown/keypress event
- */
- private void handleKeyPress(DomEvent<?> event) {
- if (time != null
- && time.getElement().isOrHasChild(
- (Node) event.getNativeEvent().getEventTarget().cast())) {
- int nativeKeyCode = event.getNativeEvent().getKeyCode();
- if (nativeKeyCode == getSelectKey()) {
- onSubmit(); // submit happens if enter key hit down on listboxes
- event.preventDefault();
- event.stopPropagation();
- }
- return;
- }
-
- // Check tabs
- int keycode = event.getNativeEvent().getKeyCode();
- if (keycode == KeyCodes.KEY_TAB && event.getNativeEvent().getShiftKey()) {
- if (onTabOut(event)) {
- return;
- }
- }
-
- // Handle the navigation
- if (handleNavigation(keycode, event.getNativeEvent().getCtrlKey()
- || event.getNativeEvent().getMetaKey(), event.getNativeEvent()
- .getShiftKey())) {
- event.preventDefault();
- }
-
- }
-
- /**
- * Notifies submit-listeners of a submit event
- */
- private void onSubmit() {
- if (getSubmitListener() != null) {
- getSubmitListener().onSubmit();
- }
- }
-
- /**
- * Notifies submit-listeners of a cancel event
- */
- private void onCancel() {
- if (getSubmitListener() != null) {
- getSubmitListener().onCancel();
- }
- }
-
- /**
- * Handles the keyboard navigation when the resolution is set to years.
- *
- * @param keycode
- * The keycode to process
- * @param ctrl
- * Is ctrl pressed?
- * @param shift
- * is shift pressed
- * @return Returns true if the keycode was processed, else false
- */
- protected boolean handleNavigationYearMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl and Shift selection not supported
- if (ctrl || shift) {
- return false;
- }
-
- else if (keycode == getPreviousKey()) {
- focusNextYear(10); // Add 10 years
- return true;
- }
-
- else if (keycode == getForwardKey()) {
- focusNextYear(1); // Add 1 year
- return true;
- }
-
- else if (keycode == getNextKey()) {
- focusPreviousYear(10); // Subtract 10 years
- return true;
- }
-
- else if (keycode == getBackwardKey()) {
- focusPreviousYear(1); // Subtract 1 year
- return true;
-
- } else if (keycode == getSelectKey()) {
- value = (Date) focusedDate.clone();
- onSubmit();
- return true;
-
- } else if (keycode == getResetKey()) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
-
- } else if (keycode == getCloseKey()) {
- // TODO fire listener, on users responsibility??
-
- return true;
- }
- return false;
- }
-
- /**
- * Handle the keyboard navigation when the resolution is set to MONTH
- *
- * @param keycode
- * The keycode to handle
- * @param ctrl
- * Was the ctrl key pressed?
- * @param shift
- * Was the shift key pressed?
- * @return
- */
- protected boolean handleNavigationMonthMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl selection not supported
- if (ctrl) {
- return false;
-
- } else if (keycode == getPreviousKey()) {
- focusNextYear(1); // Add 1 year
- return true;
-
- } else if (keycode == getForwardKey()) {
- focusNextMonth(); // Add 1 month
- return true;
-
- } else if (keycode == getNextKey()) {
- focusPreviousYear(1); // Subtract 1 year
- return true;
-
- } else if (keycode == getBackwardKey()) {
- focusPreviousMonth(); // Subtract 1 month
- return true;
-
- } else if (keycode == getSelectKey()) {
- value = (Date) focusedDate.clone();
- onSubmit();
- return true;
-
- } else if (keycode == getResetKey()) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
-
- } else if (keycode == getCloseKey() || keycode == KeyCodes.KEY_TAB) {
-
- // TODO fire close event
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Handle keyboard navigation what the resolution is set to DAY
- *
- * @param keycode
- * The keycode to handle
- * @param ctrl
- * Was the ctrl key pressed?
- * @param shift
- * Was the shift key pressed?
- * @return Return true if the key press was handled by the method, else
- * return false.
- */
- protected boolean handleNavigationDayMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl key is not in use
- if (ctrl) {
- return false;
- }
-
- /*
- * Jumps to the next day.
- */
- if (keycode == getForwardKey() && !shift) {
- // Calculate new showing value
-
- Date newCurrentDate = (Date) focusedDate.clone();
-
- newCurrentDate.setDate(newCurrentDate.getDate() + 1);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() + 1);
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps to the previous day
- */
- } else if (keycode == getBackwardKey() && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() - 1);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() - 1);
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps one week back in the calendar
- */
- } else if (keycode == getPreviousKey() && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() - 7);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()
- && focusedRow > 1) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate = newCurrentDate;
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps one week forward in the calendar
- */
- } else if (keycode == getNextKey() && !ctrl && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() + 7);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate = newCurrentDate;
- renderCalendar();
-
- }
-
- return true;
-
- /*
- * Selects the value that is chosen
- */
- } else if (keycode == getSelectKey() && !shift) {
- selectFocused();
- onSubmit(); // submit
- return true;
- } else if (keycode == getCloseKey()) {
- onCancel();
- // TODO close event
-
- return true;
-
- /*
- * Jumps to the next month
- */
- } else if (shift && keycode == getForwardKey()) {
- focusNextMonth();
- return true;
-
- /*
- * Jumps to the previous month
- */
- } else if (shift && keycode == getBackwardKey()) {
- focusPreviousMonth();
- return true;
-
- /*
- * Jumps to the next year
- */
- } else if (shift && keycode == getPreviousKey()) {
- focusNextYear(1);
- return true;
-
- /*
- * Jumps to the previous year
- */
- } else if (shift && keycode == getNextKey()) {
- focusPreviousYear(1);
- return true;
-
- /*
- * Resets the selection
- */
- } else if (keycode == getResetKey() && !shift) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
- }
-
- return false;
- }
-
- /**
- * Handles the keyboard navigation
- *
- * @param keycode
- * The key code that was pressed
- * @param ctrl
- * Was the ctrl key pressed
- * @param shift
- * Was the shift key pressed
- * @return Return true if key press was handled by the component, else
- * return false
- */
- protected boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
- if (!isEnabled() || isReadonly()) {
- return false;
- }
-
- else if (resolution == VDateField.RESOLUTION_YEAR) {
- return handleNavigationYearMode(keycode, ctrl, shift);
- }
-
- else if (resolution == VDateField.RESOLUTION_MONTH) {
- return handleNavigationMonthMode(keycode, ctrl, shift);
- }
-
- else if (resolution == VDateField.RESOLUTION_DAY) {
- return handleNavigationDayMode(keycode, ctrl, shift);
- }
-
- else {
- return handleNavigationDayMode(keycode, ctrl, shift);
- }
-
- }
-
- /**
- * Returns the reset key which will reset the calendar to the previous
- * selection. By default this is backspace but it can be overriden to change
- * the key to whatever you want.
- *
- * @return
- */
- protected int getResetKey() {
- return KeyCodes.KEY_BACKSPACE;
- }
-
- /**
- * Returns the select key which selects the value. By default this is the
- * enter key but it can be changed to whatever you like by overriding this
- * method.
- *
- * @return
- */
- protected int getSelectKey() {
- return KeyCodes.KEY_ENTER;
- }
-
- /**
- * Returns the key that closes the popup window if this is a VPopopCalendar.
- * Else this does nothing. By default this is the Escape key but you can
- * change the key to whatever you want by overriding this method.
- *
- * @return
- */
- protected int getCloseKey() {
- return KeyCodes.KEY_ESCAPE;
- }
-
- /**
- * The key that selects the next day in the calendar. By default this is the
- * right arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getForwardKey() {
- return KeyCodes.KEY_RIGHT;
- }
-
- /**
- * The key that selects the previous day in the calendar. By default this is
- * the left arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getBackwardKey() {
- return KeyCodes.KEY_LEFT;
- }
-
- /**
- * The key that selects the next week in the calendar. By default this is
- * the down arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getNextKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * The key that selects the previous week in the calendar. By default this
- * is the up arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getPreviousKey() {
- return KeyCodes.KEY_UP;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google
- * .gwt.event.dom.client.MouseOutEvent)
- */
- public void onMouseOut(MouseOutEvent event) {
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
- * .gwt.event.dom.client.MouseDownEvent)
- */
- public void onMouseDown(MouseDownEvent event) {
- // Allow user to click-n-hold for fast-forward or fast-rewind.
- // Timer is first used for a 500ms delay after mousedown. After that has
- // elapsed, another timer is triggered to go off every 150ms. Both
- // timers are cancelled on mouseup or mouseout.
- if (event.getSource() instanceof VEventButton) {
- final VEventButton sender = (VEventButton) event.getSource();
- processClickEvent(sender);
- mouseTimer = new Timer() {
- @Override
- public void run() {
- mouseTimer = new Timer() {
- @Override
- public void run() {
- processClickEvent(sender);
- }
- };
- mouseTimer.scheduleRepeating(150);
- }
- };
- mouseTimer.schedule(500);
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt
- * .event.dom.client.MouseUpEvent)
- */
- public void onMouseUp(MouseUpEvent event) {
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-
- /**
- * Sets the data of the Panel.
- *
- * @param currentDate
- * The date to set
- */
- public void setDate(Date currentDate) {
-
- // Check that we are not re-rendering an already active date
- if (currentDate == value && currentDate != null) {
- return;
- }
-
- Date oldDisplayedMonth = displayedMonth;
- value = currentDate;
-
- if (value == null) {
- focusedDate = displayedMonth = null;
- } else {
- focusedDate = (Date) value.clone();
- displayedMonth = (Date) value.clone();
- }
-
- // Re-render calendar if month or year of focused date has changed
- if (oldDisplayedMonth == null || value == null
- || oldDisplayedMonth.getYear() != value.getYear()
- || oldDisplayedMonth.getMonth() != value.getMonth()) {
- renderCalendar();
- } else {
- focusDay(currentDate);
- selectFocused();
- }
-
- if (!hasFocus) {
- focusDay((Date) null);
- }
- }
-
- /**
- * TimeSelector is a widget consisting of list boxes that modifie the Date
- * object that is given for.
- *
- */
- public class VTime extends FlowPanel implements ChangeHandler {
-
- private ListBox hours;
-
- private ListBox mins;
-
- private ListBox sec;
-
- private ListBox ampm;
-
- /**
- * Constructor
- */
- public VTime() {
- super();
- setStyleName(VDateField.CLASSNAME + "-time");
- buildTime();
- }
-
- private ListBox createListBox() {
- ListBox lb = new ListBox();
- lb.setStyleName(VNativeSelect.CLASSNAME);
- lb.addChangeHandler(this);
- lb.addBlurHandler(VCalendarPanel.this);
- lb.addFocusHandler(VCalendarPanel.this);
- return lb;
- }
-
- /**
- * Constructs the ListBoxes and updates their value
- *
- * @param redraw
- * Should new instances of the listboxes be created
- */
- private void buildTime() {
- clear();
-
- hours = createListBox();
- if (getDateTimeService().isTwelveHourClock()) {
- hours.addItem("12");
- for (int i = 1; i < 12; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
- }
- } else {
- for (int i = 0; i < 24; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
- }
- }
-
- hours.addChangeHandler(this);
- if (getDateTimeService().isTwelveHourClock()) {
- ampm = createListBox();
- final String[] ampmText = getDateTimeService().getAmPmStrings();
- ampm.addItem(ampmText[0]);
- ampm.addItem(ampmText[1]);
- ampm.addChangeHandler(this);
- }
-
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- mins = createListBox();
- for (int i = 0; i < 60; i++) {
- mins.addItem((i < 10) ? "0" + i : "" + i);
- }
- mins.addChangeHandler(this);
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- sec = createListBox();
- for (int i = 0; i < 60; i++) {
- sec.addItem((i < 10) ? "0" + i : "" + i);
- }
- sec.addChangeHandler(this);
- }
-
- final String delimiter = getDateTimeService().getClockDelimeter();
- if (isReadonly()) {
- int h = 0;
- if (value != null) {
- h = value.getHours();
- }
- if (getDateTimeService().isTwelveHourClock()) {
- h -= h < 12 ? 0 : 12;
- }
- add(new VLabel(h < 10 ? "0" + h : "" + h));
- } else {
- add(hours);
- }
-
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- add(new VLabel(delimiter));
- if (isReadonly()) {
- final int m = mins.getSelectedIndex();
- add(new VLabel(m < 10 ? "0" + m : "" + m));
- } else {
- add(mins);
- }
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- add(new VLabel(delimiter));
- if (isReadonly()) {
- final int s = sec.getSelectedIndex();
- add(new VLabel(s < 10 ? "0" + s : "" + s));
- } else {
- add(sec);
- }
- }
- if (getResolution() == VDateField.RESOLUTION_HOUR) {
- add(new VLabel(delimiter + "00")); // o'clock
- }
- if (getDateTimeService().isTwelveHourClock()) {
- add(new VLabel("&nbsp;"));
- if (isReadonly()) {
- int i = 0;
- if (value != null) {
- i = (value.getHours() < 12) ? 0 : 1;
- }
- add(new VLabel(ampm.getItemText(i)));
- } else {
- add(ampm);
- }
- }
-
- if (isReadonly()) {
- return;
- }
-
- // Update times
- updateTimes();
-
- ListBox lastDropDown = getLastDropDown();
- lastDropDown.addKeyDownHandler(new KeyDownHandler() {
- public void onKeyDown(KeyDownEvent event) {
- boolean shiftKey = event.getNativeEvent().getShiftKey();
- if (shiftKey) {
- return;
- } else {
- int nativeKeyCode = event.getNativeKeyCode();
- if (nativeKeyCode == KeyCodes.KEY_TAB) {
- onTabOut(event);
- }
- }
- }
- });
-
- }
-
- private ListBox getLastDropDown() {
- int i = getWidgetCount() - 1;
- while (i >= 0) {
- Widget widget = getWidget(i);
- if (widget instanceof ListBox) {
- return (ListBox) widget;
- }
- i--;
- }
- return null;
- }
-
- /**
- * Updates the valus to correspond to the values in value
- */
- public void updateTimes() {
- boolean selected = true;
- if (value == null) {
- value = new Date();
- selected = false;
- }
- if (getDateTimeService().isTwelveHourClock()) {
- int h = value.getHours();
- ampm.setSelectedIndex(h < 12 ? 0 : 1);
- h -= ampm.getSelectedIndex() * 12;
- hours.setSelectedIndex(h);
- } else {
- hours.setSelectedIndex(value.getHours());
- }
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- mins.setSelectedIndex(value.getMinutes());
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- sec.setSelectedIndex(value.getSeconds());
- }
- if (getDateTimeService().isTwelveHourClock()) {
- ampm.setSelectedIndex(value.getHours() < 12 ? 0 : 1);
- }
-
- hours.setEnabled(isEnabled());
- if (mins != null) {
- mins.setEnabled(isEnabled());
- }
- if (sec != null) {
- sec.setEnabled(isEnabled());
- }
- if (ampm != null) {
- ampm.setEnabled(isEnabled());
- }
-
- }
-
- private int getMilliseconds() {
- return DateTimeService.getMilliseconds(value);
- }
-
- private DateTimeService getDateTimeService() {
- if (dateTimeService == null) {
- dateTimeService = new DateTimeService();
- }
- return dateTimeService;
- }
-
- /*
- * (non-Javadoc) VT
- *
- * @see
- * com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt
- * .event.dom.client.ChangeEvent)
- */
- public void onChange(ChangeEvent event) {
- /*
- * Value from dropdowns gets always set for the value. Like year and
- * month when resolution is month or year.
- */
- if (event.getSource() == hours) {
- int h = hours.getSelectedIndex();
- if (getDateTimeService().isTwelveHourClock()) {
- h = h + ampm.getSelectedIndex() * 12;
- }
- value.setHours(h);
- if (timeChangeListener != null) {
- timeChangeListener.changed(h, value.getMinutes(),
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == mins) {
- final int m = mins.getSelectedIndex();
- value.setMinutes(m);
- if (timeChangeListener != null) {
- timeChangeListener.changed(value.getHours(), m,
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == sec) {
- final int s = sec.getSelectedIndex();
- value.setSeconds(s);
- if (timeChangeListener != null) {
- timeChangeListener.changed(value.getHours(),
- value.getMinutes(), s,
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == ampm) {
- final int h = hours.getSelectedIndex()
- + (ampm.getSelectedIndex() * 12);
- value.setHours(h);
- if (timeChangeListener != null) {
- timeChangeListener.changed(h, value.getMinutes(),
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- }
-
- private class Day extends InlineHTML {
- private static final String BASECLASS = VDateField.CLASSNAME
- + "-calendarpanel-day";
- private final Date date;
-
- Day(Date date) {
- super("" + date.getDate());
- setStyleName(BASECLASS);
- this.date = date;
- addClickHandler(dayClickHandler);
- }
-
- public Date getDate() {
- return date;
- }
- }
-
- public Date getDate() {
- return value;
- }
-
- /**
- * If true should be returned if the panel will not be used after this
- * event.
- *
- * @param event
- * @return
- */
- protected boolean onTabOut(DomEvent<?> event) {
- if (focusOutListener != null) {
- return focusOutListener.onFocusOut(event);
- }
- return false;
- }
-
- /**
- * A focus out listener is triggered when the panel loosed focus. This can
- * happen either after a user clicks outside the panel or tabs out.
- *
- * @param listener
- * The listener to trigger
- */
- public void setFocusOutListener(FocusOutListener listener) {
- focusOutListener = listener;
- }
-
- /**
- * The submit listener is called when the user selects a value from the
- * calender either by clicking the day or selects it by keyboard.
- *
- * @param submitListener
- * The listener to trigger
- */
- public void setSubmitListener(SubmitListener submitListener) {
- this.submitListener = submitListener;
- }
-
- /**
- * The given FocusChangeListener is notified when the focused date changes
- * by user either clicking on a new date or by using the keyboard.
- *
- * @param listener
- * The FocusChangeListener to be notified
- */
- public void setFocusChangeListener(FocusChangeListener listener) {
- focusChangeListener = listener;
- }
-
- /**
- * The time change listener is triggered when the user changes the time.
- *
- * @param listener
- */
- public void setTimeChangeListener(TimeChangeListener listener) {
- timeChangeListener = listener;
- }
-
- /**
- * Returns the submit listener that listens to selection made from the panel
- *
- * @return The listener or NULL if no listener has been set
- */
- public SubmitListener getSubmitListener() {
- return submitListener;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
- * .dom.client.BlurEvent)
- */
- public void onBlur(final BlurEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
- hasFocus = false;
- focusDay(null);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event
- * .dom.client.FocusEvent)
- */
- public void onFocus(FocusEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
- hasFocus = true;
-
- // Focuses the current day if the calendar shows the days
- if (focusedDay != null) {
- focusDay(focusedDate);
- }
- }
- }
-
- private static final String SUBPART_NEXT_MONTH = "nextmon";
- private static final String SUBPART_PREV_MONTH = "prevmon";
-
- private static final String SUBPART_NEXT_YEAR = "nexty";
- private static final String SUBPART_PREV_YEAR = "prevy";
- private static final String SUBPART_HOUR_SELECT = "h";
- private static final String SUBPART_MINUTE_SELECT = "m";
- private static final String SUBPART_SECS_SELECT = "s";
- private static final String SUBPART_MSECS_SELECT = "ms";
- private static final String SUBPART_AMPM_SELECT = "ampm";
- private static final String SUBPART_DAY = "day";
- private static final String SUBPART_MONTH_YEAR_HEADER = "header";
-
- public String getSubPartName(Element subElement) {
- if (contains(nextMonth, subElement)) {
- return SUBPART_NEXT_MONTH;
- } else if (contains(prevMonth, subElement)) {
- return SUBPART_PREV_MONTH;
- } else if (contains(nextYear, subElement)) {
- return SUBPART_NEXT_YEAR;
- } else if (contains(prevYear, subElement)) {
- return SUBPART_PREV_YEAR;
- } else if (contains(days, subElement)) {
- // Day, find out which dayOfMonth and use that as the identifier
- Day day = Util.findWidget(subElement, Day.class);
- if (day != null) {
- Date date = day.getDate();
- int id = date.getDate();
- if (date.getMonth() < displayedMonth.getMonth()) {
- id -= DateTimeService.getNumberOfDaysInMonth(date);
- } else if (date.getMonth() > displayedMonth.getMonth()) {
- id += DateTimeService
- .getNumberOfDaysInMonth(displayedMonth);
- }
- return SUBPART_DAY + id;
- }
- } else if (time != null) {
- if (contains(time.hours, subElement)) {
- return SUBPART_HOUR_SELECT;
- } else if (contains(time.mins, subElement)) {
- return SUBPART_MINUTE_SELECT;
- } else if (contains(time.sec, subElement)) {
- return SUBPART_SECS_SELECT;
- } else if (contains(time.ampm, subElement)) {
- return SUBPART_AMPM_SELECT;
-
- }
- } else if (getCellFormatter().getElement(0, 2).isOrHasChild(subElement)) {
- return SUBPART_MONTH_YEAR_HEADER;
- }
-
- return null;
- }
-
- /**
- * Checks if subElement is inside the widget DOM hierarchy.
- *
- * @param w
- * @param subElement
- * @return true if {@code w} is a parent of subElement, false otherwise.
- */
- private boolean contains(Widget w, Element subElement) {
- if (w == null || w.getElement() == null) {
- return false;
- }
-
- return w.getElement().isOrHasChild(subElement);
- }
-
- public Element getSubPartElement(String subPart) {
- if (SUBPART_NEXT_MONTH.equals(subPart)) {
- return nextMonth.getElement();
- }
- if (SUBPART_PREV_MONTH.equals(subPart)) {
- return prevMonth.getElement();
- }
- if (SUBPART_NEXT_YEAR.equals(subPart)) {
- return nextYear.getElement();
- }
- if (SUBPART_PREV_YEAR.equals(subPart)) {
- return prevYear.getElement();
- }
- if (SUBPART_HOUR_SELECT.equals(subPart)) {
- return time.hours.getElement();
- }
- if (SUBPART_MINUTE_SELECT.equals(subPart)) {
- return time.mins.getElement();
- }
- if (SUBPART_SECS_SELECT.equals(subPart)) {
- return time.sec.getElement();
- }
- if (SUBPART_AMPM_SELECT.equals(subPart)) {
- return time.ampm.getElement();
- }
- if (subPart.startsWith(SUBPART_DAY)) {
- // can be less than 1 or greater than the number of days in the current month
- // these map to the "off-month" days
- int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY
- .length()));
- Date date = new Date(displayedMonth.getYear(),
- displayedMonth.getMonth(), dayOfMonth);
- Iterator<Widget> iter = days.iterator();
- while (iter.hasNext()) {
- Widget w = iter.next();
- if (w instanceof Day) {
- Day day = (Day) w;
- if (day.getDate().equals(date)) {
- return day.getElement();
- }
- }
- }
- }
-
- if (SUBPART_MONTH_YEAR_HEADER.equals(subPart)) {
- return (Element) getCellFormatter().getElement(0, 2).getChild(0);
- }
- return null;
- }
-
- @Override
- protected void onDetach() {
- super.onDetach();
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+import java.util.Iterator;
+
+import com.google.gwt.dom.client.Node;
+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.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseUpEvent;
+import com.google.gwt.event.dom.client.MouseUpHandler;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.InlineHTML;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.ui.label.VLabel;
+
+@SuppressWarnings("deprecation")
+public class VCalendarPanel extends FocusableFlexTable implements
+ KeyDownHandler, KeyPressHandler, MouseOutHandler, MouseDownHandler,
+ MouseUpHandler, BlurHandler, FocusHandler, SubPartAware {
+
+ public interface SubmitListener {
+
+ /**
+ * Called when calendar user triggers a submitting operation in calendar
+ * panel. Eg. clicking on day or hitting enter.
+ */
+ void onSubmit();
+
+ /**
+ * On eg. ESC key.
+ */
+ void onCancel();
+ }
+
+ /**
+ * Blur listener that listens to blur event from the panel
+ */
+ public interface FocusOutListener {
+ /**
+ * @return true if the calendar panel is not used after focus moves out
+ */
+ boolean onFocusOut(DomEvent<?> event);
+ }
+
+ /**
+ * FocusChangeListener is notified when the panel changes its _focused_
+ * value.
+ */
+ public interface FocusChangeListener {
+ void focusChanged(Date focusedDate);
+ }
+
+ /**
+ * Dispatches an event when the panel when time is changed
+ */
+ public interface TimeChangeListener {
+
+ void changed(int hour, int min, int sec, int msec);
+ }
+
+ /**
+ * Represents a Date button in the calendar
+ */
+ private class VEventButton extends Button {
+ public VEventButton() {
+ addMouseDownHandler(VCalendarPanel.this);
+ addMouseOutHandler(VCalendarPanel.this);
+ addMouseUpHandler(VCalendarPanel.this);
+ }
+ }
+
+ private static final String CN_FOCUSED = "focused";
+
+ private static final String CN_TODAY = "today";
+
+ private static final String CN_SELECTED = "selected";
+
+ private static final String CN_OFFMONTH = "offmonth";
+
+ /**
+ * Represents a click handler for when a user selects a value by using the
+ * mouse
+ */
+ private ClickHandler dayClickHandler = new ClickHandler() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
+ * .event.dom.client.ClickEvent)
+ */
+ public void onClick(ClickEvent event) {
+ Day day = (Day) event.getSource();
+ focusDay(day.getDate());
+ selectFocused();
+ onSubmit();
+ }
+ };
+
+ private VEventButton prevYear;
+
+ private VEventButton nextYear;
+
+ private VEventButton prevMonth;
+
+ private VEventButton nextMonth;
+
+ private VTime time;
+
+ private FlexTable days = new FlexTable();
+
+ private int resolution = VDateField.RESOLUTION_YEAR;
+
+ private int focusedRow;
+
+ private Timer mouseTimer;
+
+ private Date value;
+
+ private boolean enabled = true;
+
+ private boolean readonly = false;
+
+ private DateTimeService dateTimeService;
+
+ private boolean showISOWeekNumbers;
+
+ private Date displayedMonth;
+
+ private Date focusedDate;
+
+ private Day selectedDay;
+
+ private Day focusedDay;
+
+ private FocusOutListener focusOutListener;
+
+ private SubmitListener submitListener;
+
+ private FocusChangeListener focusChangeListener;
+
+ private TimeChangeListener timeChangeListener;
+
+ private boolean hasFocus = false;
+
+ public VCalendarPanel() {
+
+ setStyleName(VDateField.CLASSNAME + "-calendarpanel");
+
+ /*
+ * Firefox auto-repeat works correctly only if we use a key press
+ * handler, other browsers handle it correctly when using a key down
+ * handler
+ */
+ if (BrowserInfo.get().isGecko()) {
+ addKeyPressHandler(this);
+ } else {
+ addKeyDownHandler(this);
+ }
+ addFocusHandler(this);
+ addBlurHandler(this);
+
+ }
+
+ /**
+ * Sets the focus to given date in the current view. Used when moving in the
+ * calendar with the keyboard.
+ *
+ * @param date
+ * A Date representing the day of month to be focused. Must be
+ * one of the days currently visible.
+ */
+ private void focusDay(Date date) {
+ // Only used when calender body is present
+ if (resolution > VDateField.RESOLUTION_MONTH) {
+ if (focusedDay != null) {
+ focusedDay.removeStyleDependentName(CN_FOCUSED);
+ }
+
+ if (date != null && focusedDate != null) {
+ focusedDate.setTime(date.getTime());
+ int rowCount = days.getRowCount();
+ for (int i = 0; i < rowCount; i++) {
+ int cellCount = days.getCellCount(i);
+ for (int j = 0; j < cellCount; j++) {
+ Widget widget = days.getWidget(i, j);
+ if (widget != null && widget instanceof Day) {
+ Day curday = (Day) widget;
+ if (curday.getDate().equals(date)) {
+ curday.addStyleDependentName(CN_FOCUSED);
+ focusedDay = curday;
+ focusedRow = i;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the selection highlight to a given day in the current view
+ *
+ * @param date
+ * A Date representing the day of month to be selected. Must be
+ * one of the days currently visible.
+ *
+ */
+ private void selectDate(Date date) {
+ if (selectedDay != null) {
+ selectedDay.removeStyleDependentName(CN_SELECTED);
+ }
+
+ int rowCount = days.getRowCount();
+ for (int i = 0; i < rowCount; i++) {
+ int cellCount = days.getCellCount(i);
+ for (int j = 0; j < cellCount; j++) {
+ Widget widget = days.getWidget(i, j);
+ if (widget != null && widget instanceof Day) {
+ Day curday = (Day) widget;
+ if (curday.getDate().equals(date)) {
+ curday.addStyleDependentName(CN_SELECTED);
+ selectedDay = curday;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates year, month, day from focusedDate to value
+ */
+ private void selectFocused() {
+ if (focusedDate != null) {
+ if (value == null) {
+ // No previously selected value (set to null on server side).
+ // Create a new date using current date and time
+ value = new Date();
+ }
+ /*
+ * #5594 set Date (day) to 1 in order to prevent any kind of
+ * wrapping of months when later setting the month. (e.g. 31 ->
+ * month with 30 days -> wraps to the 1st of the following month,
+ * e.g. 31st of May -> 31st of April = 1st of May)
+ */
+ value.setDate(1);
+ if (value.getYear() != focusedDate.getYear()) {
+ value.setYear(focusedDate.getYear());
+ }
+ if (value.getMonth() != focusedDate.getMonth()) {
+ value.setMonth(focusedDate.getMonth());
+ }
+ if (value.getDate() != focusedDate.getDate()) {
+ }
+ // We always need to set the date, even if it hasn't changed, since
+ // it was forced to 1 above.
+ value.setDate(focusedDate.getDate());
+
+ selectDate(focusedDate);
+ } else {
+ VConsole.log("Trying to select a the focused date which is NULL!");
+ }
+ }
+
+ protected boolean onValueChange() {
+ return false;
+ }
+
+ public int getResolution() {
+ return resolution;
+ }
+
+ public void setResolution(int resolution) {
+ this.resolution = resolution;
+ if (time != null) {
+ time.removeFromParent();
+ time = null;
+ }
+ }
+
+ private boolean isReadonly() {
+ return readonly;
+ }
+
+ private boolean isEnabled() {
+ return enabled;
+ }
+
+ private void clearCalendarBody(boolean remove) {
+ if (!remove) {
+ // Leave the cells in place but clear their contents
+
+ // This has the side effect of ensuring that the calendar always
+ // contain 7 rows.
+ for (int row = 1; row < 7; row++) {
+ for (int col = 0; col < 8; col++) {
+ days.setHTML(row, col, "&nbsp;");
+ }
+ }
+ } else if (getRowCount() > 1) {
+ removeRow(1);
+ days.clear();
+ }
+ }
+
+ /**
+ * Builds the top buttons and current month and year header.
+ *
+ * @param needsMonth
+ * Should the month buttons be visible?
+ */
+ private void buildCalendarHeader(boolean needsMonth) {
+
+ getRowFormatter().addStyleName(0,
+ VDateField.CLASSNAME + "-calendarpanel-header");
+
+ if (prevMonth == null && needsMonth) {
+ prevMonth = new VEventButton();
+ prevMonth.setHTML("&lsaquo;");
+ prevMonth.setStyleName("v-button-prevmonth");
+ prevMonth.setTabIndex(-1);
+ nextMonth = new VEventButton();
+ nextMonth.setHTML("&rsaquo;");
+ nextMonth.setStyleName("v-button-nextmonth");
+ nextMonth.setTabIndex(-1);
+ getFlexCellFormatter().setStyleName(0, 3,
+ VDateField.CLASSNAME + "-calendarpanel-nextmonth");
+ getFlexCellFormatter().setStyleName(0, 1,
+ VDateField.CLASSNAME + "-calendarpanel-prevmonth");
+
+ setWidget(0, 3, nextMonth);
+ setWidget(0, 1, prevMonth);
+ } else if (prevMonth != null && !needsMonth) {
+ // Remove month traverse buttons
+ remove(prevMonth);
+ remove(nextMonth);
+ prevMonth = null;
+ nextMonth = null;
+ }
+
+ if (prevYear == null) {
+ prevYear = new VEventButton();
+ prevYear.setHTML("&laquo;");
+ prevYear.setStyleName("v-button-prevyear");
+ prevYear.setTabIndex(-1);
+ nextYear = new VEventButton();
+ nextYear.setHTML("&raquo;");
+ nextYear.setStyleName("v-button-nextyear");
+ nextYear.setTabIndex(-1);
+ setWidget(0, 0, prevYear);
+ setWidget(0, 4, nextYear);
+ getFlexCellFormatter().setStyleName(0, 0,
+ VDateField.CLASSNAME + "-calendarpanel-prevyear");
+ getFlexCellFormatter().setStyleName(0, 4,
+ VDateField.CLASSNAME + "-calendarpanel-nextyear");
+ }
+
+ final String monthName = needsMonth ? getDateTimeService().getMonth(
+ focusedDate.getMonth()) : "";
+ final int year = focusedDate.getYear() + 1900;
+ getFlexCellFormatter().setStyleName(0, 2,
+ VDateField.CLASSNAME + "-calendarpanel-month");
+ setHTML(0, 2, "<span class=\"" + VDateField.CLASSNAME
+ + "-calendarpanel-month\">" + monthName + " " + year
+ + "</span>");
+ }
+
+ private DateTimeService getDateTimeService() {
+ return dateTimeService;
+ }
+
+ public void setDateTimeService(DateTimeService dateTimeService) {
+ this.dateTimeService = dateTimeService;
+ }
+
+ /**
+ * Returns whether ISO 8601 week numbers should be shown in the value
+ * selector or not. ISO 8601 defines that a week always starts with a Monday
+ * so the week numbers are only shown if this is the case.
+ *
+ * @return true if week number should be shown, false otherwise
+ */
+ public boolean isShowISOWeekNumbers() {
+ return showISOWeekNumbers;
+ }
+
+ public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
+ this.showISOWeekNumbers = showISOWeekNumbers;
+ }
+
+ /**
+ * Builds the day and time selectors of the calendar.
+ */
+ private void buildCalendarBody() {
+
+ final int weekColumn = 0;
+ final int firstWeekdayColumn = 1;
+ final int headerRow = 0;
+
+ setWidget(1, 0, days);
+ setCellPadding(0);
+ setCellSpacing(0);
+ getFlexCellFormatter().setColSpan(1, 0, 5);
+ getFlexCellFormatter().setStyleName(1, 0,
+ VDateField.CLASSNAME + "-calendarpanel-body");
+
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
+ "v-week");
+ days.setHTML(headerRow, weekColumn, "<strong></strong>");
+ // Hide the week column if week numbers are not to be displayed.
+ days.getFlexCellFormatter().setVisible(headerRow, weekColumn,
+ isShowISOWeekNumbers());
+
+ days.getRowFormatter().setStyleName(headerRow,
+ VDateField.CLASSNAME + "-calendarpanel-weekdays");
+
+ if (isShowISOWeekNumbers()) {
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
+ "v-first");
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn, "");
+ days.getRowFormatter().addStyleName(headerRow,
+ VDateField.CLASSNAME + "-calendarpanel-weeknumbers");
+ } else {
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "");
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn, "v-first");
+ }
+
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn + 6, "v-last");
+
+ // Print weekday names
+ final int firstDay = getDateTimeService().getFirstDayOfWeek();
+ for (int i = 0; i < 7; i++) {
+ int day = i + firstDay;
+ if (day > 6) {
+ day = 0;
+ }
+ if (getResolution() > VDateField.RESOLUTION_MONTH) {
+ days.setHTML(headerRow, firstWeekdayColumn + i, "<strong>"
+ + getDateTimeService().getShortDay(day) + "</strong>");
+ } else {
+ days.setHTML(headerRow, firstWeekdayColumn + i, "");
+ }
+ }
+
+ // Zero out hours, minutes, seconds, and milliseconds to compare dates
+ // without time part
+ final Date tmp = new Date();
+ final Date today = new Date(tmp.getYear(), tmp.getMonth(),
+ tmp.getDate());
+
+ final Date selectedDate = value == null ? null : new Date(
+ value.getYear(), value.getMonth(), value.getDate());
+
+ final int startWeekDay = getDateTimeService().getStartWeekDay(
+ displayedMonth);
+ final Date curr = (Date) displayedMonth.clone();
+ // Start from the first day of the week that at least partially belongs
+ // to the current month
+ curr.setDate(1 - startWeekDay);
+
+ // No month has more than 6 weeks so 6 is a safe maximum for rows.
+ for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {
+ for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
+
+ // Actually write the day of month
+ Day day = new Day((Date) curr.clone());
+
+ if (curr.equals(selectedDate)) {
+ day.addStyleDependentName(CN_SELECTED);
+ selectedDay = day;
+ }
+ if (curr.equals(today)) {
+ day.addStyleDependentName(CN_TODAY);
+ }
+ if (curr.equals(focusedDate)) {
+ focusedDay = day;
+ focusedRow = weekOfMonth;
+ if (hasFocus) {
+ day.addStyleDependentName(CN_FOCUSED);
+ }
+ }
+ if (curr.getMonth() != displayedMonth.getMonth()) {
+ day.addStyleDependentName(CN_OFFMONTH);
+ }
+
+ days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);
+
+ // ISO week numbers if requested
+ days.getCellFormatter().setVisible(weekOfMonth, weekColumn,
+ isShowISOWeekNumbers());
+ if (isShowISOWeekNumbers()) {
+ final String baseCssClass = VDateField.CLASSNAME
+ + "-calendarpanel-weeknumber";
+ String weekCssClass = baseCssClass;
+
+ int weekNumber = DateTimeService.getISOWeekNumber(curr);
+
+ days.setHTML(weekOfMonth, 0, "<span class=\""
+ + weekCssClass + "\"" + ">" + weekNumber
+ + "</span>");
+ }
+ curr.setDate(curr.getDate() + 1);
+ }
+ }
+ }
+
+ /**
+ * Do we need the time selector
+ *
+ * @return True if it is required
+ */
+ private boolean isTimeSelectorNeeded() {
+ return getResolution() > VDateField.RESOLUTION_DAY;
+ }
+
+ /**
+ * Updates the calendar and text field with the selected dates.
+ */
+ public void renderCalendar() {
+ if (focusedDate == null) {
+ Date now = new Date();
+ // focusedDate must have zero hours, mins, secs, millisecs
+ focusedDate = new Date(now.getYear(), now.getMonth(), now.getDate());
+ displayedMonth = new Date(now.getYear(), now.getMonth(), 1);
+ }
+
+ if (getResolution() <= VDateField.RESOLUTION_MONTH
+ && focusChangeListener != null) {
+ focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
+ }
+
+ final boolean needsMonth = getResolution() > VDateField.RESOLUTION_YEAR;
+ boolean needsBody = getResolution() >= VDateField.RESOLUTION_DAY;
+ buildCalendarHeader(needsMonth);
+ clearCalendarBody(!needsBody);
+ if (needsBody) {
+ buildCalendarBody();
+ }
+
+ if (isTimeSelectorNeeded() && time == null) {
+ time = new VTime();
+ setWidget(2, 0, time);
+ getFlexCellFormatter().setColSpan(2, 0, 5);
+ getFlexCellFormatter().setStyleName(2, 0,
+ VDateField.CLASSNAME + "-calendarpanel-time");
+ } else if (isTimeSelectorNeeded()) {
+ time.updateTimes();
+ } else if (time != null) {
+ remove(time);
+ }
+ }
+
+ /**
+ * Moves the focus forward the given number of days.
+ */
+ private void focusNextDay(int days) {
+ int oldMonth = focusedDate.getMonth();
+ focusedDate.setDate(focusedDate.getDate() + days);
+
+ if (focusedDate.getMonth() == oldMonth) {
+ // Month did not change, only move the selection
+ focusDay(focusedDate);
+ } else {
+ // If the month changed we need to re-render the calendar
+ displayedMonth.setMonth(focusedDate.getMonth());
+ renderCalendar();
+ }
+ }
+
+ /**
+ * Moves the focus backward the given number of days.
+ */
+ private void focusPreviousDay(int days) {
+ focusNextDay(-days);
+ }
+
+ /**
+ * Selects the next month
+ */
+ private void focusNextMonth() {
+
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setMonth(currentMonth + 1);
+ int requestedMonth = (currentMonth + 1) % 12;
+
+ /*
+ * If the selected value was e.g. 31.3 the new value would be 31.4 but
+ * this value is invalid so the new value will be 1.5. This is taken
+ * care of by decreasing the value until we have the correct month.
+ */
+ while (focusedDate.getMonth() != requestedMonth) {
+ focusedDate.setDate(focusedDate.getDate() - 1);
+ }
+ displayedMonth.setMonth(displayedMonth.getMonth() + 1);
+
+ renderCalendar();
+ }
+
+ /**
+ * Selects the previous month
+ */
+ private void focusPreviousMonth() {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setMonth(currentMonth - 1);
+
+ /*
+ * If the selected value was e.g. 31.12 the new value would be 31.11 but
+ * this value is invalid so the new value will be 1.12. This is taken
+ * care of by decreasing the value until we have the correct month.
+ */
+ while (focusedDate.getMonth() == currentMonth) {
+ focusedDate.setDate(focusedDate.getDate() - 1);
+ }
+ displayedMonth.setMonth(displayedMonth.getMonth() - 1);
+
+ renderCalendar();
+ }
+
+ /**
+ * Selects the previous year
+ */
+ private void focusPreviousYear(int years) {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setYear(focusedDate.getYear() - years);
+ displayedMonth.setYear(displayedMonth.getYear() - years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
+ renderCalendar();
+ }
+
+ /**
+ * Selects the next year
+ */
+ private void focusNextYear(int years) {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setYear(focusedDate.getYear() + years);
+ displayedMonth.setYear(displayedMonth.getYear() + years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
+ renderCalendar();
+ }
+
+ /**
+ * Handles a user click on the component
+ *
+ * @param sender
+ * The component that was clicked
+ * @param updateVariable
+ * Should the value field be updated
+ *
+ */
+ private void processClickEvent(Widget sender) {
+ if (!isEnabled() || isReadonly()) {
+ return;
+ }
+ if (sender == prevYear) {
+ focusPreviousYear(1);
+ } else if (sender == nextYear) {
+ focusNextYear(1);
+ } else if (sender == prevMonth) {
+ focusPreviousMonth();
+ } else if (sender == nextMonth) {
+ focusNextMonth();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
+ * .event.dom.client.KeyDownEvent)
+ */
+ public void onKeyDown(KeyDownEvent event) {
+ handleKeyPress(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google
+ * .gwt.event.dom.client.KeyPressEvent)
+ */
+ public void onKeyPress(KeyPressEvent event) {
+ handleKeyPress(event);
+ }
+
+ /**
+ * Handles the keypress from both the onKeyPress event and the onKeyDown
+ * event
+ *
+ * @param event
+ * The keydown/keypress event
+ */
+ private void handleKeyPress(DomEvent<?> event) {
+ if (time != null
+ && time.getElement().isOrHasChild(
+ (Node) event.getNativeEvent().getEventTarget().cast())) {
+ int nativeKeyCode = event.getNativeEvent().getKeyCode();
+ if (nativeKeyCode == getSelectKey()) {
+ onSubmit(); // submit happens if enter key hit down on listboxes
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ return;
+ }
+
+ // Check tabs
+ int keycode = event.getNativeEvent().getKeyCode();
+ if (keycode == KeyCodes.KEY_TAB && event.getNativeEvent().getShiftKey()) {
+ if (onTabOut(event)) {
+ return;
+ }
+ }
+
+ // Handle the navigation
+ if (handleNavigation(keycode, event.getNativeEvent().getCtrlKey()
+ || event.getNativeEvent().getMetaKey(), event.getNativeEvent()
+ .getShiftKey())) {
+ event.preventDefault();
+ }
+
+ }
+
+ /**
+ * Notifies submit-listeners of a submit event
+ */
+ private void onSubmit() {
+ if (getSubmitListener() != null) {
+ getSubmitListener().onSubmit();
+ }
+ }
+
+ /**
+ * Notifies submit-listeners of a cancel event
+ */
+ private void onCancel() {
+ if (getSubmitListener() != null) {
+ getSubmitListener().onCancel();
+ }
+ }
+
+ /**
+ * Handles the keyboard navigation when the resolution is set to years.
+ *
+ * @param keycode
+ * The keycode to process
+ * @param ctrl
+ * Is ctrl pressed?
+ * @param shift
+ * is shift pressed
+ * @return Returns true if the keycode was processed, else false
+ */
+ protected boolean handleNavigationYearMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl and Shift selection not supported
+ if (ctrl || shift) {
+ return false;
+ }
+
+ else if (keycode == getPreviousKey()) {
+ focusNextYear(10); // Add 10 years
+ return true;
+ }
+
+ else if (keycode == getForwardKey()) {
+ focusNextYear(1); // Add 1 year
+ return true;
+ }
+
+ else if (keycode == getNextKey()) {
+ focusPreviousYear(10); // Subtract 10 years
+ return true;
+ }
+
+ else if (keycode == getBackwardKey()) {
+ focusPreviousYear(1); // Subtract 1 year
+ return true;
+
+ } else if (keycode == getSelectKey()) {
+ value = (Date) focusedDate.clone();
+ onSubmit();
+ return true;
+
+ } else if (keycode == getResetKey()) {
+ // Restore showing value the selected value
+ focusedDate.setTime(value.getTime());
+ renderCalendar();
+ return true;
+
+ } else if (keycode == getCloseKey()) {
+ // TODO fire listener, on users responsibility??
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Handle the keyboard navigation when the resolution is set to MONTH
+ *
+ * @param keycode
+ * The keycode to handle
+ * @param ctrl
+ * Was the ctrl key pressed?
+ * @param shift
+ * Was the shift key pressed?
+ * @return
+ */
+ protected boolean handleNavigationMonthMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl selection not supported
+ if (ctrl) {
+ return false;
+
+ } else if (keycode == getPreviousKey()) {
+ focusNextYear(1); // Add 1 year
+ return true;
+
+ } else if (keycode == getForwardKey()) {
+ focusNextMonth(); // Add 1 month
+ return true;
+
+ } else if (keycode == getNextKey()) {
+ focusPreviousYear(1); // Subtract 1 year
+ return true;
+
+ } else if (keycode == getBackwardKey()) {
+ focusPreviousMonth(); // Subtract 1 month
+ return true;
+
+ } else if (keycode == getSelectKey()) {
+ value = (Date) focusedDate.clone();
+ onSubmit();
+ return true;
+
+ } else if (keycode == getResetKey()) {
+ // Restore showing value the selected value
+ focusedDate.setTime(value.getTime());
+ renderCalendar();
+ return true;
+
+ } else if (keycode == getCloseKey() || keycode == KeyCodes.KEY_TAB) {
+
+ // TODO fire close event
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handle keyboard navigation what the resolution is set to DAY
+ *
+ * @param keycode
+ * The keycode to handle
+ * @param ctrl
+ * Was the ctrl key pressed?
+ * @param shift
+ * Was the shift key pressed?
+ * @return Return true if the key press was handled by the method, else
+ * return false.
+ */
+ protected boolean handleNavigationDayMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl key is not in use
+ if (ctrl) {
+ return false;
+ }
+
+ /*
+ * Jumps to the next day.
+ */
+ if (keycode == getForwardKey() && !shift) {
+ focusNextDay(1);
+ return true;
+
+ /*
+ * Jumps to the previous day
+ */
+ } else if (keycode == getBackwardKey() && !shift) {
+ focusPreviousDay(1);
+ return true;
+
+ /*
+ * Jumps one week forward in the calendar
+ */
+ } else if (keycode == getNextKey() && !shift) {
+ focusNextDay(7);
+ return true;
+
+ /*
+ * Jumps one week back in the calendar
+ */
+ } else if (keycode == getPreviousKey() && !shift) {
+ focusPreviousDay(7);
+ return true;
+
+ /*
+ * Selects the value that is chosen
+ */
+ } else if (keycode == getSelectKey() && !shift) {
+ selectFocused();
+ onSubmit(); // submit
+ return true;
+
+ } else if (keycode == getCloseKey()) {
+ onCancel();
+ // TODO close event
+
+ return true;
+
+ /*
+ * Jumps to the next month
+ */
+ } else if (shift && keycode == getForwardKey()) {
+ focusNextMonth();
+ return true;
+
+ /*
+ * Jumps to the previous month
+ */
+ } else if (shift && keycode == getBackwardKey()) {
+ focusPreviousMonth();
+ return true;
+
+ /*
+ * Jumps to the next year
+ */
+ } else if (shift && keycode == getPreviousKey()) {
+ focusNextYear(1);
+ return true;
+
+ /*
+ * Jumps to the previous year
+ */
+ } else if (shift && keycode == getNextKey()) {
+ focusPreviousYear(1);
+ return true;
+
+ /*
+ * Resets the selection
+ */
+ } else if (keycode == getResetKey() && !shift) {
+ // Restore showing value the selected value
+ focusedDate = new Date(value.getYear(), value.getMonth(),
+ value.getDate());
+ displayedMonth = new Date(value.getYear(), value.getMonth(), 1);
+ renderCalendar();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles the keyboard navigation
+ *
+ * @param keycode
+ * The key code that was pressed
+ * @param ctrl
+ * Was the ctrl key pressed
+ * @param shift
+ * Was the shift key pressed
+ * @return Return true if key press was handled by the component, else
+ * return false
+ */
+ protected boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
+ if (!isEnabled() || isReadonly()) {
+ return false;
+ }
+
+ else if (resolution == VDateField.RESOLUTION_YEAR) {
+ return handleNavigationYearMode(keycode, ctrl, shift);
+ }
+
+ else if (resolution == VDateField.RESOLUTION_MONTH) {
+ return handleNavigationMonthMode(keycode, ctrl, shift);
+ }
+
+ else if (resolution == VDateField.RESOLUTION_DAY) {
+ return handleNavigationDayMode(keycode, ctrl, shift);
+ }
+
+ else {
+ return handleNavigationDayMode(keycode, ctrl, shift);
+ }
+
+ }
+
+ /**
+ * Returns the reset key which will reset the calendar to the previous
+ * selection. By default this is backspace but it can be overriden to change
+ * the key to whatever you want.
+ *
+ * @return
+ */
+ protected int getResetKey() {
+ return KeyCodes.KEY_BACKSPACE;
+ }
+
+ /**
+ * Returns the select key which selects the value. By default this is the
+ * enter key but it can be changed to whatever you like by overriding this
+ * method.
+ *
+ * @return
+ */
+ protected int getSelectKey() {
+ return KeyCodes.KEY_ENTER;
+ }
+
+ /**
+ * Returns the key that closes the popup window if this is a VPopopCalendar.
+ * Else this does nothing. By default this is the Escape key but you can
+ * change the key to whatever you want by overriding this method.
+ *
+ * @return
+ */
+ protected int getCloseKey() {
+ return KeyCodes.KEY_ESCAPE;
+ }
+
+ /**
+ * The key that selects the next day in the calendar. By default this is the
+ * right arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getForwardKey() {
+ return KeyCodes.KEY_RIGHT;
+ }
+
+ /**
+ * The key that selects the previous day in the calendar. By default this is
+ * the left arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getBackwardKey() {
+ return KeyCodes.KEY_LEFT;
+ }
+
+ /**
+ * The key that selects the next week in the calendar. By default this is
+ * the down arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getNextKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * The key that selects the previous week in the calendar. By default this
+ * is the up arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getPreviousKey() {
+ return KeyCodes.KEY_UP;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google
+ * .gwt.event.dom.client.MouseOutEvent)
+ */
+ public void onMouseOut(MouseOutEvent event) {
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
+ * .gwt.event.dom.client.MouseDownEvent)
+ */
+ public void onMouseDown(MouseDownEvent event) {
+ // Allow user to click-n-hold for fast-forward or fast-rewind.
+ // Timer is first used for a 500ms delay after mousedown. After that has
+ // elapsed, another timer is triggered to go off every 150ms. Both
+ // timers are cancelled on mouseup or mouseout.
+ if (event.getSource() instanceof VEventButton) {
+ final VEventButton sender = (VEventButton) event.getSource();
+ processClickEvent(sender);
+ mouseTimer = new Timer() {
+ @Override
+ public void run() {
+ mouseTimer = new Timer() {
+ @Override
+ public void run() {
+ processClickEvent(sender);
+ }
+ };
+ mouseTimer.scheduleRepeating(150);
+ }
+ };
+ mouseTimer.schedule(500);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt
+ * .event.dom.client.MouseUpEvent)
+ */
+ public void onMouseUp(MouseUpEvent event) {
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+
+ /**
+ * Sets the data of the Panel.
+ *
+ * @param currentDate
+ * The date to set
+ */
+ public void setDate(Date currentDate) {
+
+ // Check that we are not re-rendering an already active date
+ if (currentDate == value && currentDate != null) {
+ return;
+ }
+
+ Date oldDisplayedMonth = displayedMonth;
+ value = currentDate;
+
+ if (value == null) {
+ focusedDate = displayedMonth = null;
+ } else {
+ focusedDate = new Date(value.getYear(), value.getMonth(),
+ value.getDate());
+ displayedMonth = new Date(value.getYear(), value.getMonth(), 1);
+ }
+
+ // Re-render calendar if month or year of focused date has changed
+ if (oldDisplayedMonth == null || value == null
+ || oldDisplayedMonth.getYear() != value.getYear()
+ || oldDisplayedMonth.getMonth() != value.getMonth()) {
+ renderCalendar();
+ } else {
+ focusDay(focusedDate);
+ selectFocused();
+ }
+
+ if (!hasFocus) {
+ focusDay(null);
+ }
+ }
+
+ /**
+ * TimeSelector is a widget consisting of list boxes that modifie the Date
+ * object that is given for.
+ *
+ */
+ public class VTime extends FlowPanel implements ChangeHandler {
+
+ private ListBox hours;
+
+ private ListBox mins;
+
+ private ListBox sec;
+
+ private ListBox ampm;
+
+ /**
+ * Constructor
+ */
+ public VTime() {
+ super();
+ setStyleName(VDateField.CLASSNAME + "-time");
+ buildTime();
+ }
+
+ private ListBox createListBox() {
+ ListBox lb = new ListBox();
+ lb.setStyleName(VNativeSelect.CLASSNAME);
+ lb.addChangeHandler(this);
+ lb.addBlurHandler(VCalendarPanel.this);
+ lb.addFocusHandler(VCalendarPanel.this);
+ return lb;
+ }
+
+ /**
+ * Constructs the ListBoxes and updates their value
+ *
+ * @param redraw
+ * Should new instances of the listboxes be created
+ */
+ private void buildTime() {
+ clear();
+
+ hours = createListBox();
+ if (getDateTimeService().isTwelveHourClock()) {
+ hours.addItem("12");
+ for (int i = 1; i < 12; i++) {
+ hours.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ } else {
+ for (int i = 0; i < 24; i++) {
+ hours.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ }
+
+ hours.addChangeHandler(this);
+ if (getDateTimeService().isTwelveHourClock()) {
+ ampm = createListBox();
+ final String[] ampmText = getDateTimeService().getAmPmStrings();
+ ampm.addItem(ampmText[0]);
+ ampm.addItem(ampmText[1]);
+ ampm.addChangeHandler(this);
+ }
+
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ mins = createListBox();
+ for (int i = 0; i < 60; i++) {
+ mins.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ mins.addChangeHandler(this);
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ sec = createListBox();
+ for (int i = 0; i < 60; i++) {
+ sec.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ sec.addChangeHandler(this);
+ }
+
+ final String delimiter = getDateTimeService().getClockDelimeter();
+ if (isReadonly()) {
+ int h = 0;
+ if (value != null) {
+ h = value.getHours();
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ h -= h < 12 ? 0 : 12;
+ }
+ add(new VLabel(h < 10 ? "0" + h : "" + h));
+ } else {
+ add(hours);
+ }
+
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ add(new VLabel(delimiter));
+ if (isReadonly()) {
+ final int m = mins.getSelectedIndex();
+ add(new VLabel(m < 10 ? "0" + m : "" + m));
+ } else {
+ add(mins);
+ }
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ add(new VLabel(delimiter));
+ if (isReadonly()) {
+ final int s = sec.getSelectedIndex();
+ add(new VLabel(s < 10 ? "0" + s : "" + s));
+ } else {
+ add(sec);
+ }
+ }
+ if (getResolution() == VDateField.RESOLUTION_HOUR) {
+ add(new VLabel(delimiter + "00")); // o'clock
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ add(new VLabel("&nbsp;"));
+ if (isReadonly()) {
+ int i = 0;
+ if (value != null) {
+ i = (value.getHours() < 12) ? 0 : 1;
+ }
+ add(new VLabel(ampm.getItemText(i)));
+ } else {
+ add(ampm);
+ }
+ }
+
+ if (isReadonly()) {
+ return;
+ }
+
+ // Update times
+ updateTimes();
+
+ ListBox lastDropDown = getLastDropDown();
+ lastDropDown.addKeyDownHandler(new KeyDownHandler() {
+ public void onKeyDown(KeyDownEvent event) {
+ boolean shiftKey = event.getNativeEvent().getShiftKey();
+ if (shiftKey) {
+ return;
+ } else {
+ int nativeKeyCode = event.getNativeKeyCode();
+ if (nativeKeyCode == KeyCodes.KEY_TAB) {
+ onTabOut(event);
+ }
+ }
+ }
+ });
+
+ }
+
+ private ListBox getLastDropDown() {
+ int i = getWidgetCount() - 1;
+ while (i >= 0) {
+ Widget widget = getWidget(i);
+ if (widget instanceof ListBox) {
+ return (ListBox) widget;
+ }
+ i--;
+ }
+ return null;
+ }
+
+ /**
+ * Updates the valus to correspond to the values in value
+ */
+ public void updateTimes() {
+ boolean selected = true;
+ if (value == null) {
+ value = new Date();
+ selected = false;
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ int h = value.getHours();
+ ampm.setSelectedIndex(h < 12 ? 0 : 1);
+ h -= ampm.getSelectedIndex() * 12;
+ hours.setSelectedIndex(h);
+ } else {
+ hours.setSelectedIndex(value.getHours());
+ }
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ mins.setSelectedIndex(value.getMinutes());
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ sec.setSelectedIndex(value.getSeconds());
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ ampm.setSelectedIndex(value.getHours() < 12 ? 0 : 1);
+ }
+
+ hours.setEnabled(isEnabled());
+ if (mins != null) {
+ mins.setEnabled(isEnabled());
+ }
+ if (sec != null) {
+ sec.setEnabled(isEnabled());
+ }
+ if (ampm != null) {
+ ampm.setEnabled(isEnabled());
+ }
+
+ }
+
+ private int getMilliseconds() {
+ return DateTimeService.getMilliseconds(value);
+ }
+
+ private DateTimeService getDateTimeService() {
+ if (dateTimeService == null) {
+ dateTimeService = new DateTimeService();
+ }
+ return dateTimeService;
+ }
+
+ /*
+ * (non-Javadoc) VT
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt
+ * .event.dom.client.ChangeEvent)
+ */
+ public void onChange(ChangeEvent event) {
+ /*
+ * Value from dropdowns gets always set for the value. Like year and
+ * month when resolution is month or year.
+ */
+ if (event.getSource() == hours) {
+ int h = hours.getSelectedIndex();
+ if (getDateTimeService().isTwelveHourClock()) {
+ h = h + ampm.getSelectedIndex() * 12;
+ }
+ value.setHours(h);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(h, value.getMinutes(),
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == mins) {
+ final int m = mins.getSelectedIndex();
+ value.setMinutes(m);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(value.getHours(), m,
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == sec) {
+ final int s = sec.getSelectedIndex();
+ value.setSeconds(s);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(value.getHours(),
+ value.getMinutes(), s,
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == ampm) {
+ final int h = hours.getSelectedIndex()
+ + (ampm.getSelectedIndex() * 12);
+ value.setHours(h);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(h, value.getMinutes(),
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ }
+
+ /**
+ * A widget representing a single day in the calendar panel.
+ */
+ private class Day extends InlineHTML {
+ private static final String BASECLASS = VDateField.CLASSNAME
+ + "-calendarpanel-day";
+ private final Date date;
+
+ Day(Date date) {
+ super("" + date.getDate());
+ setStyleName(BASECLASS);
+ this.date = date;
+ addClickHandler(dayClickHandler);
+ }
+
+ public Date getDate() {
+ return date;
+ }
+ }
+
+ public Date getDate() {
+ return value;
+ }
+
+ /**
+ * If true should be returned if the panel will not be used after this
+ * event.
+ *
+ * @param event
+ * @return
+ */
+ protected boolean onTabOut(DomEvent<?> event) {
+ if (focusOutListener != null) {
+ return focusOutListener.onFocusOut(event);
+ }
+ return false;
+ }
+
+ /**
+ * A focus out listener is triggered when the panel loosed focus. This can
+ * happen either after a user clicks outside the panel or tabs out.
+ *
+ * @param listener
+ * The listener to trigger
+ */
+ public void setFocusOutListener(FocusOutListener listener) {
+ focusOutListener = listener;
+ }
+
+ /**
+ * The submit listener is called when the user selects a value from the
+ * calender either by clicking the day or selects it by keyboard.
+ *
+ * @param submitListener
+ * The listener to trigger
+ */
+ public void setSubmitListener(SubmitListener submitListener) {
+ this.submitListener = submitListener;
+ }
+
+ /**
+ * The given FocusChangeListener is notified when the focused date changes
+ * by user either clicking on a new date or by using the keyboard.
+ *
+ * @param listener
+ * The FocusChangeListener to be notified
+ */
+ public void setFocusChangeListener(FocusChangeListener listener) {
+ focusChangeListener = listener;
+ }
+
+ /**
+ * The time change listener is triggered when the user changes the time.
+ *
+ * @param listener
+ */
+ public void setTimeChangeListener(TimeChangeListener listener) {
+ timeChangeListener = listener;
+ }
+
+ /**
+ * Returns the submit listener that listens to selection made from the panel
+ *
+ * @return The listener or NULL if no listener has been set
+ */
+ public SubmitListener getSubmitListener() {
+ return submitListener;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
+ * .dom.client.BlurEvent)
+ */
+ public void onBlur(final BlurEvent event) {
+ if (event.getSource() instanceof VCalendarPanel) {
+ hasFocus = false;
+ focusDay(null);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event
+ * .dom.client.FocusEvent)
+ */
+ public void onFocus(FocusEvent event) {
+ if (event.getSource() instanceof VCalendarPanel) {
+ hasFocus = true;
+
+ // Focuses the current day if the calendar shows the days
+ if (focusedDay != null) {
+ focusDay(focusedDate);
+ }
+ }
+ }
+
+ private static final String SUBPART_NEXT_MONTH = "nextmon";
+ private static final String SUBPART_PREV_MONTH = "prevmon";
+
+ private static final String SUBPART_NEXT_YEAR = "nexty";
+ private static final String SUBPART_PREV_YEAR = "prevy";
+ private static final String SUBPART_HOUR_SELECT = "h";
+ private static final String SUBPART_MINUTE_SELECT = "m";
+ private static final String SUBPART_SECS_SELECT = "s";
+ private static final String SUBPART_MSECS_SELECT = "ms";
+ private static final String SUBPART_AMPM_SELECT = "ampm";
+ private static final String SUBPART_DAY = "day";
+ private static final String SUBPART_MONTH_YEAR_HEADER = "header";
+
+ public String getSubPartName(Element subElement) {
+ if (contains(nextMonth, subElement)) {
+ return SUBPART_NEXT_MONTH;
+ } else if (contains(prevMonth, subElement)) {
+ return SUBPART_PREV_MONTH;
+ } else if (contains(nextYear, subElement)) {
+ return SUBPART_NEXT_YEAR;
+ } else if (contains(prevYear, subElement)) {
+ return SUBPART_PREV_YEAR;
+ } else if (contains(days, subElement)) {
+ // Day, find out which dayOfMonth and use that as the identifier
+ Day day = Util.findWidget(subElement, Day.class);
+ if (day != null) {
+ Date date = day.getDate();
+ int id = date.getDate();
+ // Zero or negative ids map to days of the preceding month,
+ // past-the-end-of-month ids to days of the following month
+ if (date.getMonth() < displayedMonth.getMonth()) {
+ id -= DateTimeService.getNumberOfDaysInMonth(date);
+ } else if (date.getMonth() > displayedMonth.getMonth()) {
+ id += DateTimeService
+ .getNumberOfDaysInMonth(displayedMonth);
+ }
+ return SUBPART_DAY + id;
+ }
+ } else if (time != null) {
+ if (contains(time.hours, subElement)) {
+ return SUBPART_HOUR_SELECT;
+ } else if (contains(time.mins, subElement)) {
+ return SUBPART_MINUTE_SELECT;
+ } else if (contains(time.sec, subElement)) {
+ return SUBPART_SECS_SELECT;
+ } else if (contains(time.ampm, subElement)) {
+ return SUBPART_AMPM_SELECT;
+
+ }
+ } else if (getCellFormatter().getElement(0, 2).isOrHasChild(subElement)) {
+ return SUBPART_MONTH_YEAR_HEADER;
+ }
+
+ return null;
+ }
+
+ /**
+ * Checks if subElement is inside the widget DOM hierarchy.
+ *
+ * @param w
+ * @param subElement
+ * @return true if {@code w} is a parent of subElement, false otherwise.
+ */
+ private boolean contains(Widget w, Element subElement) {
+ if (w == null || w.getElement() == null) {
+ return false;
+ }
+
+ return w.getElement().isOrHasChild(subElement);
+ }
+
+ public Element getSubPartElement(String subPart) {
+ if (SUBPART_NEXT_MONTH.equals(subPart)) {
+ return nextMonth.getElement();
+ }
+ if (SUBPART_PREV_MONTH.equals(subPart)) {
+ return prevMonth.getElement();
+ }
+ if (SUBPART_NEXT_YEAR.equals(subPart)) {
+ return nextYear.getElement();
+ }
+ if (SUBPART_PREV_YEAR.equals(subPart)) {
+ return prevYear.getElement();
+ }
+ if (SUBPART_HOUR_SELECT.equals(subPart)) {
+ return time.hours.getElement();
+ }
+ if (SUBPART_MINUTE_SELECT.equals(subPart)) {
+ return time.mins.getElement();
+ }
+ if (SUBPART_SECS_SELECT.equals(subPart)) {
+ return time.sec.getElement();
+ }
+ if (SUBPART_AMPM_SELECT.equals(subPart)) {
+ return time.ampm.getElement();
+ }
+ if (subPart.startsWith(SUBPART_DAY)) {
+ // Zero or negative ids map to days in the preceding month,
+ // past-the-end-of-month ids to days in the following month
+ int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY
+ .length()));
+ Date date = new Date(displayedMonth.getYear(),
+ displayedMonth.getMonth(), dayOfMonth);
+ Iterator<Widget> iter = days.iterator();
+ while (iter.hasNext()) {
+ Widget w = iter.next();
+ if (w instanceof Day) {
+ Day day = (Day) w;
+ if (day.getDate().equals(date)) {
+ return day.getElement();
+ }
+ }
+ }
+ }
+
+ if (SUBPART_MONTH_YEAR_HEADER.equals(subPart)) {
+ return (Element) getCellFormatter().getElement(0, 2).getChild(0);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onDetach() {
+ super.onDetach();
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
index d92d7e37ed..320520cb39 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
@@ -14,7 +14,6 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
@@ -101,8 +100,4 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox implements
client.updateVariable(id, EventId.BLUR, "", true);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
index 03233c6e27..9fee6a8ba6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
@@ -1,96 +1,99 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.EventHelper;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VTooltip;
-
-public class VCheckBoxPaintable extends VAbstractPaintableWidget {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Save details
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
-
- getWidgetForPaintable().focusHandlerRegistration = EventHelper
- .updateFocusHandler(this, client,
- getWidgetForPaintable().focusHandlerRegistration);
- getWidgetForPaintable().blurHandlerRegistration = EventHelper
- .updateBlurHandler(this, client,
- getWidgetForPaintable().blurHandlerRegistration);
-
- if (uidl.hasAttribute("error")) {
- if (getWidgetForPaintable().errorIndicatorElement == null) {
- getWidgetForPaintable().errorIndicatorElement = DOM
- .createSpan();
- getWidgetForPaintable().errorIndicatorElement
- .setInnerHTML("&nbsp;");
- DOM.setElementProperty(
- getWidgetForPaintable().errorIndicatorElement,
- "className", "v-errorindicator");
- DOM.appendChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().errorIndicatorElement);
- DOM.sinkEvents(getWidgetForPaintable().errorIndicatorElement,
- VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
- } else {
- DOM.setStyleAttribute(
- getWidgetForPaintable().errorIndicatorElement,
- "display", "");
- }
- } else if (getWidgetForPaintable().errorIndicatorElement != null) {
- DOM.setStyleAttribute(
- getWidgetForPaintable().errorIndicatorElement, "display",
- "none");
- }
-
- if (uidl.hasAttribute("readonly")) {
- getWidgetForPaintable().setEnabled(false);
- }
-
- if (uidl.hasAttribute("icon")) {
- if (getWidgetForPaintable().icon == null) {
- getWidgetForPaintable().icon = new Icon(client);
- DOM.insertChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().icon.getElement(), 1);
- getWidgetForPaintable().icon
- .sinkEvents(VTooltip.TOOLTIP_EVENTS);
- getWidgetForPaintable().icon.sinkEvents(Event.ONCLICK);
- }
- getWidgetForPaintable().icon
- .setUri(uidl.getStringAttribute("icon"));
- } else if (getWidgetForPaintable().icon != null) {
- // detach icon
- DOM.removeChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().icon.getElement());
- getWidgetForPaintable().icon = null;
- }
-
- // Set text
- getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
- getWidgetForPaintable()
- .setValue(
- uidl.getBooleanVariable(getWidgetForPaintable().VARIABLE_STATE));
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
- }
-
- @Override
- public VCheckBox getWidgetForPaintable() {
- return (VCheckBox) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VCheckBox.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventHelper;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VTooltip;
+
+public class VCheckBoxPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ getWidgetForPaintable().focusHandlerRegistration = EventHelper
+ .updateFocusHandler(this, client,
+ getWidgetForPaintable().focusHandlerRegistration);
+ getWidgetForPaintable().blurHandlerRegistration = EventHelper
+ .updateBlurHandler(this, client,
+ getWidgetForPaintable().blurHandlerRegistration);
+
+ if (uidl.hasAttribute("error")) {
+ if (getWidgetForPaintable().errorIndicatorElement == null) {
+ getWidgetForPaintable().errorIndicatorElement = DOM
+ .createSpan();
+ getWidgetForPaintable().errorIndicatorElement
+ .setInnerHTML("&nbsp;");
+ DOM.setElementProperty(
+ getWidgetForPaintable().errorIndicatorElement,
+ "className", "v-errorindicator");
+ DOM.appendChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().errorIndicatorElement);
+ DOM.sinkEvents(getWidgetForPaintable().errorIndicatorElement,
+ VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
+ } else {
+ DOM.setStyleAttribute(
+ getWidgetForPaintable().errorIndicatorElement,
+ "display", "");
+ }
+ } else if (getWidgetForPaintable().errorIndicatorElement != null) {
+ DOM.setStyleAttribute(
+ getWidgetForPaintable().errorIndicatorElement, "display",
+ "none");
+ }
+
+ if (uidl.hasAttribute("readonly")) {
+ getWidgetForPaintable().setEnabled(false);
+ }
+
+ if (uidl.hasAttribute("icon")) {
+ if (getWidgetForPaintable().icon == null) {
+ getWidgetForPaintable().icon = new Icon(client);
+ DOM.insertChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().icon.getElement(), 1);
+ getWidgetForPaintable().icon
+ .sinkEvents(VTooltip.TOOLTIP_EVENTS);
+ getWidgetForPaintable().icon.sinkEvents(Event.ONCLICK);
+ }
+ getWidgetForPaintable().icon
+ .setUri(uidl.getStringAttribute("icon"));
+ } else if (getWidgetForPaintable().icon != null) {
+ // detach icon
+ DOM.removeChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().icon.getElement());
+ getWidgetForPaintable().icon = null;
+ }
+
+ // Set text
+ getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
+ getWidgetForPaintable()
+ .setValue(
+ uidl.getBooleanVariable(getWidgetForPaintable().VARIABLE_STATE));
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ }
+
+ @Override
+ public VCheckBox getWidgetForPaintable() {
+ return (VCheckBox) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCheckBox.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
index e56d333dad..839b84061c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
@@ -294,10 +294,6 @@ public class VCssLayout extends SimplePanel implements Container {
return cssProperty;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
/**
* Sets CSS classes for margin and spacing based on the given parameters.
*
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
index d8640e3fe5..4d551fa5e8 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
@@ -1,61 +1,64 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VCssLayoutPaintable extends VAbstractPaintableWidgetContainer {
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getWidgetForPaintable().panel.getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
- clickEventHandler.handleEventHandlerRegistration(client);
-
- getWidgetForPaintable().setMarginAndSpacingStyles(
- new VMarginInfo(uidl.getIntAttribute("margins")),
- uidl.hasAttribute("spacing"));
- getWidgetForPaintable().panel.updateFromUIDL(uidl, client);
- getWidgetForPaintable().rendering = false;
- }
-
- @Override
- public VCssLayout getWidgetForPaintable() {
- return (VCssLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VCssLayout.class);
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- getWidgetForPaintable().panel.updateCaption(component, uidl);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCssLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().panel.getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().setMarginAndSpacingStyles(
+ new VMarginInfo(uidl.getIntAttribute("margins")),
+ uidl.hasAttribute("spacing"));
+ getWidgetForPaintable().panel.updateFromUIDL(uidl, client);
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ public VCssLayout getWidgetForPaintable() {
+ return (VCssLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCssLayout.class);
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ getWidgetForPaintable().panel.updateCaption(component, uidl);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
index ca18104c86..d8181cf00c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
@@ -111,8 +111,4 @@ public class VCustomComponent extends SimplePanel implements Container {
}
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
index 3abcd9cd75..585466f4f7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
@@ -1,79 +1,82 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VCustomComponentPaintable extends
- VAbstractPaintableWidgetContainer {
-
- public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
- getWidgetForPaintable().client = client;
-
- final UIDL child = uidl.getChildUIDL(0);
- if (child != null) {
- final VPaintableWidget paintable = client.getPaintable(child);
- Widget widget = paintable.getWidgetForPaintable();
- if (widget != getWidgetForPaintable().getWidget()) {
- if (getWidgetForPaintable().getWidget() != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(getWidgetForPaintable().getWidget()));
- getWidgetForPaintable().clear();
- }
- getWidgetForPaintable().setWidget(widget);
- }
- paintable.updateFromUIDL(child, client);
- }
-
- boolean updateDynamicSize = getWidgetForPaintable().updateDynamicSize();
- if (updateDynamicSize) {
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- // FIXME deferred relative size update needed to fix some
- // scrollbar issues in sampler. This must be the wrong way
- // to do it. Might be that some other component is broken.
- client.handleComponentRelativeSize(getWidgetForPaintable());
-
- }
- });
- }
-
- getWidgetForPaintable().renderSpace.setWidth(getWidgetForPaintable()
- .getElement().getOffsetWidth());
- getWidgetForPaintable().renderSpace.setHeight(getWidgetForPaintable()
- .getElement().getOffsetHeight());
-
- /*
- * Needed to update client size if the size of this component has
- * changed and the child uses relative size(s).
- */
- client.runDescendentsLayout(getWidgetForPaintable());
-
- getWidgetForPaintable().rendering = false;
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VCustomComponent.class);
- }
-
- @Override
- public VCustomComponent getWidgetForPaintable() {
- return (VCustomComponent) super.getWidgetForPaintable();
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, custom component dont render composition roots caption
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCustomComponentPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ getWidgetForPaintable().client = client;
+
+ final UIDL child = uidl.getChildUIDL(0);
+ if (child != null) {
+ final VPaintableWidget paintable = client.getPaintable(child);
+ Widget widget = paintable.getWidgetForPaintable();
+ if (widget != getWidgetForPaintable().getWidget()) {
+ if (getWidgetForPaintable().getWidget() != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().getWidget()));
+ getWidgetForPaintable().clear();
+ }
+ getWidgetForPaintable().setWidget(widget);
+ }
+ paintable.updateFromUIDL(child, client);
+ }
+
+ boolean updateDynamicSize = getWidgetForPaintable().updateDynamicSize();
+ if (updateDynamicSize) {
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ // FIXME deferred relative size update needed to fix some
+ // scrollbar issues in sampler. This must be the wrong way
+ // to do it. Might be that some other component is broken.
+ client.handleComponentRelativeSize(getWidgetForPaintable());
+
+ }
+ });
+ }
+
+ getWidgetForPaintable().renderSpace.setWidth(getWidgetForPaintable()
+ .getElement().getOffsetWidth());
+ getWidgetForPaintable().renderSpace.setHeight(getWidgetForPaintable()
+ .getElement().getOffsetHeight());
+
+ /*
+ * Needed to update client size if the size of this component has
+ * changed and the child uses relative size(s).
+ */
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCustomComponent.class);
+ }
+
+ @Override
+ public VCustomComponent getWidgetForPaintable() {
+ return (VCustomComponent) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, custom component dont render composition roots caption
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
index 7a5f630587..4aa838b660 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
@@ -590,8 +590,4 @@ public class VCustomLayout extends ComplexPanel implements Container,
return larger;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
index 7997355136..9cf877f446 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
@@ -1,87 +1,90 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer {
-
- /** Update the layout from UIDL */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
- // ApplicationConnection manages generic component features
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().pid = uidl.getId();
- if (!getWidgetForPaintable().hasTemplate()) {
- // Update HTML template only once
- getWidgetForPaintable().initializeHTML(uidl, client);
- }
-
- // Evaluate scripts
- VCustomLayout.eval(getWidgetForPaintable().scripts);
- getWidgetForPaintable().scripts = null;
-
- getWidgetForPaintable().iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(getWidgetForPaintable());
-
- Set<Widget> oldWidgets = new HashSet<Widget>();
- oldWidgets.addAll(getWidgetForPaintable().locationToWidget.values());
-
- // For all contained widgets
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
- final UIDL uidlForChild = (UIDL) i.next();
- if (uidlForChild.getTag().equals("location")) {
- final String location = uidlForChild.getStringAttribute("name");
- UIDL childUIDL = uidlForChild.getChildUIDL(0);
- final VPaintableWidget childPaintable = client
- .getPaintable(childUIDL);
- Widget childWidget = childPaintable.getWidgetForPaintable();
- try {
- getWidgetForPaintable().setWidget(childWidget, location);
- childPaintable.updateFromUIDL(childUIDL, client);
- } catch (final IllegalArgumentException e) {
- // If no location is found, this component is not visible
- }
- oldWidgets.remove(childWidget);
- }
- }
- for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
- .hasNext();) {
- Widget oldWidget = iterator.next();
- if (oldWidget.isAttached()) {
- // slot of this widget is emptied, remove it
- getWidgetForPaintable().remove(oldWidget);
- }
- }
-
- getWidgetForPaintable().iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(getWidgetForPaintable());
-
- }
-
- @Override
- public VCustomLayout getWidgetForPaintable() {
- return (VCustomLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VCustomLayout.class);
- }
-
- public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
- getWidgetForPaintable().updateCaption(paintable, uidl);
-
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ /** Update the layout from UIDL */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ // ApplicationConnection manages generic component features
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().pid = uidl.getId();
+ if (!getWidgetForPaintable().hasTemplate()) {
+ // Update HTML template only once
+ getWidgetForPaintable().initializeHTML(uidl, client);
+ }
+
+ // Evaluate scripts
+ VCustomLayout.eval(getWidgetForPaintable().scripts);
+ getWidgetForPaintable().scripts = null;
+
+ getWidgetForPaintable().iLayout();
+ // TODO Check if this is needed
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ Set<Widget> oldWidgets = new HashSet<Widget>();
+ oldWidgets.addAll(getWidgetForPaintable().locationToWidget.values());
+
+ // For all contained widgets
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL uidlForChild = (UIDL) i.next();
+ if (uidlForChild.getTag().equals("location")) {
+ final String location = uidlForChild.getStringAttribute("name");
+ UIDL childUIDL = uidlForChild.getChildUIDL(0);
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUIDL);
+ Widget childWidget = childPaintable.getWidgetForPaintable();
+ try {
+ getWidgetForPaintable().setWidget(childWidget, location);
+ childPaintable.updateFromUIDL(childUIDL, client);
+ } catch (final IllegalArgumentException e) {
+ // If no location is found, this component is not visible
+ }
+ oldWidgets.remove(childWidget);
+ }
+ }
+ for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
+ .hasNext();) {
+ Widget oldWidget = iterator.next();
+ if (oldWidget.isAttached()) {
+ // slot of this widget is emptied, remove it
+ getWidgetForPaintable().remove(oldWidget);
+ }
+ }
+
+ getWidgetForPaintable().iLayout();
+ // TODO Check if this is needed
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ }
+
+ @Override
+ public VCustomLayout getWidgetForPaintable() {
+ return (VCustomLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCustomLayout.class);
+ }
+
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ getWidgetForPaintable().updateCaption(paintable, uidl);
+
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
index 6fb8456258..6bf1d4a3a7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
@@ -1,87 +1,87 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.google.gwt.event.dom.client.DomEvent;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
-
-/**
- * A client side implementation for InlineDateField
- */
-public class VDateFieldCalendar extends VDateField {
-
- protected final VCalendarPanel calendarPanel;
-
- public VDateFieldCalendar() {
- super();
- calendarPanel = new VCalendarPanel();
- add(calendarPanel);
- calendarPanel.setSubmitListener(new SubmitListener() {
- public void onSubmit() {
- updateValueFromPanel();
- }
-
- public void onCancel() {
- // TODO Auto-generated method stub
-
- }
- });
- calendarPanel.setFocusOutListener(new FocusOutListener() {
- public boolean onFocusOut(DomEvent<?> event) {
- updateValueFromPanel();
- return false;
- }
- });
- }
-
- /**
- * TODO refactor: almost same method as in VPopupCalendar.updateValue
- */
- @SuppressWarnings("deprecation")
- protected void updateValueFromPanel() {
- Date date2 = calendarPanel.getDate();
- Date currentDate = getCurrentDate();
- if (currentDate == null || date2.getTime() != currentDate.getTime()) {
- setCurrentDate((Date) date2.clone());
- getClient().updateVariable(getId(), "year", date2.getYear() + 1900,
- false);
- if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
- getClient().updateVariable(getId(), "month",
- date2.getMonth() + 1, false);
- if (getCurrentResolution() > RESOLUTION_MONTH) {
- getClient().updateVariable(getId(), "day", date2.getDate(),
- false);
- if (getCurrentResolution() > RESOLUTION_DAY) {
- getClient().updateVariable(getId(), "hour",
- date2.getHours(), false);
- if (getCurrentResolution() > RESOLUTION_HOUR) {
- getClient().updateVariable(getId(), "min",
- date2.getMinutes(), false);
- if (getCurrentResolution() > RESOLUTION_MIN) {
- getClient().updateVariable(getId(), "sec",
- date2.getSeconds(), false);
- if (getCurrentResolution() > RESOLUTION_SEC) {
- getClient().updateVariable(
- getId(),
- "msec",
- DateTimeService
- .getMilliseconds(date2),
- false);
- }
- }
- }
- }
- }
- }
- if (isImmediate()) {
- getClient().sendPendingVariableChanges();
- }
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.event.dom.client.DomEvent;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
+
+/**
+ * A client side implementation for InlineDateField
+ */
+public class VDateFieldCalendar extends VDateField {
+
+ protected final VCalendarPanel calendarPanel;
+
+ public VDateFieldCalendar() {
+ super();
+ calendarPanel = new VCalendarPanel();
+ add(calendarPanel);
+ calendarPanel.setSubmitListener(new SubmitListener() {
+ public void onSubmit() {
+ updateValueFromPanel();
+ }
+
+ public void onCancel() {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ calendarPanel.setFocusOutListener(new FocusOutListener() {
+ public boolean onFocusOut(DomEvent<?> event) {
+ updateValueFromPanel();
+ return false;
+ }
+ });
+ }
+
+ /**
+ * TODO refactor: almost same method as in VPopupCalendar.updateValue
+ */
+ @SuppressWarnings("deprecation")
+ protected void updateValueFromPanel() {
+ Date date2 = calendarPanel.getDate();
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || date2.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) date2.clone());
+ getClient().updateVariable(getId(), "year", date2.getYear() + 1900,
+ false);
+ if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
+ getClient().updateVariable(getId(), "month",
+ date2.getMonth() + 1, false);
+ if (getCurrentResolution() > RESOLUTION_MONTH) {
+ getClient().updateVariable(getId(), "day", date2.getDate(),
+ false);
+ if (getCurrentResolution() > RESOLUTION_DAY) {
+ getClient().updateVariable(getId(), "hour",
+ date2.getHours(), false);
+ if (getCurrentResolution() > RESOLUTION_HOUR) {
+ getClient().updateVariable(getId(), "min",
+ date2.getMinutes(), false);
+ if (getCurrentResolution() > RESOLUTION_MIN) {
+ getClient().updateVariable(getId(), "sec",
+ date2.getSeconds(), false);
+ if (getCurrentResolution() > RESOLUTION_SEC) {
+ getClient().updateVariable(
+ getId(),
+ "msec",
+ DateTimeService
+ .getMilliseconds(date2),
+ false);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (isImmediate()) {
+ getClient().sendPendingVariableChanges();
+ }
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java
index 4aaf1c2dd3..a4bbe64a30 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java
@@ -1,3 +1,6 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
package com.vaadin.terminal.gwt.client.ui;
import java.util.Date;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
index 1deb155001..2d2f0fcad3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
@@ -1,71 +1,74 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashMap;
-import java.util.Set;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VDragAndDropWrapperPaintable extends VCustomComponentPaintable {
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
- super.updateFromUIDL(uidl, client);
- if (!uidl.hasAttribute("cached") && !uidl.hasAttribute("hidden")) {
- UIDL acceptCrit = uidl.getChildByTagName("-ac");
- if (acceptCrit == null) {
- getWidgetForPaintable().dropHandler = null;
- } else {
- if (getWidgetForPaintable().dropHandler == null) {
- getWidgetForPaintable().dropHandler = getWidgetForPaintable().new CustomDropHandler();
- }
- getWidgetForPaintable().dropHandler
- .updateAcceptRules(acceptCrit);
- }
-
- Set<String> variableNames = uidl.getVariableNames();
- for (String fileId : variableNames) {
- if (fileId.startsWith("rec-")) {
- String receiverUrl = uidl.getStringVariable(fileId);
- fileId = fileId.substring(4);
- if (getWidgetForPaintable().fileIdToReceiver == null) {
- getWidgetForPaintable().fileIdToReceiver = new HashMap<String, String>();
- }
- if ("".equals(receiverUrl)) {
- Integer id = Integer.parseInt(fileId);
- int indexOf = getWidgetForPaintable().fileIds
- .indexOf(id);
- if (indexOf != -1) {
- getWidgetForPaintable().files.remove(indexOf);
- getWidgetForPaintable().fileIds.remove(indexOf);
- }
- } else {
- getWidgetForPaintable().fileIdToReceiver.put(fileId,
- receiverUrl);
- }
- }
- }
- getWidgetForPaintable().startNextUpload();
-
- getWidgetForPaintable().dragStartMode = uidl
- .getIntAttribute(VDragAndDropWrapper.DRAG_START_MODE);
- getWidgetForPaintable().initDragStartMode();
- getWidgetForPaintable().html5DataFlavors = uidl
- .getMapAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS);
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VDragAndDropWrapper.class);
- }
-
- @Override
- public VDragAndDropWrapper getWidgetForPaintable() {
- return (VDragAndDropWrapper) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VDragAndDropWrapperPaintable extends VCustomComponentPaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ super.updateFromUIDL(uidl, client);
+ if (!uidl.hasAttribute("cached") && !uidl.hasAttribute("hidden")) {
+ UIDL acceptCrit = uidl.getChildByTagName("-ac");
+ if (acceptCrit == null) {
+ getWidgetForPaintable().dropHandler = null;
+ } else {
+ if (getWidgetForPaintable().dropHandler == null) {
+ getWidgetForPaintable().dropHandler = getWidgetForPaintable().new CustomDropHandler();
+ }
+ getWidgetForPaintable().dropHandler
+ .updateAcceptRules(acceptCrit);
+ }
+
+ Set<String> variableNames = uidl.getVariableNames();
+ for (String fileId : variableNames) {
+ if (fileId.startsWith("rec-")) {
+ String receiverUrl = uidl.getStringVariable(fileId);
+ fileId = fileId.substring(4);
+ if (getWidgetForPaintable().fileIdToReceiver == null) {
+ getWidgetForPaintable().fileIdToReceiver = new HashMap<String, String>();
+ }
+ if ("".equals(receiverUrl)) {
+ Integer id = Integer.parseInt(fileId);
+ int indexOf = getWidgetForPaintable().fileIds
+ .indexOf(id);
+ if (indexOf != -1) {
+ getWidgetForPaintable().files.remove(indexOf);
+ getWidgetForPaintable().fileIds.remove(indexOf);
+ }
+ } else {
+ getWidgetForPaintable().fileIdToReceiver.put(fileId,
+ receiverUrl);
+ }
+ }
+ }
+ getWidgetForPaintable().startNextUpload();
+
+ getWidgetForPaintable().dragStartMode = uidl
+ .getIntAttribute(VDragAndDropWrapper.DRAG_START_MODE);
+ getWidgetForPaintable().initDragStartMode();
+ getWidgetForPaintable().html5DataFlavors = uidl
+ .getMapAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VDragAndDropWrapper.class);
+ }
+
+ @Override
+ public VDragAndDropWrapper getWidgetForPaintable() {
+ return (VDragAndDropWrapper) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
index 7006a82fd1..b54c3dd943 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
@@ -1003,6 +1003,20 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
* The filter to apply to the components
*/
public void filterOptions(int page, String filter) {
+ filterOptions(page, filter, true);
+ }
+
+ /**
+ * Filters the options at certain page using the given filter
+ *
+ * @param page
+ * The page to filter
+ * @param filter
+ * The filter to apply to the options
+ * @param immediate
+ * Whether to send the options request immediately
+ */
+ private void filterOptions(int page, String filter, boolean immediate) {
if (filter.equals(lastFilter) && currentPage == page) {
if (!suggestionPopup.isAttached()) {
suggestionPopup.showSuggestions(currentSuggestions,
@@ -1022,7 +1036,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
waitingForFilteringResponse = true;
client.updateVariable(paintableId, "filter", filter, false);
- client.updateVariable(paintableId, "page", page, true);
+ client.updateVariable(paintableId, "page", page, immediate);
lastFilter = filter;
currentPage = page;
}
@@ -1404,7 +1418,12 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
// ask suggestionPopup if it was just closed, we are using GWT
// Popup's auto close feature
if (!suggestionPopup.isJustClosed()) {
- filterOptions(-1, "");
+ // If a focus event is not going to be sent, send the options
+ // request immediately; otherwise queue in the same burst as the
+ // focus event. Fixes #8321.
+ boolean immediate = focused
+ || !client.hasWidgetEventListeners(this, EventId.FOCUS);
+ filterOptions(-1, "", immediate);
popupOpenerClicked = true;
lastFilter = "";
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VForm.java b/src/com/vaadin/terminal/gwt/client/ui/VForm.java
index d70d7ed0d8..f3276db008 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VForm.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VForm.java
@@ -195,10 +195,6 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent()));
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
@Override
protected void add(Widget child, Element container) {
// Overridden to allow VFormPaintable to call this. Should be removed
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
index b2357f11e1..6d3072f407 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
@@ -526,8 +526,4 @@ public class VFormLayout extends SimplePanel implements Container {
}
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
index c4590a71c9..3be2a028c5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
@@ -1,39 +1,42 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VFormLayoutPaintable extends VAbstractPaintableWidgetContainer {
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- getWidgetForPaintable().client = client;
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- getWidgetForPaintable().table.updateFromUIDL(uidl, client);
-
- getWidgetForPaintable().rendering = false;
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- getWidgetForPaintable().table.updateCaption(component, uidl);
- }
-
- @Override
- public VFormLayout getWidgetForPaintable() {
- return (VFormLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VFormLayout.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VFormLayoutPaintable extends VAbstractPaintableWidgetContainer {
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().client = client;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().table.updateFromUIDL(uidl, client);
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ getWidgetForPaintable().table.updateCaption(component, uidl);
+ }
+
+ @Override
+ public VFormLayout getWidgetForPaintable() {
+ return (VFormLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VFormLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
index 5f519c09d4..e2533591ea 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
@@ -1,173 +1,176 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VFormPaintable extends VAbstractPaintableWidgetContainer {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- if (client.updateComponent(this, uidl, false)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- boolean legendEmpty = true;
- if (uidl.hasAttribute("caption")) {
- getWidgetForPaintable().caption.setInnerText(uidl
- .getStringAttribute("caption"));
- legendEmpty = false;
- } else {
- getWidgetForPaintable().caption.setInnerText("");
- }
- if (uidl.hasAttribute("icon")) {
- if (getWidgetForPaintable().icon == null) {
- getWidgetForPaintable().icon = new Icon(client);
- getWidgetForPaintable().legend
- .insertFirst(getWidgetForPaintable().icon.getElement());
- }
- getWidgetForPaintable().icon
- .setUri(uidl.getStringAttribute("icon"));
- legendEmpty = false;
- } else {
- if (getWidgetForPaintable().icon != null) {
- getWidgetForPaintable().legend
- .removeChild(getWidgetForPaintable().icon.getElement());
- }
- }
- if (legendEmpty) {
- getWidgetForPaintable().addStyleDependentName("nocaption");
- } else {
- getWidgetForPaintable().removeStyleDependentName("nocaption");
- }
-
- if (uidl.hasAttribute("error")) {
- final UIDL errorUidl = uidl.getErrors();
- getWidgetForPaintable().errorMessage.updateFromUIDL(errorUidl);
- getWidgetForPaintable().errorMessage.setVisible(true);
- } else {
- getWidgetForPaintable().errorMessage.setVisible(false);
- }
-
- if (uidl.hasAttribute("description")) {
- getWidgetForPaintable().desc.setInnerHTML(uidl
- .getStringAttribute("description"));
- if (getWidgetForPaintable().desc.getParentElement() == null) {
- getWidgetForPaintable().fieldSet.insertAfter(
- getWidgetForPaintable().desc,
- getWidgetForPaintable().legend);
- }
- } else {
- getWidgetForPaintable().desc.setInnerHTML("");
- if (getWidgetForPaintable().desc.getParentElement() != null) {
- getWidgetForPaintable().fieldSet
- .removeChild(getWidgetForPaintable().desc);
- }
- }
-
- getWidgetForPaintable().updateSize();
-
- // first render footer so it will be easier to handle relative height of
- // main layout
- if (uidl.getChildCount() > 1
- && !uidl.getChildUIDL(1).getTag().equals("actions")) {
- // render footer
- VPaintableWidget newFooter = client.getPaintable(uidl
- .getChildUIDL(1));
- Widget newFooterWidget = newFooter.getWidgetForPaintable();
- if (getWidgetForPaintable().footer == null) {
- getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
- getWidgetForPaintable().footerContainer);
- getWidgetForPaintable().footer = newFooterWidget;
- } else if (newFooter != getWidgetForPaintable().footer) {
- getWidgetForPaintable().remove(getWidgetForPaintable().footer);
- client.unregisterPaintable(VPaintableMap.get(getConnection())
- .getPaintable(getWidgetForPaintable().footer));
- getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
- getWidgetForPaintable().footerContainer);
- }
- getWidgetForPaintable().footer = newFooterWidget;
- newFooter.updateFromUIDL(uidl.getChildUIDL(1), client);
- // needed for the main layout to know the space it has available
- getWidgetForPaintable().updateSize();
- } else {
- if (getWidgetForPaintable().footer != null) {
- getWidgetForPaintable().remove(getWidgetForPaintable().footer);
- client.unregisterPaintable(VPaintableMap.get(getConnection())
- .getPaintable(getWidgetForPaintable().footer));
- // needed for the main layout to know the space it has available
- getWidgetForPaintable().updateSize();
- }
- }
-
- final UIDL layoutUidl = uidl.getChildUIDL(0);
- VPaintableWidget newLayout = client.getPaintable(layoutUidl);
- Widget newLayoutWidget = newLayout.getWidgetForPaintable();
- if (getWidgetForPaintable().lo == null) {
- // Layout not rendered before
- getWidgetForPaintable().lo = newLayoutWidget;
- getWidgetForPaintable().add(newLayoutWidget,
- getWidgetForPaintable().fieldContainer);
- } else if (getWidgetForPaintable().lo != newLayoutWidget) {
- // Layout has changed
- client.unregisterPaintable(VPaintableMap.get(getConnection())
- .getPaintable(getWidgetForPaintable().lo));
- getWidgetForPaintable().remove(getWidgetForPaintable().lo);
- getWidgetForPaintable().lo = newLayoutWidget;
- getWidgetForPaintable().add(newLayoutWidget,
- getWidgetForPaintable().fieldContainer);
- }
- newLayout.updateFromUIDL(layoutUidl, client);
-
- // also recalculates size of the footer if undefined size form - see
- // #3710
- getWidgetForPaintable().updateSize();
- client.runDescendentsLayout(getWidgetForPaintable());
-
- // We may have actions attached
- if (uidl.getChildCount() > 1) {
- UIDL childUidl = uidl.getChildByTagName("actions");
- if (childUidl != null) {
- if (getWidgetForPaintable().shortcutHandler == null) {
- getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
- getId(), client);
- getWidgetForPaintable().keyDownRegistration = getWidgetForPaintable()
- .addDomHandler(getWidgetForPaintable(),
- KeyDownEvent.getType());
- }
- getWidgetForPaintable().shortcutHandler
- .updateActionMap(childUidl);
- }
- } else if (getWidgetForPaintable().shortcutHandler != null) {
- getWidgetForPaintable().keyDownRegistration.removeHandler();
- getWidgetForPaintable().shortcutHandler = null;
- getWidgetForPaintable().keyDownRegistration = null;
- }
-
- getWidgetForPaintable().rendering = false;
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP form don't render caption for neither field layout nor footer
- // layout
- }
-
- @Override
- public VForm getWidgetForPaintable() {
- return (VForm) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VForm.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VFormPaintable extends VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ if (client.updateComponent(this, uidl, false)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ boolean legendEmpty = true;
+ if (uidl.hasAttribute("caption")) {
+ getWidgetForPaintable().caption.setInnerText(uidl
+ .getStringAttribute("caption"));
+ legendEmpty = false;
+ } else {
+ getWidgetForPaintable().caption.setInnerText("");
+ }
+ if (uidl.hasAttribute("icon")) {
+ if (getWidgetForPaintable().icon == null) {
+ getWidgetForPaintable().icon = new Icon(client);
+ getWidgetForPaintable().legend
+ .insertFirst(getWidgetForPaintable().icon.getElement());
+ }
+ getWidgetForPaintable().icon
+ .setUri(uidl.getStringAttribute("icon"));
+ legendEmpty = false;
+ } else {
+ if (getWidgetForPaintable().icon != null) {
+ getWidgetForPaintable().legend
+ .removeChild(getWidgetForPaintable().icon.getElement());
+ }
+ }
+ if (legendEmpty) {
+ getWidgetForPaintable().addStyleDependentName("nocaption");
+ } else {
+ getWidgetForPaintable().removeStyleDependentName("nocaption");
+ }
+
+ if (uidl.hasAttribute("error")) {
+ final UIDL errorUidl = uidl.getErrors();
+ getWidgetForPaintable().errorMessage.updateFromUIDL(errorUidl);
+ getWidgetForPaintable().errorMessage.setVisible(true);
+ } else {
+ getWidgetForPaintable().errorMessage.setVisible(false);
+ }
+
+ if (uidl.hasAttribute("description")) {
+ getWidgetForPaintable().desc.setInnerHTML(uidl
+ .getStringAttribute("description"));
+ if (getWidgetForPaintable().desc.getParentElement() == null) {
+ getWidgetForPaintable().fieldSet.insertAfter(
+ getWidgetForPaintable().desc,
+ getWidgetForPaintable().legend);
+ }
+ } else {
+ getWidgetForPaintable().desc.setInnerHTML("");
+ if (getWidgetForPaintable().desc.getParentElement() != null) {
+ getWidgetForPaintable().fieldSet
+ .removeChild(getWidgetForPaintable().desc);
+ }
+ }
+
+ getWidgetForPaintable().updateSize();
+
+ // first render footer so it will be easier to handle relative height of
+ // main layout
+ if (uidl.getChildCount() > 1
+ && !uidl.getChildUIDL(1).getTag().equals("actions")) {
+ // render footer
+ VPaintableWidget newFooter = client.getPaintable(uidl
+ .getChildUIDL(1));
+ Widget newFooterWidget = newFooter.getWidgetForPaintable();
+ if (getWidgetForPaintable().footer == null) {
+ getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
+ getWidgetForPaintable().footerContainer);
+ getWidgetForPaintable().footer = newFooterWidget;
+ } else if (newFooter != getWidgetForPaintable().footer) {
+ getWidgetForPaintable().remove(getWidgetForPaintable().footer);
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().footer));
+ getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
+ getWidgetForPaintable().footerContainer);
+ }
+ getWidgetForPaintable().footer = newFooterWidget;
+ newFooter.updateFromUIDL(uidl.getChildUIDL(1), client);
+ // needed for the main layout to know the space it has available
+ getWidgetForPaintable().updateSize();
+ } else {
+ if (getWidgetForPaintable().footer != null) {
+ getWidgetForPaintable().remove(getWidgetForPaintable().footer);
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().footer));
+ // needed for the main layout to know the space it has available
+ getWidgetForPaintable().updateSize();
+ }
+ }
+
+ final UIDL layoutUidl = uidl.getChildUIDL(0);
+ VPaintableWidget newLayout = client.getPaintable(layoutUidl);
+ Widget newLayoutWidget = newLayout.getWidgetForPaintable();
+ if (getWidgetForPaintable().lo == null) {
+ // Layout not rendered before
+ getWidgetForPaintable().lo = newLayoutWidget;
+ getWidgetForPaintable().add(newLayoutWidget,
+ getWidgetForPaintable().fieldContainer);
+ } else if (getWidgetForPaintable().lo != newLayoutWidget) {
+ // Layout has changed
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().lo));
+ getWidgetForPaintable().remove(getWidgetForPaintable().lo);
+ getWidgetForPaintable().lo = newLayoutWidget;
+ getWidgetForPaintable().add(newLayoutWidget,
+ getWidgetForPaintable().fieldContainer);
+ }
+ newLayout.updateFromUIDL(layoutUidl, client);
+
+ // also recalculates size of the footer if undefined size form - see
+ // #3710
+ getWidgetForPaintable().updateSize();
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ // We may have actions attached
+ if (uidl.getChildCount() > 1) {
+ UIDL childUidl = uidl.getChildByTagName("actions");
+ if (childUidl != null) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ getWidgetForPaintable().keyDownRegistration = getWidgetForPaintable()
+ .addDomHandler(getWidgetForPaintable(),
+ KeyDownEvent.getType());
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ } else if (getWidgetForPaintable().shortcutHandler != null) {
+ getWidgetForPaintable().keyDownRegistration.removeHandler();
+ getWidgetForPaintable().shortcutHandler = null;
+ getWidgetForPaintable().keyDownRegistration = null;
+ }
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP form don't render caption for neither field layout nor footer
+ // layout
+ }
+
+ @Override
+ public VForm getWidgetForPaintable() {
+ return (VForm) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VForm.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
index e6e167f077..5302fa6f67 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
@@ -980,8 +980,4 @@ public class VGridLayout extends SimplePanel implements Container {
return Util.getPaintableForElement(client, this, element);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
index 1ef958183b..8f84f27297 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
@@ -1,193 +1,196 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.VGridLayout.Cell;
-import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
-
-public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer {
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getWidgetForPaintable().getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- @SuppressWarnings("unchecked")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- getWidgetForPaintable().client = client;
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
- clickEventHandler.handleEventHandlerRegistration(client);
-
- getWidgetForPaintable().canvas.setWidth("0px");
-
- getWidgetForPaintable().handleMargins(uidl);
- getWidgetForPaintable().detectSpacing(uidl);
-
- int cols = uidl.getIntAttribute("w");
- int rows = uidl.getIntAttribute("h");
-
- getWidgetForPaintable().columnWidths = new int[cols];
- getWidgetForPaintable().rowHeights = new int[rows];
-
- if (getWidgetForPaintable().cells == null) {
- getWidgetForPaintable().cells = new Cell[cols][rows];
- } else if (getWidgetForPaintable().cells.length != cols
- || getWidgetForPaintable().cells[0].length != rows) {
- Cell[][] newCells = new Cell[cols][rows];
- for (int i = 0; i < getWidgetForPaintable().cells.length; i++) {
- for (int j = 0; j < getWidgetForPaintable().cells[i].length; j++) {
- if (i < cols && j < rows) {
- newCells[i][j] = getWidgetForPaintable().cells[i][j];
- }
- }
- }
- getWidgetForPaintable().cells = newCells;
- }
-
- getWidgetForPaintable().nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) getWidgetForPaintable().widgetToComponentContainer
- .clone();
-
- final int[] alignments = uidl.getIntArrayAttribute("alignments");
- int alignmentIndex = 0;
-
- LinkedList<Cell> pendingCells = new LinkedList<Cell>();
-
- LinkedList<Cell> relativeHeighted = new LinkedList<Cell>();
-
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
- final UIDL r = (UIDL) i.next();
- if ("gr".equals(r.getTag())) {
- for (final Iterator<?> j = r.getChildIterator(); j.hasNext();) {
- final UIDL c = (UIDL) j.next();
- if ("gc".equals(c.getTag())) {
- Cell cell = getWidgetForPaintable().getCell(c);
- if (cell.hasContent()) {
- boolean rendered = cell.renderIfNoRelativeWidth();
- cell.alignment = alignments[alignmentIndex++];
- if (!rendered) {
- pendingCells.add(cell);
- }
-
- if (cell.colspan > 1) {
- getWidgetForPaintable().storeColSpannedCell(
- cell);
- } else if (rendered) {
- // strore non-colspanned widths to columnWidth
- // array
- if (getWidgetForPaintable().columnWidths[cell.col] < cell
- .getWidth()) {
- getWidgetForPaintable().columnWidths[cell.col] = cell
- .getWidth();
- }
- }
- if (cell.hasRelativeHeight()) {
- relativeHeighted.add(cell);
- }
- }
- }
- }
- }
- }
-
- getWidgetForPaintable().colExpandRatioArray = uidl
- .getIntArrayAttribute("colExpand");
- getWidgetForPaintable().rowExpandRatioArray = uidl
- .getIntArrayAttribute("rowExpand");
- getWidgetForPaintable().distributeColSpanWidths();
-
- getWidgetForPaintable().minColumnWidths = VGridLayout
- .cloneArray(getWidgetForPaintable().columnWidths);
- getWidgetForPaintable().expandColumns();
-
- getWidgetForPaintable().renderRemainingComponentsWithNoRelativeHeight(
- pendingCells);
-
- getWidgetForPaintable().detectRowHeights();
-
- getWidgetForPaintable().expandRows();
-
- getWidgetForPaintable().renderRemainingComponents(pendingCells);
-
- for (Cell cell : relativeHeighted) {
- // rendering done above so cell.cc should not be null
- Widget widget2 = cell.cc.getWidget();
- client.handleComponentRelativeSize(widget2);
- cell.cc.updateWidgetSize();
- }
-
- getWidgetForPaintable().layoutCells();
-
- // clean non rendered components
- for (Widget w : getWidgetForPaintable().nonRenderedWidgets.keySet()) {
- ChildComponentContainer childComponentContainer = getWidgetForPaintable().widgetToComponentContainer
- .get(w);
- getWidgetForPaintable().widgetToCell.remove(w);
- getWidgetForPaintable().widgetToComponentContainer.remove(w);
- childComponentContainer.removeFromParent();
- VPaintableMap paintableMap = VPaintableMap.get(client);
- paintableMap.unregisterPaintable(paintableMap.getPaintable(w));
- }
- getWidgetForPaintable().nonRenderedWidgets = null;
-
- getWidgetForPaintable().rendering = false;
- getWidgetForPaintable().sizeChangedDuringRendering = false;
-
- }
-
- public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
- Widget widget = paintable.getWidgetForPaintable();
- ChildComponentContainer cc = getWidgetForPaintable().widgetToComponentContainer
- .get(widget);
- if (cc != null) {
- cc.updateCaption(uidl, getConnection());
- }
- if (!getWidgetForPaintable().rendering) {
- // ensure rel size details are updated
- getWidgetForPaintable().widgetToCell.get(widget)
- .updateRelSizeStatus(uidl);
- /*
- * This was a component-only update and the possible size change
- * must be propagated to the layout
- */
- getConnection().captionSizeUpdated(widget);
- }
- }
-
- @Override
- public VGridLayout getWidgetForPaintable() {
- return (VGridLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VGridLayout.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VGridLayout.Cell;
+import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
+
+public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer {
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().canvas.setWidth("0px");
+
+ getWidgetForPaintable().handleMargins(uidl);
+ getWidgetForPaintable().detectSpacing(uidl);
+
+ int cols = uidl.getIntAttribute("w");
+ int rows = uidl.getIntAttribute("h");
+
+ getWidgetForPaintable().columnWidths = new int[cols];
+ getWidgetForPaintable().rowHeights = new int[rows];
+
+ if (getWidgetForPaintable().cells == null) {
+ getWidgetForPaintable().cells = new Cell[cols][rows];
+ } else if (getWidgetForPaintable().cells.length != cols
+ || getWidgetForPaintable().cells[0].length != rows) {
+ Cell[][] newCells = new Cell[cols][rows];
+ for (int i = 0; i < getWidgetForPaintable().cells.length; i++) {
+ for (int j = 0; j < getWidgetForPaintable().cells[i].length; j++) {
+ if (i < cols && j < rows) {
+ newCells[i][j] = getWidgetForPaintable().cells[i][j];
+ }
+ }
+ }
+ getWidgetForPaintable().cells = newCells;
+ }
+
+ getWidgetForPaintable().nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) getWidgetForPaintable().widgetToComponentContainer
+ .clone();
+
+ final int[] alignments = uidl.getIntArrayAttribute("alignments");
+ int alignmentIndex = 0;
+
+ LinkedList<Cell> pendingCells = new LinkedList<Cell>();
+
+ LinkedList<Cell> relativeHeighted = new LinkedList<Cell>();
+
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL r = (UIDL) i.next();
+ if ("gr".equals(r.getTag())) {
+ for (final Iterator<?> j = r.getChildIterator(); j.hasNext();) {
+ final UIDL c = (UIDL) j.next();
+ if ("gc".equals(c.getTag())) {
+ Cell cell = getWidgetForPaintable().getCell(c);
+ if (cell.hasContent()) {
+ boolean rendered = cell.renderIfNoRelativeWidth();
+ cell.alignment = alignments[alignmentIndex++];
+ if (!rendered) {
+ pendingCells.add(cell);
+ }
+
+ if (cell.colspan > 1) {
+ getWidgetForPaintable().storeColSpannedCell(
+ cell);
+ } else if (rendered) {
+ // strore non-colspanned widths to columnWidth
+ // array
+ if (getWidgetForPaintable().columnWidths[cell.col] < cell
+ .getWidth()) {
+ getWidgetForPaintable().columnWidths[cell.col] = cell
+ .getWidth();
+ }
+ }
+ if (cell.hasRelativeHeight()) {
+ relativeHeighted.add(cell);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ getWidgetForPaintable().colExpandRatioArray = uidl
+ .getIntArrayAttribute("colExpand");
+ getWidgetForPaintable().rowExpandRatioArray = uidl
+ .getIntArrayAttribute("rowExpand");
+ getWidgetForPaintable().distributeColSpanWidths();
+
+ getWidgetForPaintable().minColumnWidths = VGridLayout
+ .cloneArray(getWidgetForPaintable().columnWidths);
+ getWidgetForPaintable().expandColumns();
+
+ getWidgetForPaintable().renderRemainingComponentsWithNoRelativeHeight(
+ pendingCells);
+
+ getWidgetForPaintable().detectRowHeights();
+
+ getWidgetForPaintable().expandRows();
+
+ getWidgetForPaintable().renderRemainingComponents(pendingCells);
+
+ for (Cell cell : relativeHeighted) {
+ // rendering done above so cell.cc should not be null
+ Widget widget2 = cell.cc.getWidget();
+ client.handleComponentRelativeSize(widget2);
+ cell.cc.updateWidgetSize();
+ }
+
+ getWidgetForPaintable().layoutCells();
+
+ // clean non rendered components
+ for (Widget w : getWidgetForPaintable().nonRenderedWidgets.keySet()) {
+ ChildComponentContainer childComponentContainer = getWidgetForPaintable().widgetToComponentContainer
+ .get(w);
+ getWidgetForPaintable().widgetToCell.remove(w);
+ getWidgetForPaintable().widgetToComponentContainer.remove(w);
+ childComponentContainer.removeFromParent();
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ paintableMap.unregisterPaintable(paintableMap.getPaintable(w));
+ }
+ getWidgetForPaintable().nonRenderedWidgets = null;
+
+ getWidgetForPaintable().rendering = false;
+ getWidgetForPaintable().sizeChangedDuringRendering = false;
+
+ }
+
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ ChildComponentContainer cc = getWidgetForPaintable().widgetToComponentContainer
+ .get(widget);
+ if (cc != null) {
+ cc.updateCaption(uidl, getConnection());
+ }
+ if (!getWidgetForPaintable().rendering) {
+ // ensure rel size details are updated
+ getWidgetForPaintable().widgetToCell.get(widget)
+ .updateRelSizeStatus(uidl);
+ /*
+ * This was a component-only update and the possible size change
+ * must be propagated to the layout
+ */
+ getConnection().captionSizeUpdated(widget);
+ }
+ }
+
+ @Override
+ public VGridLayout getWidgetForPaintable() {
+ return (VGridLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VGridLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
index b72f5222cc..acc49ece18 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
@@ -1,17 +1,20 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-
-public class VHorizontalLayoutPaintable extends VOrderedLayoutPaintable {
-
- @Override
- public VHorizontalLayout getWidgetForPaintable() {
- return (VHorizontalLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected VHorizontalLayout createWidget() {
- return GWT.create(VHorizontalLayout.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VHorizontalLayoutPaintable extends VOrderedLayoutPaintable {
+
+ @Override
+ public VHorizontalLayout getWidgetForPaintable() {
+ return (VHorizontalLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected VHorizontalLayout createWidget() {
+ return GWT.create(VHorizontalLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
index 2340ceb0b6..44141107aa 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
@@ -1,13 +1,16 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-
-public class VHorizontalSplitPanelPaintable extends
- VAbstractSplitPanelPaintable {
-
- @Override
- protected VAbstractSplitPanel createWidget() {
- return GWT.create(VSplitPanelHorizontal.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VHorizontalSplitPanelPaintable extends
+ VAbstractSplitPanelPaintable {
+
+ @Override
+ protected VAbstractSplitPanel createWidget() {
+ return GWT.create(VSplitPanelHorizontal.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java b/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
index 018df57327..aac8ca5ee7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
@@ -1,52 +1,52 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.user.client.Timer;
-
-/**
- * Executes the given command {@code delayMs} milliseconds after a call to
- * {@link #trigger()}. Calling {@link #trigger()} again before the command has
- * been executed causes the execution to be rescheduled to {@code delayMs} after
- * the second call.
- *
- */
-public class VLazyExecutor {
-
- private Timer timer;
- private int delayMs;
- private ScheduledCommand cmd;
-
- /**
- * @param delayMs
- * Delay in milliseconds to wait before executing the command
- * @param cmd
- * The command to execute
- */
- public VLazyExecutor(int delayMs, ScheduledCommand cmd) {
- this.delayMs = delayMs;
- this.cmd = cmd;
- }
-
- /**
- * Triggers execution of the command. Each call reschedules any existing
- * execution to {@link #delayMs} milliseconds from that point in time.
- */
- public void trigger() {
- if (timer == null) {
- timer = new Timer() {
- @Override
- public void run() {
- timer = null;
- cmd.execute();
- }
- };
- }
- // Schedule automatically cancels any old schedule
- timer.schedule(delayMs);
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.user.client.Timer;
+
+/**
+ * Executes the given command {@code delayMs} milliseconds after a call to
+ * {@link #trigger()}. Calling {@link #trigger()} again before the command has
+ * been executed causes the execution to be rescheduled to {@code delayMs} after
+ * the second call.
+ *
+ */
+public class VLazyExecutor {
+
+ private Timer timer;
+ private int delayMs;
+ private ScheduledCommand cmd;
+
+ /**
+ * @param delayMs
+ * Delay in milliseconds to wait before executing the command
+ * @param cmd
+ * The command to execute
+ */
+ public VLazyExecutor(int delayMs, ScheduledCommand cmd) {
+ this.delayMs = delayMs;
+ this.cmd = cmd;
+ }
+
+ /**
+ * Triggers execution of the command. Each call reschedules any existing
+ * execution to {@link #delayMs} milliseconds from that point in time.
+ */
+ public void trigger() {
+ if (timer == null) {
+ timer = new Timer() {
+ @Override
+ public void run() {
+ timer = null;
+ cmd.execute();
+ }
+ };
+ }
+ // Schedule automatically cancels any old schedule
+ timer.schedule(delayMs);
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
index fc709d56b3..1f6bbe6a0a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
@@ -1,109 +1,112 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public abstract class VMediaBasePaintable extends VAbstractPaintableWidget {
-
- public static final String TAG_SOURCE = "src";
-
- public static final String ATTR_PAUSE = "pause";
- public static final String ATTR_PLAY = "play";
- public static final String ATTR_MUTED = "muted";
- public static final String ATTR_CONTROLS = "ctrl";
- public static final String ATTR_AUTOPLAY = "auto";
- public static final String ATTR_RESOURCE = "res";
- public static final String ATTR_RESOURCE_TYPE = "type";
- public static final String ATTR_HTML = "html";
- public static final String ATTR_ALT_TEXT = "alt";
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().setControls(shouldShowControls(uidl));
- getWidgetForPaintable().setAutoplay(shouldAutoplay(uidl));
- getWidgetForPaintable().setMuted(isMediaMuted(uidl));
-
- // Add all sources
- for (int ix = 0; ix < uidl.getChildCount(); ix++) {
- UIDL child = uidl.getChildUIDL(ix);
- if (TAG_SOURCE.equals(child.getTag())) {
- getWidgetForPaintable().addSource(getSourceUrl(child),
- getSourceType(child));
- }
- }
- setAltText(uidl);
-
- evalPauseCommand(uidl);
- evalPlayCommand(uidl);
- }
-
- protected boolean shouldShowControls(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_CONTROLS);
- }
-
- private boolean shouldAutoplay(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_AUTOPLAY);
- }
-
- private boolean isMediaMuted(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_MUTED);
- }
-
- private boolean allowHtmlContent(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_HTML);
- }
-
- private void evalPlayCommand(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_PLAY)) {
- getWidgetForPaintable().play();
- }
- }
-
- private void evalPauseCommand(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_PAUSE)) {
- getWidgetForPaintable().pause();
- }
- }
-
- @Override
- public VMediaBase getWidgetForPaintable() {
- return (VMediaBase) super.getWidgetForPaintable();
- }
-
- /**
- * @param uidl
- * @return the URL of a resource to be used as a source for the media
- */
- private String getSourceUrl(UIDL uidl) {
- String url = getConnection().translateVaadinUri(
- uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE));
- if (url == null) {
- return "";
- }
- return url;
- }
-
- /**
- * @param uidl
- * @return the mime type of the media
- */
- private String getSourceType(UIDL uidl) {
- return uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE_TYPE);
- }
-
- private void setAltText(UIDL uidl) {
- String alt = uidl.getStringAttribute(VMediaBasePaintable.ATTR_ALT_TEXT);
-
- if (alt == null || "".equals(alt)) {
- alt = getWidgetForPaintable().getDefaultAltHtml();
- } else if (!allowHtmlContent(uidl)) {
- alt = Util.escapeHTML(alt);
- }
- getWidgetForPaintable().setAltText(alt);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public abstract class VMediaBasePaintable extends VAbstractPaintableWidget {
+
+ public static final String TAG_SOURCE = "src";
+
+ public static final String ATTR_PAUSE = "pause";
+ public static final String ATTR_PLAY = "play";
+ public static final String ATTR_MUTED = "muted";
+ public static final String ATTR_CONTROLS = "ctrl";
+ public static final String ATTR_AUTOPLAY = "auto";
+ public static final String ATTR_RESOURCE = "res";
+ public static final String ATTR_RESOURCE_TYPE = "type";
+ public static final String ATTR_HTML = "html";
+ public static final String ATTR_ALT_TEXT = "alt";
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().setControls(shouldShowControls(uidl));
+ getWidgetForPaintable().setAutoplay(shouldAutoplay(uidl));
+ getWidgetForPaintable().setMuted(isMediaMuted(uidl));
+
+ // Add all sources
+ for (int ix = 0; ix < uidl.getChildCount(); ix++) {
+ UIDL child = uidl.getChildUIDL(ix);
+ if (TAG_SOURCE.equals(child.getTag())) {
+ getWidgetForPaintable().addSource(getSourceUrl(child),
+ getSourceType(child));
+ }
+ }
+ setAltText(uidl);
+
+ evalPauseCommand(uidl);
+ evalPlayCommand(uidl);
+ }
+
+ protected boolean shouldShowControls(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_CONTROLS);
+ }
+
+ private boolean shouldAutoplay(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_AUTOPLAY);
+ }
+
+ private boolean isMediaMuted(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_MUTED);
+ }
+
+ private boolean allowHtmlContent(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_HTML);
+ }
+
+ private void evalPlayCommand(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_PLAY)) {
+ getWidgetForPaintable().play();
+ }
+ }
+
+ private void evalPauseCommand(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_PAUSE)) {
+ getWidgetForPaintable().pause();
+ }
+ }
+
+ @Override
+ public VMediaBase getWidgetForPaintable() {
+ return (VMediaBase) super.getWidgetForPaintable();
+ }
+
+ /**
+ * @param uidl
+ * @return the URL of a resource to be used as a source for the media
+ */
+ private String getSourceUrl(UIDL uidl) {
+ String url = getConnection().translateVaadinUri(
+ uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE));
+ if (url == null) {
+ return "";
+ }
+ return url;
+ }
+
+ /**
+ * @param uidl
+ * @return the mime type of the media
+ */
+ private String getSourceType(UIDL uidl) {
+ return uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE_TYPE);
+ }
+
+ private void setAltText(UIDL uidl) {
+ String alt = uidl.getStringAttribute(VMediaBasePaintable.ATTR_ALT_TEXT);
+
+ if (alt == null || "".equals(alt)) {
+ alt = getWidgetForPaintable().getDefaultAltHtml();
+ } else if (!allowHtmlContent(uidl)) {
+ alt = Util.escapeHTML(alt);
+ }
+ getWidgetForPaintable().setAltText(alt);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
index fabc77bced..ef2a49b9d0 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
@@ -1,161 +1,161 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Iterator;
-import java.util.Stack;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
-
-public class VMenuBarPaintable extends VAbstractPaintableWidget {
- /**
- * This method must be implemented to update the client-side component from
- * UIDL data received from server.
- *
- * This method is called when the page is loaded for the first time, and
- * every time UI changes in the component are received from the server.
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // This call should be made first. Ensure correct implementation,
- // and let the containing layout manage caption, etc.
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().htmlContentAllowed = uidl
- .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
-
- getWidgetForPaintable().openRootOnHover = uidl
- .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
-
- getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
-
- // For future connections
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().uidlId = uidl.getId();
-
- // Empty the menu every time it receives new information
- if (!getWidgetForPaintable().getItems().isEmpty()) {
- getWidgetForPaintable().clearItems();
- }
-
- UIDL options = uidl.getChildUIDL(0);
-
- if (uidl.hasAttribute("width")) {
- UIDL moreItemUIDL = options.getChildUIDL(0);
- StringBuffer itemHTML = new StringBuffer();
-
- if (moreItemUIDL.hasAttribute("icon")) {
- itemHTML.append("<img src=\""
- + Util.escapeAttribute(client
- .translateVaadinUri(moreItemUIDL
- .getStringAttribute("icon")))
- + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
- }
-
- String moreItemText = moreItemUIDL.getStringAttribute("text");
- if ("".equals(moreItemText)) {
- moreItemText = "&#x25BA;";
- }
- itemHTML.append(moreItemText);
-
- getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
- getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
- getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);
-
- getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
- getWidgetForPaintable());
- getWidgetForPaintable().moreItem
- .setSubMenu(getWidgetForPaintable().collapsedRootItems);
- getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
- + "-more-menuitem");
- }
-
- UIDL uidlItems = uidl.getChildUIDL(1);
- Iterator<Object> itr = uidlItems.getChildIterator();
- Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
- Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
- VMenuBar currentMenu = getWidgetForPaintable();
-
- while (itr.hasNext()) {
- UIDL item = (UIDL) itr.next();
- CustomMenuItem currentItem = null;
-
- final int itemId = item.getIntAttribute("id");
-
- boolean itemHasCommand = item.hasAttribute("command");
- boolean itemIsCheckable = item
- .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
-
- String itemHTML = getWidgetForPaintable().buildItemHTML(item);
-
- Command cmd = null;
- if (!item.hasAttribute("separator")) {
- if (itemHasCommand || itemIsCheckable) {
- // Construct a command that fires onMenuClick(int) with the
- // item's id-number
- cmd = new Command() {
- public void execute() {
- getWidgetForPaintable().hostReference
- .onMenuClick(itemId);
- }
- };
- }
- }
-
- currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
- currentItem.updateFromUIDL(item, client);
-
- if (item.getChildCount() > 0) {
- menuStack.push(currentMenu);
- iteratorStack.push(itr);
- itr = item.getChildIterator();
- currentMenu = new VMenuBar(true, currentMenu);
- if (uidl.hasAttribute("style")) {
- for (String style : uidl.getStringAttribute("style").split(
- " ")) {
- currentMenu.addStyleDependentName(style);
- }
- }
- currentItem.setSubMenu(currentMenu);
- }
-
- while (!itr.hasNext() && !iteratorStack.empty()) {
- boolean hasCheckableItem = false;
- for (CustomMenuItem menuItem : currentMenu.getItems()) {
- hasCheckableItem = hasCheckableItem
- || menuItem.isCheckable();
- }
- if (hasCheckableItem) {
- currentMenu.addStyleDependentName("check-column");
- } else {
- currentMenu.removeStyleDependentName("check-column");
- }
-
- itr = iteratorStack.pop();
- currentMenu = menuStack.pop();
- }
- }// while
-
- getWidgetForPaintable().iLayout(false);
-
- }// updateFromUIDL
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VMenuBar.class);
- }
-
- @Override
- public VMenuBar getWidgetForPaintable() {
- return (VMenuBar) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
+
+public class VMenuBarPaintable extends VAbstractPaintableWidget {
+ /**
+ * This method must be implemented to update the client-side component from
+ * UIDL data received from server.
+ *
+ * This method is called when the page is loaded for the first time, and
+ * every time UI changes in the component are received from the server.
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and let the containing layout manage caption, etc.
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().htmlContentAllowed = uidl
+ .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
+
+ getWidgetForPaintable().openRootOnHover = uidl
+ .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
+
+ getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
+
+ // For future connections
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().uidlId = uidl.getId();
+
+ // Empty the menu every time it receives new information
+ if (!getWidgetForPaintable().getItems().isEmpty()) {
+ getWidgetForPaintable().clearItems();
+ }
+
+ UIDL options = uidl.getChildUIDL(0);
+
+ if (uidl.hasAttribute("width")) {
+ UIDL moreItemUIDL = options.getChildUIDL(0);
+ StringBuffer itemHTML = new StringBuffer();
+
+ if (moreItemUIDL.hasAttribute("icon")) {
+ itemHTML.append("<img src=\""
+ + Util.escapeAttribute(client
+ .translateVaadinUri(moreItemUIDL
+ .getStringAttribute("icon")))
+ + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
+ }
+
+ String moreItemText = moreItemUIDL.getStringAttribute("text");
+ if ("".equals(moreItemText)) {
+ moreItemText = "&#x25BA;";
+ }
+ itemHTML.append(moreItemText);
+
+ getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
+ getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
+ getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);
+
+ getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
+ getWidgetForPaintable());
+ getWidgetForPaintable().moreItem
+ .setSubMenu(getWidgetForPaintable().collapsedRootItems);
+ getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
+ + "-more-menuitem");
+ }
+
+ UIDL uidlItems = uidl.getChildUIDL(1);
+ Iterator<Object> itr = uidlItems.getChildIterator();
+ Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
+ Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
+ VMenuBar currentMenu = getWidgetForPaintable();
+
+ while (itr.hasNext()) {
+ UIDL item = (UIDL) itr.next();
+ CustomMenuItem currentItem = null;
+
+ final int itemId = item.getIntAttribute("id");
+
+ boolean itemHasCommand = item.hasAttribute("command");
+ boolean itemIsCheckable = item
+ .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
+
+ String itemHTML = getWidgetForPaintable().buildItemHTML(item);
+
+ Command cmd = null;
+ if (!item.hasAttribute("separator")) {
+ if (itemHasCommand || itemIsCheckable) {
+ // Construct a command that fires onMenuClick(int) with the
+ // item's id-number
+ cmd = new Command() {
+ public void execute() {
+ getWidgetForPaintable().hostReference
+ .onMenuClick(itemId);
+ }
+ };
+ }
+ }
+
+ currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
+ currentItem.updateFromUIDL(item, client);
+
+ if (item.getChildCount() > 0) {
+ menuStack.push(currentMenu);
+ iteratorStack.push(itr);
+ itr = item.getChildIterator();
+ currentMenu = new VMenuBar(true, currentMenu);
+ if (uidl.hasAttribute("style")) {
+ for (String style : uidl.getStringAttribute("style").split(
+ " ")) {
+ currentMenu.addStyleDependentName(style);
+ }
+ }
+ currentItem.setSubMenu(currentMenu);
+ }
+
+ while (!itr.hasNext() && !iteratorStack.empty()) {
+ boolean hasCheckableItem = false;
+ for (CustomMenuItem menuItem : currentMenu.getItems()) {
+ hasCheckableItem = hasCheckableItem
+ || menuItem.isCheckable();
+ }
+ if (hasCheckableItem) {
+ currentMenu.addStyleDependentName("check-column");
+ } else {
+ currentMenu.removeStyleDependentName("check-column");
+ }
+
+ itr = iteratorStack.pop();
+ currentMenu = menuStack.pop();
+ }
+ }// while
+
+ getWidgetForPaintable().iLayout(false);
+
+ }// updateFromUIDL
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VMenuBar.class);
+ }
+
+ @Override
+ public VMenuBar getWidgetForPaintable() {
+ return (VMenuBar) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
index 128e3bd597..27407c55aa 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
@@ -1,417 +1,417 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class VNotification extends VOverlay {
-
- public static final int CENTERED = 1;
- public static final int CENTERED_TOP = 2;
- public static final int CENTERED_BOTTOM = 3;
- public static final int TOP_LEFT = 4;
- public static final int TOP_RIGHT = 5;
- public static final int BOTTOM_LEFT = 6;
- public static final int BOTTOM_RIGHT = 7;
-
- public static final int DELAY_FOREVER = -1;
- public static final int DELAY_NONE = 0;
-
- private static final String STYLENAME = "v-Notification";
- private static final int mouseMoveThreshold = 7;
- private static final int Z_INDEX_BASE = 20000;
- public static final String STYLE_SYSTEM = "system";
- private static final int FADE_ANIMATION_INTERVAL = 50; // == 20 fps
-
- private int startOpacity = 90;
- private int fadeMsec = 400;
- private int delayMsec = 1000;
-
- private Timer fader;
- private Timer delay;
-
- private int x = -1;
- private int y = -1;
-
- private String temporaryStyle;
-
- private ArrayList<EventListener> listeners;
- private static final int TOUCH_DEVICE_IDLE_DELAY = 1000;
-
- /**
- * Default constructor. You should use GWT.create instead.
- */
- public VNotification() {
- setStyleName(STYLENAME);
- sinkEvents(Event.ONCLICK);
- DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE);
- }
-
- /**
- * @deprecated Use static {@link #createNotification(int)} instead to enable
- * GWT deferred binding.
- *
- * @param delayMsec
- */
- @Deprecated
- public VNotification(int delayMsec) {
- this();
- this.delayMsec = delayMsec;
- if (BrowserInfo.get().isTouchDevice()) {
- new Timer() {
- @Override
- public void run() {
- if (isAttached()) {
- fade();
- }
- }
- }.schedule(delayMsec + TOUCH_DEVICE_IDLE_DELAY);
- }
- }
-
- /**
- * @deprecated Use static {@link #createNotification(int, int, int)} instead
- * to enable GWT deferred binding.
- *
- * @param delayMsec
- * @param fadeMsec
- * @param startOpacity
- */
- @Deprecated
- public VNotification(int delayMsec, int fadeMsec, int startOpacity) {
- this(delayMsec);
- this.fadeMsec = fadeMsec;
- this.startOpacity = startOpacity;
- }
-
- public void startDelay() {
- DOM.removeEventPreview(this);
- if (delayMsec > 0) {
- if (delay == null) {
- delay = new Timer() {
- @Override
- public void run() {
- fade();
- }
- };
- delay.schedule(delayMsec);
- }
- } else if (delayMsec == 0) {
- fade();
- }
- }
-
- @Override
- public void show() {
- show(CENTERED);
- }
-
- public void show(String style) {
- show(CENTERED, style);
- }
-
- public void show(int position) {
- show(position, null);
- }
-
- public void show(Widget widget, int position, String style) {
- setWidget(widget);
- show(position, style);
- }
-
- public void show(String html, int position, String style) {
- setWidget(new HTML(html));
- show(position, style);
- }
-
- public void show(int position, String style) {
- setOpacity(getElement(), startOpacity);
- if (style != null) {
- temporaryStyle = style;
- addStyleName(style);
- addStyleDependentName(style);
- }
- super.show();
- setPosition(position);
- }
-
- @Override
- public void hide() {
- DOM.removeEventPreview(this);
- cancelDelay();
- cancelFade();
- if (temporaryStyle != null) {
- removeStyleName(temporaryStyle);
- removeStyleDependentName(temporaryStyle);
- temporaryStyle = null;
- }
- super.hide();
- fireEvent(new HideEvent(this));
- }
-
- public void fade() {
- DOM.removeEventPreview(this);
- cancelDelay();
- if (fader == null) {
- fader = new Timer() {
- private final long start = new Date().getTime();
-
- @Override
- public void run() {
- /*
- * To make animation smooth, don't count that event happens
- * on time. Reduce opacity according to the actual time
- * spent instead of fixed decrement.
- */
- long now = new Date().getTime();
- long timeEplaced = now - start;
- float remainingFraction = 1 - timeEplaced
- / (float) fadeMsec;
- int opacity = (int) (startOpacity * remainingFraction);
- if (opacity <= 0) {
- cancel();
- hide();
- if (BrowserInfo.get().isOpera()) {
- // tray notification on opera needs to explicitly
- // define
- // size, reset it
- DOM.setStyleAttribute(getElement(), "width", "");
- DOM.setStyleAttribute(getElement(), "height", "");
- }
- } else {
- setOpacity(getElement(), opacity);
- }
- }
- };
- fader.scheduleRepeating(FADE_ANIMATION_INTERVAL);
- }
- }
-
- public void setPosition(int position) {
- final Element el = getElement();
- DOM.setStyleAttribute(el, "top", "");
- DOM.setStyleAttribute(el, "left", "");
- DOM.setStyleAttribute(el, "bottom", "");
- DOM.setStyleAttribute(el, "right", "");
- switch (position) {
- case TOP_LEFT:
- DOM.setStyleAttribute(el, "top", "0px");
- DOM.setStyleAttribute(el, "left", "0px");
- break;
- case TOP_RIGHT:
- DOM.setStyleAttribute(el, "top", "0px");
- DOM.setStyleAttribute(el, "right", "0px");
- break;
- case BOTTOM_RIGHT:
- DOM.setStyleAttribute(el, "position", "absolute");
- if (BrowserInfo.get().isOpera()) {
- // tray notification on opera needs explicitly defined size
- DOM.setStyleAttribute(el, "width", getOffsetWidth() + "px");
- DOM.setStyleAttribute(el, "height", getOffsetHeight() + "px");
- }
- DOM.setStyleAttribute(el, "bottom", "0px");
- DOM.setStyleAttribute(el, "right", "0px");
- break;
- case BOTTOM_LEFT:
- DOM.setStyleAttribute(el, "bottom", "0px");
- DOM.setStyleAttribute(el, "left", "0px");
- break;
- case CENTERED_TOP:
- center();
- DOM.setStyleAttribute(el, "top", "0px");
- break;
- case CENTERED_BOTTOM:
- center();
- DOM.setStyleAttribute(el, "top", "");
- DOM.setStyleAttribute(el, "bottom", "0px");
- break;
- default:
- case CENTERED:
- center();
- break;
- }
- }
-
- private void cancelFade() {
- if (fader != null) {
- fader.cancel();
- fader = null;
- }
- }
-
- private void cancelDelay() {
- if (delay != null) {
- delay.cancel();
- delay = null;
- }
- }
-
- private void setOpacity(Element el, int opacity) {
- DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0));
- if (BrowserInfo.get().isIE()) {
- DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity
- + ")");
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- DOM.removeEventPreview(this);
- if (fader == null) {
- fade();
- }
- }
-
- @Override
- public boolean onEventPreview(Event event) {
- int type = DOM.eventGetType(event);
- // "modal"
- if (delayMsec == -1 || temporaryStyle == STYLE_SYSTEM) {
- if (type == Event.ONCLICK) {
- if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) {
- fade();
- return false;
- }
- } else if (type == Event.ONKEYDOWN
- && event.getKeyCode() == KeyCodes.KEY_ESCAPE) {
- fade();
- return false;
- }
- if (temporaryStyle == STYLE_SYSTEM) {
- return true;
- } else {
- return false;
- }
- }
- // default
- switch (type) {
- case Event.ONMOUSEMOVE:
-
- if (x < 0) {
- x = DOM.eventGetClientX(event);
- y = DOM.eventGetClientY(event);
- } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold
- || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) {
- startDelay();
- }
- break;
- case Event.ONMOUSEDOWN:
- case Event.ONMOUSEWHEEL:
- case Event.ONSCROLL:
- startDelay();
- break;
- case Event.ONKEYDOWN:
- if (event.getRepeat()) {
- return true;
- }
- startDelay();
- break;
- default:
- break;
- }
- return true;
- }
-
- public void addEventListener(EventListener listener) {
- if (listeners == null) {
- listeners = new ArrayList<EventListener>();
- }
- listeners.add(listener);
- }
-
- public void removeEventListener(EventListener listener) {
- if (listeners == null) {
- return;
- }
- listeners.remove(listener);
- }
-
- private void fireEvent(HideEvent event) {
- if (listeners != null) {
- for (Iterator<EventListener> it = listeners.iterator(); it
- .hasNext();) {
- EventListener l = it.next();
- l.notificationHidden(event);
- }
- }
- }
-
- public static void showNotification(ApplicationConnection client,
- final UIDL notification) {
- boolean onlyPlainText = notification
- .hasAttribute(VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED);
- String html = "";
- if (notification.hasAttribute("icon")) {
- final String parsedUri = client.translateVaadinUri(notification
- .getStringAttribute("icon"));
- html += "<img src=\"" + Util.escapeAttribute(parsedUri) + "\" />";
- }
- if (notification.hasAttribute("caption")) {
- String caption = notification.getStringAttribute("caption");
- if (onlyPlainText) {
- caption = Util.escapeHTML(caption);
- caption = caption.replaceAll("\\n", "<br />");
- }
- html += "<h1>" + caption + "</h1>";
- }
- if (notification.hasAttribute("message")) {
- String message = notification.getStringAttribute("message");
- if (onlyPlainText) {
- message = Util.escapeHTML(message);
- message = message.replaceAll("\\n", "<br />");
- }
- html += "<p>" + message + "</p>";
- }
-
- final String style = notification.hasAttribute("style") ? notification
- .getStringAttribute("style") : null;
- final int position = notification.getIntAttribute("position");
- final int delay = notification.getIntAttribute("delay");
- createNotification(delay).show(html, position, style);
- }
-
- public static VNotification createNotification(int delayMsec) {
- final VNotification notification = GWT.create(VNotification.class);
- notification.delayMsec = delayMsec;
- if (BrowserInfo.get().isTouchDevice()) {
- new Timer() {
- @Override
- public void run() {
- if (notification.isAttached()) {
- notification.fade();
- }
- }
- }.schedule(notification.delayMsec + TOUCH_DEVICE_IDLE_DELAY);
- }
- return notification;
- }
-
- public class HideEvent extends EventObject {
-
- public HideEvent(Object source) {
- super(source);
- }
- }
-
- public interface EventListener extends java.util.EventListener {
- public void notificationHidden(HideEvent event);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public class VNotification extends VOverlay {
+
+ public static final int CENTERED = 1;
+ public static final int CENTERED_TOP = 2;
+ public static final int CENTERED_BOTTOM = 3;
+ public static final int TOP_LEFT = 4;
+ public static final int TOP_RIGHT = 5;
+ public static final int BOTTOM_LEFT = 6;
+ public static final int BOTTOM_RIGHT = 7;
+
+ public static final int DELAY_FOREVER = -1;
+ public static final int DELAY_NONE = 0;
+
+ private static final String STYLENAME = "v-Notification";
+ private static final int mouseMoveThreshold = 7;
+ private static final int Z_INDEX_BASE = 20000;
+ public static final String STYLE_SYSTEM = "system";
+ private static final int FADE_ANIMATION_INTERVAL = 50; // == 20 fps
+
+ private int startOpacity = 90;
+ private int fadeMsec = 400;
+ private int delayMsec = 1000;
+
+ private Timer fader;
+ private Timer delay;
+
+ private int x = -1;
+ private int y = -1;
+
+ private String temporaryStyle;
+
+ private ArrayList<EventListener> listeners;
+ private static final int TOUCH_DEVICE_IDLE_DELAY = 1000;
+
+ /**
+ * Default constructor. You should use GWT.create instead.
+ */
+ public VNotification() {
+ setStyleName(STYLENAME);
+ sinkEvents(Event.ONCLICK);
+ DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE);
+ }
+
+ /**
+ * @deprecated Use static {@link #createNotification(int)} instead to enable
+ * GWT deferred binding.
+ *
+ * @param delayMsec
+ */
+ @Deprecated
+ public VNotification(int delayMsec) {
+ this();
+ this.delayMsec = delayMsec;
+ if (BrowserInfo.get().isTouchDevice()) {
+ new Timer() {
+ @Override
+ public void run() {
+ if (isAttached()) {
+ fade();
+ }
+ }
+ }.schedule(delayMsec + TOUCH_DEVICE_IDLE_DELAY);
+ }
+ }
+
+ /**
+ * @deprecated Use static {@link #createNotification(int, int, int)} instead
+ * to enable GWT deferred binding.
+ *
+ * @param delayMsec
+ * @param fadeMsec
+ * @param startOpacity
+ */
+ @Deprecated
+ public VNotification(int delayMsec, int fadeMsec, int startOpacity) {
+ this(delayMsec);
+ this.fadeMsec = fadeMsec;
+ this.startOpacity = startOpacity;
+ }
+
+ public void startDelay() {
+ DOM.removeEventPreview(this);
+ if (delayMsec > 0) {
+ if (delay == null) {
+ delay = new Timer() {
+ @Override
+ public void run() {
+ fade();
+ }
+ };
+ delay.schedule(delayMsec);
+ }
+ } else if (delayMsec == 0) {
+ fade();
+ }
+ }
+
+ @Override
+ public void show() {
+ show(CENTERED);
+ }
+
+ public void show(String style) {
+ show(CENTERED, style);
+ }
+
+ public void show(int position) {
+ show(position, null);
+ }
+
+ public void show(Widget widget, int position, String style) {
+ setWidget(widget);
+ show(position, style);
+ }
+
+ public void show(String html, int position, String style) {
+ setWidget(new HTML(html));
+ show(position, style);
+ }
+
+ public void show(int position, String style) {
+ setOpacity(getElement(), startOpacity);
+ if (style != null) {
+ temporaryStyle = style;
+ addStyleName(style);
+ addStyleDependentName(style);
+ }
+ super.show();
+ setPosition(position);
+ }
+
+ @Override
+ public void hide() {
+ DOM.removeEventPreview(this);
+ cancelDelay();
+ cancelFade();
+ if (temporaryStyle != null) {
+ removeStyleName(temporaryStyle);
+ removeStyleDependentName(temporaryStyle);
+ temporaryStyle = null;
+ }
+ super.hide();
+ fireEvent(new HideEvent(this));
+ }
+
+ public void fade() {
+ DOM.removeEventPreview(this);
+ cancelDelay();
+ if (fader == null) {
+ fader = new Timer() {
+ private final long start = new Date().getTime();
+
+ @Override
+ public void run() {
+ /*
+ * To make animation smooth, don't count that event happens
+ * on time. Reduce opacity according to the actual time
+ * spent instead of fixed decrement.
+ */
+ long now = new Date().getTime();
+ long timeEplaced = now - start;
+ float remainingFraction = 1 - timeEplaced
+ / (float) fadeMsec;
+ int opacity = (int) (startOpacity * remainingFraction);
+ if (opacity <= 0) {
+ cancel();
+ hide();
+ if (BrowserInfo.get().isOpera()) {
+ // tray notification on opera needs to explicitly
+ // define
+ // size, reset it
+ DOM.setStyleAttribute(getElement(), "width", "");
+ DOM.setStyleAttribute(getElement(), "height", "");
+ }
+ } else {
+ setOpacity(getElement(), opacity);
+ }
+ }
+ };
+ fader.scheduleRepeating(FADE_ANIMATION_INTERVAL);
+ }
+ }
+
+ public void setPosition(int position) {
+ final Element el = getElement();
+ DOM.setStyleAttribute(el, "top", "");
+ DOM.setStyleAttribute(el, "left", "");
+ DOM.setStyleAttribute(el, "bottom", "");
+ DOM.setStyleAttribute(el, "right", "");
+ switch (position) {
+ case TOP_LEFT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case TOP_RIGHT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_RIGHT:
+ DOM.setStyleAttribute(el, "position", "absolute");
+ if (BrowserInfo.get().isOpera()) {
+ // tray notification on opera needs explicitly defined size
+ DOM.setStyleAttribute(el, "width", getOffsetWidth() + "px");
+ DOM.setStyleAttribute(el, "height", getOffsetHeight() + "px");
+ }
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_LEFT:
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case CENTERED_TOP:
+ center();
+ DOM.setStyleAttribute(el, "top", "0px");
+ break;
+ case CENTERED_BOTTOM:
+ center();
+ DOM.setStyleAttribute(el, "top", "");
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ break;
+ default:
+ case CENTERED:
+ center();
+ break;
+ }
+ }
+
+ private void cancelFade() {
+ if (fader != null) {
+ fader.cancel();
+ fader = null;
+ }
+ }
+
+ private void cancelDelay() {
+ if (delay != null) {
+ delay.cancel();
+ delay = null;
+ }
+ }
+
+ private void setOpacity(Element el, int opacity) {
+ DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0));
+ if (BrowserInfo.get().isIE()) {
+ DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity
+ + ")");
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ DOM.removeEventPreview(this);
+ if (fader == null) {
+ fade();
+ }
+ }
+
+ @Override
+ public boolean onEventPreview(Event event) {
+ int type = DOM.eventGetType(event);
+ // "modal"
+ if (delayMsec == -1 || temporaryStyle == STYLE_SYSTEM) {
+ if (type == Event.ONCLICK) {
+ if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) {
+ fade();
+ return false;
+ }
+ } else if (type == Event.ONKEYDOWN
+ && event.getKeyCode() == KeyCodes.KEY_ESCAPE) {
+ fade();
+ return false;
+ }
+ if (temporaryStyle == STYLE_SYSTEM) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ // default
+ switch (type) {
+ case Event.ONMOUSEMOVE:
+
+ if (x < 0) {
+ x = DOM.eventGetClientX(event);
+ y = DOM.eventGetClientY(event);
+ } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold
+ || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) {
+ startDelay();
+ }
+ break;
+ case Event.ONMOUSEDOWN:
+ case Event.ONMOUSEWHEEL:
+ case Event.ONSCROLL:
+ startDelay();
+ break;
+ case Event.ONKEYDOWN:
+ if (event.getRepeat()) {
+ return true;
+ }
+ startDelay();
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ public void addEventListener(EventListener listener) {
+ if (listeners == null) {
+ listeners = new ArrayList<EventListener>();
+ }
+ listeners.add(listener);
+ }
+
+ public void removeEventListener(EventListener listener) {
+ if (listeners == null) {
+ return;
+ }
+ listeners.remove(listener);
+ }
+
+ private void fireEvent(HideEvent event) {
+ if (listeners != null) {
+ for (Iterator<EventListener> it = listeners.iterator(); it
+ .hasNext();) {
+ EventListener l = it.next();
+ l.notificationHidden(event);
+ }
+ }
+ }
+
+ public static void showNotification(ApplicationConnection client,
+ final UIDL notification) {
+ boolean onlyPlainText = notification
+ .hasAttribute(VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED);
+ String html = "";
+ if (notification.hasAttribute("icon")) {
+ final String parsedUri = client.translateVaadinUri(notification
+ .getStringAttribute("icon"));
+ html += "<img src=\"" + Util.escapeAttribute(parsedUri) + "\" />";
+ }
+ if (notification.hasAttribute("caption")) {
+ String caption = notification.getStringAttribute("caption");
+ if (onlyPlainText) {
+ caption = Util.escapeHTML(caption);
+ caption = caption.replaceAll("\\n", "<br />");
+ }
+ html += "<h1>" + caption + "</h1>";
+ }
+ if (notification.hasAttribute("message")) {
+ String message = notification.getStringAttribute("message");
+ if (onlyPlainText) {
+ message = Util.escapeHTML(message);
+ message = message.replaceAll("\\n", "<br />");
+ }
+ html += "<p>" + message + "</p>";
+ }
+
+ final String style = notification.hasAttribute("style") ? notification
+ .getStringAttribute("style") : null;
+ final int position = notification.getIntAttribute("position");
+ final int delay = notification.getIntAttribute("delay");
+ createNotification(delay).show(html, position, style);
+ }
+
+ public static VNotification createNotification(int delayMsec) {
+ final VNotification notification = GWT.create(VNotification.class);
+ notification.delayMsec = delayMsec;
+ if (BrowserInfo.get().isTouchDevice()) {
+ new Timer() {
+ @Override
+ public void run() {
+ if (notification.isAttached()) {
+ notification.fade();
+ }
+ }
+ }.schedule(notification.delayMsec + TOUCH_DEVICE_IDLE_DELAY);
+ }
+ return notification;
+ }
+
+ public class HideEvent extends EventObject {
+
+ public HideEvent(Object source) {
+ super(source);
+ }
+ }
+
+ public interface EventListener extends java.util.EventListener {
+ public void notificationHidden(HideEvent event);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
index 9f5576dfaf..413eadb314 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
@@ -725,8 +725,4 @@ public class VOrderedLayout extends CellBasedLayout {
return Util.getPaintableForElement(client, this, element);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
index 4720e07099..6ab1145798 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
@@ -1,254 +1,257 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayoutPaintable;
-import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
-
-public abstract class VOrderedLayoutPaintable extends CellBasedLayoutPaintable {
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getWidgetForPaintable().getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
- Widget widget = paintable.getWidgetForPaintable();
- ChildComponentContainer componentContainer = getWidgetForPaintable()
- .getComponentContainer(widget);
- componentContainer.updateCaption(uidl, getConnection());
- if (!getWidgetForPaintable().isRendering) {
- /*
- * This was a component-only update and the possible size change
- * must be propagated to the layout
- */
- getConnection().captionSizeUpdated(widget);
- }
- }
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().isRendering = true;
- super.updateFromUIDL(uidl, client);
-
- // Only non-cached, visible UIDL:s can introduce changes
- if (uidl.getBooleanAttribute("cached")
- || uidl.getBooleanAttribute("invisible")) {
- getWidgetForPaintable().isRendering = false;
- return;
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- // IStopWatch w = new IStopWatch("OrderedLayout.updateFromUIDL");
-
- ArrayList<Widget> uidlWidgets = new ArrayList<Widget>(
- uidl.getChildCount());
- ArrayList<ChildComponentContainer> relativeSizeComponents = new ArrayList<ChildComponentContainer>();
- ArrayList<UIDL> relativeSizeComponentUIDL = new ArrayList<UIDL>();
-
- int pos = 0;
- for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) {
- final UIDL childUIDL = (UIDL) it.next();
- final VPaintableWidget childPaintable = client
- .getPaintable(childUIDL);
- Widget widget = childPaintable.getWidgetForPaintable();
-
- // Create container for component
- ChildComponentContainer childComponentContainer = getWidgetForPaintable()
- .getComponentContainer(widget);
-
- if (childComponentContainer == null) {
- // This is a new component
- childComponentContainer = getWidgetForPaintable()
- .createChildContainer(childPaintable);
- } else {
- /*
- * The widget may be null if the same paintable has been
- * rendered in a different component container while this has
- * been invisible. Ensure the childComponentContainer has the
- * widget attached. See e.g. #5372
- */
- childComponentContainer.setPaintable(childPaintable);
- }
-
- getWidgetForPaintable().addOrMoveChild(childComponentContainer,
- pos++);
-
- /*
- * Components which are to be expanded in the same orientation as
- * the layout are rendered later when it is clear how much space
- * they can use
- */
- if (!Util.isCached(childUIDL)) {
- FloatSize relativeSize = Util.parseRelativeSize(childUIDL);
- childComponentContainer.setRelativeSize(relativeSize);
- }
-
- if (childComponentContainer
- .isComponentRelativeSized(getWidgetForPaintable().orientation)) {
- relativeSizeComponents.add(childComponentContainer);
- relativeSizeComponentUIDL.add(childUIDL);
- } else {
- if (getWidgetForPaintable().isDynamicWidth()) {
- childComponentContainer.renderChild(childUIDL, client, -1);
- } else {
- childComponentContainer
- .renderChild(childUIDL, client,
- getWidgetForPaintable().activeLayoutSize
- .getWidth());
- }
- if (getWidgetForPaintable().sizeHasChangedDuringRendering
- && Util.isCached(childUIDL)) {
- // notify cached relative sized component about size
- // chance
- client.handleComponentRelativeSize(childComponentContainer
- .getWidget());
- }
- }
-
- uidlWidgets.add(widget);
-
- }
-
- // w.mark("Rendering of "
- // + (uidlWidgets.size() - relativeSizeComponents.size())
- // + " absolute size components done");
-
- /*
- * Remove any children after pos. These are the ones that previously
- * were in the layout but have now been removed
- */
- getWidgetForPaintable().removeChildrenAfter(pos);
-
- // w.mark("Old children removed");
-
- /* Fetch alignments and expand ratio from UIDL */
- getWidgetForPaintable().updateAlignmentsAndExpandRatios(uidl,
- uidlWidgets);
- // w.mark("Alignments and expand ratios updated");
-
- /* Fetch widget sizes from rendered components */
- getWidgetForPaintable().updateWidgetSizes();
- // w.mark("Widget sizes updated");
-
- getWidgetForPaintable().recalculateLayout();
- // w.mark("Layout size calculated (" + activeLayoutSize +
- // ") offsetSize: "
- // + getOffsetWidth() + "," + getOffsetHeight());
-
- /* Render relative size components */
- for (int i = 0; i < relativeSizeComponents.size(); i++) {
- ChildComponentContainer childComponentContainer = relativeSizeComponents
- .get(i);
- UIDL childUIDL = relativeSizeComponentUIDL.get(i);
-
- if (getWidgetForPaintable().isDynamicWidth()) {
- childComponentContainer.renderChild(childUIDL, client, -1);
- } else {
- childComponentContainer.renderChild(childUIDL, client,
- getWidgetForPaintable().activeLayoutSize.getWidth());
- }
-
- if (Util.isCached(childUIDL)) {
- /*
- * We must update the size of the relative sized component if
- * the expand ratio or something else in the layout changes
- * which affects the size of a relative sized component
- */
- client.handleComponentRelativeSize(childComponentContainer
- .getWidget());
- }
-
- // childComponentContainer.updateWidgetSize();
- }
-
- // w.mark("Rendering of " + (relativeSizeComponents.size())
- // + " relative size components done");
-
- /* Fetch widget sizes for relative size components */
- for (ChildComponentContainer childComponentContainer : getWidgetForPaintable()
- .getComponentContainers()) {
-
- /* Update widget size from DOM */
- childComponentContainer.updateWidgetSize();
- }
-
- // w.mark("Widget sizes updated");
-
- /*
- * Components with relative size in main direction may affect the layout
- * size in the other direction
- */
- if ((getWidgetForPaintable().isHorizontal() && getWidgetForPaintable()
- .isDynamicHeight())
- || (getWidgetForPaintable().isVertical() && getWidgetForPaintable()
- .isDynamicWidth())) {
- getWidgetForPaintable().layoutSizeMightHaveChanged();
- }
- // w.mark("Layout dimensions updated");
-
- /* Update component spacing */
- getWidgetForPaintable().updateContainerMargins();
-
- /*
- * Update component sizes for components with relative size in non-main
- * direction
- */
- if (getWidgetForPaintable().updateRelativeSizesInNonMainDirection()) {
- // Sizes updated - might affect the other dimension so we need to
- // recheck the widget sizes and recalculate layout dimensions
- getWidgetForPaintable().updateWidgetSizes();
- getWidgetForPaintable().layoutSizeMightHaveChanged();
- }
- getWidgetForPaintable().calculateAlignments();
- // w.mark("recalculateComponentSizesAndAlignments done");
-
- getWidgetForPaintable().setRootSize();
-
- if (BrowserInfo.get().isIE()) {
- /*
- * This should fix the issue with padding not always taken into
- * account for the containers leading to no spacing between
- * elements.
- */
- getWidgetForPaintable().root.getStyle().setProperty("zoom", "1");
- }
-
- // w.mark("runDescendentsLayout done");
- getWidgetForPaintable().isRendering = false;
- getWidgetForPaintable().sizeHasChangedDuringRendering = false;
- }
-
- @Override
- protected abstract VOrderedLayout createWidget();
-
- @Override
- public VOrderedLayout getWidgetForPaintable() {
- return (VOrderedLayout) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayoutPaintable;
+import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
+
+public abstract class VOrderedLayoutPaintable extends CellBasedLayoutPaintable {
+
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ ChildComponentContainer componentContainer = getWidgetForPaintable()
+ .getComponentContainer(widget);
+ componentContainer.updateCaption(uidl, getConnection());
+ if (!getWidgetForPaintable().isRendering) {
+ /*
+ * This was a component-only update and the possible size change
+ * must be propagated to the layout
+ */
+ getConnection().captionSizeUpdated(widget);
+ }
+ }
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().isRendering = true;
+ super.updateFromUIDL(uidl, client);
+
+ // Only non-cached, visible UIDL:s can introduce changes
+ if (uidl.getBooleanAttribute("cached")
+ || uidl.getBooleanAttribute("invisible")) {
+ getWidgetForPaintable().isRendering = false;
+ return;
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ // IStopWatch w = new IStopWatch("OrderedLayout.updateFromUIDL");
+
+ ArrayList<Widget> uidlWidgets = new ArrayList<Widget>(
+ uidl.getChildCount());
+ ArrayList<ChildComponentContainer> relativeSizeComponents = new ArrayList<ChildComponentContainer>();
+ ArrayList<UIDL> relativeSizeComponentUIDL = new ArrayList<UIDL>();
+
+ int pos = 0;
+ for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) {
+ final UIDL childUIDL = (UIDL) it.next();
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUIDL);
+ Widget widget = childPaintable.getWidgetForPaintable();
+
+ // Create container for component
+ ChildComponentContainer childComponentContainer = getWidgetForPaintable()
+ .getComponentContainer(widget);
+
+ if (childComponentContainer == null) {
+ // This is a new component
+ childComponentContainer = getWidgetForPaintable()
+ .createChildContainer(childPaintable);
+ } else {
+ /*
+ * The widget may be null if the same paintable has been
+ * rendered in a different component container while this has
+ * been invisible. Ensure the childComponentContainer has the
+ * widget attached. See e.g. #5372
+ */
+ childComponentContainer.setPaintable(childPaintable);
+ }
+
+ getWidgetForPaintable().addOrMoveChild(childComponentContainer,
+ pos++);
+
+ /*
+ * Components which are to be expanded in the same orientation as
+ * the layout are rendered later when it is clear how much space
+ * they can use
+ */
+ if (!Util.isCached(childUIDL)) {
+ FloatSize relativeSize = Util.parseRelativeSize(childUIDL);
+ childComponentContainer.setRelativeSize(relativeSize);
+ }
+
+ if (childComponentContainer
+ .isComponentRelativeSized(getWidgetForPaintable().orientation)) {
+ relativeSizeComponents.add(childComponentContainer);
+ relativeSizeComponentUIDL.add(childUIDL);
+ } else {
+ if (getWidgetForPaintable().isDynamicWidth()) {
+ childComponentContainer.renderChild(childUIDL, client, -1);
+ } else {
+ childComponentContainer
+ .renderChild(childUIDL, client,
+ getWidgetForPaintable().activeLayoutSize
+ .getWidth());
+ }
+ if (getWidgetForPaintable().sizeHasChangedDuringRendering
+ && Util.isCached(childUIDL)) {
+ // notify cached relative sized component about size
+ // chance
+ client.handleComponentRelativeSize(childComponentContainer
+ .getWidget());
+ }
+ }
+
+ uidlWidgets.add(widget);
+
+ }
+
+ // w.mark("Rendering of "
+ // + (uidlWidgets.size() - relativeSizeComponents.size())
+ // + " absolute size components done");
+
+ /*
+ * Remove any children after pos. These are the ones that previously
+ * were in the layout but have now been removed
+ */
+ getWidgetForPaintable().removeChildrenAfter(pos);
+
+ // w.mark("Old children removed");
+
+ /* Fetch alignments and expand ratio from UIDL */
+ getWidgetForPaintable().updateAlignmentsAndExpandRatios(uidl,
+ uidlWidgets);
+ // w.mark("Alignments and expand ratios updated");
+
+ /* Fetch widget sizes from rendered components */
+ getWidgetForPaintable().updateWidgetSizes();
+ // w.mark("Widget sizes updated");
+
+ getWidgetForPaintable().recalculateLayout();
+ // w.mark("Layout size calculated (" + activeLayoutSize +
+ // ") offsetSize: "
+ // + getOffsetWidth() + "," + getOffsetHeight());
+
+ /* Render relative size components */
+ for (int i = 0; i < relativeSizeComponents.size(); i++) {
+ ChildComponentContainer childComponentContainer = relativeSizeComponents
+ .get(i);
+ UIDL childUIDL = relativeSizeComponentUIDL.get(i);
+
+ if (getWidgetForPaintable().isDynamicWidth()) {
+ childComponentContainer.renderChild(childUIDL, client, -1);
+ } else {
+ childComponentContainer.renderChild(childUIDL, client,
+ getWidgetForPaintable().activeLayoutSize.getWidth());
+ }
+
+ if (Util.isCached(childUIDL)) {
+ /*
+ * We must update the size of the relative sized component if
+ * the expand ratio or something else in the layout changes
+ * which affects the size of a relative sized component
+ */
+ client.handleComponentRelativeSize(childComponentContainer
+ .getWidget());
+ }
+
+ // childComponentContainer.updateWidgetSize();
+ }
+
+ // w.mark("Rendering of " + (relativeSizeComponents.size())
+ // + " relative size components done");
+
+ /* Fetch widget sizes for relative size components */
+ for (ChildComponentContainer childComponentContainer : getWidgetForPaintable()
+ .getComponentContainers()) {
+
+ /* Update widget size from DOM */
+ childComponentContainer.updateWidgetSize();
+ }
+
+ // w.mark("Widget sizes updated");
+
+ /*
+ * Components with relative size in main direction may affect the layout
+ * size in the other direction
+ */
+ if ((getWidgetForPaintable().isHorizontal() && getWidgetForPaintable()
+ .isDynamicHeight())
+ || (getWidgetForPaintable().isVertical() && getWidgetForPaintable()
+ .isDynamicWidth())) {
+ getWidgetForPaintable().layoutSizeMightHaveChanged();
+ }
+ // w.mark("Layout dimensions updated");
+
+ /* Update component spacing */
+ getWidgetForPaintable().updateContainerMargins();
+
+ /*
+ * Update component sizes for components with relative size in non-main
+ * direction
+ */
+ if (getWidgetForPaintable().updateRelativeSizesInNonMainDirection()) {
+ // Sizes updated - might affect the other dimension so we need to
+ // recheck the widget sizes and recalculate layout dimensions
+ getWidgetForPaintable().updateWidgetSizes();
+ getWidgetForPaintable().layoutSizeMightHaveChanged();
+ }
+ getWidgetForPaintable().calculateAlignments();
+ // w.mark("recalculateComponentSizesAndAlignments done");
+
+ getWidgetForPaintable().setRootSize();
+
+ if (BrowserInfo.get().isIE()) {
+ /*
+ * This should fix the issue with padding not always taken into
+ * account for the containers leading to no spacing between
+ * elements.
+ */
+ getWidgetForPaintable().root.getStyle().setProperty("zoom", "1");
+ }
+
+ // w.mark("runDescendentsLayout done");
+ getWidgetForPaintable().isRendering = false;
+ getWidgetForPaintable().sizeHasChangedDuringRendering = false;
+ }
+
+ @Override
+ protected abstract VOrderedLayout createWidget();
+
+ @Override
+ public VOrderedLayout getWidgetForPaintable() {
+ return (VOrderedLayout) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
index 354a42c4d5..82b362a385 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
@@ -432,8 +432,4 @@ public class VPanel extends SimplePanel implements Container,
return shortcutHandler;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
index 198d7f4020..df4554ea5e 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
@@ -1,175 +1,178 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VPanelPaintable extends VAbstractPaintableWidgetContainer {
-
- public static final String CLICK_EVENT_IDENTIFIER = "click";
-
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
- if (!uidl.hasAttribute("cached")) {
-
- // Handle caption displaying and style names, prior generics.
- // Affects size
- // calculations
-
- // Restore default stylenames
- getWidgetForPaintable().contentNode.setClassName(VPanel.CLASSNAME
- + "-content");
- getWidgetForPaintable().bottomDecoration
- .setClassName(VPanel.CLASSNAME + "-deco");
- getWidgetForPaintable().captionNode.setClassName(VPanel.CLASSNAME
- + "-caption");
- boolean hasCaption = false;
- if (uidl.hasAttribute("caption")
- && !uidl.getStringAttribute("caption").equals("")) {
- getWidgetForPaintable().setCaption(
- uidl.getStringAttribute("caption"));
- hasCaption = true;
- } else {
- getWidgetForPaintable().setCaption("");
- getWidgetForPaintable().captionNode
- .setClassName(VPanel.CLASSNAME + "-nocaption");
- }
-
- // Add proper stylenames for all elements. This way we can prevent
- // unwanted CSS selector inheritance.
- if (uidl.hasAttribute("style")) {
- final String[] styles = uidl.getStringAttribute("style").split(
- " ");
- final String captionBaseClass = VPanel.CLASSNAME
- + (hasCaption ? "-caption" : "-nocaption");
- final String contentBaseClass = VPanel.CLASSNAME + "-content";
- final String decoBaseClass = VPanel.CLASSNAME + "-deco";
- String captionClass = captionBaseClass;
- String contentClass = contentBaseClass;
- String decoClass = decoBaseClass;
- for (int i = 0; i < styles.length; i++) {
- captionClass += " " + captionBaseClass + "-" + styles[i];
- contentClass += " " + contentBaseClass + "-" + styles[i];
- decoClass += " " + decoBaseClass + "-" + styles[i];
- }
- getWidgetForPaintable().captionNode.setClassName(captionClass);
- getWidgetForPaintable().contentNode.setClassName(contentClass);
- getWidgetForPaintable().bottomDecoration
- .setClassName(decoClass);
-
- }
- }
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, false)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- getWidgetForPaintable().setIconUri(uidl, client);
-
- getWidgetForPaintable().handleError(uidl);
-
- // Render content
- final UIDL layoutUidl = uidl.getChildUIDL(0);
- final VPaintableWidget newLayout = client.getPaintable(layoutUidl);
- if (newLayout != getWidgetForPaintable().layout) {
- if (getWidgetForPaintable().layout != null) {
- client.unregisterPaintable(getWidgetForPaintable().layout);
- }
- getWidgetForPaintable()
- .setWidget(newLayout.getWidgetForPaintable());
- getWidgetForPaintable().layout = newLayout;
- }
- getWidgetForPaintable().layout.updateFromUIDL(layoutUidl, client);
-
- // We may have actions attached to this panel
- if (uidl.getChildCount() > 1) {
- final int cnt = uidl.getChildCount();
- for (int i = 1; i < cnt; i++) {
- UIDL childUidl = uidl.getChildUIDL(i);
- if (childUidl.getTag().equals("actions")) {
- if (getWidgetForPaintable().shortcutHandler == null) {
- getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
- getId(), client);
- }
- getWidgetForPaintable().shortcutHandler
- .updateActionMap(childUidl);
- }
- }
- }
-
- if (uidl.hasVariable("scrollTop")
- && uidl.getIntVariable("scrollTop") != getWidgetForPaintable().scrollTop) {
- getWidgetForPaintable().scrollTop = uidl
- .getIntVariable("scrollTop");
- getWidgetForPaintable().contentNode
- .setScrollTop(getWidgetForPaintable().scrollTop);
- // re-read the actual scrollTop in case invalid value was set
- // (scrollTop != 0 when no scrollbar exists, other values would be
- // caught by scroll listener), see #3784
- getWidgetForPaintable().scrollTop = getWidgetForPaintable().contentNode
- .getScrollTop();
- }
-
- if (uidl.hasVariable("scrollLeft")
- && uidl.getIntVariable("scrollLeft") != getWidgetForPaintable().scrollLeft) {
- getWidgetForPaintable().scrollLeft = uidl
- .getIntVariable("scrollLeft");
- getWidgetForPaintable().contentNode
- .setScrollLeft(getWidgetForPaintable().scrollLeft);
- // re-read the actual scrollTop in case invalid value was set
- // (scrollTop != 0 when no scrollbar exists, other values would be
- // caught by scroll listener), see #3784
- getWidgetForPaintable().scrollLeft = getWidgetForPaintable().contentNode
- .getScrollLeft();
- }
-
- // Must be run after scrollTop is set as Webkit overflow fix re-sets the
- // scrollTop
- getWidgetForPaintable().runHacks(false);
-
- // And apply tab index
- if (uidl.hasVariable("tabindex")) {
- getWidgetForPaintable().contentNode.setTabIndex(uidl
- .getIntVariable("tabindex"));
- }
-
- getWidgetForPaintable().rendering = false;
-
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP: layouts caption, errors etc not rendered in Panel
- }
-
- @Override
- public VPanel getWidgetForPaintable() {
- return (VPanel) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VPanel.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VPanelPaintable extends VAbstractPaintableWidgetContainer {
+
+ public static final String CLICK_EVENT_IDENTIFIER = "click";
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ if (!uidl.hasAttribute("cached")) {
+
+ // Handle caption displaying and style names, prior generics.
+ // Affects size
+ // calculations
+
+ // Restore default stylenames
+ getWidgetForPaintable().contentNode.setClassName(VPanel.CLASSNAME
+ + "-content");
+ getWidgetForPaintable().bottomDecoration
+ .setClassName(VPanel.CLASSNAME + "-deco");
+ getWidgetForPaintable().captionNode.setClassName(VPanel.CLASSNAME
+ + "-caption");
+ boolean hasCaption = false;
+ if (uidl.hasAttribute("caption")
+ && !uidl.getStringAttribute("caption").equals("")) {
+ getWidgetForPaintable().setCaption(
+ uidl.getStringAttribute("caption"));
+ hasCaption = true;
+ } else {
+ getWidgetForPaintable().setCaption("");
+ getWidgetForPaintable().captionNode
+ .setClassName(VPanel.CLASSNAME + "-nocaption");
+ }
+
+ // Add proper stylenames for all elements. This way we can prevent
+ // unwanted CSS selector inheritance.
+ if (uidl.hasAttribute("style")) {
+ final String[] styles = uidl.getStringAttribute("style").split(
+ " ");
+ final String captionBaseClass = VPanel.CLASSNAME
+ + (hasCaption ? "-caption" : "-nocaption");
+ final String contentBaseClass = VPanel.CLASSNAME + "-content";
+ final String decoBaseClass = VPanel.CLASSNAME + "-deco";
+ String captionClass = captionBaseClass;
+ String contentClass = contentBaseClass;
+ String decoClass = decoBaseClass;
+ for (int i = 0; i < styles.length; i++) {
+ captionClass += " " + captionBaseClass + "-" + styles[i];
+ contentClass += " " + contentBaseClass + "-" + styles[i];
+ decoClass += " " + decoBaseClass + "-" + styles[i];
+ }
+ getWidgetForPaintable().captionNode.setClassName(captionClass);
+ getWidgetForPaintable().contentNode.setClassName(contentClass);
+ getWidgetForPaintable().bottomDecoration
+ .setClassName(decoClass);
+
+ }
+ }
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ getWidgetForPaintable().setIconUri(uidl, client);
+
+ getWidgetForPaintable().handleError(uidl);
+
+ // Render content
+ final UIDL layoutUidl = uidl.getChildUIDL(0);
+ final VPaintableWidget newLayout = client.getPaintable(layoutUidl);
+ if (newLayout != getWidgetForPaintable().layout) {
+ if (getWidgetForPaintable().layout != null) {
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ }
+ getWidgetForPaintable()
+ .setWidget(newLayout.getWidgetForPaintable());
+ getWidgetForPaintable().layout = newLayout;
+ }
+ getWidgetForPaintable().layout.updateFromUIDL(layoutUidl, client);
+
+ // We may have actions attached to this panel
+ if (uidl.getChildCount() > 1) {
+ final int cnt = uidl.getChildCount();
+ for (int i = 1; i < cnt; i++) {
+ UIDL childUidl = uidl.getChildUIDL(i);
+ if (childUidl.getTag().equals("actions")) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ }
+ }
+
+ if (uidl.hasVariable("scrollTop")
+ && uidl.getIntVariable("scrollTop") != getWidgetForPaintable().scrollTop) {
+ getWidgetForPaintable().scrollTop = uidl
+ .getIntVariable("scrollTop");
+ getWidgetForPaintable().contentNode
+ .setScrollTop(getWidgetForPaintable().scrollTop);
+ // re-read the actual scrollTop in case invalid value was set
+ // (scrollTop != 0 when no scrollbar exists, other values would be
+ // caught by scroll listener), see #3784
+ getWidgetForPaintable().scrollTop = getWidgetForPaintable().contentNode
+ .getScrollTop();
+ }
+
+ if (uidl.hasVariable("scrollLeft")
+ && uidl.getIntVariable("scrollLeft") != getWidgetForPaintable().scrollLeft) {
+ getWidgetForPaintable().scrollLeft = uidl
+ .getIntVariable("scrollLeft");
+ getWidgetForPaintable().contentNode
+ .setScrollLeft(getWidgetForPaintable().scrollLeft);
+ // re-read the actual scrollTop in case invalid value was set
+ // (scrollTop != 0 when no scrollbar exists, other values would be
+ // caught by scroll listener), see #3784
+ getWidgetForPaintable().scrollLeft = getWidgetForPaintable().contentNode
+ .getScrollLeft();
+ }
+
+ // Must be run after scrollTop is set as Webkit overflow fix re-sets the
+ // scrollTop
+ getWidgetForPaintable().runHacks(false);
+
+ // And apply tab index
+ if (uidl.hasVariable("tabindex")) {
+ getWidgetForPaintable().contentNode.setTabIndex(uidl
+ .getIntVariable("tabindex"));
+ }
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP: layouts caption, errors etc not rendered in Panel
+ }
+
+ @Override
+ public VPanel getWidgetForPaintable() {
+ return (VPanel) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPanel.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java b/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
index 945f0d85e6..5182457067 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
@@ -1,21 +1,21 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.DOM;
-
-/**
- * This class represents a password field.
- *
- * @author Vaadin Ltd.
- *
- */
-public class VPasswordField extends VTextField {
-
- public VPasswordField() {
- super(DOM.createInputPassword());
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.DOM;
+
+/**
+ * This class represents a password field.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class VPasswordField extends VTextField {
+
+ public VPasswordField() {
+ super(DOM.createInputPassword());
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
index 223e13c8d7..1c0b937e05 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
@@ -1,378 +1,378 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
-
-/**
- * Represents a date selection component with a text field and a popup date
- * selector.
- *
- * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
- * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
- * and then pass set it by calling the
- * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
- *
- */
-public class VPopupCalendar extends VTextualDate implements Field,
- ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
-
- protected static final String POPUP_PRIMARY_STYLE_NAME = VDateField.CLASSNAME
- + "-popup";
-
- protected final Button calendarToggle;
-
- protected VCalendarPanel calendar;
-
- protected final VOverlay popup;
- private boolean open = false;
- protected boolean parsable = true;
-
- public VPopupCalendar() {
- super();
-
- calendarToggle = new Button();
- calendarToggle.setStyleName(CLASSNAME + "-button");
- calendarToggle.setText("");
- calendarToggle.addClickHandler(this);
- // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
- calendarToggle.getElement().setTabIndex(-2);
- add(calendarToggle);
-
- calendar = GWT.create(VCalendarPanel.class);
- calendar.setFocusOutListener(new FocusOutListener() {
- public boolean onFocusOut(DomEvent<?> event) {
- event.preventDefault();
- closeCalendarPanel();
- return true;
- }
- });
-
- calendar.setSubmitListener(new SubmitListener() {
- public void onSubmit() {
- // Update internal value and send valuechange event if immediate
- updateValue(calendar.getDate());
-
- // Update text field (a must when not immediate).
- buildDate(true);
-
- closeCalendarPanel();
- }
-
- public void onCancel() {
- closeCalendarPanel();
- }
- });
-
- popup = new VOverlay(true, true, true);
- popup.setStyleName(POPUP_PRIMARY_STYLE_NAME);
- popup.setWidget(calendar);
- popup.addCloseHandler(this);
-
- DOM.setElementProperty(calendar.getElement(), "id",
- "PID_VAADIN_POPUPCAL");
-
- sinkEvents(Event.ONKEYDOWN);
-
- }
-
- @SuppressWarnings("deprecation")
- protected void updateValue(Date newDate) {
- Date currentDate = getCurrentDate();
- if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
- setCurrentDate((Date) newDate.clone());
- getClient().updateVariable(getId(), "year",
- newDate.getYear() + 1900, false);
- if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
- getClient().updateVariable(getId(), "month",
- newDate.getMonth() + 1, false);
- if (getCurrentResolution() > RESOLUTION_MONTH) {
- getClient().updateVariable(getId(), "day",
- newDate.getDate(), false);
- if (getCurrentResolution() > RESOLUTION_DAY) {
- getClient().updateVariable(getId(), "hour",
- newDate.getHours(), false);
- if (getCurrentResolution() > RESOLUTION_HOUR) {
- getClient().updateVariable(getId(), "min",
- newDate.getMinutes(), false);
- if (getCurrentResolution() > RESOLUTION_MIN) {
- getClient().updateVariable(getId(), "sec",
- newDate.getSeconds(), false);
- }
- }
- }
- }
- }
- if (isImmediate()) {
- getClient().sendPendingVariableChanges();
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
- */
- @Override
- public void setStyleName(String style) {
- // make sure the style is there before size calculation
- super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
- }
-
- /**
- * Opens the calendar panel popup
- */
- public void openCalendarPanel() {
-
- if (!open && !readonly) {
- open = true;
-
- if (getCurrentDate() != null) {
- calendar.setDate((Date) getCurrentDate().clone());
- } else {
- calendar.setDate(new Date());
- }
-
- // clear previous values
- popup.setWidth("");
- popup.setHeight("");
- popup.setPopupPositionAndShow(new PositionCallback() {
- public void setPosition(int offsetWidth, int offsetHeight) {
- final int w = offsetWidth;
- final int h = offsetHeight;
- final int browserWindowWidth = Window.getClientWidth()
- + Window.getScrollLeft();
- final int browserWindowHeight = Window.getClientHeight()
- + Window.getScrollTop();
- int t = calendarToggle.getAbsoluteTop();
- int l = calendarToggle.getAbsoluteLeft();
-
- // Add a little extra space to the right to avoid
- // problems with IE7 scrollbars and to make it look
- // nicer.
- int extraSpace = 30;
-
- boolean overflowRight = false;
- if (l + +w + extraSpace > browserWindowWidth) {
- overflowRight = true;
- // Part of the popup is outside the browser window
- // (to the right)
- l = browserWindowWidth - w - extraSpace;
- }
-
- if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
- // Part of the popup is outside the browser window
- // (below)
- t = browserWindowHeight - h
- - calendarToggle.getOffsetHeight() - 30;
- if (!overflowRight) {
- // Show to the right of the popup button unless we
- // are in the lower right corner of the screen
- l += calendarToggle.getOffsetWidth();
- }
- }
-
- // fix size
- popup.setWidth(w + "px");
- popup.setHeight(h + "px");
-
- popup.setPopupPosition(l,
- t + calendarToggle.getOffsetHeight() + 2);
-
- /*
- * We have to wait a while before focusing since the popup
- * needs to be opened before we can focus
- */
- Timer focusTimer = new Timer() {
- @Override
- public void run() {
- setFocus(true);
- }
- };
-
- focusTimer.schedule(100);
- }
- });
- } else {
- VConsole.error("Cannot reopen popup, it is already open!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
- * .dom.client.ClickEvent)
- */
- public void onClick(ClickEvent event) {
- if (event.getSource() == calendarToggle && isEnabled()) {
- openCalendarPanel();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
- * .event.logical.shared.CloseEvent)
- */
- public void onClose(CloseEvent<PopupPanel> event) {
- if (event.getSource() == popup) {
- buildDate();
- if (!BrowserInfo.get().isTouchDevice()) {
- /*
- * Move focus to textbox, unless on touch device (avoids opening
- * virtual keyboard).
- */
- focus();
- }
-
- // TODO resolve what the "Sigh." is all about and document it here
- // Sigh.
- Timer t = new Timer() {
- @Override
- public void run() {
- open = false;
- }
- };
- t.schedule(100);
- }
- }
-
- /**
- * Sets focus to Calendar panel.
- *
- * @param focus
- */
- public void setFocus(boolean focus) {
- calendar.setFocus(focus);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
- */
- @Override
- protected int getFieldExtraWidth() {
- if (fieldExtraWidth < 0) {
- fieldExtraWidth = super.getFieldExtraWidth();
- fieldExtraWidth += calendarToggle.getOffsetWidth();
- }
- return fieldExtraWidth;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
- */
- @Override
- protected void buildDate() {
- // Save previous value
- String previousValue = getText();
- super.buildDate();
-
- // Restore previous value if the input could not be parsed
- if (!parsable) {
- setText(previousValue);
- }
- }
-
- /**
- * Update the text field contents from the date. See {@link #buildDate()}.
- *
- * @param forceValid
- * true to force the text field to be updated, false to only
- * update if the parsable flag is true.
- */
- protected void buildDate(boolean forceValid) {
- if (forceValid) {
- parsable = true;
- }
- buildDate();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
- * .gwt.user.client.Event)
- */
- @Override
- public void onBrowserEvent(com.google.gwt.user.client.Event event) {
- super.onBrowserEvent(event);
- if (DOM.eventGetType(event) == Event.ONKEYDOWN
- && event.getKeyCode() == getOpenCalenderPanelKey()) {
- openCalendarPanel();
- event.preventDefault();
- }
- }
-
- /**
- * Get the key code that opens the calendar panel. By default it is the down
- * key but you can override this to be whatever you like
- *
- * @return
- */
- protected int getOpenCalenderPanelKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * Closes the open popup panel
- */
- public void closeCalendarPanel() {
- if (open) {
- popup.hide(true);
- }
- }
-
- private final String CALENDAR_TOGGLE_ID = "popupButton";
-
- @Override
- public Element getSubPartElement(String subPart) {
- if (subPart.equals(CALENDAR_TOGGLE_ID)) {
- return calendarToggle.getElement();
- }
-
- return super.getSubPartElement(subPart);
- }
-
- @Override
- public String getSubPartName(Element subElement) {
- if (calendarToggle.getElement().isOrHasChild(subElement)) {
- return CALENDAR_TOGGLE_ID;
- }
-
- return super.getSubPartName(subElement);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
+
+/**
+ * Represents a date selection component with a text field and a popup date
+ * selector.
+ *
+ * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
+ * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
+ * and then pass set it by calling the
+ * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
+ *
+ */
+public class VPopupCalendar extends VTextualDate implements Field,
+ ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
+
+ protected static final String POPUP_PRIMARY_STYLE_NAME = VDateField.CLASSNAME
+ + "-popup";
+
+ protected final Button calendarToggle;
+
+ protected VCalendarPanel calendar;
+
+ protected final VOverlay popup;
+ private boolean open = false;
+ protected boolean parsable = true;
+
+ public VPopupCalendar() {
+ super();
+
+ calendarToggle = new Button();
+ calendarToggle.setStyleName(CLASSNAME + "-button");
+ calendarToggle.setText("");
+ calendarToggle.addClickHandler(this);
+ // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
+ calendarToggle.getElement().setTabIndex(-2);
+ add(calendarToggle);
+
+ calendar = GWT.create(VCalendarPanel.class);
+ calendar.setFocusOutListener(new FocusOutListener() {
+ public boolean onFocusOut(DomEvent<?> event) {
+ event.preventDefault();
+ closeCalendarPanel();
+ return true;
+ }
+ });
+
+ calendar.setSubmitListener(new SubmitListener() {
+ public void onSubmit() {
+ // Update internal value and send valuechange event if immediate
+ updateValue(calendar.getDate());
+
+ // Update text field (a must when not immediate).
+ buildDate(true);
+
+ closeCalendarPanel();
+ }
+
+ public void onCancel() {
+ closeCalendarPanel();
+ }
+ });
+
+ popup = new VOverlay(true, true, true);
+ popup.setStyleName(POPUP_PRIMARY_STYLE_NAME);
+ popup.setWidget(calendar);
+ popup.addCloseHandler(this);
+
+ DOM.setElementProperty(calendar.getElement(), "id",
+ "PID_VAADIN_POPUPCAL");
+
+ sinkEvents(Event.ONKEYDOWN);
+
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void updateValue(Date newDate) {
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) newDate.clone());
+ getClient().updateVariable(getId(), "year",
+ newDate.getYear() + 1900, false);
+ if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
+ getClient().updateVariable(getId(), "month",
+ newDate.getMonth() + 1, false);
+ if (getCurrentResolution() > RESOLUTION_MONTH) {
+ getClient().updateVariable(getId(), "day",
+ newDate.getDate(), false);
+ if (getCurrentResolution() > RESOLUTION_DAY) {
+ getClient().updateVariable(getId(), "hour",
+ newDate.getHours(), false);
+ if (getCurrentResolution() > RESOLUTION_HOUR) {
+ getClient().updateVariable(getId(), "min",
+ newDate.getMinutes(), false);
+ if (getCurrentResolution() > RESOLUTION_MIN) {
+ getClient().updateVariable(getId(), "sec",
+ newDate.getSeconds(), false);
+ }
+ }
+ }
+ }
+ }
+ if (isImmediate()) {
+ getClient().sendPendingVariableChanges();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
+ */
+ @Override
+ public void setStyleName(String style) {
+ // make sure the style is there before size calculation
+ super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
+ }
+
+ /**
+ * Opens the calendar panel popup
+ */
+ public void openCalendarPanel() {
+
+ if (!open && !readonly) {
+ open = true;
+
+ if (getCurrentDate() != null) {
+ calendar.setDate((Date) getCurrentDate().clone());
+ } else {
+ calendar.setDate(new Date());
+ }
+
+ // clear previous values
+ popup.setWidth("");
+ popup.setHeight("");
+ popup.setPopupPositionAndShow(new PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ final int w = offsetWidth;
+ final int h = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int browserWindowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
+ int t = calendarToggle.getAbsoluteTop();
+ int l = calendarToggle.getAbsoluteLeft();
+
+ // Add a little extra space to the right to avoid
+ // problems with IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflowRight = false;
+ if (l + +w + extraSpace > browserWindowWidth) {
+ overflowRight = true;
+ // Part of the popup is outside the browser window
+ // (to the right)
+ l = browserWindowWidth - w - extraSpace;
+ }
+
+ if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
+ // Part of the popup is outside the browser window
+ // (below)
+ t = browserWindowHeight - h
+ - calendarToggle.getOffsetHeight() - 30;
+ if (!overflowRight) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ l += calendarToggle.getOffsetWidth();
+ }
+ }
+
+ // fix size
+ popup.setWidth(w + "px");
+ popup.setHeight(h + "px");
+
+ popup.setPopupPosition(l,
+ t + calendarToggle.getOffsetHeight() + 2);
+
+ /*
+ * We have to wait a while before focusing since the popup
+ * needs to be opened before we can focus
+ */
+ Timer focusTimer = new Timer() {
+ @Override
+ public void run() {
+ setFocus(true);
+ }
+ };
+
+ focusTimer.schedule(100);
+ }
+ });
+ } else {
+ VConsole.error("Cannot reopen popup, it is already open!");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
+ * .dom.client.ClickEvent)
+ */
+ public void onClick(ClickEvent event) {
+ if (event.getSource() == calendarToggle && isEnabled()) {
+ openCalendarPanel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
+ * .event.logical.shared.CloseEvent)
+ */
+ public void onClose(CloseEvent<PopupPanel> event) {
+ if (event.getSource() == popup) {
+ buildDate();
+ if (!BrowserInfo.get().isTouchDevice()) {
+ /*
+ * Move focus to textbox, unless on touch device (avoids opening
+ * virtual keyboard).
+ */
+ focus();
+ }
+
+ // TODO resolve what the "Sigh." is all about and document it here
+ // Sigh.
+ Timer t = new Timer() {
+ @Override
+ public void run() {
+ open = false;
+ }
+ };
+ t.schedule(100);
+ }
+ }
+
+ /**
+ * Sets focus to Calendar panel.
+ *
+ * @param focus
+ */
+ public void setFocus(boolean focus) {
+ calendar.setFocus(focus);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
+ */
+ @Override
+ protected int getFieldExtraWidth() {
+ if (fieldExtraWidth < 0) {
+ fieldExtraWidth = super.getFieldExtraWidth();
+ fieldExtraWidth += calendarToggle.getOffsetWidth();
+ }
+ return fieldExtraWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
+ */
+ @Override
+ protected void buildDate() {
+ // Save previous value
+ String previousValue = getText();
+ super.buildDate();
+
+ // Restore previous value if the input could not be parsed
+ if (!parsable) {
+ setText(previousValue);
+ }
+ }
+
+ /**
+ * Update the text field contents from the date. See {@link #buildDate()}.
+ *
+ * @param forceValid
+ * true to force the text field to be updated, false to only
+ * update if the parsable flag is true.
+ */
+ protected void buildDate(boolean forceValid) {
+ if (forceValid) {
+ parsable = true;
+ }
+ buildDate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
+ * .gwt.user.client.Event)
+ */
+ @Override
+ public void onBrowserEvent(com.google.gwt.user.client.Event event) {
+ super.onBrowserEvent(event);
+ if (DOM.eventGetType(event) == Event.ONKEYDOWN
+ && event.getKeyCode() == getOpenCalenderPanelKey()) {
+ openCalendarPanel();
+ event.preventDefault();
+ }
+ }
+
+ /**
+ * Get the key code that opens the calendar panel. By default it is the down
+ * key but you can override this to be whatever you like
+ *
+ * @return
+ */
+ protected int getOpenCalenderPanelKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Closes the open popup panel
+ */
+ public void closeCalendarPanel() {
+ if (open) {
+ popup.hide(true);
+ }
+ }
+
+ private final String CALENDAR_TOGGLE_ID = "popupButton";
+
+ @Override
+ public Element getSubPartElement(String subPart) {
+ if (subPart.equals(CALENDAR_TOGGLE_ID)) {
+ return calendarToggle.getElement();
+ }
+
+ return super.getSubPartElement(subPart);
+ }
+
+ @Override
+ public String getSubPartName(Element subElement) {
+ if (calendarToggle.getElement().isOrHasChild(subElement)) {
+ return CALENDAR_TOGGLE_ID;
+ }
+
+ return super.getSubPartName(subElement);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
index 34bf0ca619..b3acc9a9a7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
@@ -424,8 +424,4 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
};
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}// class VPopupView
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java
index 627f925d77..cd8965ffc6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java
@@ -1,104 +1,107 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VCaption;
-import com.vaadin.terminal.gwt.client.VCaptionWrapper;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VPopupViewPaintable extends VAbstractPaintableWidgetContainer {
-
- /**
- *
- *
- * @see com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
- * com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // This call should be made first. Ensure correct implementation,
- // and don't let the containing layout manage caption.
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
- // These are for future server connections
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().uidlId = uidl.getId();
-
- getWidgetForPaintable().hostPopupVisible = uidl
- .getBooleanVariable("popupVisibility");
-
- getWidgetForPaintable().setHTML(uidl.getStringAttribute("html"));
-
- if (uidl.hasAttribute("hideOnMouseOut")) {
- getWidgetForPaintable().popup.setHideOnMouseOut(uidl
- .getBooleanAttribute("hideOnMouseOut"));
- }
-
- // Render the popup if visible and show it.
- if (getWidgetForPaintable().hostPopupVisible) {
- UIDL popupUIDL = uidl.getChildUIDL(0);
-
- // showPopupOnTop(popup, hostReference);
- getWidgetForPaintable().preparePopup(getWidgetForPaintable().popup);
- getWidgetForPaintable().popup.updateFromUIDL(popupUIDL, client);
- if (uidl.hasAttribute("style")) {
- final String[] styles = uidl.getStringAttribute("style").split(
- " ");
- final StringBuffer styleBuf = new StringBuffer();
- final String primaryName = getWidgetForPaintable().popup
- .getStylePrimaryName();
- styleBuf.append(primaryName);
- for (int i = 0; i < styles.length; i++) {
- styleBuf.append(" ");
- styleBuf.append(primaryName);
- styleBuf.append("-");
- styleBuf.append(styles[i]);
- }
- getWidgetForPaintable().popup.setStyleName(styleBuf.toString());
- } else {
- getWidgetForPaintable().popup
- .setStyleName(getWidgetForPaintable().popup
- .getStylePrimaryName());
- }
- getWidgetForPaintable().showPopup(getWidgetForPaintable().popup);
-
- // The popup shouldn't be visible, try to hide it.
- } else {
- getWidgetForPaintable().popup.hide();
- }
- }// updateFromUIDL
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- if (VCaption.isNeeded(uidl)) {
- if (getWidgetForPaintable().popup.captionWrapper != null) {
- getWidgetForPaintable().popup.captionWrapper
- .updateCaption(uidl);
- } else {
- getWidgetForPaintable().popup.captionWrapper = new VCaptionWrapper(
- component, getConnection());
- getWidgetForPaintable().popup
- .setWidget(getWidgetForPaintable().popup.captionWrapper);
- getWidgetForPaintable().popup.captionWrapper
- .updateCaption(uidl);
- }
- } else {
- if (getWidgetForPaintable().popup.captionWrapper != null) {
- getWidgetForPaintable().popup
- .setWidget(getWidgetForPaintable().popup.popupComponentWidget);
- }
- }
- }
-
- @Override
- public VPopupView getWidgetForPaintable() {
- return (VPopupView) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VPopupView.class);
- }
-
-}
+/*
+ @VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VCaption;
+import com.vaadin.terminal.gwt.client.VCaptionWrapper;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VPopupViewPaintable extends VAbstractPaintableWidgetContainer {
+
+ /**
+ *
+ *
+ * @see com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
+ * com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and don't let the containing layout manage caption.
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+ // These are for future server connections
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().uidlId = uidl.getId();
+
+ getWidgetForPaintable().hostPopupVisible = uidl
+ .getBooleanVariable("popupVisibility");
+
+ getWidgetForPaintable().setHTML(uidl.getStringAttribute("html"));
+
+ if (uidl.hasAttribute("hideOnMouseOut")) {
+ getWidgetForPaintable().popup.setHideOnMouseOut(uidl
+ .getBooleanAttribute("hideOnMouseOut"));
+ }
+
+ // Render the popup if visible and show it.
+ if (getWidgetForPaintable().hostPopupVisible) {
+ UIDL popupUIDL = uidl.getChildUIDL(0);
+
+ // showPopupOnTop(popup, hostReference);
+ getWidgetForPaintable().preparePopup(getWidgetForPaintable().popup);
+ getWidgetForPaintable().popup.updateFromUIDL(popupUIDL, client);
+ if (uidl.hasAttribute("style")) {
+ final String[] styles = uidl.getStringAttribute("style").split(
+ " ");
+ final StringBuffer styleBuf = new StringBuffer();
+ final String primaryName = getWidgetForPaintable().popup
+ .getStylePrimaryName();
+ styleBuf.append(primaryName);
+ for (int i = 0; i < styles.length; i++) {
+ styleBuf.append(" ");
+ styleBuf.append(primaryName);
+ styleBuf.append("-");
+ styleBuf.append(styles[i]);
+ }
+ getWidgetForPaintable().popup.setStyleName(styleBuf.toString());
+ } else {
+ getWidgetForPaintable().popup
+ .setStyleName(getWidgetForPaintable().popup
+ .getStylePrimaryName());
+ }
+ getWidgetForPaintable().showPopup(getWidgetForPaintable().popup);
+
+ // The popup shouldn't be visible, try to hide it.
+ } else {
+ getWidgetForPaintable().popup.hide();
+ }
+ }// updateFromUIDL
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ if (VCaption.isNeeded(uidl)) {
+ if (getWidgetForPaintable().popup.captionWrapper != null) {
+ getWidgetForPaintable().popup.captionWrapper
+ .updateCaption(uidl);
+ } else {
+ getWidgetForPaintable().popup.captionWrapper = new VCaptionWrapper(
+ component, getConnection());
+ getWidgetForPaintable().popup
+ .setWidget(getWidgetForPaintable().popup.captionWrapper);
+ getWidgetForPaintable().popup.captionWrapper
+ .updateCaption(uidl);
+ }
+ } else {
+ if (getWidgetForPaintable().popup.captionWrapper != null) {
+ getWidgetForPaintable().popup
+ .setWidget(getWidgetForPaintable().popup.popupComponentWidget);
+ }
+ }
+ }
+
+ @Override
+ public VPopupView getWidgetForPaintable() {
+ return (VPopupView) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPopupView.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index de68ae96a4..b84fc1312f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -106,7 +106,7 @@ import com.vaadin.terminal.gwt.client.ui.label.VLabel;
*/
public class VScrollTable extends FlowPanel implements HasWidgets,
ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable,
- ActionOwner {
+ ActionOwner, Container {
public enum SelectMode {
NONE(0), SINGLE(1), MULTI(2);
@@ -2150,7 +2150,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.TOUCHEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU | Event.TOUCHEVENTS);
setElement(td);
@@ -2267,8 +2268,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
scrollBodyPanel.setFocus(true);
}
handleCaptionEvent(event);
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasWidgetEventListeners(
+ VScrollTable.this, HEADER_CLICK_EVENT_ID)) {
+ // Prevent showing the browser's context menu only when
+ // there is a header click listener.
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
}
@@ -2325,7 +2336,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
case Event.ONMOUSEDOWN:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHSTART) {
/*
* prevent using this event in e.g. scrolling
@@ -2344,7 +2356,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
case Event.ONMOUSEUP:
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
dragging = false;
DOM.releaseCapture(getElement());
if (moved) {
@@ -2371,7 +2384,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (!moved) {
// mouse event was a click to header -> sort column
- if (sortable) {
+ if (sortable && Util.isTouchEventOrLeftMouseButton(event)) {
if (sortColumn.equals(cid)) {
// just toggle order
client.updateVariable(paintableId, "sortascending",
@@ -2404,9 +2417,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
break;
}
break;
+ case Event.ONDBLCLICK:
+ fireHeaderClickedEvent(event);
+ break;
case Event.ONTOUCHMOVE:
case Event.ONMOUSEMOVE:
- if (dragging) {
+ if (dragging && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHMOVE) {
/*
* prevent using this event in e.g. scrolling
@@ -2452,6 +2468,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private void onResizeEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = true;
DOM.setCapture(getElement());
dragStartX = DOM.eventGetClientX(event);
@@ -2460,6 +2479,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.eventPreventDefault(event);
break;
case Event.ONMOUSEUP:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = false;
DOM.releaseCapture(getElement());
tHead.disableAutoColumnWidthCalculation(this);
@@ -2474,6 +2496,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
fireColumnResizeEvent(cid, originalWidth, getColWidth(cid));
break;
case Event.ONMOUSEMOVE:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
if (isResizing) {
final int deltaX = DOM.eventGetClientX(event) - dragStartX;
if (deltaX == 0) {
@@ -3133,7 +3158,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU);
setElement(td);
}
@@ -3318,8 +3344,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
scrollBodyPanel.setFocus(true);
}
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasWidgetEventListeners(VScrollTable.this,
+ FOOTER_CLICK_EVENT_ID)) {
+ // Show browser context menu if a footer click listener is
+ // not present
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
@@ -3330,7 +3366,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* The event to handle
*/
protected void handleCaptionEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
+ if (event.getTypeInt() == Event.ONMOUSEUP
+ || event.getTypeInt() == Event.ONDBLCLICK) {
fireFooterClickedEvent(event);
}
}
@@ -4310,8 +4347,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- public class VScrollTableRow extends Panel implements ActionOwner,
- Container {
+ public class VScrollTableRow extends Panel implements ActionOwner {
private static final int TOUCHSCROLL_TIMEOUT = 70;
private static final int DRAGMODE_MULTIROW = 2;
@@ -4540,6 +4576,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.get(client).getPaintable(uidl.getId());
paintable.updateFromUIDL(uidl, client);
}
+ pendingComponentPaints.clear();
}
}
@@ -5267,29 +5304,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return paintableId;
}
- public RenderSpace getAllocatedSpace(Widget child) {
- int w = 0;
- int i = getColIndexOf(child);
- HeaderCell headerCell = tHead.getHeaderCell(i);
- if (headerCell != null) {
- if (initializedAndAttached) {
- w = headerCell.getWidth();
- } else {
- // header offset width is not absolutely correct value,
- // but a best guess (expecting similar content in all
- // columns ->
- // if one component is relative width so are others)
- w = headerCell.getOffsetWidth() - getCellExtraWidth();
- }
- }
- return new RenderSpace(w, 0) {
- @Override
- public int getHeight() {
- return (int) getRowHeight();
- }
- };
- }
-
private int getColIndexOf(Widget child) {
com.google.gwt.dom.client.Element widgetCell = child
.getElement().getParentElement().getParentElement();
@@ -5319,16 +5333,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
- public boolean requestLayout(Set<Widget> children) {
- // row size should never change and system wouldn't event
- // survive as this is a kind of fake paitable
- return true;
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, not rendered
- }
-
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
// Should never be called,
// Component container interface faked here to get layouts
@@ -6694,4 +6698,45 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return this;
}
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ VScrollTableRow row = (VScrollTableRow) oldComponent.getParent();
+ row.replaceChildComponent(oldComponent, newComponent);
+
+ }
+
+ public boolean hasChildComponent(Widget child) {
+ VScrollTableRow row = (VScrollTableRow) child.getParent();
+ return row.hasChildComponent(child);
+ }
+
+ public boolean requestLayout(Set<Widget> children) {
+ // row size should never change
+ return true;
+ }
+
+ public RenderSpace getAllocatedSpace(Widget child) {
+ // Called by widgets attached to a row
+ VScrollTableRow row = (VScrollTableRow) child.getParent();
+ int w = 0;
+ int i = row.getColIndexOf(child);
+ HeaderCell headerCell = tHead.getHeaderCell(i);
+ if (headerCell != null) {
+ if (initializedAndAttached) {
+ w = headerCell.getWidth();
+ } else {
+ // header offset width is not absolutely correct value,
+ // but a best guess (expecting similar content in all
+ // columns ->
+ // if one component is relative width so are others)
+ w = headerCell.getOffsetWidth()
+ - scrollBody.getCellExtraWidth();
+ }
+ }
+ return new RenderSpace(w, 0) {
+ @Override
+ public int getHeight() {
+ return (int) scrollBody.getRowHeight();
+ }
+ };
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
index fa7cc3d4ec..058b8f15b3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
@@ -1,254 +1,260 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.dom.client.Style.Position;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class VScrollTablePaintable extends VAbstractPaintableWidget {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
- * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {
- getWidgetForPaintable().serverCacheFirst = uidl
- .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);
- getWidgetForPaintable().serverCacheLast = uidl
- .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);
- } else {
- getWidgetForPaintable().serverCacheFirst = -1;
- getWidgetForPaintable().serverCacheLast = -1;
- }
- /*
- * We need to do this before updateComponent since updateComponent calls
- * this.setHeight() which will calculate a new body height depending on
- * the space available.
- */
- if (uidl.hasAttribute("colfooters")) {
- getWidgetForPaintable().showColFooters = uidl
- .getBooleanAttribute("colfooters");
- }
-
- getWidgetForPaintable().tFoot
- .setVisible(getWidgetForPaintable().showColFooters);
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
-
- if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {
- /*
- * The disabled shim will not cover the table body if it is relative
- * in IE8. See #7324
- */
- getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.STATIC);
- } else if (BrowserInfo.get().isIE8()) {
- getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.RELATIVE);
- }
-
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
-
- int previousTotalRows = getWidgetForPaintable().totalRows;
- getWidgetForPaintable().updateTotalRows(uidl);
- boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);
-
- getWidgetForPaintable().updateDragMode(uidl);
-
- getWidgetForPaintable().updateSelectionProperties(uidl);
-
- if (uidl.hasAttribute("alb")) {
- getWidgetForPaintable().bodyActionKeys = uidl
- .getStringArrayAttribute("alb");
- } else {
- // Need to clear the actions if the action handlers have been
- // removed
- getWidgetForPaintable().bodyActionKeys = null;
- }
-
- getWidgetForPaintable().setCacheRateFromUIDL(uidl);
-
- getWidgetForPaintable().recalcWidths = uidl
- .hasAttribute("recalcWidths");
- if (getWidgetForPaintable().recalcWidths) {
- getWidgetForPaintable().tHead.clear();
- getWidgetForPaintable().tFoot.clear();
- }
-
- getWidgetForPaintable().updatePageLength(uidl);
-
- getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);
-
- getWidgetForPaintable().showRowHeaders = uidl
- .getBooleanAttribute("rowheaders");
- getWidgetForPaintable().showColHeaders = uidl
- .getBooleanAttribute("colheaders");
-
- getWidgetForPaintable().updateSortingProperties(uidl);
-
- boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()
- .selectSelectedRows(uidl);
-
- getWidgetForPaintable().updateActionMap(uidl);
-
- getWidgetForPaintable().updateColumnProperties(uidl);
-
- UIDL ac = uidl.getChildByTagName("-ac");
- if (ac == null) {
- if (getWidgetForPaintable().dropHandler != null) {
- // remove dropHandler if not present anymore
- getWidgetForPaintable().dropHandler = null;
- }
- } else {
- if (getWidgetForPaintable().dropHandler == null) {
- getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();
- }
- getWidgetForPaintable().dropHandler.updateAcceptRules(ac);
- }
-
- UIDL partialRowAdditions = uidl.getChildByTagName("prows");
- UIDL partialRowUpdates = uidl.getChildByTagName("urows");
- if (partialRowUpdates != null || partialRowAdditions != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- getWidgetForPaintable().rowRequestHandler.cancel();
-
- getWidgetForPaintable().updateRowsInBody(partialRowUpdates);
- getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);
- } else {
- UIDL rowData = uidl.getChildByTagName("rows");
- if (rowData != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- getWidgetForPaintable().rowRequestHandler.cancel();
-
- if (!getWidgetForPaintable().recalcWidths
- && getWidgetForPaintable().initializedAndAttached) {
- getWidgetForPaintable().updateBody(rowData,
- uidl.getIntAttribute("firstrow"),
- uidl.getIntAttribute("rows"));
- if (getWidgetForPaintable().headerChangedDuringUpdate) {
- getWidgetForPaintable().triggerLazyColumnAdjustment(
- true);
- } else if (!getWidgetForPaintable()
- .isScrollPositionVisible()
- || totalRowsChanged
- || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody
- .getOffsetHeight()) {
- // webkits may still bug with their disturbing scrollbar
- // bug, see #3457
- // Run overflow fix for the scrollable area
- // #6698 - If there's a scroll going on, don't abort it
- // by changing overflows as the length of the contents
- // *shouldn't* have changed (unless the number of rows
- // or the height of the widget has also changed)
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel
- .getElement());
- }
- });
- }
- } else {
- getWidgetForPaintable().initializeRows(uidl, rowData);
- }
- }
- }
-
- if (!getWidgetForPaintable().isSelectable()) {
- getWidgetForPaintable().scrollBody
- .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");
- } else {
- getWidgetForPaintable().scrollBody
- .removeStyleName(VScrollTable.CLASSNAME
- + "-body-noselection");
- }
-
- getWidgetForPaintable().hideScrollPositionAnnotation();
- getWidgetForPaintable().purgeUnregistryBag();
-
- // selection is no in sync with server, avoid excessive server visits by
- // clearing to flag used during the normal operation
- if (!keyboardSelectionOverRowFetchInProgress) {
- getWidgetForPaintable().selectionChanged = false;
- }
-
- /*
- * This is called when the Home or page up button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (getWidgetForPaintable().selectFirstItemInNextRender
- || getWidgetForPaintable().focusFirstItemInNextRender) {
- getWidgetForPaintable().selectFirstRenderedRowInViewPort(
- getWidgetForPaintable().focusFirstItemInNextRender);
- getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;
- }
-
- /*
- * This is called when the page down or end button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (getWidgetForPaintable().selectLastItemInNextRender
- || getWidgetForPaintable().focusLastItemInNextRender) {
- getWidgetForPaintable().selectLastRenderedRowInViewPort(
- getWidgetForPaintable().focusLastItemInNextRender);
- getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;
- }
- getWidgetForPaintable().multiselectPending = false;
-
- if (getWidgetForPaintable().focusedRow != null) {
- if (!getWidgetForPaintable().focusedRow.isAttached()
- && !getWidgetForPaintable().rowRequestHandler.isRunning()) {
- // focused row has been orphaned, can't focus
- getWidgetForPaintable().focusRowFromBody();
- }
- }
-
- getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl
- .getIntAttribute("tabindex") : 0;
- getWidgetForPaintable().setProperTabIndex();
-
- getWidgetForPaintable().resizeSortedColumnForSortIndicator();
-
- // Remember this to detect situations where overflow hack might be
- // needed during scrolling
- getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody
- .getOffsetHeight();
-
- getWidgetForPaintable().rendering = false;
- getWidgetForPaintable().headerChangedDuringUpdate = false;
-
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VScrollTable.class);
- }
-
- @Override
- public VScrollTable getWidgetForPaintable() {
- return (VScrollTable) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
+ * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {
+ getWidgetForPaintable().serverCacheFirst = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);
+ getWidgetForPaintable().serverCacheLast = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);
+ } else {
+ getWidgetForPaintable().serverCacheFirst = -1;
+ getWidgetForPaintable().serverCacheLast = -1;
+ }
+ /*
+ * We need to do this before updateComponent since updateComponent calls
+ * this.setHeight() which will calculate a new body height depending on
+ * the space available.
+ */
+ if (uidl.hasAttribute("colfooters")) {
+ getWidgetForPaintable().showColFooters = uidl
+ .getBooleanAttribute("colfooters");
+ }
+
+ getWidgetForPaintable().tFoot
+ .setVisible(getWidgetForPaintable().showColFooters);
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
+
+ if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {
+ /*
+ * The disabled shim will not cover the table body if it is relative
+ * in IE8. See #7324
+ */
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.STATIC);
+ } else if (BrowserInfo.get().isIE8()) {
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.RELATIVE);
+ }
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+
+ int previousTotalRows = getWidgetForPaintable().totalRows;
+ getWidgetForPaintable().updateTotalRows(uidl);
+ boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);
+
+ getWidgetForPaintable().updateDragMode(uidl);
+
+ getWidgetForPaintable().updateSelectionProperties(uidl);
+
+ if (uidl.hasAttribute("alb")) {
+ getWidgetForPaintable().bodyActionKeys = uidl
+ .getStringArrayAttribute("alb");
+ } else {
+ // Need to clear the actions if the action handlers have been
+ // removed
+ getWidgetForPaintable().bodyActionKeys = null;
+ }
+
+ getWidgetForPaintable().setCacheRateFromUIDL(uidl);
+
+ getWidgetForPaintable().recalcWidths = uidl
+ .hasAttribute("recalcWidths");
+ if (getWidgetForPaintable().recalcWidths) {
+ getWidgetForPaintable().tHead.clear();
+ getWidgetForPaintable().tFoot.clear();
+ }
+
+ getWidgetForPaintable().updatePageLength(uidl);
+
+ getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);
+
+ getWidgetForPaintable().showRowHeaders = uidl
+ .getBooleanAttribute("rowheaders");
+ getWidgetForPaintable().showColHeaders = uidl
+ .getBooleanAttribute("colheaders");
+
+ getWidgetForPaintable().updateSortingProperties(uidl);
+
+ boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()
+ .selectSelectedRows(uidl);
+
+ getWidgetForPaintable().updateActionMap(uidl);
+
+ getWidgetForPaintable().updateColumnProperties(uidl);
+
+ UIDL ac = uidl.getChildByTagName("-ac");
+ if (ac == null) {
+ if (getWidgetForPaintable().dropHandler != null) {
+ // remove dropHandler if not present anymore
+ getWidgetForPaintable().dropHandler = null;
+ }
+ } else {
+ if (getWidgetForPaintable().dropHandler == null) {
+ getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();
+ }
+ getWidgetForPaintable().dropHandler.updateAcceptRules(ac);
+ }
+
+ UIDL partialRowAdditions = uidl.getChildByTagName("prows");
+ UIDL partialRowUpdates = uidl.getChildByTagName("urows");
+ if (partialRowUpdates != null || partialRowAdditions != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ getWidgetForPaintable().updateRowsInBody(partialRowUpdates);
+ getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);
+ } else {
+ UIDL rowData = uidl.getChildByTagName("rows");
+ if (rowData != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ if (!getWidgetForPaintable().recalcWidths
+ && getWidgetForPaintable().initializedAndAttached) {
+ getWidgetForPaintable().updateBody(rowData,
+ uidl.getIntAttribute("firstrow"),
+ uidl.getIntAttribute("rows"));
+ if (getWidgetForPaintable().headerChangedDuringUpdate) {
+ getWidgetForPaintable().triggerLazyColumnAdjustment(
+ true);
+ } else if (!getWidgetForPaintable()
+ .isScrollPositionVisible()
+ || totalRowsChanged
+ || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody
+ .getOffsetHeight()) {
+ // webkits may still bug with their disturbing scrollbar
+ // bug, see #3457
+ // Run overflow fix for the scrollable area
+ // #6698 - If there's a scroll going on, don't abort it
+ // by changing overflows as the length of the contents
+ // *shouldn't* have changed (unless the number of rows
+ // or the height of the widget has also changed)
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel
+ .getElement());
+ }
+ });
+ }
+ } else {
+ getWidgetForPaintable().initializeRows(uidl, rowData);
+ }
+ }
+ }
+
+ if (!getWidgetForPaintable().isSelectable()) {
+ getWidgetForPaintable().scrollBody
+ .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");
+ } else {
+ getWidgetForPaintable().scrollBody
+ .removeStyleName(VScrollTable.CLASSNAME
+ + "-body-noselection");
+ }
+
+ getWidgetForPaintable().hideScrollPositionAnnotation();
+ getWidgetForPaintable().purgeUnregistryBag();
+
+ // selection is no in sync with server, avoid excessive server visits by
+ // clearing to flag used during the normal operation
+ if (!keyboardSelectionOverRowFetchInProgress) {
+ getWidgetForPaintable().selectionChanged = false;
+ }
+
+ /*
+ * This is called when the Home or page up button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectFirstItemInNextRender
+ || getWidgetForPaintable().focusFirstItemInNextRender) {
+ getWidgetForPaintable().selectFirstRenderedRowInViewPort(
+ getWidgetForPaintable().focusFirstItemInNextRender);
+ getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;
+ }
+
+ /*
+ * This is called when the page down or end button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectLastItemInNextRender
+ || getWidgetForPaintable().focusLastItemInNextRender) {
+ getWidgetForPaintable().selectLastRenderedRowInViewPort(
+ getWidgetForPaintable().focusLastItemInNextRender);
+ getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;
+ }
+ getWidgetForPaintable().multiselectPending = false;
+
+ if (getWidgetForPaintable().focusedRow != null) {
+ if (!getWidgetForPaintable().focusedRow.isAttached()
+ && !getWidgetForPaintable().rowRequestHandler.isRunning()) {
+ // focused row has been orphaned, can't focus
+ getWidgetForPaintable().focusRowFromBody();
+ }
+ }
+
+ getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl
+ .getIntAttribute("tabindex") : 0;
+ getWidgetForPaintable().setProperTabIndex();
+
+ getWidgetForPaintable().resizeSortedColumnForSortIndicator();
+
+ // Remember this to detect situations where overflow hack might be
+ // needed during scrolling
+ getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody
+ .getOffsetHeight();
+
+ getWidgetForPaintable().rendering = false;
+ getWidgetForPaintable().headerChangedDuringUpdate = false;
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VScrollTable.class);
+ }
+
+ @Override
+ public VScrollTable getWidgetForPaintable() {
+ return (VScrollTable) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, not rendered
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
index 9fbbeb7181..d213a3826f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
@@ -1,517 +1,513 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-//
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-
-public class VSlider extends SimpleFocusablePanel implements Field,
- ContainerResizedListener {
-
- public static final String CLASSNAME = "v-slider";
-
- /**
- * Minimum size (width or height, depending on orientation) of the slider
- * base.
- */
- private static final int MIN_SIZE = 50;
-
- ApplicationConnection client;
-
- String id;
-
- boolean immediate;
- boolean disabled;
- boolean readonly;
-
- private int acceleration = 1;
- double min;
- double max;
- int resolution;
- Double value;
- boolean vertical;
-
- private final HTML feedback = new HTML("", false);
- private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
- @Override
- public void show() {
- super.show();
- updateFeedbackPosition();
- }
- };
-
- /* DOM element for slider's base */
- private final Element base;
- private final int BASE_BORDER_WIDTH = 1;
-
- /* DOM element for slider's handle */
- private final Element handle;
-
- /* DOM element for decrement arrow */
- private final Element smaller;
-
- /* DOM element for increment arrow */
- private final Element bigger;
-
- /* Temporary dragging/animation variables */
- private boolean dragging = false;
-
- private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
- new ScheduledCommand() {
-
- public void execute() {
- updateValueToServer();
- acceleration = 1;
- }
- });
-
- public VSlider() {
- super();
-
- base = DOM.createDiv();
- handle = DOM.createDiv();
- smaller = DOM.createDiv();
- bigger = DOM.createDiv();
-
- setStyleName(CLASSNAME);
- DOM.setElementProperty(base, "className", CLASSNAME + "-base");
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
- DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
- DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
-
- DOM.appendChild(getElement(), bigger);
- DOM.appendChild(getElement(), smaller);
- DOM.appendChild(getElement(), base);
- DOM.appendChild(base, handle);
-
- // Hide initially
- DOM.setStyleAttribute(smaller, "display", "none");
- DOM.setStyleAttribute(bigger, "display", "none");
- DOM.setStyleAttribute(handle, "visibility", "hidden");
-
- sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
- | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
-
- feedbackPopup.addStyleName(CLASSNAME + "-feedback");
- feedbackPopup.setWidget(feedback);
- }
-
- void setFeedbackValue(double value) {
- String currentValue = "" + value;
- if (resolution == 0) {
- currentValue = "" + new Double(value).intValue();
- }
- feedback.setText(currentValue);
- }
-
- private void updateFeedbackPosition() {
- if (vertical) {
- feedbackPopup.setPopupPosition(
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
- DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
- - feedbackPopup.getOffsetHeight() / 2);
- } else {
- feedbackPopup.setPopupPosition(
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
- - feedbackPopup.getOffsetWidth() / 2,
- DOM.getAbsoluteTop(handle)
- - feedbackPopup.getOffsetHeight());
- }
- }
-
- void buildBase() {
- final String styleAttribute = vertical ? "height" : "width";
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
-
- final Element p = DOM.getParent(getElement());
- if (DOM.getElementPropertyInt(p, domProperty) > 50) {
- if (vertical) {
- setHeight();
- } else {
- DOM.setStyleAttribute(base, styleAttribute, "");
- }
- } else {
- // Set minimum size and adjust after all components have
- // (supposedly) been drawn completely.
- DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- final Element p = DOM.getParent(getElement());
- if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
- if (vertical) {
- setHeight();
- } else {
- DOM.setStyleAttribute(base, styleAttribute, "");
- }
- // Ensure correct position
- setValue(value, false);
- }
- }
- });
- }
-
- // TODO attach listeners for focusing and arrow keys
- }
-
- void buildHandle() {
- final String handleAttribute = vertical ? "marginTop" : "marginLeft";
-
- DOM.setStyleAttribute(handle, handleAttribute, "0");
-
- // Restore visibility
- DOM.setStyleAttribute(handle, "visibility", "visible");
-
- }
-
- void setValue(Double value, boolean updateToServer) {
- if (value == null) {
- return;
- }
-
- if (value < min) {
- value = min;
- } else if (value > max) {
- value = max;
- }
-
- // Update handle position
- final String styleAttribute = vertical ? "marginTop" : "marginLeft";
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
- final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
- domProperty));
- final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
- domProperty)) - (2 * BASE_BORDER_WIDTH);
-
- final int range = baseSize - handleSize;
- double v = value.doubleValue();
-
- // Round value to resolution
- if (resolution > 0) {
- v = Math.round(v * Math.pow(10, resolution));
- v = v / Math.pow(10, resolution);
- } else {
- v = Math.round(v);
- }
- final double valueRange = max - min;
- double p = 0;
- if (valueRange > 0) {
- p = range * ((v - min) / valueRange);
- }
- if (p < 0) {
- p = 0;
- }
- if (vertical) {
- p = range - p;
- }
- final double pos = p;
-
- DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
-
- // Update value
- this.value = new Double(v);
- setFeedbackValue(v);
-
- if (updateToServer) {
- updateValueToServer();
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- if (disabled || readonly) {
- return;
- }
- final Element targ = DOM.eventGetTarget(event);
-
- if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
- processMouseWheelEvent(event);
- } else if (dragging || targ == handle) {
- processHandleEvent(event);
- } else if (targ == smaller) {
- decreaseValue(true);
- } else if (targ == bigger) {
- increaseValue(true);
- } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
- processBaseEvent(event);
- } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
- || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
-
- if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
- event.getShiftKey())) {
-
- feedbackPopup.show();
-
- delayedValueUpdater.trigger();
-
- DOM.eventPreventDefault(event);
- DOM.eventCancelBubble(event, true);
- }
- } else if (targ.equals(getElement())
- && DOM.eventGetType(event) == Event.ONFOCUS) {
- feedbackPopup.show();
- } else if (targ.equals(getElement())
- && DOM.eventGetType(event) == Event.ONBLUR) {
- feedbackPopup.hide();
- } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
- feedbackPopup.show();
- }
- if (Util.isTouchEvent(event)) {
- event.preventDefault(); // avoid simulated events
- event.stopPropagation();
- }
- }
-
- private void processMouseWheelEvent(final Event event) {
- final int dir = DOM.eventGetMouseWheelVelocityY(event);
-
- if (dir < 0) {
- increaseValue(false);
- } else {
- decreaseValue(false);
- }
-
- delayedValueUpdater.trigger();
-
- DOM.eventPreventDefault(event);
- DOM.eventCancelBubble(event, true);
- }
-
- private void processHandleEvent(Event event) {
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEDOWN:
- case Event.ONTOUCHSTART:
- if (!disabled && !readonly) {
- focus();
- feedbackPopup.show();
- dragging = true;
- DOM.setElementProperty(handle, "className", CLASSNAME
- + "-handle " + CLASSNAME + "-handle-active");
- DOM.setCapture(getElement());
- DOM.eventPreventDefault(event); // prevent selecting text
- DOM.eventCancelBubble(event, true);
- event.stopPropagation();
- VConsole.log("Slider move start");
- }
- break;
- case Event.ONMOUSEMOVE:
- case Event.ONTOUCHMOVE:
- if (dragging) {
- VConsole.log("Slider move");
- setValueByEvent(event, false);
- updateFeedbackPosition();
- event.stopPropagation();
- }
- break;
- case Event.ONTOUCHEND:
- feedbackPopup.hide();
- case Event.ONMOUSEUP:
- // feedbackPopup.hide();
- VConsole.log("Slider move end");
- dragging = false;
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
- DOM.releaseCapture(getElement());
- setValueByEvent(event, true);
- event.stopPropagation();
- break;
- default:
- break;
- }
- }
-
- private void processBaseEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
- if (!disabled && !readonly && !dragging) {
- setValueByEvent(event, true);
- DOM.eventCancelBubble(event, true);
- }
- }
- }
-
- private void decreaseValue(boolean updateToServer) {
- setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
- updateToServer);
- }
-
- private void increaseValue(boolean updateToServer) {
- setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
- updateToServer);
- }
-
- private void setValueByEvent(Event event, boolean updateToServer) {
- double v = min; // Fallback to min
-
- final int coord = getEventPosition(event);
-
- final int handleSize, baseSize, baseOffset;
- if (vertical) {
- handleSize = handle.getOffsetHeight();
- baseSize = base.getOffsetHeight();
- baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
- - handleSize / 2;
- } else {
- handleSize = handle.getOffsetWidth();
- baseSize = base.getOffsetWidth();
- baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
- + handleSize / 2;
- }
-
- if (vertical) {
- v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
- * (max - min) + min;
- } else {
- v = ((coord - baseOffset) / (double) (baseSize - handleSize))
- * (max - min) + min;
- }
-
- if (v < min) {
- v = min;
- } else if (v > max) {
- v = max;
- }
-
- setValue(v, updateToServer);
- }
-
- /**
- * TODO consider extracting touches support to an impl class specific for
- * webkit (only browser that really supports touches).
- *
- * @param event
- * @return
- */
- protected int getEventPosition(Event event) {
- if (vertical) {
- return Util.getTouchOrMouseClientY(event);
- } else {
- return Util.getTouchOrMouseClientX(event);
- }
- }
-
- public void iLayout() {
- if (vertical) {
- setHeight();
- }
- // Update handle position
- setValue(value, false);
- }
-
- private void setHeight() {
- // Calculate decoration size
- DOM.setStyleAttribute(base, "height", "0");
- DOM.setStyleAttribute(base, "overflow", "hidden");
- int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
- if (h < MIN_SIZE) {
- h = MIN_SIZE;
- }
- DOM.setStyleAttribute(base, "height", h + "px");
- DOM.setStyleAttribute(base, "overflow", "");
- }
-
- private void updateValueToServer() {
- client.updateVariable(id, "value", value.doubleValue(), immediate);
- }
-
- /**
- * Handles the keyboard events handled by the Slider
- *
- * @param event
- * The keyboard event received
- * @return true iff the navigation event was handled
- */
- public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
-
- // No support for ctrl moving
- if (ctrl) {
- return false;
- }
-
- if ((keycode == getNavigationUpKey() && vertical)
- || (keycode == getNavigationRightKey() && !vertical)) {
- if (shift) {
- for (int a = 0; a < acceleration; a++) {
- increaseValue(false);
- }
- acceleration++;
- } else {
- increaseValue(false);
- }
- return true;
- } else if (keycode == getNavigationDownKey() && vertical
- || (keycode == getNavigationLeftKey() && !vertical)) {
- if (shift) {
- for (int a = 0; a < acceleration; a++) {
- decreaseValue(false);
- }
- acceleration++;
- } else {
- decreaseValue(false);
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Get the key that increases the vertical slider. By default it is the up
- * arrow key but by overriding this you can change the key to whatever you
- * want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationUpKey() {
- return KeyCodes.KEY_UP;
- }
-
- /**
- * Get the key that decreases the vertical slider. By default it is the down
- * arrow key but by overriding this you can change the key to whatever you
- * want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationDownKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * Get the key that decreases the horizontal slider. By default it is the
- * left arrow key but by overriding this you can change the key to whatever
- * you want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationLeftKey() {
- return KeyCodes.KEY_LEFT;
- }
-
- /**
- * Get the key that increases the horizontal slider. By default it is the
- * right arrow key but by overriding this you can change the key to whatever
- * you want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationRightKey() {
- return KeyCodes.KEY_RIGHT;
- }
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+//
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VSlider extends SimpleFocusablePanel implements Field,
+ ContainerResizedListener {
+
+ public static final String CLASSNAME = "v-slider";
+
+ /**
+ * Minimum size (width or height, depending on orientation) of the slider
+ * base.
+ */
+ private static final int MIN_SIZE = 50;
+
+ ApplicationConnection client;
+
+ String id;
+
+ boolean immediate;
+ boolean disabled;
+ boolean readonly;
+
+ private int acceleration = 1;
+ double min;
+ double max;
+ int resolution;
+ Double value;
+ boolean vertical;
+
+ private final HTML feedback = new HTML("", false);
+ private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
+ @Override
+ public void show() {
+ super.show();
+ updateFeedbackPosition();
+ }
+ };
+
+ /* DOM element for slider's base */
+ private final Element base;
+ private final int BASE_BORDER_WIDTH = 1;
+
+ /* DOM element for slider's handle */
+ private final Element handle;
+
+ /* DOM element for decrement arrow */
+ private final Element smaller;
+
+ /* DOM element for increment arrow */
+ private final Element bigger;
+
+ /* Temporary dragging/animation variables */
+ private boolean dragging = false;
+
+ private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
+ new ScheduledCommand() {
+
+ public void execute() {
+ updateValueToServer();
+ acceleration = 1;
+ }
+ });
+
+ public VSlider() {
+ super();
+
+ base = DOM.createDiv();
+ handle = DOM.createDiv();
+ smaller = DOM.createDiv();
+ bigger = DOM.createDiv();
+
+ setStyleName(CLASSNAME);
+ DOM.setElementProperty(base, "className", CLASSNAME + "-base");
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
+ DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
+
+ DOM.appendChild(getElement(), bigger);
+ DOM.appendChild(getElement(), smaller);
+ DOM.appendChild(getElement(), base);
+ DOM.appendChild(base, handle);
+
+ // Hide initially
+ DOM.setStyleAttribute(smaller, "display", "none");
+ DOM.setStyleAttribute(bigger, "display", "none");
+ DOM.setStyleAttribute(handle, "visibility", "hidden");
+
+ sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
+ | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
+
+ feedbackPopup.addStyleName(CLASSNAME + "-feedback");
+ feedbackPopup.setWidget(feedback);
+ }
+
+ void setFeedbackValue(double value) {
+ String currentValue = "" + value;
+ if (resolution == 0) {
+ currentValue = "" + new Double(value).intValue();
+ }
+ feedback.setText(currentValue);
+ }
+
+ private void updateFeedbackPosition() {
+ if (vertical) {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
+ DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
+ - feedbackPopup.getOffsetHeight() / 2);
+ } else {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
+ - feedbackPopup.getOffsetWidth() / 2,
+ DOM.getAbsoluteTop(handle)
+ - feedbackPopup.getOffsetHeight());
+ }
+ }
+
+ void buildBase() {
+ final String styleAttribute = vertical ? "height" : "width";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > 50) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ } else {
+ // Set minimum size and adjust after all components have
+ // (supposedly) been drawn completely.
+ DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ // Ensure correct position
+ setValue(value, false);
+ }
+ }
+ });
+ }
+
+ // TODO attach listeners for focusing and arrow keys
+ }
+
+ void buildHandle() {
+ final String handleAttribute = vertical ? "marginTop" : "marginLeft";
+
+ DOM.setStyleAttribute(handle, handleAttribute, "0");
+
+ // Restore visibility
+ DOM.setStyleAttribute(handle, "visibility", "visible");
+
+ }
+
+ void setValue(Double value, boolean updateToServer) {
+ if (value == null) {
+ return;
+ }
+
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+
+ // Update handle position
+ final String styleAttribute = vertical ? "marginTop" : "marginLeft";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+ final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
+ domProperty));
+ final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
+ domProperty)) - (2 * BASE_BORDER_WIDTH);
+
+ final int range = baseSize - handleSize;
+ double v = value.doubleValue();
+
+ // Round value to resolution
+ if (resolution > 0) {
+ v = Math.round(v * Math.pow(10, resolution));
+ v = v / Math.pow(10, resolution);
+ } else {
+ v = Math.round(v);
+ }
+ final double valueRange = max - min;
+ double p = 0;
+ if (valueRange > 0) {
+ p = range * ((v - min) / valueRange);
+ }
+ if (p < 0) {
+ p = 0;
+ }
+ if (vertical) {
+ p = range - p;
+ }
+ final double pos = p;
+
+ DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
+
+ // Update value
+ this.value = new Double(v);
+ setFeedbackValue(v);
+
+ if (updateToServer) {
+ updateValueToServer();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ if (disabled || readonly) {
+ return;
+ }
+ final Element targ = DOM.eventGetTarget(event);
+
+ if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
+ processMouseWheelEvent(event);
+ } else if (dragging || targ == handle) {
+ processHandleEvent(event);
+ } else if (targ == smaller) {
+ decreaseValue(true);
+ } else if (targ == bigger) {
+ increaseValue(true);
+ } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
+ processBaseEvent(event);
+ } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
+ || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
+
+ if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
+ event.getShiftKey())) {
+
+ feedbackPopup.show();
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONFOCUS) {
+ feedbackPopup.show();
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONBLUR) {
+ feedbackPopup.hide();
+ } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ feedbackPopup.show();
+ }
+ if (Util.isTouchEvent(event)) {
+ event.preventDefault(); // avoid simulated events
+ event.stopPropagation();
+ }
+ }
+
+ private void processMouseWheelEvent(final Event event) {
+ final int dir = DOM.eventGetMouseWheelVelocityY(event);
+
+ if (dir < 0) {
+ increaseValue(false);
+ } else {
+ decreaseValue(false);
+ }
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+
+ private void processHandleEvent(Event event) {
+ switch (DOM.eventGetType(event)) {
+ case Event.ONMOUSEDOWN:
+ case Event.ONTOUCHSTART:
+ if (!disabled && !readonly) {
+ focus();
+ feedbackPopup.show();
+ dragging = true;
+ DOM.setElementProperty(handle, "className", CLASSNAME
+ + "-handle " + CLASSNAME + "-handle-active");
+ DOM.setCapture(getElement());
+ DOM.eventPreventDefault(event); // prevent selecting text
+ DOM.eventCancelBubble(event, true);
+ event.stopPropagation();
+ VConsole.log("Slider move start");
+ }
+ break;
+ case Event.ONMOUSEMOVE:
+ case Event.ONTOUCHMOVE:
+ if (dragging) {
+ VConsole.log("Slider move");
+ setValueByEvent(event, false);
+ updateFeedbackPosition();
+ event.stopPropagation();
+ }
+ break;
+ case Event.ONTOUCHEND:
+ feedbackPopup.hide();
+ case Event.ONMOUSEUP:
+ // feedbackPopup.hide();
+ VConsole.log("Slider move end");
+ dragging = false;
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.releaseCapture(getElement());
+ setValueByEvent(event, true);
+ event.stopPropagation();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void processBaseEvent(Event event) {
+ if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ if (!disabled && !readonly && !dragging) {
+ setValueByEvent(event, true);
+ DOM.eventCancelBubble(event, true);
+ }
+ }
+ }
+
+ private void decreaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void increaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void setValueByEvent(Event event, boolean updateToServer) {
+ double v = min; // Fallback to min
+
+ final int coord = getEventPosition(event);
+
+ final int handleSize, baseSize, baseOffset;
+ if (vertical) {
+ handleSize = handle.getOffsetHeight();
+ baseSize = base.getOffsetHeight();
+ baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
+ - handleSize / 2;
+ } else {
+ handleSize = handle.getOffsetWidth();
+ baseSize = base.getOffsetWidth();
+ baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
+ + handleSize / 2;
+ }
+
+ if (vertical) {
+ v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ } else {
+ v = ((coord - baseOffset) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ }
+
+ if (v < min) {
+ v = min;
+ } else if (v > max) {
+ v = max;
+ }
+
+ setValue(v, updateToServer);
+ }
+
+ /**
+ * TODO consider extracting touches support to an impl class specific for
+ * webkit (only browser that really supports touches).
+ *
+ * @param event
+ * @return
+ */
+ protected int getEventPosition(Event event) {
+ if (vertical) {
+ return Util.getTouchOrMouseClientY(event);
+ } else {
+ return Util.getTouchOrMouseClientX(event);
+ }
+ }
+
+ public void iLayout() {
+ if (vertical) {
+ setHeight();
+ }
+ // Update handle position
+ setValue(value, false);
+ }
+
+ private void setHeight() {
+ // Calculate decoration size
+ DOM.setStyleAttribute(base, "height", "0");
+ DOM.setStyleAttribute(base, "overflow", "hidden");
+ int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
+ if (h < MIN_SIZE) {
+ h = MIN_SIZE;
+ }
+ DOM.setStyleAttribute(base, "height", h + "px");
+ DOM.setStyleAttribute(base, "overflow", "");
+ }
+
+ private void updateValueToServer() {
+ client.updateVariable(id, "value", value.doubleValue(), immediate);
+ }
+
+ /**
+ * Handles the keyboard events handled by the Slider
+ *
+ * @param event
+ * The keyboard event received
+ * @return true iff the navigation event was handled
+ */
+ public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
+
+ // No support for ctrl moving
+ if (ctrl) {
+ return false;
+ }
+
+ if ((keycode == getNavigationUpKey() && vertical)
+ || (keycode == getNavigationRightKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ increaseValue(false);
+ }
+ acceleration++;
+ } else {
+ increaseValue(false);
+ }
+ return true;
+ } else if (keycode == getNavigationDownKey() && vertical
+ || (keycode == getNavigationLeftKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ decreaseValue(false);
+ }
+ acceleration++;
+ } else {
+ decreaseValue(false);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the key that increases the vertical slider. By default it is the up
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationUpKey() {
+ return KeyCodes.KEY_UP;
+ }
+
+ /**
+ * Get the key that decreases the vertical slider. By default it is the down
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationDownKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Get the key that decreases the horizontal slider. By default it is the
+ * left arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationLeftKey() {
+ return KeyCodes.KEY_LEFT;
+ }
+
+ /**
+ * Get the key that increases the horizontal slider. By default it is the
+ * right arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationRightKey() {
+ return KeyCodes.KEY_RIGHT;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
index f5b8c8a45e..6c0dc74412 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
@@ -1,78 +1,81 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VSliderPaintable extends VAbstractPaintableWidget {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
- getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
- getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
-
- getWidgetForPaintable().vertical = uidl.hasAttribute("vertical");
-
- String style = "";
- if (uidl.hasAttribute("style")) {
- style = uidl.getStringAttribute("style");
- }
-
- if (getWidgetForPaintable().vertical) {
- getWidgetForPaintable().addStyleName(
- VSlider.CLASSNAME + "-vertical");
- } else {
- getWidgetForPaintable().removeStyleName(
- VSlider.CLASSNAME + "-vertical");
- }
-
- getWidgetForPaintable().min = uidl.getDoubleAttribute("min");
- getWidgetForPaintable().max = uidl.getDoubleAttribute("max");
- getWidgetForPaintable().resolution = uidl.getIntAttribute("resolution");
- getWidgetForPaintable().value = new Double(
- uidl.getDoubleVariable("value"));
-
- getWidgetForPaintable().setFeedbackValue(getWidgetForPaintable().value);
-
- getWidgetForPaintable().buildBase();
-
- if (!getWidgetForPaintable().vertical) {
- // Draw handle with a delay to allow base to gain maximum width
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- getWidgetForPaintable().buildHandle();
- getWidgetForPaintable().setValue(
- getWidgetForPaintable().value, false);
- }
- });
- } else {
- getWidgetForPaintable().buildHandle();
- getWidgetForPaintable().setValue(getWidgetForPaintable().value,
- false);
- }
- }
-
- @Override
- public VSlider getWidgetForPaintable() {
- return (VSlider) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VSlider.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VSliderPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+
+ getWidgetForPaintable().vertical = uidl.hasAttribute("vertical");
+
+ String style = "";
+ if (uidl.hasAttribute("style")) {
+ style = uidl.getStringAttribute("style");
+ }
+
+ if (getWidgetForPaintable().vertical) {
+ getWidgetForPaintable().addStyleName(
+ VSlider.CLASSNAME + "-vertical");
+ } else {
+ getWidgetForPaintable().removeStyleName(
+ VSlider.CLASSNAME + "-vertical");
+ }
+
+ getWidgetForPaintable().min = uidl.getDoubleAttribute("min");
+ getWidgetForPaintable().max = uidl.getDoubleAttribute("max");
+ getWidgetForPaintable().resolution = uidl.getIntAttribute("resolution");
+ getWidgetForPaintable().value = new Double(
+ uidl.getDoubleVariable("value"));
+
+ getWidgetForPaintable().setFeedbackValue(getWidgetForPaintable().value);
+
+ getWidgetForPaintable().buildBase();
+
+ if (!getWidgetForPaintable().vertical) {
+ // Draw handle with a delay to allow base to gain maximum width
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ getWidgetForPaintable().buildHandle();
+ getWidgetForPaintable().setValue(
+ getWidgetForPaintable().value, false);
+ }
+ });
+ } else {
+ getWidgetForPaintable().buildHandle();
+ getWidgetForPaintable().setValue(getWidgetForPaintable().value,
+ false);
+ }
+ }
+
+ @Override
+ public VSlider getWidgetForPaintable() {
+ return (VSlider) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VSlider.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
index 553a4d673e..809c1a0380 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
@@ -1137,8 +1137,4 @@ public class VTabsheet extends VTabsheetBase {
tp.remove(index);
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java
index 3fbc52c2ca..79f6012ed1 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java
@@ -1,96 +1,99 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public abstract class VTabsheetBasePaintable extends
- VAbstractPaintableWidgetContainer {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
-
- // Ensure correct implementation
- getWidgetForPaintable().cachedUpdate = client.updateComponent(this,
- uidl, true);
- if (getWidgetForPaintable().cachedUpdate) {
- return;
- }
-
- // Update member references
- getWidgetForPaintable().id = uidl.getId();
- getWidgetForPaintable().disabled = uidl.hasAttribute("disabled");
-
- // Render content
- final UIDL tabs = uidl.getChildUIDL(0);
-
- // Paintables in the TabSheet before update
- ArrayList<Widget> oldWidgets = new ArrayList<Widget>();
- for (Iterator<Widget> iterator = getWidgetForPaintable()
- .getWidgetIterator(); iterator.hasNext();) {
- oldWidgets.add(iterator.next());
- }
-
- // Clear previous values
- getWidgetForPaintable().tabKeys.clear();
- getWidgetForPaintable().disabledTabKeys.clear();
-
- int index = 0;
- for (final Iterator<Object> it = tabs.getChildIterator(); it.hasNext();) {
- final UIDL tab = (UIDL) it.next();
- final String key = tab.getStringAttribute("key");
- final boolean selected = tab.getBooleanAttribute("selected");
- final boolean hidden = tab.getBooleanAttribute("hidden");
-
- if (tab.getBooleanAttribute("disabled")) {
- getWidgetForPaintable().disabledTabKeys.add(key);
- }
-
- getWidgetForPaintable().tabKeys.add(key);
-
- if (selected) {
- getWidgetForPaintable().activeTabIndex = index;
- }
- getWidgetForPaintable().renderTab(tab, index, selected, hidden);
- index++;
- }
-
- int tabCount = getWidgetForPaintable().getTabCount();
- while (tabCount-- > index) {
- getWidgetForPaintable().removeTab(index);
- }
-
- for (int i = 0; i < getWidgetForPaintable().getTabCount(); i++) {
- VPaintableWidget p = getWidgetForPaintable().getTab(i);
- // During the initial rendering the paintable might be null (this is
- // weird...)
- if (p != null) {
- oldWidgets.remove(p.getWidgetForPaintable());
- }
- }
-
- // Perform unregister for any paintables removed during update
- for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
- .hasNext();) {
- Widget oldWidget = iterator.next();
- VPaintableWidget oldPaintable = VPaintableMap.get(client)
- .getPaintable(oldWidget);
- if (oldWidget.isAttached()) {
- oldWidget.removeFromParent();
- }
- VPaintableMap.get(client).unregisterPaintable(oldPaintable);
- }
-
- }
-
- @Override
- public VTabsheetBase getWidgetForPaintable() {
- return (VTabsheetBase) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public abstract class VTabsheetBasePaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+
+ // Ensure correct implementation
+ getWidgetForPaintable().cachedUpdate = client.updateComponent(this,
+ uidl, true);
+ if (getWidgetForPaintable().cachedUpdate) {
+ return;
+ }
+
+ // Update member references
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().disabled = uidl.hasAttribute("disabled");
+
+ // Render content
+ final UIDL tabs = uidl.getChildUIDL(0);
+
+ // Paintables in the TabSheet before update
+ ArrayList<Widget> oldWidgets = new ArrayList<Widget>();
+ for (Iterator<Widget> iterator = getWidgetForPaintable()
+ .getWidgetIterator(); iterator.hasNext();) {
+ oldWidgets.add(iterator.next());
+ }
+
+ // Clear previous values
+ getWidgetForPaintable().tabKeys.clear();
+ getWidgetForPaintable().disabledTabKeys.clear();
+
+ int index = 0;
+ for (final Iterator<Object> it = tabs.getChildIterator(); it.hasNext();) {
+ final UIDL tab = (UIDL) it.next();
+ final String key = tab.getStringAttribute("key");
+ final boolean selected = tab.getBooleanAttribute("selected");
+ final boolean hidden = tab.getBooleanAttribute("hidden");
+
+ if (tab.getBooleanAttribute("disabled")) {
+ getWidgetForPaintable().disabledTabKeys.add(key);
+ }
+
+ getWidgetForPaintable().tabKeys.add(key);
+
+ if (selected) {
+ getWidgetForPaintable().activeTabIndex = index;
+ }
+ getWidgetForPaintable().renderTab(tab, index, selected, hidden);
+ index++;
+ }
+
+ int tabCount = getWidgetForPaintable().getTabCount();
+ while (tabCount-- > index) {
+ getWidgetForPaintable().removeTab(index);
+ }
+
+ for (int i = 0; i < getWidgetForPaintable().getTabCount(); i++) {
+ VPaintableWidget p = getWidgetForPaintable().getTab(i);
+ // During the initial rendering the paintable might be null (this is
+ // weird...)
+ if (p != null) {
+ oldWidgets.remove(p.getWidgetForPaintable());
+ }
+ }
+
+ // Perform unregister for any paintables removed during update
+ for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
+ .hasNext();) {
+ Widget oldWidget = iterator.next();
+ VPaintableWidget oldPaintable = VPaintableMap.get(client)
+ .getPaintable(oldWidget);
+ if (oldWidget.isAttached()) {
+ oldWidget.removeFromParent();
+ }
+ VPaintableMap.get(client).unregisterPaintable(oldPaintable);
+ }
+
+ }
+
+ @Override
+ public VTabsheetBase getWidgetForPaintable() {
+ return (VTabsheetBase) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java
index e8d6da757e..0d32484e10 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java
@@ -1,82 +1,85 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VTabsheetPaintable extends VTabsheetBasePaintable {
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- if (!uidl.getBooleanAttribute("cached")) {
- // Handle stylename changes before generics (might affect size
- // calculations)
- getWidgetForPaintable().handleStyleNames(uidl);
- }
-
- super.updateFromUIDL(uidl, client);
- if (getWidgetForPaintable().cachedUpdate) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- // tabs; push or not
- if (!getWidgetForPaintable().isDynamicWidth()) {
- // FIXME: This makes tab sheet tabs go to 1px width on every update
- // and then back to original width
- // update width later, in updateTabScroller();
- DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "1px");
- DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
- "hidden");
- } else {
- getWidgetForPaintable().showAllTabs();
- DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "");
- DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
- "visible");
- getWidgetForPaintable().updateDynamicWidth();
- }
-
- if (!getWidgetForPaintable().isDynamicHeight()) {
- // Must update height after the styles have been set
- getWidgetForPaintable().updateContentNodeHeight();
- getWidgetForPaintable().updateOpenTabSize();
- }
-
- getWidgetForPaintable().iLayout();
-
- // Re run relative size update to ensure optimal scrollbars
- // TODO isolate to situation that visible tab has undefined height
- try {
- client.handleComponentRelativeSize(getWidgetForPaintable().tp
- .getWidget(getWidgetForPaintable().tp.getVisibleWidget()));
- } catch (Exception e) {
- // Ignore, most likely empty tabsheet
- }
-
- getWidgetForPaintable().renderInformation
- .updateSize(getWidgetForPaintable().getElement());
-
- getWidgetForPaintable().waitingForResponse = false;
- getWidgetForPaintable().rendering = false;
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VTabsheet.class);
- }
-
- @Override
- public VTabsheet getWidgetForPaintable() {
- return (VTabsheet) super.getWidgetForPaintable();
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- /* Tabsheet does not render its children's captions */
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VTabsheetPaintable extends VTabsheetBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (!uidl.getBooleanAttribute("cached")) {
+ // Handle stylename changes before generics (might affect size
+ // calculations)
+ getWidgetForPaintable().handleStyleNames(uidl);
+ }
+
+ super.updateFromUIDL(uidl, client);
+ if (getWidgetForPaintable().cachedUpdate) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ // tabs; push or not
+ if (!getWidgetForPaintable().isDynamicWidth()) {
+ // FIXME: This makes tab sheet tabs go to 1px width on every update
+ // and then back to original width
+ // update width later, in updateTabScroller();
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "1px");
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
+ "hidden");
+ } else {
+ getWidgetForPaintable().showAllTabs();
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "");
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
+ "visible");
+ getWidgetForPaintable().updateDynamicWidth();
+ }
+
+ if (!getWidgetForPaintable().isDynamicHeight()) {
+ // Must update height after the styles have been set
+ getWidgetForPaintable().updateContentNodeHeight();
+ getWidgetForPaintable().updateOpenTabSize();
+ }
+
+ getWidgetForPaintable().iLayout();
+
+ // Re run relative size update to ensure optimal scrollbars
+ // TODO isolate to situation that visible tab has undefined height
+ try {
+ client.handleComponentRelativeSize(getWidgetForPaintable().tp
+ .getWidget(getWidgetForPaintable().tp.getVisibleWidget()));
+ } catch (Exception e) {
+ // Ignore, most likely empty tabsheet
+ }
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ getWidgetForPaintable().waitingForResponse = false;
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTabsheet.class);
+ }
+
+ @Override
+ public VTabsheet getWidgetForPaintable() {
+ return (VTabsheet) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ /* Tabsheet does not render its children's captions */
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
index c33daed440..126b0ebea1 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
@@ -1,214 +1,214 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.event.dom.client.TouchStartEvent;
-import com.google.gwt.event.dom.client.TouchStartHandler;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.ComplexPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.Util;
-
-/**
- * A panel that displays all of its child widgets in a 'deck', where only one
- * can be visible at a time. It is used by
- * {@link com.vaadin.terminal.gwt.client.ui.VTabsheet}.
- *
- * This class has the same basic functionality as the GWT DeckPanel
- * {@link com.google.gwt.user.client.ui.DeckPanel}, with the exception that it
- * doesn't manipulate the child widgets' width and height attributes.
- */
-public class VTabsheetPanel extends ComplexPanel {
-
- private Widget visibleWidget;
- private TouchScrollDelegate touchScrollDelegate;
-
- /**
- * Creates an empty tabsheet panel.
- */
- public VTabsheetPanel() {
- setElement(DOM.createDiv());
- sinkEvents(Event.TOUCHEVENTS);
- addDomHandler(new TouchStartHandler() {
- public void onTouchStart(TouchStartEvent event) {
- /*
- * All container elements needs to be scrollable by one finger.
- * Update the scrollable element list of touch delegate on each
- * touch start.
- */
- NodeList<Node> childNodes = getElement().getChildNodes();
- Element[] elements = new Element[childNodes.getLength()];
- for (int i = 0; i < elements.length; i++) {
- elements[i] = (Element) childNodes.getItem(i);
- }
- getTouchScrollDelegate().setElements(elements);
- getTouchScrollDelegate().onTouchStart(event);
- }
- }, TouchStartEvent.getType());
- }
-
- protected TouchScrollDelegate getTouchScrollDelegate() {
- if (touchScrollDelegate == null) {
- touchScrollDelegate = new TouchScrollDelegate();
- }
- return touchScrollDelegate;
-
- }
-
- /**
- * Adds the specified widget to the deck.
- *
- * @param w
- * the widget to be added
- */
- @Override
- public void add(Widget w) {
- Element el = createContainerElement();
- DOM.appendChild(getElement(), el);
- super.add(w, el);
- }
-
- private Element createContainerElement() {
- Element el = DOM.createDiv();
- DOM.setStyleAttribute(el, "position", "absolute");
- DOM.setStyleAttribute(el, "overflow", "auto");
- hide(el);
- return el;
- }
-
- /**
- * Gets the index of the currently-visible widget.
- *
- * @return the visible widget's index
- */
- public int getVisibleWidget() {
- return getWidgetIndex(visibleWidget);
- }
-
- /**
- * Inserts a widget before the specified index.
- *
- * @param w
- * the widget to be inserted
- * @param beforeIndex
- * the index before which it will be inserted
- * @throws IndexOutOfBoundsException
- * if <code>beforeIndex</code> is out of range
- */
- public void insert(Widget w, int beforeIndex) {
- Element el = createContainerElement();
- DOM.insertChild(getElement(), el, beforeIndex);
- super.insert(w, el, beforeIndex, false);
- }
-
- @Override
- public boolean remove(Widget w) {
- Element child = w.getElement();
- Element parent = null;
- if (child != null) {
- parent = DOM.getParent(child);
- }
- final boolean removed = super.remove(w);
- if (removed) {
- if (visibleWidget == w) {
- visibleWidget = null;
- }
- if (parent != null) {
- DOM.removeChild(getElement(), parent);
- }
- }
- return removed;
- }
-
- /**
- * Shows the widget at the specified index. This causes the currently-
- * visible widget to be hidden.
- *
- * @param index
- * the index of the widget to be shown
- */
- public void showWidget(int index) {
- checkIndexBoundsForAccess(index);
- Widget newVisible = getWidget(index);
- if (visibleWidget != newVisible) {
- if (visibleWidget != null) {
- hide(DOM.getParent(visibleWidget.getElement()));
- }
- visibleWidget = newVisible;
- unHide(DOM.getParent(visibleWidget.getElement()));
- }
- }
-
- private void hide(Element e) {
- DOM.setStyleAttribute(e, "visibility", "hidden");
- DOM.setStyleAttribute(e, "top", "-100000px");
- DOM.setStyleAttribute(e, "left", "-100000px");
- }
-
- private void unHide(Element e) {
- DOM.setStyleAttribute(e, "top", "0px");
- DOM.setStyleAttribute(e, "left", "0px");
- DOM.setStyleAttribute(e, "visibility", "");
- }
-
- public void fixVisibleTabSize(int width, int height, int minWidth) {
- if (visibleWidget == null) {
- return;
- }
-
- boolean dynamicHeight = false;
-
- if (height < 0) {
- height = visibleWidget.getOffsetHeight();
- dynamicHeight = true;
- }
- if (width < 0) {
- width = visibleWidget.getOffsetWidth();
- }
- if (width < minWidth) {
- width = minWidth;
- }
-
- Element wrapperDiv = (Element) visibleWidget.getElement()
- .getParentElement();
-
- // width first
- getElement().getStyle().setPropertyPx("width", width);
- wrapperDiv.getStyle().setPropertyPx("width", width);
-
- if (dynamicHeight) {
- // height of widget might have changed due wrapping
- height = visibleWidget.getOffsetHeight();
- }
- // v-tabsheet-tabsheetpanel height
- getElement().getStyle().setPropertyPx("height", height);
-
- // widget wrapper height
- wrapperDiv.getStyle().setPropertyPx("height", height);
- runWebkitOverflowAutoFix();
- }
-
- public void runWebkitOverflowAutoFix() {
- if (visibleWidget != null) {
- Util.runWebkitOverflowAutoFix(DOM.getParent(visibleWidget
- .getElement()));
- }
-
- }
-
- public void replaceComponent(Widget oldComponent, Widget newComponent) {
- boolean isVisible = (visibleWidget == oldComponent);
- int widgetIndex = getWidgetIndex(oldComponent);
- remove(oldComponent);
- insert(newComponent, widgetIndex);
- if (isVisible) {
- showWidget(widgetIndex);
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.event.dom.client.TouchStartEvent;
+import com.google.gwt.event.dom.client.TouchStartHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.Util;
+
+/**
+ * A panel that displays all of its child widgets in a 'deck', where only one
+ * can be visible at a time. It is used by
+ * {@link com.vaadin.terminal.gwt.client.ui.VTabsheet}.
+ *
+ * This class has the same basic functionality as the GWT DeckPanel
+ * {@link com.google.gwt.user.client.ui.DeckPanel}, with the exception that it
+ * doesn't manipulate the child widgets' width and height attributes.
+ */
+public class VTabsheetPanel extends ComplexPanel {
+
+ private Widget visibleWidget;
+ private TouchScrollDelegate touchScrollDelegate;
+
+ /**
+ * Creates an empty tabsheet panel.
+ */
+ public VTabsheetPanel() {
+ setElement(DOM.createDiv());
+ sinkEvents(Event.TOUCHEVENTS);
+ addDomHandler(new TouchStartHandler() {
+ public void onTouchStart(TouchStartEvent event) {
+ /*
+ * All container elements needs to be scrollable by one finger.
+ * Update the scrollable element list of touch delegate on each
+ * touch start.
+ */
+ NodeList<Node> childNodes = getElement().getChildNodes();
+ Element[] elements = new Element[childNodes.getLength()];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = (Element) childNodes.getItem(i);
+ }
+ getTouchScrollDelegate().setElements(elements);
+ getTouchScrollDelegate().onTouchStart(event);
+ }
+ }, TouchStartEvent.getType());
+ }
+
+ protected TouchScrollDelegate getTouchScrollDelegate() {
+ if (touchScrollDelegate == null) {
+ touchScrollDelegate = new TouchScrollDelegate();
+ }
+ return touchScrollDelegate;
+
+ }
+
+ /**
+ * Adds the specified widget to the deck.
+ *
+ * @param w
+ * the widget to be added
+ */
+ @Override
+ public void add(Widget w) {
+ Element el = createContainerElement();
+ DOM.appendChild(getElement(), el);
+ super.add(w, el);
+ }
+
+ private Element createContainerElement() {
+ Element el = DOM.createDiv();
+ DOM.setStyleAttribute(el, "position", "absolute");
+ DOM.setStyleAttribute(el, "overflow", "auto");
+ hide(el);
+ return el;
+ }
+
+ /**
+ * Gets the index of the currently-visible widget.
+ *
+ * @return the visible widget's index
+ */
+ public int getVisibleWidget() {
+ return getWidgetIndex(visibleWidget);
+ }
+
+ /**
+ * Inserts a widget before the specified index.
+ *
+ * @param w
+ * the widget to be inserted
+ * @param beforeIndex
+ * the index before which it will be inserted
+ * @throws IndexOutOfBoundsException
+ * if <code>beforeIndex</code> is out of range
+ */
+ public void insert(Widget w, int beforeIndex) {
+ Element el = createContainerElement();
+ DOM.insertChild(getElement(), el, beforeIndex);
+ super.insert(w, el, beforeIndex, false);
+ }
+
+ @Override
+ public boolean remove(Widget w) {
+ Element child = w.getElement();
+ Element parent = null;
+ if (child != null) {
+ parent = DOM.getParent(child);
+ }
+ final boolean removed = super.remove(w);
+ if (removed) {
+ if (visibleWidget == w) {
+ visibleWidget = null;
+ }
+ if (parent != null) {
+ DOM.removeChild(getElement(), parent);
+ }
+ }
+ return removed;
+ }
+
+ /**
+ * Shows the widget at the specified index. This causes the currently-
+ * visible widget to be hidden.
+ *
+ * @param index
+ * the index of the widget to be shown
+ */
+ public void showWidget(int index) {
+ checkIndexBoundsForAccess(index);
+ Widget newVisible = getWidget(index);
+ if (visibleWidget != newVisible) {
+ if (visibleWidget != null) {
+ hide(DOM.getParent(visibleWidget.getElement()));
+ }
+ visibleWidget = newVisible;
+ unHide(DOM.getParent(visibleWidget.getElement()));
+ }
+ }
+
+ private void hide(Element e) {
+ DOM.setStyleAttribute(e, "visibility", "hidden");
+ DOM.setStyleAttribute(e, "top", "-100000px");
+ DOM.setStyleAttribute(e, "left", "-100000px");
+ }
+
+ private void unHide(Element e) {
+ DOM.setStyleAttribute(e, "top", "0px");
+ DOM.setStyleAttribute(e, "left", "0px");
+ DOM.setStyleAttribute(e, "visibility", "");
+ }
+
+ public void fixVisibleTabSize(int width, int height, int minWidth) {
+ if (visibleWidget == null) {
+ return;
+ }
+
+ boolean dynamicHeight = false;
+
+ if (height < 0) {
+ height = visibleWidget.getOffsetHeight();
+ dynamicHeight = true;
+ }
+ if (width < 0) {
+ width = visibleWidget.getOffsetWidth();
+ }
+ if (width < minWidth) {
+ width = minWidth;
+ }
+
+ Element wrapperDiv = (Element) visibleWidget.getElement()
+ .getParentElement();
+
+ // width first
+ getElement().getStyle().setPropertyPx("width", width);
+ wrapperDiv.getStyle().setPropertyPx("width", width);
+
+ if (dynamicHeight) {
+ // height of widget might have changed due wrapping
+ height = visibleWidget.getOffsetHeight();
+ }
+ // v-tabsheet-tabsheetpanel height
+ getElement().getStyle().setPropertyPx("height", height);
+
+ // widget wrapper height
+ wrapperDiv.getStyle().setPropertyPx("height", height);
+ runWebkitOverflowAutoFix();
+ }
+
+ public void runWebkitOverflowAutoFix() {
+ if (visibleWidget != null) {
+ Util.runWebkitOverflowAutoFix(DOM.getParent(visibleWidget
+ .getElement()));
+ }
+
+ }
+
+ public void replaceComponent(Widget oldComponent, Widget newComponent) {
+ boolean isVisible = (visibleWidget == oldComponent);
+ int widgetIndex = getWidgetIndex(oldComponent);
+ remove(oldComponent);
+ insert(newComponent, widgetIndex);
+ if (isVisible) {
+ showWidget(widgetIndex);
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java b/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
index bd58c38829..2c8ed24693 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
@@ -1,63 +1,63 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-
-/**
- * This class represents a multiline textfield (textarea).
- *
- * TODO consider replacing this with a RichTextArea based implementation. IE
- * does not support CSS height for textareas in Strict mode :-(
- *
- * @author Vaadin Ltd.
- *
- */
-public class VTextArea extends VTextField {
- public static final String CLASSNAME = "v-textarea";
-
- public VTextArea() {
- super(DOM.createTextArea());
- setStyleName(CLASSNAME);
- }
-
- public void setRows(int rows) {
- setRows(getElement(), rows);
- }
-
- private native void setRows(Element e, int r)
- /*-{
- try {
- if(e.tagName.toLowerCase() == "textarea")
- e.rows = r;
- } catch (e) {}
- }-*/;
-
- @Override
- public void onBrowserEvent(Event event) {
- if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- if (getText().length() > getMaxLength()) {
- setText(getText().substring(0, getMaxLength()));
- }
- }
- });
- }
- super.onBrowserEvent(event);
- }
-
- @Override
- public int getCursorPos() {
- // This is needed so that TextBoxImplIE6 is used to return the correct
- // position for old Internet Explorer versions where it has to be
- // detected in a different way.
- return getImpl().getTextAreaCursorPos(getElement());
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+
+/**
+ * This class represents a multiline textfield (textarea).
+ *
+ * TODO consider replacing this with a RichTextArea based implementation. IE
+ * does not support CSS height for textareas in Strict mode :-(
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class VTextArea extends VTextField {
+ public static final String CLASSNAME = "v-textarea";
+
+ public VTextArea() {
+ super(DOM.createTextArea());
+ setStyleName(CLASSNAME);
+ }
+
+ public void setRows(int rows) {
+ setRows(getElement(), rows);
+ }
+
+ private native void setRows(Element e, int r)
+ /*-{
+ try {
+ if(e.tagName.toLowerCase() == "textarea")
+ e.rows = r;
+ } catch (e) {}
+ }-*/;
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ if (getText().length() > getMaxLength()) {
+ setText(getText().substring(0, getMaxLength()));
+ }
+ }
+ });
+ }
+ super.onBrowserEvent(event);
+ }
+
+ @Override
+ public int getCursorPos() {
+ // This is needed so that TextBoxImplIE6 is used to return the correct
+ // position for old Internet Explorer versions where it has to be
+ // detected in a different way.
+ return getImpl().getTextAreaCursorPos(getElement());
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
index c058a15376..69aecebb06 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
@@ -1,228 +1,231 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.TooltipInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.VTree.TreeNode;
-
-public class VTreePaintable extends VAbstractPaintableWidget {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Ensure correct implementation and let container manage caption
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().rendering = true;
-
- getWidgetForPaintable().client = client;
-
- if (uidl.hasAttribute("partialUpdate")) {
- handleUpdate(uidl);
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- getWidgetForPaintable().paintableId = uidl.getId();
-
- getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
-
- getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
- getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
-
- getWidgetForPaintable().dragMode = uidl.hasAttribute("dragMode") ? uidl
- .getIntAttribute("dragMode") : 0;
-
- getWidgetForPaintable().isNullSelectionAllowed = uidl
- .getBooleanAttribute("nullselect");
-
- if (uidl.hasAttribute("alb")) {
- getWidgetForPaintable().bodyActionKeys = uidl
- .getStringArrayAttribute("alb");
- }
-
- getWidgetForPaintable().body.clear();
- // clear out any references to nodes that no longer are attached
- getWidgetForPaintable().clearNodeToKeyMap();
- TreeNode childTree = null;
- UIDL childUidl = null;
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
- childUidl = (UIDL) i.next();
- if ("actions".equals(childUidl.getTag())) {
- updateActionMap(childUidl);
- continue;
- } else if ("-ac".equals(childUidl.getTag())) {
- getWidgetForPaintable().updateDropHandler(childUidl);
- continue;
- }
- childTree = getWidgetForPaintable().new TreeNode();
- updateNodeFromUIDL(childTree, childUidl);
- getWidgetForPaintable().body.add(childTree);
- childTree.addStyleDependentName("root");
- childTree.childNodeContainer.addStyleDependentName("root");
- }
- if (childTree != null && childUidl != null) {
- boolean leaf = !childUidl.getTag().equals("node");
- childTree.addStyleDependentName(leaf ? "leaf-last" : "last");
- childTree.childNodeContainer.addStyleDependentName("last");
- }
- final String selectMode = uidl.getStringAttribute("selectmode");
- getWidgetForPaintable().selectable = !"none".equals(selectMode);
- getWidgetForPaintable().isMultiselect = "multi".equals(selectMode);
-
- if (getWidgetForPaintable().isMultiselect) {
- getWidgetForPaintable().multiSelectMode = uidl
- .getIntAttribute("multiselectmode");
- }
-
- getWidgetForPaintable().selectedIds = uidl
- .getStringArrayVariableAsSet("selected");
-
- // Update lastSelection and focusedNode to point to *actual* nodes again
- // after the old ones have been cleared from the body. This fixes focus
- // and keyboard navigation issues as described in #7057 and other
- // tickets.
- if (getWidgetForPaintable().lastSelection != null) {
- getWidgetForPaintable().lastSelection = getWidgetForPaintable()
- .getNodeByKey(getWidgetForPaintable().lastSelection.key);
- }
- if (getWidgetForPaintable().focusedNode != null) {
- getWidgetForPaintable().setFocusedNode(
- getWidgetForPaintable().getNodeByKey(
- getWidgetForPaintable().focusedNode.key));
- }
-
- if (getWidgetForPaintable().lastSelection == null
- && getWidgetForPaintable().focusedNode == null
- && !getWidgetForPaintable().selectedIds.isEmpty()) {
- getWidgetForPaintable().setFocusedNode(
- getWidgetForPaintable().getNodeByKey(
- getWidgetForPaintable().selectedIds.iterator()
- .next()));
- getWidgetForPaintable().focusedNode.setFocused(false);
- }
-
- getWidgetForPaintable().rendering = false;
-
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VTree.class);
- }
-
- @Override
- public VTree getWidgetForPaintable() {
- return (VTree) super.getWidgetForPaintable();
- }
-
- private void handleUpdate(UIDL uidl) {
- final TreeNode rootNode = getWidgetForPaintable().getNodeByKey(
- uidl.getStringAttribute("rootKey"));
- if (rootNode != null) {
- if (!rootNode.getState()) {
- // expanding node happened server side
- rootNode.setState(true, false);
- }
- renderChildNodes(rootNode, (Iterator) uidl.getChildIterator());
- }
- }
-
- /**
- * Registers action for the root and also for individual nodes
- *
- * @param uidl
- */
- private void updateActionMap(UIDL uidl) {
- final Iterator<?> it = uidl.getChildIterator();
- while (it.hasNext()) {
- final UIDL action = (UIDL) it.next();
- final String key = action.getStringAttribute("key");
- final String caption = action.getStringAttribute("caption");
- String iconUrl = null;
- if (action.hasAttribute("icon")) {
- iconUrl = getConnection().translateVaadinUri(
- action.getStringAttribute("icon"));
- }
- getWidgetForPaintable().registerAction(key, caption, iconUrl);
- }
-
- }
-
- public void updateNodeFromUIDL(TreeNode treeNode, UIDL uidl) {
- String nodeKey = uidl.getStringAttribute("key");
- treeNode.setText(uidl.getStringAttribute("caption"));
- treeNode.key = nodeKey;
-
- getWidgetForPaintable().registerNode(treeNode);
-
- if (uidl.hasAttribute("al")) {
- treeNode.actionKeys = uidl.getStringArrayAttribute("al");
- }
-
- if (uidl.getTag().equals("node")) {
- if (uidl.getChildCount() == 0) {
- treeNode.childNodeContainer.setVisible(false);
- } else {
- renderChildNodes(treeNode, (Iterator) uidl.getChildIterator());
- treeNode.childrenLoaded = true;
- }
- } else {
- treeNode.addStyleName(TreeNode.CLASSNAME + "-leaf");
- }
- if (uidl.hasAttribute("style")) {
- treeNode.setNodeStyleName(uidl.getStringAttribute("style"));
- }
-
- String description = uidl.getStringAttribute("descr");
- if (description != null && getConnection() != null) {
- // Set tooltip
- TooltipInfo info = new TooltipInfo(description);
- getConnection().registerTooltip(this, nodeKey, info);
- } else {
- // Remove possible previous tooltip
- getConnection().registerTooltip(this, nodeKey, null);
- }
-
- if (uidl.getBooleanAttribute("expanded") && !treeNode.getState()) {
- treeNode.setState(true, false);
- }
-
- if (uidl.getBooleanAttribute("selected")) {
- treeNode.setSelected(true);
- // ensure that identifier is in selectedIds array (this may be a
- // partial update)
- getWidgetForPaintable().selectedIds.add(nodeKey);
- }
-
- treeNode.setIcon(uidl.getStringAttribute("icon"));
- }
-
- void renderChildNodes(TreeNode containerNode, Iterator<UIDL> i) {
- containerNode.childNodeContainer.clear();
- containerNode.childNodeContainer.setVisible(true);
- while (i.hasNext()) {
- final UIDL childUidl = i.next();
- // actions are in bit weird place, don't mix them with children,
- // but current node's actions
- if ("actions".equals(childUidl.getTag())) {
- updateActionMap(childUidl);
- continue;
- }
- final TreeNode childTree = getWidgetForPaintable().new TreeNode();
- updateNodeFromUIDL(childTree, childUidl);
- containerNode.add(childTree);
- if (!i.hasNext()) {
- childTree
- .addStyleDependentName(childTree.isLeaf() ? "leaf-last"
- : "last");
- childTree.childNodeContainer.addStyleDependentName("last");
- }
- }
- containerNode.childrenLoaded = true;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.TooltipInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VTree.TreeNode;
+
+public class VTreePaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Ensure correct implementation and let container manage caption
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().client = client;
+
+ if (uidl.hasAttribute("partialUpdate")) {
+ handleUpdate(uidl);
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().paintableId = uidl.getId();
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+
+ getWidgetForPaintable().dragMode = uidl.hasAttribute("dragMode") ? uidl
+ .getIntAttribute("dragMode") : 0;
+
+ getWidgetForPaintable().isNullSelectionAllowed = uidl
+ .getBooleanAttribute("nullselect");
+
+ if (uidl.hasAttribute("alb")) {
+ getWidgetForPaintable().bodyActionKeys = uidl
+ .getStringArrayAttribute("alb");
+ }
+
+ getWidgetForPaintable().body.clear();
+ // clear out any references to nodes that no longer are attached
+ getWidgetForPaintable().clearNodeToKeyMap();
+ TreeNode childTree = null;
+ UIDL childUidl = null;
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ childUidl = (UIDL) i.next();
+ if ("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
+ continue;
+ } else if ("-ac".equals(childUidl.getTag())) {
+ getWidgetForPaintable().updateDropHandler(childUidl);
+ continue;
+ }
+ childTree = getWidgetForPaintable().new TreeNode();
+ updateNodeFromUIDL(childTree, childUidl);
+ getWidgetForPaintable().body.add(childTree);
+ childTree.addStyleDependentName("root");
+ childTree.childNodeContainer.addStyleDependentName("root");
+ }
+ if (childTree != null && childUidl != null) {
+ boolean leaf = !childUidl.getTag().equals("node");
+ childTree.addStyleDependentName(leaf ? "leaf-last" : "last");
+ childTree.childNodeContainer.addStyleDependentName("last");
+ }
+ final String selectMode = uidl.getStringAttribute("selectmode");
+ getWidgetForPaintable().selectable = !"none".equals(selectMode);
+ getWidgetForPaintable().isMultiselect = "multi".equals(selectMode);
+
+ if (getWidgetForPaintable().isMultiselect) {
+ getWidgetForPaintable().multiSelectMode = uidl
+ .getIntAttribute("multiselectmode");
+ }
+
+ getWidgetForPaintable().selectedIds = uidl
+ .getStringArrayVariableAsSet("selected");
+
+ // Update lastSelection and focusedNode to point to *actual* nodes again
+ // after the old ones have been cleared from the body. This fixes focus
+ // and keyboard navigation issues as described in #7057 and other
+ // tickets.
+ if (getWidgetForPaintable().lastSelection != null) {
+ getWidgetForPaintable().lastSelection = getWidgetForPaintable()
+ .getNodeByKey(getWidgetForPaintable().lastSelection.key);
+ }
+ if (getWidgetForPaintable().focusedNode != null) {
+ getWidgetForPaintable().setFocusedNode(
+ getWidgetForPaintable().getNodeByKey(
+ getWidgetForPaintable().focusedNode.key));
+ }
+
+ if (getWidgetForPaintable().lastSelection == null
+ && getWidgetForPaintable().focusedNode == null
+ && !getWidgetForPaintable().selectedIds.isEmpty()) {
+ getWidgetForPaintable().setFocusedNode(
+ getWidgetForPaintable().getNodeByKey(
+ getWidgetForPaintable().selectedIds.iterator()
+ .next()));
+ getWidgetForPaintable().focusedNode.setFocused(false);
+ }
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTree.class);
+ }
+
+ @Override
+ public VTree getWidgetForPaintable() {
+ return (VTree) super.getWidgetForPaintable();
+ }
+
+ private void handleUpdate(UIDL uidl) {
+ final TreeNode rootNode = getWidgetForPaintable().getNodeByKey(
+ uidl.getStringAttribute("rootKey"));
+ if (rootNode != null) {
+ if (!rootNode.getState()) {
+ // expanding node happened server side
+ rootNode.setState(true, false);
+ }
+ renderChildNodes(rootNode, (Iterator) uidl.getChildIterator());
+ }
+ }
+
+ /**
+ * Registers action for the root and also for individual nodes
+ *
+ * @param uidl
+ */
+ private void updateActionMap(UIDL uidl) {
+ final Iterator<?> it = uidl.getChildIterator();
+ while (it.hasNext()) {
+ final UIDL action = (UIDL) it.next();
+ final String key = action.getStringAttribute("key");
+ final String caption = action.getStringAttribute("caption");
+ String iconUrl = null;
+ if (action.hasAttribute("icon")) {
+ iconUrl = getConnection().translateVaadinUri(
+ action.getStringAttribute("icon"));
+ }
+ getWidgetForPaintable().registerAction(key, caption, iconUrl);
+ }
+
+ }
+
+ public void updateNodeFromUIDL(TreeNode treeNode, UIDL uidl) {
+ String nodeKey = uidl.getStringAttribute("key");
+ treeNode.setText(uidl.getStringAttribute("caption"));
+ treeNode.key = nodeKey;
+
+ getWidgetForPaintable().registerNode(treeNode);
+
+ if (uidl.hasAttribute("al")) {
+ treeNode.actionKeys = uidl.getStringArrayAttribute("al");
+ }
+
+ if (uidl.getTag().equals("node")) {
+ if (uidl.getChildCount() == 0) {
+ treeNode.childNodeContainer.setVisible(false);
+ } else {
+ renderChildNodes(treeNode, (Iterator) uidl.getChildIterator());
+ treeNode.childrenLoaded = true;
+ }
+ } else {
+ treeNode.addStyleName(TreeNode.CLASSNAME + "-leaf");
+ }
+ if (uidl.hasAttribute("style")) {
+ treeNode.setNodeStyleName(uidl.getStringAttribute("style"));
+ }
+
+ String description = uidl.getStringAttribute("descr");
+ if (description != null && getConnection() != null) {
+ // Set tooltip
+ TooltipInfo info = new TooltipInfo(description);
+ getConnection().registerTooltip(this, nodeKey, info);
+ } else {
+ // Remove possible previous tooltip
+ getConnection().registerTooltip(this, nodeKey, null);
+ }
+
+ if (uidl.getBooleanAttribute("expanded") && !treeNode.getState()) {
+ treeNode.setState(true, false);
+ }
+
+ if (uidl.getBooleanAttribute("selected")) {
+ treeNode.setSelected(true);
+ // ensure that identifier is in selectedIds array (this may be a
+ // partial update)
+ getWidgetForPaintable().selectedIds.add(nodeKey);
+ }
+
+ treeNode.setIcon(uidl.getStringAttribute("icon"));
+ }
+
+ void renderChildNodes(TreeNode containerNode, Iterator<UIDL> i) {
+ containerNode.childNodeContainer.clear();
+ containerNode.childNodeContainer.setVisible(true);
+ while (i.hasNext()) {
+ final UIDL childUidl = i.next();
+ // actions are in bit weird place, don't mix them with children,
+ // but current node's actions
+ if ("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
+ continue;
+ }
+ final TreeNode childTree = getWidgetForPaintable().new TreeNode();
+ updateNodeFromUIDL(childTree, childUidl);
+ containerNode.childNodeContainer.add(childTree);
+ if (!i.hasNext()) {
+ childTree
+ .addStyleDependentName(childTree.isLeaf() ? "leaf-last"
+ : "last");
+ childTree.childNodeContainer.addStyleDependentName("last");
+ }
+ }
+ containerNode.childrenLoaded = true;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
index 0eddca0ed3..f0c284c2d0 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
@@ -223,29 +223,6 @@ public class VTreeTable extends VScrollTable {
}
}
- @Override
- public RenderSpace getAllocatedSpace(Widget child) {
- if (widgetInHierarchyColumn == child) {
- final int hierarchyAndIconWidth = getHierarchyAndIconWidth();
- final RenderSpace allocatedSpace = super
- .getAllocatedSpace(child);
- return new RenderSpace() {
- @Override
- public int getWidth() {
- return allocatedSpace.getWidth()
- - hierarchyAndIconWidth;
- }
-
- @Override
- public int getHeight() {
- return allocatedSpace.getHeight();
- }
-
- };
- }
- return super.getAllocatedSpace(child);
- }
-
private int getHierarchyAndIconWidth() {
int consumedSpace = treeSpacer.getOffsetWidth();
if (treeSpacer.getParentElement().getChildCount() > 2) {
@@ -824,4 +801,27 @@ public class VTreeTable extends VScrollTable {
int newTotalRows = uidl.getIntAttribute("totalrows");
setTotalRows(newTotalRows);
}
+
+ @Override
+ public RenderSpace getAllocatedSpace(Widget child) {
+ VTreeTableRow row = (VTreeTableRow) child.getParent();
+ if (row.widgetInHierarchyColumn == child) {
+ final int hierarchyAndIconWidth = row.getHierarchyAndIconWidth();
+ final RenderSpace allocatedSpace = super.getAllocatedSpace(child);
+ return new RenderSpace() {
+ @Override
+ public int getWidth() {
+ return allocatedSpace.getWidth() - hierarchyAndIconWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return allocatedSpace.getHeight();
+ }
+
+ };
+ }
+ return super.getAllocatedSpace(child);
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
index 9b6f03f612..8c159f43de 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
@@ -1,101 +1,101 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
-import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;
-
-public class VTreeTablePaintable extends VScrollTablePaintable {
- public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- FocusableScrollPanel widget = null;
- int scrollPosition = 0;
- if (getWidgetForPaintable().collapseRequest) {
- widget = (FocusableScrollPanel) getWidgetForPaintable()
- .getWidget(1);
- scrollPosition = widget.getScrollPosition();
- }
- getWidgetForPaintable().animationsEnabled = uidl
- .getBooleanAttribute("animate");
- getWidgetForPaintable().colIndexOfHierarchy = uidl
- .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
- .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
- int oldTotalRows = getWidgetForPaintable().getTotalRows();
- super.updateFromUIDL(uidl, client);
- if (getWidgetForPaintable().collapseRequest) {
- if (getWidgetForPaintable().collapsedRowKey != null
- && getWidgetForPaintable().scrollBody != null) {
- VScrollTableRow row = getWidgetForPaintable()
- .getRenderedRowByKey(
- getWidgetForPaintable().collapsedRowKey);
- if (row != null) {
- getWidgetForPaintable().setRowFocus(row);
- getWidgetForPaintable().focus();
- }
- }
-
- int scrollPosition2 = widget.getScrollPosition();
- if (scrollPosition != scrollPosition2) {
- widget.setScrollPosition(scrollPosition);
- }
-
- // check which rows are needed from the server and initiate a
- // deferred fetch
- getWidgetForPaintable().onScroll(null);
- }
- // Recalculate table size if collapse request, or if page length is zero
- // (not sent by server) and row count changes (#7908).
- if (getWidgetForPaintable().collapseRequest
- || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()
- .getTotalRows() != oldTotalRows)) {
- /*
- * Ensure that possibly removed/added scrollbars are considered.
- * Triggers row calculations, removes cached rows etc. Basically
- * cleans up state. Be careful if touching this, you will break
- * pageLength=0 if you remove this.
- */
- getWidgetForPaintable().triggerLazyColumnAdjustment(true);
-
- getWidgetForPaintable().collapseRequest = false;
- }
- if (uidl.hasAttribute("focusedRow")) {
- String key = uidl.getStringAttribute("focusedRow");
- getWidgetForPaintable().setRowFocus(
- getWidgetForPaintable().getRenderedRowByKey(key));
- getWidgetForPaintable().focusParentResponsePending = false;
- } else if (uidl.hasAttribute("clearFocusPending")) {
- // Special case to detect a response to a focusParent request that
- // does not return any focusedRow because the selected node has no
- // parent
- getWidgetForPaintable().focusParentResponsePending = false;
- }
-
- while (!getWidgetForPaintable().collapseRequest
- && !getWidgetForPaintable().focusParentResponsePending
- && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {
- // Keep replaying any queued events as long as we don't have any
- // potential content changes pending
- PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents
- .removeFirst();
- getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,
- event.shift);
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VTreeTable.class);
- }
-
- @Override
- public VTreeTable getWidgetForPaintable() {
- return (VTreeTable) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
+import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;
+
+public class VTreeTablePaintable extends VScrollTablePaintable {
+ public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ FocusableScrollPanel widget = null;
+ int scrollPosition = 0;
+ if (getWidgetForPaintable().collapseRequest) {
+ widget = (FocusableScrollPanel) getWidgetForPaintable()
+ .getWidget(1);
+ scrollPosition = widget.getScrollPosition();
+ }
+ getWidgetForPaintable().animationsEnabled = uidl
+ .getBooleanAttribute("animate");
+ getWidgetForPaintable().colIndexOfHierarchy = uidl
+ .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
+ .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
+ int oldTotalRows = getWidgetForPaintable().getTotalRows();
+ super.updateFromUIDL(uidl, client);
+ if (getWidgetForPaintable().collapseRequest) {
+ if (getWidgetForPaintable().collapsedRowKey != null
+ && getWidgetForPaintable().scrollBody != null) {
+ VScrollTableRow row = getWidgetForPaintable()
+ .getRenderedRowByKey(
+ getWidgetForPaintable().collapsedRowKey);
+ if (row != null) {
+ getWidgetForPaintable().setRowFocus(row);
+ getWidgetForPaintable().focus();
+ }
+ }
+
+ int scrollPosition2 = widget.getScrollPosition();
+ if (scrollPosition != scrollPosition2) {
+ widget.setScrollPosition(scrollPosition);
+ }
+
+ // check which rows are needed from the server and initiate a
+ // deferred fetch
+ getWidgetForPaintable().onScroll(null);
+ }
+ // Recalculate table size if collapse request, or if page length is zero
+ // (not sent by server) and row count changes (#7908).
+ if (getWidgetForPaintable().collapseRequest
+ || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()
+ .getTotalRows() != oldTotalRows)) {
+ /*
+ * Ensure that possibly removed/added scrollbars are considered.
+ * Triggers row calculations, removes cached rows etc. Basically
+ * cleans up state. Be careful if touching this, you will break
+ * pageLength=0 if you remove this.
+ */
+ getWidgetForPaintable().triggerLazyColumnAdjustment(true);
+
+ getWidgetForPaintable().collapseRequest = false;
+ }
+ if (uidl.hasAttribute("focusedRow")) {
+ String key = uidl.getStringAttribute("focusedRow");
+ getWidgetForPaintable().setRowFocus(
+ getWidgetForPaintable().getRenderedRowByKey(key));
+ getWidgetForPaintable().focusParentResponsePending = false;
+ } else if (uidl.hasAttribute("clearFocusPending")) {
+ // Special case to detect a response to a focusParent request that
+ // does not return any focusedRow because the selected node has no
+ // parent
+ getWidgetForPaintable().focusParentResponsePending = false;
+ }
+
+ while (!getWidgetForPaintable().collapseRequest
+ && !getWidgetForPaintable().focusParentResponsePending
+ && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {
+ // Keep replaying any queued events as long as we don't have any
+ // potential content changes pending
+ PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents
+ .removeFirst();
+ getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,
+ event.shift);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTreeTable.class);
+ }
+
+ @Override
+ public VTreeTable getWidgetForPaintable() {
+ return (VTreeTable) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
index e733b2e73b..a7fe89017b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
@@ -26,7 +26,6 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
@@ -616,8 +615,4 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
return null;
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java
index 5378218ece..71c6d91c69 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java
@@ -1,17 +1,20 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-
-public class VVerticalLayoutPaintable extends VOrderedLayoutPaintable {
-
- @Override
- public VVerticalLayout getWidgetForPaintable() {
- return (VVerticalLayout) super.getWidgetForPaintable();
- }
-
- @Override
- protected VVerticalLayout createWidget() {
- return GWT.create(VVerticalLayout.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VVerticalLayoutPaintable extends VOrderedLayoutPaintable {
+
+ @Override
+ public VVerticalLayout getWidgetForPaintable() {
+ return (VVerticalLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected VVerticalLayout createWidget() {
+ return GWT.create(VVerticalLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
index d60a3185af..a2dc1fbbb2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
@@ -1,12 +1,15 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-
-public class VVerticalSplitPanelPaintable extends VAbstractSplitPanelPaintable {
-
- @Override
- protected VAbstractSplitPanel createWidget() {
- return GWT.create(VSplitPanelVertical.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VVerticalSplitPanelPaintable extends VAbstractSplitPanelPaintable {
+
+ @Override
+ protected VAbstractSplitPanel createWidget() {
+ return GWT.create(VSplitPanelVertical.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
index a9a46671be..53b79344cf 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
@@ -1,38 +1,41 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VVideoPaintable extends VMediaBasePaintable {
- public static final String ATTR_POSTER = "poster";
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- super.updateFromUIDL(uidl, client);
- setPosterFromUIDL(uidl);
- }
-
- private void setPosterFromUIDL(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_POSTER)) {
- getWidgetForPaintable().setPoster(
- getConnection().translateVaadinUri(
- uidl.getStringAttribute(ATTR_POSTER)));
- }
- }
-
- @Override
- public VVideo getWidgetForPaintable() {
- return (VVideo) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VVideo.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VVideoPaintable extends VMediaBasePaintable {
+ public static final String ATTR_POSTER = "poster";
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+ super.updateFromUIDL(uidl, client);
+ setPosterFromUIDL(uidl);
+ }
+
+ private void setPosterFromUIDL(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_POSTER)) {
+ getWidgetForPaintable().setPoster(
+ getConnection().translateVaadinUri(
+ uidl.getStringAttribute(ATTR_POSTER)));
+ }
+ }
+
+ @Override
+ public VVideo getWidgetForPaintable() {
+ return (VVideo) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VVideo.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java
index 7002c6279f..ea5610cdaa 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VView.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java
@@ -553,8 +553,4 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
getElement().focus();
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
index ebec292ecb..94e7bfd9af 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
@@ -1,331 +1,338 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashSet;
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VViewPaintable extends VAbstractPaintableWidgetContainer {
-
- private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
-
- public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- getWidgetForPaintable().id = uidl.getId();
- boolean firstPaint = getWidgetForPaintable().connection == null;
- getWidgetForPaintable().connection = client;
-
- getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
- getWidgetForPaintable().resizeLazy = uidl
- .hasAttribute(VView.RESIZE_LAZY);
- String newTheme = uidl.getStringAttribute("theme");
- if (getWidgetForPaintable().theme != null
- && !newTheme.equals(getWidgetForPaintable().theme)) {
- // Complete page refresh is needed due css can affect layout
- // calculations etc
- getWidgetForPaintable().reloadHostPage();
- } else {
- getWidgetForPaintable().theme = newTheme;
- }
- if (uidl.hasAttribute("style")) {
- getWidgetForPaintable().setStyleName(
- getWidgetForPaintable().getStylePrimaryName() + " "
- + uidl.getStringAttribute("style"));
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- if (!getWidgetForPaintable().isEmbedded()
- && uidl.hasAttribute("caption")) {
- // only change window title if we're in charge of the whole page
- com.google.gwt.user.client.Window.setTitle(uidl
- .getStringAttribute("caption"));
- }
-
- // Process children
- int childIndex = 0;
-
- // Open URL:s
- boolean isClosed = false; // was this window closed?
- while (childIndex < uidl.getChildCount()
- && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
- final UIDL open = uidl.getChildUIDL(childIndex);
- final String url = client.translateVaadinUri(open
- .getStringAttribute("src"));
- final String target = open.getStringAttribute("name");
- if (target == null) {
- // source will be opened to this browser window, but we may have
- // to finish rendering this window in case this is a download
- // (and window stays open).
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- VView.goTo(url);
- }
- });
- } else if ("_self".equals(target)) {
- // This window is closing (for sure). Only other opens are
- // relevant in this change. See #3558, #2144
- isClosed = true;
- VView.goTo(url);
- } else {
- String options;
- if (open.hasAttribute("border")) {
- if (open.getStringAttribute("border").equals("minimal")) {
- options = "menubar=yes,location=no,status=no";
- } else {
- options = "menubar=no,location=no,status=no";
- }
-
- } else {
- options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
- }
-
- if (open.hasAttribute("width")) {
- int w = open.getIntAttribute("width");
- options += ",width=" + w;
- }
- if (open.hasAttribute("height")) {
- int h = open.getIntAttribute("height");
- options += ",height=" + h;
- }
-
- Window.open(url, target, options);
- }
- childIndex++;
- }
- if (isClosed) {
- // don't render the content, something else will be opened to this
- // browser view
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- // Draw this application level window
- UIDL childUidl = uidl.getChildUIDL(childIndex);
- final VPaintableWidget lo = client.getPaintable(childUidl);
-
- if (getWidgetForPaintable().layout != null) {
- if (getWidgetForPaintable().layout != lo) {
- // remove old
- client.unregisterPaintable(getWidgetForPaintable().layout);
- // add new
- getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
- getWidgetForPaintable().layout = lo;
- }
- } else {
- getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
- getWidgetForPaintable().layout = lo;
- }
-
- getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
- if (!childUidl.getBooleanAttribute("cached")) {
- getWidgetForPaintable().updateParentFrameSize();
- }
-
- // Save currently open subwindows to track which will need to be closed
- final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(
- getWidgetForPaintable().subWindows);
-
- // Handle other UIDL children
- while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {
- String tag = childUidl.getTag().intern();
- if (tag == "actions") {
- if (getWidgetForPaintable().actionHandler == null) {
- getWidgetForPaintable().actionHandler = new ShortcutActionHandler(
- getWidgetForPaintable().id, client);
- }
- getWidgetForPaintable().actionHandler
- .updateActionMap(childUidl);
- } else if (tag == "execJS") {
- String script = childUidl.getStringAttribute("script");
- VView.eval(script);
- } else if (tag == "notifications") {
- for (final Iterator<?> it = childUidl.getChildIterator(); it
- .hasNext();) {
- final UIDL notification = (UIDL) it.next();
- VNotification.showNotification(client, notification);
- }
- } else {
- // subwindows
- final VPaintableWidget w = client.getPaintable(childUidl);
- if (getWidgetForPaintable().subWindows.contains(w)) {
- removedSubWindows.remove(w);
- } else {
- getWidgetForPaintable().subWindows.add((VWindow) w);
- }
- w.updateFromUIDL(childUidl, client);
- }
- }
-
- // Close old windows which where not in UIDL anymore
- for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem
- .hasNext();) {
- final VWindow w = rem.next();
- client.unregisterPaintable(VPaintableMap.get(getConnection())
- .getPaintable(w));
- getWidgetForPaintable().subWindows.remove(w);
- w.hide();
- }
-
- if (uidl.hasAttribute("focused")) {
- // set focused component when render phase is finished
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- VPaintableWidget paintable = (VPaintableWidget) uidl
- .getPaintableAttribute("focused", getConnection());
-
- final Widget toBeFocused = paintable
- .getWidgetForPaintable();
- /*
- * Two types of Widgets can be focused, either implementing
- * GWT HasFocus of a thinner Vaadin specific Focusable
- * interface.
- */
- if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
- final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
- toBeFocusedWidget.setFocus(true);
- } else if (toBeFocused instanceof Focusable) {
- ((Focusable) toBeFocused).focus();
- } else {
- VConsole.log("Could not focus component");
- }
- }
- });
- }
-
- // Add window listeners on first paint, to prevent premature
- // variablechanges
- if (firstPaint) {
- Window.addWindowClosingHandler(getWidgetForPaintable());
- Window.addResizeHandler(getWidgetForPaintable());
- }
-
- getWidgetForPaintable().onResize();
-
- // finally set scroll position from UIDL
- if (uidl.hasVariable("scrollTop")) {
- getWidgetForPaintable().scrollable = true;
- getWidgetForPaintable().scrollTop = uidl
- .getIntVariable("scrollTop");
- DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
- "scrollTop", getWidgetForPaintable().scrollTop);
- getWidgetForPaintable().scrollLeft = uidl
- .getIntVariable("scrollLeft");
- DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
- "scrollLeft", getWidgetForPaintable().scrollLeft);
- } else {
- getWidgetForPaintable().scrollable = false;
- }
-
- // Safari workaround must be run after scrollTop is updated as it sets
- // scrollTop using a deferred command.
- if (BrowserInfo.get().isSafari()) {
- Util.runWebkitOverflowAutoFix(getWidgetForPaintable().getElement());
- }
-
- getWidgetForPaintable().scrollIntoView(uidl);
-
- if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) {
- getWidgetForPaintable().currentFragment = uidl
- .getStringAttribute(VView.FRAGMENT_VARIABLE);
- if (!getWidgetForPaintable().currentFragment.equals(History
- .getToken())) {
- History.newItem(getWidgetForPaintable().currentFragment, true);
- }
- } else {
- // Initial request for which the server doesn't yet have a fragment
- // (and haven't shown any interest in getting one)
- getWidgetForPaintable().currentFragment = History.getToken();
-
- // Include current fragment in the next request
- client.updateVariable(getWidgetForPaintable().id,
- VView.FRAGMENT_VARIABLE,
- getWidgetForPaintable().currentFragment, false);
- }
-
- getWidgetForPaintable().rendering = false;
- }
-
- public void init(String rootPanelId,
- ApplicationConnection applicationConnection) {
- DOM.sinkEvents(getWidgetForPaintable().getElement(), Event.ONKEYDOWN
- | Event.ONSCROLL);
-
- // iview is focused when created so element needs tabIndex
- // 1 due 0 is at the end of natural tabbing order
- DOM.setElementProperty(getWidgetForPaintable().getElement(),
- "tabIndex", "1");
-
- RootPanel root = RootPanel.get(rootPanelId);
-
- // Remove the v-app-loading or any splash screen added inside the div by
- // the user
- root.getElement().setInnerHTML("");
- // For backwards compatibility with static index pages only.
- // No longer added by AbstractApplicationServlet/Portlet
- root.removeStyleName("v-app-loading");
-
- String themeUri = applicationConnection.getConfiguration()
- .getThemeUri();
- String themeName = themeUri.substring(themeUri.lastIndexOf('/'));
- themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");
- root.addStyleName("v-theme-" + themeName);
-
- root.add(getWidgetForPaintable());
-
- if (applicationConnection.getConfiguration().isStandalone()) {
- // set focus to iview element by default to listen possible keyboard
- // shortcuts. For embedded applications this is unacceptable as we
- // don't want to steal focus from the main page nor we don't want
- // side-effects from focusing (scrollIntoView).
- getWidgetForPaintable().getElement().focus();
- }
-
- getWidgetForPaintable().parentFrame = VView.getParentFrame();
- }
-
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP The main view never draws caption for its layout
- }
-
- @Override
- public VView getWidgetForPaintable() {
- return (VView) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VView.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.Focusable;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VViewPaintable extends VAbstractPaintableWidgetContainer {
+
+ private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
+
+ public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ // As VView is not created in the same way as all other paintables we
+ // have to set the id here
+ setId(uidl.getId());
+ getWidgetForPaintable().id = uidl.getId();
+ boolean firstPaint = getWidgetForPaintable().connection == null;
+ getWidgetForPaintable().connection = client;
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+ getWidgetForPaintable().resizeLazy = uidl
+ .hasAttribute(VView.RESIZE_LAZY);
+ String newTheme = uidl.getStringAttribute("theme");
+ if (getWidgetForPaintable().theme != null
+ && !newTheme.equals(getWidgetForPaintable().theme)) {
+ // Complete page refresh is needed due css can affect layout
+ // calculations etc
+ getWidgetForPaintable().reloadHostPage();
+ } else {
+ getWidgetForPaintable().theme = newTheme;
+ }
+ if (uidl.hasAttribute("style")) {
+ getWidgetForPaintable().setStyleName(
+ getWidgetForPaintable().getStylePrimaryName() + " "
+ + uidl.getStringAttribute("style"));
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ if (!getWidgetForPaintable().isEmbedded()
+ && uidl.hasAttribute("caption")) {
+ // only change window title if we're in charge of the whole page
+ com.google.gwt.user.client.Window.setTitle(uidl
+ .getStringAttribute("caption"));
+ }
+
+ // Process children
+ int childIndex = 0;
+
+ // Open URL:s
+ boolean isClosed = false; // was this window closed?
+ while (childIndex < uidl.getChildCount()
+ && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
+ final UIDL open = uidl.getChildUIDL(childIndex);
+ final String url = client.translateVaadinUri(open
+ .getStringAttribute("src"));
+ final String target = open.getStringAttribute("name");
+ if (target == null) {
+ // source will be opened to this browser window, but we may have
+ // to finish rendering this window in case this is a download
+ // (and window stays open).
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ VView.goTo(url);
+ }
+ });
+ } else if ("_self".equals(target)) {
+ // This window is closing (for sure). Only other opens are
+ // relevant in this change. See #3558, #2144
+ isClosed = true;
+ VView.goTo(url);
+ } else {
+ String options;
+ if (open.hasAttribute("border")) {
+ if (open.getStringAttribute("border").equals("minimal")) {
+ options = "menubar=yes,location=no,status=no";
+ } else {
+ options = "menubar=no,location=no,status=no";
+ }
+
+ } else {
+ options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
+ }
+
+ if (open.hasAttribute("width")) {
+ int w = open.getIntAttribute("width");
+ options += ",width=" + w;
+ }
+ if (open.hasAttribute("height")) {
+ int h = open.getIntAttribute("height");
+ options += ",height=" + h;
+ }
+
+ Window.open(url, target, options);
+ }
+ childIndex++;
+ }
+ if (isClosed) {
+ // don't render the content, something else will be opened to this
+ // browser view
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ // Draw this application level window
+ UIDL childUidl = uidl.getChildUIDL(childIndex);
+ final VPaintableWidget lo = client.getPaintable(childUidl);
+
+ if (getWidgetForPaintable().layout != null) {
+ if (getWidgetForPaintable().layout != lo) {
+ // remove old
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ // add new
+ getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+ } else {
+ getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+
+ getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
+ if (!childUidl.getBooleanAttribute("cached")) {
+ getWidgetForPaintable().updateParentFrameSize();
+ }
+
+ // Save currently open subwindows to track which will need to be closed
+ final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(
+ getWidgetForPaintable().subWindows);
+
+ // Handle other UIDL children
+ while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {
+ String tag = childUidl.getTag().intern();
+ if (tag == "actions") {
+ if (getWidgetForPaintable().actionHandler == null) {
+ getWidgetForPaintable().actionHandler = new ShortcutActionHandler(
+ getWidgetForPaintable().id, client);
+ }
+ getWidgetForPaintable().actionHandler
+ .updateActionMap(childUidl);
+ } else if (tag == "execJS") {
+ String script = childUidl.getStringAttribute("script");
+ VView.eval(script);
+ } else if (tag == "notifications") {
+ for (final Iterator<?> it = childUidl.getChildIterator(); it
+ .hasNext();) {
+ final UIDL notification = (UIDL) it.next();
+ VNotification.showNotification(client, notification);
+ }
+ } else {
+ // subwindows
+ final VWindowPaintable w = (VWindowPaintable) client
+ .getPaintable(childUidl);
+ VWindow windowWidget = w.getWidgetForPaintable();
+ if (getWidgetForPaintable().subWindows.contains(windowWidget)) {
+ removedSubWindows.remove(windowWidget);
+ } else {
+ getWidgetForPaintable().subWindows.add(windowWidget);
+ }
+ w.updateFromUIDL(childUidl, client);
+ }
+ }
+
+ // Close old windows which where not in UIDL anymore
+ for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem
+ .hasNext();) {
+ final VWindow w = rem.next();
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(w));
+ getWidgetForPaintable().subWindows.remove(w);
+ w.hide();
+ }
+
+ if (uidl.hasAttribute("focused")) {
+ // set focused component when render phase is finished
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ VPaintableWidget paintable = (VPaintableWidget) uidl
+ .getPaintableAttribute("focused", getConnection());
+
+ final Widget toBeFocused = paintable
+ .getWidgetForPaintable();
+ /*
+ * Two types of Widgets can be focused, either implementing
+ * GWT HasFocus of a thinner Vaadin specific Focusable
+ * interface.
+ */
+ if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
+ final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
+ toBeFocusedWidget.setFocus(true);
+ } else if (toBeFocused instanceof Focusable) {
+ ((Focusable) toBeFocused).focus();
+ } else {
+ VConsole.log("Could not focus component");
+ }
+ }
+ });
+ }
+
+ // Add window listeners on first paint, to prevent premature
+ // variablechanges
+ if (firstPaint) {
+ Window.addWindowClosingHandler(getWidgetForPaintable());
+ Window.addResizeHandler(getWidgetForPaintable());
+ }
+
+ getWidgetForPaintable().onResize();
+
+ // finally set scroll position from UIDL
+ if (uidl.hasVariable("scrollTop")) {
+ getWidgetForPaintable().scrollable = true;
+ getWidgetForPaintable().scrollTop = uidl
+ .getIntVariable("scrollTop");
+ DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
+ "scrollTop", getWidgetForPaintable().scrollTop);
+ getWidgetForPaintable().scrollLeft = uidl
+ .getIntVariable("scrollLeft");
+ DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
+ "scrollLeft", getWidgetForPaintable().scrollLeft);
+ } else {
+ getWidgetForPaintable().scrollable = false;
+ }
+
+ // Safari workaround must be run after scrollTop is updated as it sets
+ // scrollTop using a deferred command.
+ if (BrowserInfo.get().isSafari()) {
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().getElement());
+ }
+
+ getWidgetForPaintable().scrollIntoView(uidl);
+
+ if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) {
+ getWidgetForPaintable().currentFragment = uidl
+ .getStringAttribute(VView.FRAGMENT_VARIABLE);
+ if (!getWidgetForPaintable().currentFragment.equals(History
+ .getToken())) {
+ History.newItem(getWidgetForPaintable().currentFragment, true);
+ }
+ } else {
+ // Initial request for which the server doesn't yet have a fragment
+ // (and haven't shown any interest in getting one)
+ getWidgetForPaintable().currentFragment = History.getToken();
+
+ // Include current fragment in the next request
+ client.updateVariable(getWidgetForPaintable().id,
+ VView.FRAGMENT_VARIABLE,
+ getWidgetForPaintable().currentFragment, false);
+ }
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void init(String rootPanelId,
+ ApplicationConnection applicationConnection) {
+ DOM.sinkEvents(getWidgetForPaintable().getElement(), Event.ONKEYDOWN
+ | Event.ONSCROLL);
+
+ // iview is focused when created so element needs tabIndex
+ // 1 due 0 is at the end of natural tabbing order
+ DOM.setElementProperty(getWidgetForPaintable().getElement(),
+ "tabIndex", "1");
+
+ RootPanel root = RootPanel.get(rootPanelId);
+
+ // Remove the v-app-loading or any splash screen added inside the div by
+ // the user
+ root.getElement().setInnerHTML("");
+ // For backwards compatibility with static index pages only.
+ // No longer added by AbstractApplicationServlet/Portlet
+ root.removeStyleName("v-app-loading");
+
+ String themeUri = applicationConnection.getConfiguration()
+ .getThemeUri();
+ String themeName = themeUri.substring(themeUri.lastIndexOf('/'));
+ themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");
+ root.addStyleName("v-theme-" + themeName);
+
+ root.add(getWidgetForPaintable());
+
+ if (applicationConnection.getConfiguration().isStandalone()) {
+ // set focus to iview element by default to listen possible keyboard
+ // shortcuts. For embedded applications this is unacceptable as we
+ // don't want to steal focus from the main page nor we don't want
+ // side-effects from focusing (scrollIntoView).
+ getWidgetForPaintable().getElement().focus();
+ }
+
+ getWidgetForPaintable().parentFrame = VView.getParentFrame();
+ }
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP The main view never draws caption for its layout
+ }
+
+ @Override
+ public VView getWidgetForPaintable() {
+ return (VView) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VView.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
index 662b77a7b0..d4c8f74605 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
@@ -643,7 +643,7 @@ public class VWindow extends VOverlay implements Container,
}
private void onResizeEvent(Event event) {
- if (resizable) {
+ if (resizable && Util.isTouchEventOrLeftMouseButton(event)) {
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
case Event.ONTOUCHSTART:
@@ -860,6 +860,10 @@ public class VWindow extends VOverlay implements Container,
}
private void onDragEvent(Event event) {
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
+
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
if (event.getTouches().length() > 1) {
@@ -971,7 +975,7 @@ public class VWindow extends VOverlay implements Container,
}
public RenderSpace getAllocatedSpace(Widget child) {
- if (child == layout) {
+ if (child == layout.getWidgetForPaintable()) {
return renderSpace;
} else {
// Exception ??
@@ -980,7 +984,7 @@ public class VWindow extends VOverlay implements Container,
}
public boolean hasChildComponent(Widget component) {
- if (component == layout) {
+ if (component == layout.getWidgetForPaintable()) {
return true;
} else {
return false;
@@ -1040,8 +1044,4 @@ public class VWindow extends VOverlay implements Container,
contentPanel.focus();
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
index 25fd951dd9..633e28d0c3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
@@ -1,296 +1,299 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Frame;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
-
-public class VWindowPaintable extends VAbstractPaintableWidgetContainer
- implements BeforeShortcutActionListener {
-
- private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
-
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return getWidgetForPaintable().addDomHandler(handler, type);
- }
- };
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().id = uidl.getId();
- getWidgetForPaintable().client = client;
-
- // Workaround needed for Testing Tools (GWT generates window DOM
- // slightly different in different browsers).
- DOM.setElementProperty(getWidgetForPaintable().closeBox, "id",
- getWidgetForPaintable().id + "_window_close");
-
- if (uidl.hasAttribute("invisible")) {
- getWidgetForPaintable().hide();
- return;
- }
-
- if (!uidl.hasAttribute("cached")) {
- if (uidl.getBooleanAttribute("modal") != getWidgetForPaintable().vaadinModality) {
- getWidgetForPaintable().setVaadinModality(
- !getWidgetForPaintable().vaadinModality);
- }
- if (!getWidgetForPaintable().isAttached()) {
- getWidgetForPaintable().setVisible(false); // hide until
- // possible centering
- getWidgetForPaintable().show();
- }
- if (uidl.getBooleanAttribute("resizable") != getWidgetForPaintable().resizable) {
- getWidgetForPaintable().setResizable(
- !getWidgetForPaintable().resizable);
- }
- getWidgetForPaintable().resizeLazy = uidl
- .hasAttribute(VView.RESIZE_LAZY);
-
- getWidgetForPaintable().setDraggable(
- !uidl.hasAttribute("fixedposition"));
-
- // Caption must be set before required header size is measured. If
- // the caption attribute is missing the caption should be cleared.
- getWidgetForPaintable().setCaption(
- uidl.getStringAttribute("caption"),
- uidl.getStringAttribute("icon"));
- }
-
- getWidgetForPaintable().visibilityChangesDisabled = true;
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
- getWidgetForPaintable().visibilityChangesDisabled = false;
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
-
- getWidgetForPaintable().setClosable(
- !uidl.getBooleanAttribute("readonly"));
-
- // Initialize the position form UIDL
- int positionx = uidl.getIntVariable("positionx");
- int positiony = uidl.getIntVariable("positiony");
- if (positionx >= 0 || positiony >= 0) {
- if (positionx < 0) {
- positionx = 0;
- }
- if (positiony < 0) {
- positiony = 0;
- }
- getWidgetForPaintable().setPopupPosition(positionx, positiony);
- }
-
- boolean showingUrl = false;
- int childIndex = 0;
- UIDL childUidl = uidl.getChildUIDL(childIndex++);
- while ("open".equals(childUidl.getTag())) {
- // TODO multiple opens with the same target will in practice just
- // open the last one - should we fix that somehow?
- final String parsedUri = client.translateVaadinUri(childUidl
- .getStringAttribute("src"));
- if (!childUidl.hasAttribute("name")) {
- final Frame frame = new Frame();
- DOM.setStyleAttribute(frame.getElement(), "width", "100%");
- DOM.setStyleAttribute(frame.getElement(), "height", "100%");
- DOM.setStyleAttribute(frame.getElement(), "border", "0px");
- frame.setUrl(parsedUri);
- getWidgetForPaintable().contentPanel.setWidget(frame);
- showingUrl = true;
- } else {
- final String target = childUidl.getStringAttribute("name");
- Window.open(parsedUri, target, "");
- }
- childUidl = uidl.getChildUIDL(childIndex++);
- }
-
- final VPaintableWidget lo = client.getPaintable(childUidl);
- if (getWidgetForPaintable().layout != null) {
- if (getWidgetForPaintable().layout != lo) {
- // remove old
- client.unregisterPaintable(getWidgetForPaintable().layout);
- getWidgetForPaintable().contentPanel
- .remove(getWidgetForPaintable().layout
- .getWidgetForPaintable());
- // add new
- if (!showingUrl) {
- getWidgetForPaintable().contentPanel.setWidget(lo
- .getWidgetForPaintable());
- }
- getWidgetForPaintable().layout = lo;
- }
- } else if (!showingUrl) {
- getWidgetForPaintable().contentPanel.setWidget(lo
- .getWidgetForPaintable());
- getWidgetForPaintable().layout = lo;
- }
-
- getWidgetForPaintable().dynamicWidth = !uidl.hasAttribute("width");
- getWidgetForPaintable().dynamicHeight = !uidl.hasAttribute("height");
-
- getWidgetForPaintable().layoutRelativeWidth = uidl
- .hasAttribute("layoutRelativeWidth");
- getWidgetForPaintable().layoutRelativeHeight = uidl
- .hasAttribute("layoutRelativeHeight");
-
- if (getWidgetForPaintable().dynamicWidth
- && getWidgetForPaintable().layoutRelativeWidth) {
- /*
- * Relative layout width, fix window width before rendering (width
- * according to caption)
- */
- getWidgetForPaintable().setNaturalWidth();
- }
-
- getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
- if (!getWidgetForPaintable().dynamicHeight
- && getWidgetForPaintable().layoutRelativeWidth) {
- /*
- * Relative layout width, and fixed height. Must update the size to
- * be able to take scrollbars into account (layout gets narrower
- * space if it is higher than the window) -> only vertical scrollbar
- */
- client.runDescendentsLayout(getWidgetForPaintable());
- }
-
- /*
- * No explicit width is set and the layout does not have relative width
- * so fix the size according to the layout.
- */
- if (getWidgetForPaintable().dynamicWidth
- && !getWidgetForPaintable().layoutRelativeWidth) {
- getWidgetForPaintable().setNaturalWidth();
- }
-
- if (getWidgetForPaintable().dynamicHeight
- && getWidgetForPaintable().layoutRelativeHeight) {
- // Prevent resizing until height has been fixed
- getWidgetForPaintable().resizable = false;
- }
-
- // we may have actions and notifications
- if (uidl.getChildCount() > 1) {
- final int cnt = uidl.getChildCount();
- for (int i = 1; i < cnt; i++) {
- childUidl = uidl.getChildUIDL(i);
- if (childUidl.getTag().equals("actions")) {
- if (getWidgetForPaintable().shortcutHandler == null) {
- getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
- getId(), client);
- }
- getWidgetForPaintable().shortcutHandler
- .updateActionMap(childUidl);
- }
- }
-
- }
-
- // setting scrollposition must happen after children is rendered
- getWidgetForPaintable().contentPanel.setScrollPosition(uidl
- .getIntVariable("scrollTop"));
- getWidgetForPaintable().contentPanel.setHorizontalScrollPosition(uidl
- .getIntVariable("scrollLeft"));
-
- // Center this window on screen if requested
- // This has to be here because we might not know the content size before
- // everything is painted into the window
- if (uidl.getBooleanAttribute("center")) {
- // mark as centered - this is unset on move/resize
- getWidgetForPaintable().centered = true;
- getWidgetForPaintable().center();
- } else {
- // don't try to center the window anymore
- getWidgetForPaintable().centered = false;
- }
- getWidgetForPaintable().updateShadowSizeAndPosition();
- getWidgetForPaintable().setVisible(true);
-
- boolean sizeReduced = false;
- // ensure window is not larger than browser window
- if (getWidgetForPaintable().getOffsetWidth() > Window.getClientWidth()) {
- getWidgetForPaintable().setWidth(Window.getClientWidth() + "px");
- sizeReduced = true;
- }
- if (getWidgetForPaintable().getOffsetHeight() > Window
- .getClientHeight()) {
- getWidgetForPaintable().setHeight(Window.getClientHeight() + "px");
- sizeReduced = true;
- }
-
- if (getWidgetForPaintable().dynamicHeight
- && getWidgetForPaintable().layoutRelativeHeight) {
- /*
- * Window height is undefined, layout is 100% high so the layout
- * should define the initial window height but on resize the layout
- * should be as high as the window. We fix the height to deal with
- * this.
- */
-
- int h = getWidgetForPaintable().contents.getOffsetHeight()
- + getWidgetForPaintable().getExtraHeight();
- int w = getWidgetForPaintable().getElement().getOffsetWidth();
-
- client.updateVariable(getId(), "height", h, false);
- client.updateVariable(getId(), "width", w, true);
- }
-
- if (sizeReduced) {
- // If we changed the size we need to update the size of the child
- // component if it is relative (#3407)
- client.runDescendentsLayout(getWidgetForPaintable());
- }
-
- Util.runWebkitOverflowAutoFix(getWidgetForPaintable().contentPanel
- .getElement());
-
- client.getView().getWidgetForPaintable().scrollIntoView(uidl);
-
- if (uidl.hasAttribute("bringToFront")) {
- /*
- * Focus as a side-efect. Will be overridden by
- * ApplicationConnection if another component was focused by the
- * server side.
- */
- getWidgetForPaintable().contentPanel.focus();
- getWidgetForPaintable().bringToFrontSequence = uidl
- .getIntAttribute("bringToFront");
- VWindow.deferOrdering();
- }
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, window has own caption, layout captio not rendered
- }
-
- public void onBeforeShortcutAction(Event e) {
- // NOP, nothing to update just avoid workaround ( causes excess
- // blur/focus )
- }
-
- @Override
- public VWindow getWidgetForPaintable() {
- return (VWindow) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VWindow.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Frame;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+
+public class VWindowPaintable extends VAbstractPaintableWidgetContainer
+ implements BeforeShortcutActionListener {
+
+ private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().client = client;
+
+ // Workaround needed for Testing Tools (GWT generates window DOM
+ // slightly different in different browsers).
+ DOM.setElementProperty(getWidgetForPaintable().closeBox, "id",
+ getWidgetForPaintable().id + "_window_close");
+
+ if (uidl.hasAttribute("invisible")) {
+ getWidgetForPaintable().hide();
+ return;
+ }
+
+ if (!uidl.hasAttribute("cached")) {
+ if (uidl.getBooleanAttribute("modal") != getWidgetForPaintable().vaadinModality) {
+ getWidgetForPaintable().setVaadinModality(
+ !getWidgetForPaintable().vaadinModality);
+ }
+ if (!getWidgetForPaintable().isAttached()) {
+ getWidgetForPaintable().setVisible(false); // hide until
+ // possible centering
+ getWidgetForPaintable().show();
+ }
+ if (uidl.getBooleanAttribute("resizable") != getWidgetForPaintable().resizable) {
+ getWidgetForPaintable().setResizable(
+ !getWidgetForPaintable().resizable);
+ }
+ getWidgetForPaintable().resizeLazy = uidl
+ .hasAttribute(VView.RESIZE_LAZY);
+
+ getWidgetForPaintable().setDraggable(
+ !uidl.hasAttribute("fixedposition"));
+
+ // Caption must be set before required header size is measured. If
+ // the caption attribute is missing the caption should be cleared.
+ getWidgetForPaintable().setCaption(
+ uidl.getStringAttribute("caption"),
+ uidl.getStringAttribute("icon"));
+ }
+
+ getWidgetForPaintable().visibilityChangesDisabled = true;
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+ getWidgetForPaintable().visibilityChangesDisabled = false;
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ getWidgetForPaintable().setClosable(
+ !uidl.getBooleanAttribute("readonly"));
+
+ // Initialize the position form UIDL
+ int positionx = uidl.getIntVariable("positionx");
+ int positiony = uidl.getIntVariable("positiony");
+ if (positionx >= 0 || positiony >= 0) {
+ if (positionx < 0) {
+ positionx = 0;
+ }
+ if (positiony < 0) {
+ positiony = 0;
+ }
+ getWidgetForPaintable().setPopupPosition(positionx, positiony);
+ }
+
+ boolean showingUrl = false;
+ int childIndex = 0;
+ UIDL childUidl = uidl.getChildUIDL(childIndex++);
+ while ("open".equals(childUidl.getTag())) {
+ // TODO multiple opens with the same target will in practice just
+ // open the last one - should we fix that somehow?
+ final String parsedUri = client.translateVaadinUri(childUidl
+ .getStringAttribute("src"));
+ if (!childUidl.hasAttribute("name")) {
+ final Frame frame = new Frame();
+ DOM.setStyleAttribute(frame.getElement(), "width", "100%");
+ DOM.setStyleAttribute(frame.getElement(), "height", "100%");
+ DOM.setStyleAttribute(frame.getElement(), "border", "0px");
+ frame.setUrl(parsedUri);
+ getWidgetForPaintable().contentPanel.setWidget(frame);
+ showingUrl = true;
+ } else {
+ final String target = childUidl.getStringAttribute("name");
+ Window.open(parsedUri, target, "");
+ }
+ childUidl = uidl.getChildUIDL(childIndex++);
+ }
+
+ final VPaintableWidget lo = client.getPaintable(childUidl);
+ if (getWidgetForPaintable().layout != null) {
+ if (getWidgetForPaintable().layout != lo) {
+ // remove old
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ getWidgetForPaintable().contentPanel
+ .remove(getWidgetForPaintable().layout
+ .getWidgetForPaintable());
+ // add new
+ if (!showingUrl) {
+ getWidgetForPaintable().contentPanel.setWidget(lo
+ .getWidgetForPaintable());
+ }
+ getWidgetForPaintable().layout = lo;
+ }
+ } else if (!showingUrl) {
+ getWidgetForPaintable().contentPanel.setWidget(lo
+ .getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+
+ getWidgetForPaintable().dynamicWidth = !uidl.hasAttribute("width");
+ getWidgetForPaintable().dynamicHeight = !uidl.hasAttribute("height");
+
+ getWidgetForPaintable().layoutRelativeWidth = uidl
+ .hasAttribute("layoutRelativeWidth");
+ getWidgetForPaintable().layoutRelativeHeight = uidl
+ .hasAttribute("layoutRelativeHeight");
+
+ if (getWidgetForPaintable().dynamicWidth
+ && getWidgetForPaintable().layoutRelativeWidth) {
+ /*
+ * Relative layout width, fix window width before rendering (width
+ * according to caption)
+ */
+ getWidgetForPaintable().setNaturalWidth();
+ }
+
+ getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
+ if (!getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeWidth) {
+ /*
+ * Relative layout width, and fixed height. Must update the size to
+ * be able to take scrollbars into account (layout gets narrower
+ * space if it is higher than the window) -> only vertical scrollbar
+ */
+ client.runDescendentsLayout(getWidgetForPaintable());
+ }
+
+ /*
+ * No explicit width is set and the layout does not have relative width
+ * so fix the size according to the layout.
+ */
+ if (getWidgetForPaintable().dynamicWidth
+ && !getWidgetForPaintable().layoutRelativeWidth) {
+ getWidgetForPaintable().setNaturalWidth();
+ }
+
+ if (getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeHeight) {
+ // Prevent resizing until height has been fixed
+ getWidgetForPaintable().resizable = false;
+ }
+
+ // we may have actions and notifications
+ if (uidl.getChildCount() > 1) {
+ final int cnt = uidl.getChildCount();
+ for (int i = 1; i < cnt; i++) {
+ childUidl = uidl.getChildUIDL(i);
+ if (childUidl.getTag().equals("actions")) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ }
+
+ }
+
+ // setting scrollposition must happen after children is rendered
+ getWidgetForPaintable().contentPanel.setScrollPosition(uidl
+ .getIntVariable("scrollTop"));
+ getWidgetForPaintable().contentPanel.setHorizontalScrollPosition(uidl
+ .getIntVariable("scrollLeft"));
+
+ // Center this window on screen if requested
+ // This has to be here because we might not know the content size before
+ // everything is painted into the window
+ if (uidl.getBooleanAttribute("center")) {
+ // mark as centered - this is unset on move/resize
+ getWidgetForPaintable().centered = true;
+ getWidgetForPaintable().center();
+ } else {
+ // don't try to center the window anymore
+ getWidgetForPaintable().centered = false;
+ }
+ getWidgetForPaintable().updateShadowSizeAndPosition();
+ getWidgetForPaintable().setVisible(true);
+
+ boolean sizeReduced = false;
+ // ensure window is not larger than browser window
+ if (getWidgetForPaintable().getOffsetWidth() > Window.getClientWidth()) {
+ getWidgetForPaintable().setWidth(Window.getClientWidth() + "px");
+ sizeReduced = true;
+ }
+ if (getWidgetForPaintable().getOffsetHeight() > Window
+ .getClientHeight()) {
+ getWidgetForPaintable().setHeight(Window.getClientHeight() + "px");
+ sizeReduced = true;
+ }
+
+ if (getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeHeight) {
+ /*
+ * Window height is undefined, layout is 100% high so the layout
+ * should define the initial window height but on resize the layout
+ * should be as high as the window. We fix the height to deal with
+ * this.
+ */
+
+ int h = getWidgetForPaintable().contents.getOffsetHeight()
+ + getWidgetForPaintable().getExtraHeight();
+ int w = getWidgetForPaintable().getElement().getOffsetWidth();
+
+ client.updateVariable(getId(), "height", h, false);
+ client.updateVariable(getId(), "width", w, true);
+ }
+
+ if (sizeReduced) {
+ // If we changed the size we need to update the size of the child
+ // component if it is relative (#3407)
+ client.runDescendentsLayout(getWidgetForPaintable());
+ }
+
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().contentPanel
+ .getElement());
+
+ client.getView().getWidgetForPaintable().scrollIntoView(uidl);
+
+ if (uidl.hasAttribute("bringToFront")) {
+ /*
+ * Focus as a side-efect. Will be overridden by
+ * ApplicationConnection if another component was focused by the
+ * server side.
+ */
+ getWidgetForPaintable().contentPanel.focus();
+ getWidgetForPaintable().bringToFrontSequence = uidl
+ .getIntAttribute("bringToFront");
+ VWindow.deferOrdering();
+ }
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, window has own caption, layout captio not rendered
+ }
+
+ public void onBeforeShortcutAction(Event e) {
+ // NOP, nothing to update just avoid workaround ( causes excess
+ // blur/focus )
+ }
+
+ @Override
+ public VWindow getWidgetForPaintable() {
+ return (VWindow) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VWindow.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
index 269afde25d..c57f705c75 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
@@ -1,71 +1,71 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui.label;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.PreElement;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
-
-public class VLabelPaintable extends VAbstractPaintableWidget {
- public VLabelPaintable() {
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- boolean sinkOnloads = false;
-
- final String mode = uidl.getStringAttribute("mode");
- if (mode == null || "text".equals(mode)) {
- getWidgetForPaintable().setText(uidl.getChildString(0));
- } else if ("pre".equals(mode)) {
- PreElement preElement = Document.get().createPreElement();
- preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));
- // clear existing content
- getWidgetForPaintable().setHTML("");
- // add preformatted text to dom
- getWidgetForPaintable().getElement().appendChild(preElement);
- } else if ("uidl".equals(mode)) {
- getWidgetForPaintable().setHTML(uidl.getChildrenAsXML());
- } else if ("xhtml".equals(mode)) {
- UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);
- if (content.getChildCount() > 0) {
- getWidgetForPaintable().setHTML(content.getChildString(0));
- } else {
- getWidgetForPaintable().setHTML("");
- }
- sinkOnloads = true;
- } else if ("xml".equals(mode)) {
- getWidgetForPaintable().setHTML(
- uidl.getChildUIDL(0).getChildString(0));
- } else if ("raw".equals(mode)) {
- getWidgetForPaintable().setHTML(
- uidl.getChildUIDL(0).getChildString(0));
- sinkOnloads = true;
- } else {
- getWidgetForPaintable().setText("");
- }
- if (sinkOnloads) {
- Util.sinkOnloadForImages(getWidgetForPaintable().getElement());
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VLabel.class);
- }
-
- @Override
- public VLabel getWidgetForPaintable() {
- return (VLabel) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.label;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.PreElement;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+
+public class VLabelPaintable extends VAbstractPaintableWidget {
+ public VLabelPaintable() {
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ boolean sinkOnloads = false;
+
+ final String mode = uidl.getStringAttribute("mode");
+ if (mode == null || "text".equals(mode)) {
+ getWidgetForPaintable().setText(uidl.getChildString(0));
+ } else if ("pre".equals(mode)) {
+ PreElement preElement = Document.get().createPreElement();
+ preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));
+ // clear existing content
+ getWidgetForPaintable().setHTML("");
+ // add preformatted text to dom
+ getWidgetForPaintable().getElement().appendChild(preElement);
+ } else if ("uidl".equals(mode)) {
+ getWidgetForPaintable().setHTML(uidl.getChildrenAsXML());
+ } else if ("xhtml".equals(mode)) {
+ UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);
+ if (content.getChildCount() > 0) {
+ getWidgetForPaintable().setHTML(content.getChildString(0));
+ } else {
+ getWidgetForPaintable().setHTML("");
+ }
+ sinkOnloads = true;
+ } else if ("xml".equals(mode)) {
+ getWidgetForPaintable().setHTML(
+ uidl.getChildUIDL(0).getChildString(0));
+ } else if ("raw".equals(mode)) {
+ getWidgetForPaintable().setHTML(
+ uidl.getChildUIDL(0).getChildString(0));
+ sinkOnloads = true;
+ } else {
+ getWidgetForPaintable().setText("");
+ }
+ if (sinkOnloads) {
+ Util.sinkOnloadForImages(getWidgetForPaintable().getElement());
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VLabel.class);
+ }
+
+ @Override
+ public VLabel getWidgetForPaintable() {
+ return (VLabel) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java
index e99425311b..c41652fb3d 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java
@@ -1,81 +1,84 @@
-package com.vaadin.terminal.gwt.client.ui.layout;
-
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidgetContainer;
-import com.vaadin.terminal.gwt.client.ui.VMarginInfo;
-
-public abstract class CellBasedLayoutPaintable extends
- VAbstractPaintableWidgetContainer {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
-
- // Only non-cached UIDL:s can introduce changes
- if (uidl.getBooleanAttribute("cached")) {
- return;
- }
-
- /**
- * Margin and spacind detection depends on classNames and must be set
- * before setting size. Here just update the details from UIDL and from
- * overridden setStyleName run actual margin detections.
- */
- updateMarginAndSpacingInfo(uidl);
-
- /*
- * This call should be made first. Ensure correct implementation, handle
- * size etc.
- */
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- handleDynamicDimensions(uidl);
- }
-
- private void handleDynamicDimensions(UIDL uidl) {
- String w = uidl.hasAttribute("width") ? uidl
- .getStringAttribute("width") : "";
-
- String h = uidl.hasAttribute("height") ? uidl
- .getStringAttribute("height") : "";
-
- if (w.equals("")) {
- getWidgetForPaintable().dynamicWidth = true;
- } else {
- getWidgetForPaintable().dynamicWidth = false;
- }
-
- if (h.equals("")) {
- getWidgetForPaintable().dynamicHeight = true;
- } else {
- getWidgetForPaintable().dynamicHeight = false;
- }
-
- }
-
- void updateMarginAndSpacingInfo(UIDL uidl) {
- if (!uidl.hasAttribute("invisible")) {
- int bitMask = uidl.getIntAttribute("margins");
- if (getWidgetForPaintable().activeMarginsInfo.getBitMask() != bitMask) {
- getWidgetForPaintable().activeMarginsInfo = new VMarginInfo(
- bitMask);
- getWidgetForPaintable().marginsNeedsRecalculation = true;
- }
- boolean spacing = uidl.getBooleanAttribute("spacing");
- if (spacing != getWidgetForPaintable().spacingEnabled) {
- getWidgetForPaintable().marginsNeedsRecalculation = true;
- getWidgetForPaintable().spacingEnabled = spacing;
- }
- }
- }
-
- @Override
- protected abstract CellBasedLayout createWidget();
-
- @Override
- public CellBasedLayout getWidgetForPaintable() {
- return (CellBasedLayout) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.layout;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidgetContainer;
+import com.vaadin.terminal.gwt.client.ui.VMarginInfo;
+
+public abstract class CellBasedLayoutPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+
+ // Only non-cached UIDL:s can introduce changes
+ if (uidl.getBooleanAttribute("cached")) {
+ return;
+ }
+
+ /**
+ * Margin and spacind detection depends on classNames and must be set
+ * before setting size. Here just update the details from UIDL and from
+ * overridden setStyleName run actual margin detections.
+ */
+ updateMarginAndSpacingInfo(uidl);
+
+ /*
+ * This call should be made first. Ensure correct implementation, handle
+ * size etc.
+ */
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ handleDynamicDimensions(uidl);
+ }
+
+ private void handleDynamicDimensions(UIDL uidl) {
+ String w = uidl.hasAttribute("width") ? uidl
+ .getStringAttribute("width") : "";
+
+ String h = uidl.hasAttribute("height") ? uidl
+ .getStringAttribute("height") : "";
+
+ if (w.equals("")) {
+ getWidgetForPaintable().dynamicWidth = true;
+ } else {
+ getWidgetForPaintable().dynamicWidth = false;
+ }
+
+ if (h.equals("")) {
+ getWidgetForPaintable().dynamicHeight = true;
+ } else {
+ getWidgetForPaintable().dynamicHeight = false;
+ }
+
+ }
+
+ void updateMarginAndSpacingInfo(UIDL uidl) {
+ if (!uidl.hasAttribute("invisible")) {
+ int bitMask = uidl.getIntAttribute("margins");
+ if (getWidgetForPaintable().activeMarginsInfo.getBitMask() != bitMask) {
+ getWidgetForPaintable().activeMarginsInfo = new VMarginInfo(
+ bitMask);
+ getWidgetForPaintable().marginsNeedsRecalculation = true;
+ }
+ boolean spacing = uidl.getBooleanAttribute("spacing");
+ if (spacing != getWidgetForPaintable().spacingEnabled) {
+ getWidgetForPaintable().marginsNeedsRecalculation = true;
+ getWidgetForPaintable().spacingEnabled = spacing;
+ }
+ }
+ }
+
+ @Override
+ protected abstract CellBasedLayout createWidget();
+
+ @Override
+ public CellBasedLayout getWidgetForPaintable() {
+ return (CellBasedLayout) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
index a586929d13..c1678369b3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
@@ -346,8 +346,4 @@ public class VRichTextArea extends Composite implements Field, ChangeHandler,
rta.setTabIndex(index);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java
index 477cd13dd5..ec83f294f2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java
@@ -1,76 +1,79 @@
-package com.vaadin.terminal.gwt.client.ui.richtextarea;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
-
-public class VRichTextAreaPaintable extends VAbstractPaintableWidget implements
- BeforeShortcutActionListener {
-
- public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- if (uidl.hasVariable("text")) {
- getWidgetForPaintable().currentValue = uidl
- .getStringVariable("text");
- if (getWidgetForPaintable().rta.isAttached()) {
- getWidgetForPaintable().rta
- .setHTML(getWidgetForPaintable().currentValue);
- } else {
- getWidgetForPaintable().html
- .setHTML(getWidgetForPaintable().currentValue);
- }
- }
- if (!uidl.hasAttribute("cached")) {
- getWidgetForPaintable().setEnabled(
- !uidl.getBooleanAttribute("disabled"));
- }
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().setReadOnly(
- uidl.getBooleanAttribute("readonly"));
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
- int newMaxLength = uidl.hasAttribute("maxLength") ? uidl
- .getIntAttribute("maxLength") : -1;
- if (newMaxLength >= 0) {
- if (getWidgetForPaintable().maxLength == -1) {
- getWidgetForPaintable().keyPressHandler = getWidgetForPaintable().rta
- .addKeyPressHandler(getWidgetForPaintable());
- }
- getWidgetForPaintable().maxLength = newMaxLength;
- } else if (getWidgetForPaintable().maxLength != -1) {
- getWidgetForPaintable().getElement().setAttribute("maxlength", "");
- getWidgetForPaintable().maxLength = -1;
- getWidgetForPaintable().keyPressHandler.removeHandler();
- }
-
- if (uidl.hasAttribute("selectAll")) {
- getWidgetForPaintable().selectAll();
- }
-
- }
-
- public void onBeforeShortcutAction(Event e) {
- getWidgetForPaintable().synchronizeContentToServer();
- }
-
- @Override
- public VRichTextArea getWidgetForPaintable() {
- return (VRichTextArea) super.getWidgetForPaintable();
- };
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VRichTextArea.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.richtextarea;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+
+public class VRichTextAreaPaintable extends VAbstractPaintableWidget implements
+ BeforeShortcutActionListener {
+
+ public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ if (uidl.hasVariable("text")) {
+ getWidgetForPaintable().currentValue = uidl
+ .getStringVariable("text");
+ if (getWidgetForPaintable().rta.isAttached()) {
+ getWidgetForPaintable().rta
+ .setHTML(getWidgetForPaintable().currentValue);
+ } else {
+ getWidgetForPaintable().html
+ .setHTML(getWidgetForPaintable().currentValue);
+ }
+ }
+ if (!uidl.hasAttribute("cached")) {
+ getWidgetForPaintable().setEnabled(
+ !uidl.getBooleanAttribute("disabled"));
+ }
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().setReadOnly(
+ uidl.getBooleanAttribute("readonly"));
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ int newMaxLength = uidl.hasAttribute("maxLength") ? uidl
+ .getIntAttribute("maxLength") : -1;
+ if (newMaxLength >= 0) {
+ if (getWidgetForPaintable().maxLength == -1) {
+ getWidgetForPaintable().keyPressHandler = getWidgetForPaintable().rta
+ .addKeyPressHandler(getWidgetForPaintable());
+ }
+ getWidgetForPaintable().maxLength = newMaxLength;
+ } else if (getWidgetForPaintable().maxLength != -1) {
+ getWidgetForPaintable().getElement().setAttribute("maxlength", "");
+ getWidgetForPaintable().maxLength = -1;
+ getWidgetForPaintable().keyPressHandler.removeHandler();
+ }
+
+ if (uidl.hasAttribute("selectAll")) {
+ getWidgetForPaintable().selectAll();
+ }
+
+ }
+
+ public void onBeforeShortcutAction(Event e) {
+ getWidgetForPaintable().synchronizeContentToServer();
+ }
+
+ @Override
+ public VRichTextArea getWidgetForPaintable() {
+ return (VRichTextArea) super.getWidgetForPaintable();
+ };
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VRichTextArea.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java b/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
index 93627c1ff1..2c9828b66b 100644
--- a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
+++ b/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
@@ -1,175 +1,175 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.portlet.ClientDataRequest;
-import javax.portlet.PortletRequest;
-import javax.portlet.ResourceRequest;
-
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedRequest;
-
-/**
- * Wrapper for {@link PortletRequest} and its subclasses.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedRequest
- * @see WrappedPortletResponse
- */
-public class WrappedPortletRequest implements WrappedRequest {
-
- private final PortletRequest request;
- private final DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a portlet request and an associated deployment configuration
- *
- * @param request
- * the portlet request to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedPortletRequest(PortletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- this.request = request;
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- public Object getAttribute(String name) {
- return request.getAttribute(name);
- }
-
- public int getContentLength() {
- try {
- return ((ClientDataRequest) request).getContentLength();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content lenght only available for ClientDataRequests");
- }
- }
-
- public InputStream getInputStream() throws IOException {
- try {
- return ((ClientDataRequest) request).getPortletInputStream();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Input data only available for ClientDataRequests");
- }
- }
-
- public String getParameter(String name) {
- return request.getParameter(name);
- }
-
- public Map<String, String[]> getParameterMap() {
- return request.getParameterMap();
- }
-
- public void setAttribute(String name, Object o) {
- request.setAttribute(name, o);
- }
-
- public String getRequestPathInfo() {
- if (request instanceof ResourceRequest) {
- return ((ResourceRequest) request).getResourceID();
- } else {
- return null;
- }
- }
-
- public int getSessionMaxInactiveInterval() {
- return request.getPortletSession().getMaxInactiveInterval();
- }
-
- public Object getSessionAttribute(String name) {
- return request.getPortletSession().getAttribute(name);
- }
-
- public void setSessionAttribute(String name, Object attribute) {
- request.getPortletSession().setAttribute(name, attribute);
- }
-
- /**
- * Gets the original, unwrapped portlet request.
- *
- * @return the unwrapped portlet request
- */
- public PortletRequest getPortletRequest() {
- return request;
- }
-
- public String getContentType() {
- try {
- return ((ResourceRequest) request).getContentType();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content type only available for ResourceRequests");
- }
- }
-
- public BrowserDetails getBrowserDetails() {
- // No browserDetails available for normal requests
- return null;
- }
-
- public Locale getLocale() {
- return request.getLocale();
- }
-
- public String getRemoteAddr() {
- return null;
- }
-
- public boolean isSecure() {
- return request.isSecure();
- }
-
- public String getHeader(String string) {
- return null;
- }
-
- /**
- * Reads a portal property from the portal context of the wrapped request.
- *
- * @param name
- * a string with the name of the portal property to get
- * @return a string with the value of the property, or <code>null</code> if
- * the property is not defined
- */
- public String getPortalProperty(String name) {
- return request.getPortalContext().getProperty(name);
- }
-
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- /**
- * Helper method to get a <code>WrappedPortlettRequest</code> from a
- * <code>WrappedRequest</code>. Aside from casting, this method also takes
- * care of situations where there's another level of wrapping.
- *
- * @param request
- * a wrapped request
- * @return a wrapped portlet request
- * @throws ClassCastException
- * if the wrapped request doesn't wrap a portlet request
- */
- public static WrappedPortletRequest cast(WrappedRequest request) {
- if (request instanceof CombinedRequest) {
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- return (WrappedPortletRequest) request;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceRequest;
+
+import com.vaadin.terminal.CombinedRequest;
+import com.vaadin.terminal.DeploymentConfiguration;
+import com.vaadin.terminal.WrappedRequest;
+
+/**
+ * Wrapper for {@link PortletRequest} and its subclasses.
+ *
+ * @author Vaadin Ltd.
+ * @since 7.0
+ *
+ * @see WrappedRequest
+ * @see WrappedPortletResponse
+ */
+public class WrappedPortletRequest implements WrappedRequest {
+
+ private final PortletRequest request;
+ private final DeploymentConfiguration deploymentConfiguration;
+
+ /**
+ * Wraps a portlet request and an associated deployment configuration
+ *
+ * @param request
+ * the portlet request to wrap
+ * @param deploymentConfiguration
+ * the associated deployment configuration
+ */
+ public WrappedPortletRequest(PortletRequest request,
+ DeploymentConfiguration deploymentConfiguration) {
+ this.request = request;
+ this.deploymentConfiguration = deploymentConfiguration;
+ }
+
+ public Object getAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ public int getContentLength() {
+ try {
+ return ((ClientDataRequest) request).getContentLength();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Content lenght only available for ClientDataRequests");
+ }
+ }
+
+ public InputStream getInputStream() throws IOException {
+ try {
+ return ((ClientDataRequest) request).getPortletInputStream();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Input data only available for ClientDataRequests");
+ }
+ }
+
+ public String getParameter(String name) {
+ return request.getParameter(name);
+ }
+
+ public Map<String, String[]> getParameterMap() {
+ return request.getParameterMap();
+ }
+
+ public void setAttribute(String name, Object o) {
+ request.setAttribute(name, o);
+ }
+
+ public String getRequestPathInfo() {
+ if (request instanceof ResourceRequest) {
+ return ((ResourceRequest) request).getResourceID();
+ } else {
+ return null;
+ }
+ }
+
+ public int getSessionMaxInactiveInterval() {
+ return request.getPortletSession().getMaxInactiveInterval();
+ }
+
+ public Object getSessionAttribute(String name) {
+ return request.getPortletSession().getAttribute(name);
+ }
+
+ public void setSessionAttribute(String name, Object attribute) {
+ request.getPortletSession().setAttribute(name, attribute);
+ }
+
+ /**
+ * Gets the original, unwrapped portlet request.
+ *
+ * @return the unwrapped portlet request
+ */
+ public PortletRequest getPortletRequest() {
+ return request;
+ }
+
+ public String getContentType() {
+ try {
+ return ((ResourceRequest) request).getContentType();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Content type only available for ResourceRequests");
+ }
+ }
+
+ public BrowserDetails getBrowserDetails() {
+ // No browserDetails available for normal requests
+ return null;
+ }
+
+ public Locale getLocale() {
+ return request.getLocale();
+ }
+
+ public String getRemoteAddr() {
+ return null;
+ }
+
+ public boolean isSecure() {
+ return request.isSecure();
+ }
+
+ public String getHeader(String string) {
+ return null;
+ }
+
+ /**
+ * Reads a portal property from the portal context of the wrapped request.
+ *
+ * @param name
+ * a string with the name of the portal property to get
+ * @return a string with the value of the property, or <code>null</code> if
+ * the property is not defined
+ */
+ public String getPortalProperty(String name) {
+ return request.getPortalContext().getProperty(name);
+ }
+
+ public DeploymentConfiguration getDeploymentConfiguration() {
+ return deploymentConfiguration;
+ }
+
+ /**
+ * Helper method to get a <code>WrappedPortlettRequest</code> from a
+ * <code>WrappedRequest</code>. Aside from casting, this method also takes
+ * care of situations where there's another level of wrapping.
+ *
+ * @param request
+ * a wrapped request
+ * @return a wrapped portlet request
+ * @throws ClassCastException
+ * if the wrapped request doesn't wrap a portlet request
+ */
+ public static WrappedPortletRequest cast(WrappedRequest request) {
+ if (request instanceof CombinedRequest) {
+ CombinedRequest combinedRequest = (CombinedRequest) request;
+ request = combinedRequest.getSecondRequest();
+ }
+ return (WrappedPortletRequest) request;
+ }
+}
diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java
index 8bba9fc46d..fc3ef5056d 100644
--- a/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/src/com/vaadin/ui/AbstractOrderedLayout.java
@@ -54,7 +54,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
@Override
public void addComponent(Component c) {
// Add to components before calling super.addComponent
- // so that it is available to AttachListeners
+ // so that it is available to AttachListeners
components.add(c);
try {
super.addComponent(c);
@@ -75,7 +75,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
public void addComponentAsFirst(Component c) {
// If c is already in this, we must remove it before proceeding
// see ticket #7668
- if (c.getParent() == this) {
+ if(c.getParent() == this) {
removeComponent(c);
}
components.addFirst(c);
@@ -100,9 +100,9 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
public void addComponent(Component c, int index) {
// If c is already in this, we must remove it before proceeding
// see ticket #7668
- if (c.getParent() == this) {
+ if(c.getParent() == this) {
// When c is removed, all components after it are shifted down
- if (index > getComponentIndex(c)) {
+ if(index > getComponentIndex(c)) {
index--;
}
removeComponent(c);
diff --git a/src/com/vaadin/ui/ComboBox.java b/src/com/vaadin/ui/ComboBox.java
index b4307188a7..013fe6ab85 100644
--- a/src/com/vaadin/ui/ComboBox.java
+++ b/src/com/vaadin/ui/ComboBox.java
@@ -1,130 +1,130 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
-import com.vaadin.terminal.gwt.client.ui.VFilterSelectPaintable;
-
-/**
- * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's
- * turned of by default to avoid mistakes. Items are filtered based on user
- * input, and loaded dynamically ("lazy-loading") from the server. You can turn
- * on newItemsAllowed and change filtering mode (and also turn it off), but you
- * can not turn on multi-select mode.
- *
- */
-@SuppressWarnings("serial")
-@ClientWidget(VFilterSelectPaintable.class)
-public class ComboBox extends Select {
-
- private String inputPrompt = null;
-
- /**
- * If text input is not allowed, the ComboBox behaves like a pretty
- * NativeSelect - the user can not enter any text and clicking the text
- * field opens the drop down with options
- */
- private boolean textInputAllowed = true;
-
- public ComboBox() {
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Collection<?> options) {
- super(caption, options);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Container dataSource) {
- super(caption, dataSource);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption) {
- super(caption);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- @Override
- public void setMultiSelect(boolean multiSelect) {
- if (multiSelect && !isMultiSelect()) {
- throw new UnsupportedOperationException("Multiselect not supported");
- }
- super.setMultiSelect(multiSelect);
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the
- * select would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- * the desired input prompt, or null to disable
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- super.paintContent(target);
-
- if (!textInputAllowed) {
- target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
- }
- }
-
- /**
- * Sets whether it is possible to input text into the field or whether the
- * field area of the component is just used to show what is selected. By
- * disabling text input, the comboBox will work in the same way as a
- * {@link NativeSelect}
- *
- * @see #isTextInputAllowed()
- *
- * @param textInputAllowed
- * true to allow entering text, false to just show the current
- * selection
- */
- public void setTextInputAllowed(boolean textInputAllowed) {
- this.textInputAllowed = textInputAllowed;
- requestRepaint();
- }
-
- /**
- * Returns true if the user can enter text into the field to either filter
- * the selections or enter a new value if {@link #isNewItemsAllowed()}
- * returns true. If text input is disabled, the comboBox will work in the
- * same way as a {@link NativeSelect}
- *
- * @return
- */
- public boolean isTextInputAllowed() {
- return textInputAllowed;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Collection;
+
+import com.vaadin.data.Container;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelectPaintable;
+
+/**
+ * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's
+ * turned of by default to avoid mistakes. Items are filtered based on user
+ * input, and loaded dynamically ("lazy-loading") from the server. You can turn
+ * on newItemsAllowed and change filtering mode (and also turn it off), but you
+ * can not turn on multi-select mode.
+ *
+ */
+@SuppressWarnings("serial")
+@ClientWidget(VFilterSelectPaintable.class)
+public class ComboBox extends Select {
+
+ private String inputPrompt = null;
+
+ /**
+ * If text input is not allowed, the ComboBox behaves like a pretty
+ * NativeSelect - the user can not enter any text and clicking the text
+ * field opens the drop down with options
+ */
+ private boolean textInputAllowed = true;
+
+ public ComboBox() {
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption, Collection<?> options) {
+ super(caption, options);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption, Container dataSource) {
+ super(caption, dataSource);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption) {
+ super(caption);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ @Override
+ public void setMultiSelect(boolean multiSelect) {
+ if (multiSelect && !isMultiSelect()) {
+ throw new UnsupportedOperationException("Multiselect not supported");
+ }
+ super.setMultiSelect(multiSelect);
+ }
+
+ /**
+ * Gets the current input prompt.
+ *
+ * @see #setInputPrompt(String)
+ * @return the current input prompt, or null if not enabled
+ */
+ public String getInputPrompt() {
+ return inputPrompt;
+ }
+
+ /**
+ * Sets the input prompt - a textual prompt that is displayed when the
+ * select would otherwise be empty, to prompt the user for input.
+ *
+ * @param inputPrompt
+ * the desired input prompt, or null to disable
+ */
+ public void setInputPrompt(String inputPrompt) {
+ this.inputPrompt = inputPrompt;
+ requestRepaint();
+ }
+
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ if (inputPrompt != null) {
+ target.addAttribute("prompt", inputPrompt);
+ }
+ super.paintContent(target);
+
+ if (!textInputAllowed) {
+ target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
+ }
+ }
+
+ /**
+ * Sets whether it is possible to input text into the field or whether the
+ * field area of the component is just used to show what is selected. By
+ * disabling text input, the comboBox will work in the same way as a
+ * {@link NativeSelect}
+ *
+ * @see #isTextInputAllowed()
+ *
+ * @param textInputAllowed
+ * true to allow entering text, false to just show the current
+ * selection
+ */
+ public void setTextInputAllowed(boolean textInputAllowed) {
+ this.textInputAllowed = textInputAllowed;
+ requestRepaint();
+ }
+
+ /**
+ * Returns true if the user can enter text into the field to either filter
+ * the selections or enter a new value if {@link #isNewItemsAllowed()}
+ * returns true. If text input is disabled, the comboBox will work in the
+ * same way as a {@link NativeSelect}
+ *
+ * @return
+ */
+ public boolean isTextInputAllowed() {
+ return textInputAllowed;
+ }
+
+}
diff --git a/src/com/vaadin/ui/InlineDateField.java b/src/com/vaadin/ui/InlineDateField.java
index b0e830a75a..b4160604ff 100644
--- a/src/com/vaadin/ui/InlineDateField.java
+++ b/src/com/vaadin/ui/InlineDateField.java
@@ -1,48 +1,48 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendarPaintable;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector inline.
- *
- * </p>
- *
- * @see DateField
- * @see PopupDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@ClientWidget(VDateFieldCalendarPaintable.class)
-public class InlineDateField extends DateField {
-
- public InlineDateField() {
- super();
- }
-
- public InlineDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public InlineDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public InlineDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public InlineDateField(String caption) {
- super(caption);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Date;
+
+import com.vaadin.data.Property;
+import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendarPaintable;
+
+/**
+ * <p>
+ * A date entry component, which displays the actual date selector inline.
+ *
+ * </p>
+ *
+ * @see DateField
+ * @see PopupDateField
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 5.0
+ */
+@ClientWidget(VDateFieldCalendarPaintable.class)
+public class InlineDateField extends DateField {
+
+ public InlineDateField() {
+ super();
+ }
+
+ public InlineDateField(Property dataSource) throws IllegalArgumentException {
+ super(dataSource);
+ }
+
+ public InlineDateField(String caption, Date value) {
+ super(caption, value);
+ }
+
+ public InlineDateField(String caption, Property dataSource) {
+ super(caption, dataSource);
+ }
+
+ public InlineDateField(String caption) {
+ super(caption);
+ }
+
+}
diff --git a/src/com/vaadin/ui/PopupDateField.java b/src/com/vaadin/ui/PopupDateField.java
index d25608a4c4..3688d4035f 100644
--- a/src/com/vaadin/ui/PopupDateField.java
+++ b/src/com/vaadin/ui/PopupDateField.java
@@ -1,80 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector as a popup.
- *
- * </p>
- *
- * @see DateField
- * @see InlineDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-public class PopupDateField extends DateField {
-
- private String inputPrompt = null;
-
- public PopupDateField() {
- super();
- }
-
- public PopupDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public PopupDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public PopupDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public PopupDateField(String caption) {
- super(caption);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
-
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the field
- * would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Date;
+
+import com.vaadin.data.Property;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+
+/**
+ * <p>
+ * A date entry component, which displays the actual date selector as a popup.
+ *
+ * </p>
+ *
+ * @see DateField
+ * @see InlineDateField
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 5.0
+ */
+public class PopupDateField extends DateField {
+
+ private String inputPrompt = null;
+
+ public PopupDateField() {
+ super();
+ }
+
+ public PopupDateField(Property dataSource) throws IllegalArgumentException {
+ super(dataSource);
+ }
+
+ public PopupDateField(String caption, Date value) {
+ super(caption, value);
+ }
+
+ public PopupDateField(String caption, Property dataSource) {
+ super(caption, dataSource);
+ }
+
+ public PopupDateField(String caption) {
+ super(caption);
+ }
+
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ super.paintContent(target);
+
+ if (inputPrompt != null) {
+ target.addAttribute("prompt", inputPrompt);
+ }
+ }
+
+ /**
+ * Gets the current input prompt.
+ *
+ * @see #setInputPrompt(String)
+ * @return the current input prompt, or null if not enabled
+ */
+ public String getInputPrompt() {
+ return inputPrompt;
+ }
+
+ /**
+ * Sets the input prompt - a textual prompt that is displayed when the field
+ * would otherwise be empty, to prompt the user for input.
+ *
+ * @param inputPrompt
+ */
+ public void setInputPrompt(String inputPrompt) {
+ this.inputPrompt = inputPrompt;
+ requestRepaint();
+ }
+
+}