From: Artur Signell
Date: Tue, 31 Jan 2012 16:49:57 +0000 (+0200)
Subject: Merge commit '116cd1f29a432fe5ca64f3023a9fec1ca130f078' (origin/6.8)
X-Git-Tag: 7.0.0.alpha2~484
X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=94a7e95d37925e8784fc00d4b4f800f6bf7c1ee8;p=vaadin-framework.git
Merge commit '116cd1f29a432fe5ca64f3023a9fec1ca130f078' (origin/6.8)
Manually merged CRLF changes + additional small patch for changes that SHOULD NOT be in the changeset but that the SVN -> GIT sync script has added
---
94a7e95d37925e8784fc00d4b4f800f6bf7c1ee8
diff --cc src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 8ca6c95069,0000000000..2584a4770b
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@@ -1,157 -1,0 +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 extends FieldGroup {
-
- private Class beanType;
-
- private static Boolean beanValidationImplementationAvailable = null;
-
- public BeanFieldGroup(Class 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 getItemDataSource() {
- return (BeanItem) 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 extends FieldGroup {
++
++ private Class beanType;
++
++ private static Boolean beanValidationImplementationAvailable = null;
++
++ public BeanFieldGroup(Class 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 getItemDataSource() {
++ return (BeanItem) 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;
++ }
+}
diff --cc src/com/vaadin/data/fieldgroup/Caption.java
index e9ae01a2d2,0000000000..b990b720cd
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/Caption.java
+++ b/src/com/vaadin/data/fieldgroup/Caption.java
@@@ -1,15 -1,0 +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 --cc src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
index 2fc7bc6b7e,0000000000..569f643998
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
@@@ -1,156 -1,0 +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 createField(Class> type, Class 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 createEnumField(Class> type,
- Class 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 createBooleanField(Class 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 createAbstractTextField(
- Class fieldType) {
- if (fieldType == AbstractTextField.class) {
- fieldType = (Class) 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
- * 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 createDefaultField(Class> type,
- Class 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 createField(Class> type, Class 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 createEnumField(Class> type,
++ Class 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 createBooleanField(Class 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 createAbstractTextField(
++ Class fieldType) {
++ if (fieldType == AbstractTextField.class) {
++ fieldType = (Class) 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
++ * 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 createDefaultField(Class> type,
++ Class 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 --cc src/com/vaadin/data/fieldgroup/FieldGroup.java
index 381f4fef3f,0000000000..3df19f5bc9
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@@ -1,978 -1,0 +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.
- *
- * 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.
- *
- *
- * {@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.
- *
- * 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.
- *
- *
- * @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.
- *
- * 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.
- *
- *
- * @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 buildAndBind(String caption, Object propertyId,
- Class 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.
- *
- * 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.
- *
- *
- * @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 build(String caption, Class> dataType,
- Class 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.
++ *
++ * 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.
++ *
++ *
++ * {@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.
++ *
++ *
++ * @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> propertyIdToField = new HashMap>();
++ private LinkedHashMap, Object> fieldToPropertyId = new LinkedHashMap, Object>();
++ private List commitHandlers = new ArrayList();
++
++ /**
++ * 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.
++ *
++ *
++ * @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.
++ *
++ * 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.
++ *
++ *
++ * The default is to use buffered mode.
++ *
++ *
++ * @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.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ * The fields are not returned in any specific order.
++ *
++ *
++ * @return A collection with all bound Fields
++ */
++ public Collection> 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)}.
++ *
++ * This method also adds validators when applicable.
++ *
++ *
++ * @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 Property.Transactional wrapInTransactionalProperty(
++ Property itemProperty) {
++ return new TransactionalPropertyWrapper(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.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ *
++ * No guarantee is given for the order of the property ids
++ *
++ *
++ * @return A collection of bound property ids
++ */
++ public Collection 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.
++ *
++ * Will always return an empty collection before an item has been set using
++ * {@link #setItemDataSource(Item)}.
++ *
++ *
++ * No guarantee is given for the order of the property ids
++ *
++ *
++ * @return A collection of property ids that have not been bound to fields
++ */
++ public Collection getUnboundPropertyIds() {
++ if (getItemDataSource() == null) {
++ return new ArrayList();
++ }
++ List unboundPropertyIds = new ArrayList();
++ unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
++ unboundPropertyIds.removeAll(propertyIdToField.keySet());
++ return unboundPropertyIds;
++ }
++
++ /**
++ * Commits all changes done to the bound fields.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ * 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}.
++ *
++ * Use {@link #addCommitHandler(CommitHandler)} and
++ * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
++ * commit handler.
++ *
++ * @return A collection of commit handlers
++ */
++ protected Collection 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.
++ *
++ * 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..
++ *
++ * 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.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ *
++ * For example:
++ *
++ *
++ * 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);
++ *
++ *
++ *
++ * 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.
++ *
++ * 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.
++ *
++ * 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.
++ *
++ *
++ * @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.
++ *
++ * 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.
++ *
++ *
++ * @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 buildAndBind(String caption, Object propertyId,
++ Class 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.
++ *
++ * 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.
++ *
++ *
++ * @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 build(String caption, Class> dataType,
++ Class 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;
++ }
+}
diff --cc src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
index 6945a492bd,0000000000..80c012cbdc
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
@@@ -1,31 -1,0 +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 createField(Class> dataType, Class 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 createField(Class> dataType, Class fieldType);
++}
diff --cc src/com/vaadin/data/fieldgroup/PropertyId.java
index 588fdc3020,0000000000..268047401d
mode 100644,000000..100644
--- a/src/com/vaadin/data/fieldgroup/PropertyId.java
+++ b/src/com/vaadin/data/fieldgroup/PropertyId.java
@@@ -1,15 -1,0 +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 --cc src/com/vaadin/data/util/TextFileProperty.java
index 77325e141d,cfa8d4fabf..5ebba98062
--- a/src/com/vaadin/data/util/TextFileProperty.java
+++ b/src/com/vaadin/data/util/TextFileProperty.java
@@@ -1,141 -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 {
-
- 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 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 {
++public class TextFileProperty extends AbstractProperty {
+
+ 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> getType() {
++ public Class getType() {
+ return String.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#getValue()
+ */
- public Object 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 --cc src/com/vaadin/data/util/TransactionalPropertyWrapper.java
index de44dbe544,0000000000..06ec0935c3
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
@@@ -1,107 -1,0 +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
- */
- public class TransactionalPropertyWrapper extends AbstractProperty
- implements ValueChangeNotifier, Property.Transactional {
-
- private Property wrappedProperty;
- private boolean inTransaction = false;
- private boolean valueChangePending;
- private T valueBeforeTransaction;
-
- public TransactionalPropertyWrapper(Property 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 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
++ */
++public class TransactionalPropertyWrapper extends AbstractProperty
++ implements ValueChangeNotifier, Property.Transactional {
++
++ private Property wrappedProperty;
++ private boolean inTransaction = false;
++ private boolean valueChangePending;
++ private T valueBeforeTransaction;
++
++ public TransactionalPropertyWrapper(Property 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 getWrappedProperty() {
++ return wrappedProperty;
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/Converter.java
index 065d06b071,0000000000..b8c15e8cdc
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/Converter.java
+++ b/src/com/vaadin/data/util/converter/Converter.java
@@@ -1,159 -1,0 +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.
- *
- * 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.
- *
- *
- * Converters must not have any side effects (never update UI from inside a
- * converter).
- *
- *
- * All Converters must be stateless and thread safe.
- *
- *
- * If conversion of a value fails, a {@link ConversionException} is thrown.
- *
- *
- * @param
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
- * @param
- * The presentation type. Must be compatible with what
- * {@link #getPresentationType()} returns.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
- public interface Converter extends Serializable {
-
- /**
- * Converts the given value from target type to source type.
- *
- * A converter can optionally use locale to do the conversion.
- *
- * 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.
- *
- * A converter can optionally use locale to do the conversion.
- *
- * 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 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 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 ConversionException without a detail
- * message.
- */
- public ConversionException() {
- }
-
- /**
- * Constructs a new ConversionException 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 ConversionException 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.
++ *
++ * 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.
++ *
++ *
++ * Converters must not have any side effects (never update UI from inside a
++ * converter).
++ *
++ *
++ * All Converters must be stateless and thread safe.
++ *
++ *
++ * If conversion of a value fails, a {@link ConversionException} is thrown.
++ *
++ *
++ * @param
++ * The model type. Must be compatible with what
++ * {@link #getModelType()} returns.
++ * @param
++ * The presentation type. Must be compatible with what
++ * {@link #getPresentationType()} returns.
++ * @author Vaadin Ltd.
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public interface Converter extends Serializable {
++
++ /**
++ * Converts the given value from target type to source type.
++ *
++ * A converter can optionally use locale to do the conversion.
++ *
++ * 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.
++ *
++ * A converter can optionally use locale to do the conversion.
++ *
++ * 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 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 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 ConversionException without a detail
++ * message.
++ */
++ public ConversionException() {
++ }
++
++ /**
++ * Constructs a new ConversionException 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 ConversionException 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 --cc src/com/vaadin/data/util/converter/ConverterFactory.java
index 451f84185d,0000000000..ed4ab41ac0
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/ConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/ConverterFactory.java
@@@ -1,23 -1,0 +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 Converter createConverter(
- Class presentationType, Class 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 Converter createConverter(
++ Class presentationType, Class modelType);
++
++}
diff --cc src/com/vaadin/data/util/converter/DateToLongConverter.java
index d66adece06,0000000000..537800f617
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/DateToLongConverter.java
+++ b/src/com/vaadin/data/util/converter/DateToLongConverter.java
@@@ -1,68 -1,0 +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 {
-
- /*
- * (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 getModelType() {
- return Long.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class 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 {
++
++ /*
++ * (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 getModelType() {
++ return Long.class;
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
++ */
++ public Class getPresentationType() {
++ return Date.class;
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 9233624819,0000000000..3ad7b6a85b
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@@ -1,100 -1,0 +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}.
- *
- * Custom converters can be provided by extending this class and using
- * {@link Application#setConverterFactory(ConverterFactory)}.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class DefaultConverterFactory implements ConverterFactory {
-
- private final static Logger log = Logger
- .getLogger(DefaultConverterFactory.class.getName());
-
- public Converter createConverter(
- Class presentationType, Class modelType) {
- Converter converter = findConverter(
- presentationType, modelType);
- if (converter != null) {
- log.finest(getClass().getName() + " created a "
- + converter.getClass());
- return converter;
- }
-
- // Try to find a reverse converter
- Converter reverseConverter = findConverter(
- modelType, presentationType);
- if (reverseConverter != null) {
- log.finest(getClass().getName() + " created a reverse "
- + reverseConverter.getClass());
- return new ReverseConverter(reverseConverter);
- }
-
- log.finest(getClass().getName() + " could not find a converter for "
- + presentationType.getName() + " to " + modelType.getName()
- + " conversion");
- return null;
-
- }
-
- protected Converter findConverter(
- Class presentationType, Class modelType) {
- if (presentationType == String.class) {
- // TextField converters and more
- Converter converter = (Converter) createStringConverter(modelType);
- if (converter != null) {
- return converter;
- }
- } else if (presentationType == Date.class) {
- // DateField converters and more
- Converter converter = (Converter) createDateConverter(modelType);
- if (converter != null) {
- return converter;
- }
- }
-
- return null;
-
- }
-
- protected Converter createDateConverter(Class> sourceType) {
- if (Long.class.isAssignableFrom(sourceType)) {
- return new DateToLongConverter();
- } else {
- return null;
- }
- }
-
- protected Converter 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}.
++ *
++ * Custom converters can be provided by extending this class and using
++ * {@link Application#setConverterFactory(ConverterFactory)}.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class DefaultConverterFactory implements ConverterFactory {
++
++ private final static Logger log = Logger
++ .getLogger(DefaultConverterFactory.class.getName());
++
++ public Converter createConverter(
++ Class presentationType, Class modelType) {
++ Converter converter = findConverter(
++ presentationType, modelType);
++ if (converter != null) {
++ log.finest(getClass().getName() + " created a "
++ + converter.getClass());
++ return converter;
++ }
++
++ // Try to find a reverse converter
++ Converter reverseConverter = findConverter(
++ modelType, presentationType);
++ if (reverseConverter != null) {
++ log.finest(getClass().getName() + " created a reverse "
++ + reverseConverter.getClass());
++ return new ReverseConverter(reverseConverter);
++ }
++
++ log.finest(getClass().getName() + " could not find a converter for "
++ + presentationType.getName() + " to " + modelType.getName()
++ + " conversion");
++ return null;
++
++ }
++
++ protected Converter findConverter(
++ Class presentationType, Class modelType) {
++ if (presentationType == String.class) {
++ // TextField converters and more
++ Converter converter = (Converter) createStringConverter(modelType);
++ if (converter != null) {
++ return converter;
++ }
++ } else if (presentationType == Date.class) {
++ // DateField converters and more
++ Converter converter = (Converter) createDateConverter(modelType);
++ if (converter != null) {
++ return converter;
++ }
++ }
++
++ return null;
++
++ }
++
++ protected Converter createDateConverter(Class> sourceType) {
++ if (Long.class.isAssignableFrom(sourceType)) {
++ return new DateToLongConverter();
++ } else {
++ return null;
++ }
++ }
++
++ protected Converter 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 --cc src/com/vaadin/data/util/converter/ReverseConverter.java
index b191d1ca0b,0000000000..1c561f29e8
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/ReverseConverter.java
+++ b/src/com/vaadin/data/util/converter/ReverseConverter.java
@@@ -1,80 -1,0 +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
- * The source type
- * @param
- * The target type
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class ReverseConverter implements
- Converter {
-
- private Converter 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 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 getModelType() {
- return realConverter.getPresentationType();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getTargetType()
- */
- public Class 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
++ * The source type
++ * @param
++ * The target type
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class ReverseConverter implements
++ Converter {
++
++ private Converter 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 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 getModelType() {
++ return realConverter.getPresentationType();
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getTargetType()
++ */
++ public Class getPresentationType() {
++ return realConverter.getModelType();
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/StringToBooleanConverter.java
index 3b2034a361,0000000000..96a3a3d071
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
@@@ -1,104 -1,0 +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().
- *
- * Leading and trailing white spaces are ignored when converting from a String.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class StringToBooleanConverter implements Converter {
-
- /*
- * (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 getModelType() {
- return Boolean.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class 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().
++ *
++ * Leading and trailing white spaces are ignored when converting from a String.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class StringToBooleanConverter implements Converter {
++
++ /*
++ * (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 getModelType() {
++ return Boolean.class;
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
++ */
++ public Class getPresentationType() {
++ return String.class;
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/StringToDateConverter.java
index 2aa9395532,0000000000..6f3c2e47f6
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/StringToDateConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDateConverter.java
@@@ -1,108 -1,0 +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.
- *
- * Leading and trailing white spaces are ignored when converting from a String.
- *
- *
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class StringToDateConverter implements Converter {
-
- /**
- * 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 getModelType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class 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.
++ *
++ * Leading and trailing white spaces are ignored when converting from a String.
++ *
++ *
++ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class StringToDateConverter implements Converter {
++
++ /**
++ * 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 getModelType() {
++ return Date.class;
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
++ */
++ public Class getPresentationType() {
++ return String.class;
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/StringToDoubleConverter.java
index 29c6329451,0000000000..60a38f4127
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
@@@ -1,103 -1,0 +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.
- *
- * Leading and trailing white spaces are ignored when converting from a String.
- *
- *
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class StringToDoubleConverter implements Converter {
-
- /**
- * 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 getModelType() {
- return Double.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class 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.
++ *
++ * Leading and trailing white spaces are ignored when converting from a String.
++ *
++ *
++ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class StringToDoubleConverter implements Converter {
++
++ /**
++ * 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 getModelType() {
++ return Double.class;
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
++ */
++ public Class getPresentationType() {
++ return String.class;
++ }
++}
diff --cc src/com/vaadin/data/util/converter/StringToIntegerConverter.java
index 7fa4458c51,0000000000..e55feec3b6
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
@@@ -1,84 -1,0 +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.
- *
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class StringToIntegerConverter implements Converter {
-
- /**
- * 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 getModelType() {
- return Integer.class;
- }
-
- public Class 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.
++ *
++ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class StringToIntegerConverter implements Converter {
++
++ /**
++ * 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 getModelType() {
++ return Integer.class;
++ }
++
++ public Class getPresentationType() {
++ return String.class;
++ }
++
++}
diff --cc src/com/vaadin/data/util/converter/StringToNumberConverter.java
index 64944a434c,0000000000..d1816007e7
mode 100644,000000..100644
--- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
@@@ -1,107 -1,0 +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.
- *
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- *
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class StringToNumberConverter implements Converter {
-
- /**
- * 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 getModelType() {
- return Number.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class 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.
++ *
++ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
++ *
++ *
++ * @author Vaadin Ltd
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class StringToNumberConverter implements Converter {
++
++ /**
++ * 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 getModelType() {
++ return Number.class;
++ }
++
++ /*
++ * (non-Javadoc)
++ *
++ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
++ */
++ public Class getPresentationType() {
++ return String.class;
++ }
++
++}
diff --cc src/com/vaadin/data/validator/BeanValidator.java
index 939fd2e9c4,0000000000..817df85248
mode 100644,000000..100644
--- a/src/com/vaadin/data/validator/BeanValidator.java
+++ b/src/com/vaadin/data/validator/BeanValidator.java
@@@ -1,173 -1,0 +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 exceptions = new ArrayList();
- 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(" ");
- }
- 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 exceptions = new ArrayList();
++ 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(" ");
++ }
++ 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;
++ }
++
+}
diff --cc src/com/vaadin/data/validator/DateRangeValidator.java
index 42f5a224ed,0000000000..24f3d3ce10
mode 100644,000000..100644
--- a/src/com/vaadin/data/validator/DateRangeValidator.java
+++ b/src/com/vaadin/data/validator/DateRangeValidator.java
@@@ -1,51 -1,0 +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.
- *
- *
- * 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.
- *
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
- public class DateRangeValidator extends RangeValidator {
-
- /**
- * Creates a validator for checking that an Date is within a given range.
- *
- * 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.
- *
- *
- * 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.
- *
- *
- * @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.
++ *
++ *
++ * 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.
++ *
++ *
++ * @author Vaadin Ltd.
++ * @version
++ * @VERSION@
++ * @since 7.0
++ */
++public class DateRangeValidator extends RangeValidator {
++
++ /**
++ * Creates a validator for checking that an Date is within a given range.
++ *
++ * 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.
++ *
++ *
++ * 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.
++ *
++ *
++ * @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 --cc src/com/vaadin/data/validator/RangeValidator.java
index 457f046360,0000000000..433271274f
mode 100644,000000..100644
--- a/src/com/vaadin/data/validator/RangeValidator.java
+++ b/src/com/vaadin/data/validator/RangeValidator.java
@@@ -1,186 -1,0 +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.
- *
- * 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)}.
- *
- *
- * @param
- * 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 extends AbstractValidator {
-
- private T minValue = null;
- private boolean minValueIncluded = true;
- private T maxValue = null;
- private boolean maxValueIncluded = true;
- private Class 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 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 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.
++ *
++ * 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)}.
++ *
++ *
++ * @param
++ * 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 extends AbstractValidator {
++
++ private T minValue = null;
++ private boolean minValueIncluded = true;
++ private T maxValue = null;
++ private boolean maxValueIncluded = true;
++ private Class 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 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 getType() {
++ return type;
++ }
++
++}
diff --cc src/com/vaadin/external/json/JSONException.java
index 9d97a32d7d,0000000000..d799021506
mode 100644,000000..100644
--- a/src/com/vaadin/external/json/JSONException.java
+++ b/src/com/vaadin/external/json/JSONException.java
@@@ -1,28 -1,0 +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 --cc src/com/vaadin/external/json/JSONString.java
index 7b574d1915,0000000000..cc7e4d8c07
mode 100644,000000..100644
--- a/src/com/vaadin/external/json/JSONString.java
+++ b/src/com/vaadin/external/json/JSONString.java
@@@ -1,21 -1,0 +1,21 @@@
- package com.vaadin.external.json;
-
- import java.io.Serializable;
-
- /**
- * The JSONString interface allows a toJSONString()
- * method so that a class can change the behavior of
- * JSONObject.toString(), JSONArray.toString(), and
- * JSONWriter.value(Object). The
- * toJSONString method will be used instead of the default behavior
- * of using the Object's toString() method and quoting the result.
- */
- public interface JSONString extends Serializable {
- /**
- * The toJSONString 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 JSONString interface allows a toJSONString()
++ * method so that a class can change the behavior of
++ * JSONObject.toString(), JSONArray.toString(), and
++ * JSONWriter.value(Object). The
++ * toJSONString method will be used instead of the default behavior
++ * of using the Object's toString() method and quoting the result.
++ */
++public interface JSONString extends Serializable {
++ /**
++ * The toJSONString method allows a class to produce its own
++ * JSON serialization.
++ *
++ * @return A strictly syntactically correct JSON text.
++ */
++ public String toJSONString();
++}
diff --cc src/com/vaadin/external/json/JSONStringer.java
index c4a1af600a,0000000000..465f27aaab
mode 100644,000000..100644
--- a/src/com/vaadin/external/json/JSONStringer.java
+++ b/src/com/vaadin/external/json/JSONStringer.java
@@@ -1,78 -1,0 +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.
- *
- * A JSONStringer instance provides a value method for appending
- * values to the
- * text, and a key
- * method for adding keys before values in objects. There are array
- * and endArray methods that make and bound array values, and
- * object and endObject methods which make and bound
- * object values. All of these methods return the JSONWriter instance,
- * permitting cascade style. For example,
- * The first method called must be array or object.
- * 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.
- *
- * 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 null if there was a
- * problem in the construction of the JSON text (such as the calls to
- * array were not properly balanced with calls to
- * endArray).
- * @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.
++ *
++ * A JSONStringer instance provides a value method for appending
++ * values to the
++ * text, and a key
++ * method for adding keys before values in objects. There are array
++ * and endArray methods that make and bound array values, and
++ * object and endObject methods which make and bound
++ * object values. All of these methods return the JSONWriter instance,
++ * permitting cascade style. For example,
++ * The first method called must be array or object.
++ * 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.
++ *
++ * 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 null if there was a
++ * problem in the construction of the JSON text (such as the calls to
++ * array were not properly balanced with calls to
++ * endArray).
++ * @return The JSON text.
++ */
++ public String toString() {
++ return this.mode == 'd' ? this.writer.toString() : null;
++ }
++}
diff --cc src/com/vaadin/external/json/JSONWriter.java
index 438721b7b2,0000000000..5f9ddeeae2
mode 100644,000000..100644
--- a/src/com/vaadin/external/json/JSONWriter.java
+++ b/src/com/vaadin/external/json/JSONWriter.java
@@@ -1,355 -1,0 +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.
- *
- * A JSONWriter instance provides a value method for appending
- * values to the text, and a key method for adding keys before
- * values in objects. There are array and endArray
- * methods that make and bound array values, and object and
- * endObject methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting a cascade style. For
- * example,
- *
- *
- * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!")
- * .endObject();
- *
- *
- * which writes
- *
- *
- * {"JSON":"Hello, World!"}
- *
- *
- * The first method called must be array or object.
- * 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.
- *
- * 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
- * endArray will be appended to this array. The
- * endArray 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
- * array.
- *
- * @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
- * object.
- *
- * @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
- * endObject will be appended to this object. The
- * endObject 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 true or the value false
- * .
- *
- * @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.
++ *
++ * A JSONWriter instance provides a value method for appending
++ * values to the text, and a key method for adding keys before
++ * values in objects. There are array and endArray
++ * methods that make and bound array values, and object and
++ * endObject methods which make and bound object values. All of
++ * these methods return the JSONWriter instance, permitting a cascade style. For
++ * example,
++ *
++ *
++ * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!")
++ * .endObject();
++ *
++ *
++ * which writes
++ *
++ *
++ * {"JSON":"Hello, World!"}
++ *
++ *
++ * The first method called must be array or object.
++ * 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.
++ *
++ * 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
++ * endArray will be appended to this array. The
++ * endArray 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
++ * array.
++ *
++ * @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
++ * object.
++ *
++ * @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
++ * endObject will be appended to this object. The
++ * endObject 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 true or the value false
++ * .
++ *
++ * @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 --cc src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
index d9ca56be05,aaef981bab..89e106f063
--- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
+++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
@@@ -1,356 -1,305 +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.
- *
- * Note that Internet Explorer 8 and newer will return the document mode so
- * IE8 rendering as IE7 will return 7.
- *
- *
- * @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.
+ *
+ * Note that Internet Explorer 8 and newer will return the document mode so
+ * IE8 rendering as IE7 will return 7.
+ *
+ *
+ * @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 --cc src/com/vaadin/terminal/gwt/client/VPaintable.java
index d85c6d33e2,0000000000..f7b7eaba83
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintable.java
@@@ -1,74 -1,0 +1,74 @@@
- /*
- @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.
- // *
- // * 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.
- // *
- // *
- // * @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.
++ // *
++ // * 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.
++ // *
++ // *
++ // * @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();
++}
diff --cc src/com/vaadin/terminal/gwt/client/VPaintableMap.java
index f21d85558c,0000000000..aa3e8e3cb8
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
@@@ -1,403 -1,0 +1,403 @@@
- /*
- @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 idToPaintable = new HashMap();
- private Map paintableToId = new HashMap();
-
- public static VPaintableMap get(ApplicationConnection applicationConnection) {
- return applicationConnection.getPaintableMap();
- }
-
- @Deprecated
- private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
- .create();
-
- private Set unregistryBag = new HashSet();
-
- /**
- * 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.
- *
- * The paintableId is used in the UIDL to identify a specific widget
- * instance, effectively linking the widget with it's server side Component.
- *
- *
- * @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);
- }
- /*
- * 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 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 idToPaintable = new HashMap();
++ private Map paintableToId = new HashMap();
++
++ public static VPaintableMap get(ApplicationConnection applicationConnection) {
++ return applicationConnection.getPaintableMap();
++ }
++
++ @Deprecated
++ private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
++ .create();
++
++ private Set unregistryBag = new HashSet();
++
++ /**
++ * 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.
++ *
++ * The paintableId is used in the UIDL to identify a specific widget
++ * instance, effectively linking the widget with it's server side Component.
++ *
++ *
++ * @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);
++ }
++ /*
++ * 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 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 --cc src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
index 27535806c1,0000000000..9a0b6eacf6
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
@@@ -1,84 -1,0 +1,84 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type 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 unrenderedPids = new HashSet(
- getWidgetForPaintable().pidToComponentWrappper.keySet());
-
- for (Iterator 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();
- }
- }
++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 HandlerRegistration registerHandler(
++ H handler, Type 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 unrenderedPids = new HashSet(
++ getWidgetForPaintable().pidToComponentWrappper.keySet());
++
++ for (Iterator 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 --cc src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
index 90da0ef4ac,0000000000..09bf02ec43
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
@@@ -1,103 -1,0 +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 --cc src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
index b3e19f037a,0000000000..1f78c02f58
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
@@@ -1,17 -1,0 +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 --cc src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
index 1ff066d004,0000000000..84c3ab5221
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
@@@ -1,140 -1,0 +1,140 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type 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();
-
- }
++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 HandlerRegistration registerHandler(
++ H handler, Type 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 --cc src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
index 3f28818073,0000000000..4136d02c30
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
@@@ -1,68 -1,0 +1,68 @@@
- 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 */
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
index e949d95104,0000000000..dae602a668
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
@@@ -1,37 -1,0 +1,37 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
index 99eadc9558,a2f03d6176..b5c07ca278
--- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
@@@ -1,1739 -1,1787 +1,1739 @@@
- /*
- @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, " ");
- }
- }
- } 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("‹");
- prevMonth.setStyleName("v-button-prevmonth");
- prevMonth.setTabIndex(-1);
- nextMonth = new VEventButton();
- nextMonth.setHTML("›");
- 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("«");
- prevYear.setStyleName("v-button-prevyear");
- prevYear.setTabIndex(-1);
- nextYear = new VEventButton();
- nextYear.setHTML("»");
- 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, "" + monthName + " " + year
- + "");
- }
-
- 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, "");
- // 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, ""
- + getDateTimeService().getShortDay(day) + "");
- } 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, "" + weekNumber
- + "");
- }
- 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(" "));
- 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 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, " ");
+ }
+ }
+ } 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("‹");
+ prevMonth.setStyleName("v-button-prevmonth");
+ prevMonth.setTabIndex(-1);
+ nextMonth = new VEventButton();
+ nextMonth.setHTML("›");
+ 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("«");
+ prevYear.setStyleName("v-button-prevyear");
+ prevYear.setTabIndex(-1);
+ nextYear = new VEventButton();
+ nextYear.setHTML("»");
+ 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, "" + monthName + " " + year
+ + "");
+ }
+
+ 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, "");
+ // 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, ""
+ + getDateTimeService().getShortDay(day) + "");
+ } 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, "" + weekNumber
+ + "");
+ }
+ 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 Widget sender = (Widget) event.getSource();
++ 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 msec;
-
+ 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);
+ }
- if (getResolution() == VDateField.RESOLUTION_MSEC) {
- msec = createListBox();
- for (int i = 0; i < 1000; i++) {
- if (i < 10) {
- msec.addItem("00" + i);
- } else if (i < 100) {
- msec.addItem("0" + i);
- } else {
- msec.addItem("" + i);
- }
- }
- msec.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_MSEC) {
- add(new VLabel("."));
- if (isReadonly()) {
- final int m = getMilliseconds();
- final String ms = m < 100 ? "0" + m : "" + m;
- add(new VLabel(m < 10 ? "0" + ms : ms));
- } else {
- add(msec);
- }
- }
+ if (getResolution() == VDateField.RESOLUTION_HOUR) {
+ add(new VLabel(delimiter + "00")); // o'clock
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ add(new VLabel(" "));
+ 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 (getResolution() == VDateField.RESOLUTION_MSEC) {
- if (selected) {
- msec.setSelectedIndex(getMilliseconds());
- } else {
- msec.setSelectedIndex(0);
- }
- }
+ 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 (msec != null) {
- msec.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() == msec) {
- final int ms = msec.getSelectedIndex();
- DateTimeService.setMilliseconds(value, ms);
- if (timeChangeListener != null) {
- timeChangeListener.changed(value.getHours(),
- value.getMinutes(), value.getSeconds(), ms);
- }
- 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.msec, subElement)) {
- return SUBPART_MSECS_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_MSECS_SELECT.equals(subPart)) {
- return time.msec.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 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 --cc src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
index 03233c6e27,0000000000..06ef54c13a
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
@@@ -1,96 -1,0 +1,96 @@@
- 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(" ");
- 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);
- }
-
- }
++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(" ");
++ 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 --cc src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
index d8640e3fe5,0000000000..1b4db40962
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
@@@ -1,61 -1,0 +1,61 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type 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);
- }
-
- }
++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 HandlerRegistration registerHandler(
++ H handler, Type 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 --cc src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
index 3abcd9cd75,0000000000..7c0568e28e
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
@@@ -1,79 -1,0 +1,79 @@@
- 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
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
index 7997355136,0000000000..01190b39be
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
@@@ -1,87 -1,0 +1,87 @@@
- 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 oldWidgets = new HashSet();
- 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 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);
-
- }
- }
++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 oldWidgets = new HashSet();
++ 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 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 --cc src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
index 6fb8456258,91388edcaf..6bf1d4a3a7
--- a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
@@@ -1,87 -1,153 +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.ApplicationConnection;
+ import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusChangeListener;
+ import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+ import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.TimeChangeListener;
+
+ /**
+ * A client side implementation for InlineDateField
+ */
+ public class VDateFieldCalendar extends VDateField {
+
- private final VCalendarPanel calendarPanel;
++ 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;
+ }
+ });
+ }
+
- @Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- super.updateFromUIDL(uidl, client);
- calendarPanel.setShowISOWeekNumbers(isShowISOWeekNumbers());
- calendarPanel.setDateTimeService(getDateTimeService());
- calendarPanel.setResolution(getCurrentResolution());
- Date currentDate = getCurrentDate();
- if (currentDate != null) {
- calendarPanel.setDate(new Date(currentDate.getTime()));
- } else {
- calendarPanel.setDate(null);
- }
-
- if (currentResolution > RESOLUTION_DAY) {
- calendarPanel.setTimeChangeListener(new TimeChangeListener() {
- public void changed(int hour, int min, int sec, int msec) {
- Date d = getDate();
- if (d == null) {
- // date currently null, use the value from calendarPanel
- // (~ client time at the init of the widget)
- d = (Date) calendarPanel.getDate().clone();
- }
- d.setHours(hour);
- d.setMinutes(min);
- d.setSeconds(sec);
- DateTimeService.setMilliseconds(d, msec);
-
- // Always update time changes to the server
- calendarPanel.setDate(d);
- updateValueFromPanel();
- }
- });
- }
-
- if (currentResolution <= RESOLUTION_MONTH) {
- calendarPanel.setFocusChangeListener(new FocusChangeListener() {
- public void focusChanged(Date date) {
- Date date2 = new Date();
- if (calendarPanel.getDate() != null) {
- date2.setTime(calendarPanel.getDate().getTime());
- }
- /*
- * Update the value of calendarPanel
- */
- date2.setYear(date.getYear());
- date2.setMonth(date.getMonth());
- calendarPanel.setDate(date2);
- /*
- * Then update the value from panel to server
- */
- updateValueFromPanel();
- }
- });
- } else {
- calendarPanel.setFocusChangeListener(null);
- }
-
- // Update possible changes
- calendarPanel.renderCalendar();
- }
-
+ /**
+ * TODO refactor: almost same method as in VPopupCalendar.updateValue
+ */
+ @SuppressWarnings("deprecation")
- private void updateValueFromPanel() {
++ 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 --cc src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
index 1deb155001,0000000000..2a3189d9ba
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
@@@ -1,71 -1,0 +1,71 @@@
- 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 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();
- }
- 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();
- }
-
- }
++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 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();
++ }
++ 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 --cc src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
index c4590a71c9,0000000000..1efdcfc722
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
@@@ -1,39 -1,0 +1,39 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
index 5f519c09d4,0000000000..4b59d64a71
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
@@@ -1,173 -1,0 +1,173 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
index 1ef958183b,0000000000..639ac1f8de
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
@@@ -1,193 -1,0 +1,193 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type 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) getWidgetForPaintable().widgetToComponentContainer
- .clone();
-
- final int[] alignments = uidl.getIntArrayAttribute("alignments");
- int alignmentIndex = 0;
-
- LinkedList pendingCells = new LinkedList();
-
- LinkedList relativeHeighted = new LinkedList();
-
- 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);
- }
-
- }
++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 HandlerRegistration registerHandler(
++ H handler, Type 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) getWidgetForPaintable().widgetToComponentContainer
++ .clone();
++
++ final int[] alignments = uidl.getIntArrayAttribute("alignments");
++ int alignmentIndex = 0;
++
++ LinkedList pendingCells = new LinkedList();
++
++ LinkedList relativeHeighted = new LinkedList();
++
++ 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 --cc src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
index b72f5222cc,0000000000..e5fb4e138b
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
@@@ -1,17 -1,0 +1,17 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
index 2340ceb0b6,0000000000..ebc8a5e523
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
@@@ -1,13 -1,0 +1,13 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
index fc709d56b3,0000000000..bef770f38b
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
@@@ -1,109 -1,0 +1,109 @@@
- 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);
- }
-
- }
++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 --cc src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
index fabc77bced,0000000000..ef2a49b9d0
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
@@@ -1,161 -1,0 +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("");
- }
-
- String moreItemText = moreItemUIDL.getStringAttribute("text");
- if ("".equals(moreItemText)) {
- moreItemText = "►";
- }
- 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 itr = uidlItems.getChildIterator();
- Stack> iteratorStack = new Stack>();
- Stack menuStack = new Stack();
- 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("");
++ }
++
++ String moreItemText = moreItemUIDL.getStringAttribute("text");
++ if ("".equals(moreItemText)) {
++ moreItemText = "►";
++ }
++ 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 itr = uidlItems.getChildIterator();
++ Stack> iteratorStack = new Stack>();
++ Stack menuStack = new Stack();
++ 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 --cc src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
index 4720e07099,0000000000..5fa4f18efe
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayoutPaintable.java
@@@ -1,254 -1,0 +1,254 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type 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 uidlWidgets = new ArrayList(
- uidl.getChildCount());
- ArrayList relativeSizeComponents = new ArrayList();
- ArrayList relativeSizeComponentUIDL = new ArrayList();
-
- int pos = 0;
- for (final Iterator 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();
- }
-
- }
++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 HandlerRegistration registerHandler(
++ H handler, Type 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 uidlWidgets = new ArrayList(
++ uidl.getChildCount());
++ ArrayList relativeSizeComponents = new ArrayList();
++ ArrayList relativeSizeComponentUIDL = new ArrayList();
++
++ int pos = 0;
++ for (final Iterator 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 --cc src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
index 198d7f4020,0000000000..c401c6db84
mode 100644,000000..100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
@@@ -1,175 -1,0 +1,175 @@@
- 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 HandlerRegistration registerHandler(
- H handler, Type