summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-02-07 10:58:50 +0200
committerLeif Åstrand <leif@vaadin.com>2012-02-07 10:58:50 +0200
commite30776113d6a0403fa500e9d6b3892bafbc1ee17 (patch)
tree25dd75052f17162c7338b9a505c919b0ec2b72a4 /src
parent226e0ab34ae8ac22037a94fdc3568e6f93a06374 (diff)
parent787eedd131c5694a7db55d3b89bf4ddb4a6d673f (diff)
downloadvaadin-framework-e30776113d6a0403fa500e9d6b3892bafbc1ee17.tar.gz
vaadin-framework-e30776113d6a0403fa500e9d6b3892bafbc1ee17.zip
Merge remote branch 'origin/master' into layoutperformance
Conflicts: src/com/vaadin/terminal/gwt/client/ApplicationConnection.java src/com/vaadin/terminal/gwt/client/Util.java src/com/vaadin/terminal/gwt/client/VPaintableMap.java src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
Diffstat (limited to 'src')
-rw-r--r--src/com/google/gwt/dom/client/VaadinDOMImplSafari.java52
-rw-r--r--src/com/vaadin/data/fieldgroup/BeanFieldGroup.java312
-rw-r--r--src/com/vaadin/data/fieldgroup/Caption.java30
-rw-r--r--src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java312
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroup.java1954
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java62
-rw-r--r--src/com/vaadin/data/fieldgroup/PropertyId.java30
-rw-r--r--src/com/vaadin/data/util/TextFileProperty.java282
-rw-r--r--src/com/vaadin/data/util/TransactionalPropertyWrapper.java214
-rw-r--r--src/com/vaadin/data/util/converter/Converter.java318
-rw-r--r--src/com/vaadin/data/util/converter/ConverterFactory.java46
-rw-r--r--src/com/vaadin/data/util/converter/DateToLongConverter.java136
-rw-r--r--src/com/vaadin/data/util/converter/DefaultConverterFactory.java200
-rw-r--r--src/com/vaadin/data/util/converter/ReverseConverter.java160
-rw-r--r--src/com/vaadin/data/util/converter/StringToBooleanConverter.java208
-rw-r--r--src/com/vaadin/data/util/converter/StringToDateConverter.java216
-rw-r--r--src/com/vaadin/data/util/converter/StringToDoubleConverter.java206
-rw-r--r--src/com/vaadin/data/util/converter/StringToIntegerConverter.java168
-rw-r--r--src/com/vaadin/data/util/converter/StringToNumberConverter.java214
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java184
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheMap.java60
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/Reference.java112
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/RowId.java162
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java330
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java114
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java270
-rw-r--r--src/com/vaadin/data/validator/BeanValidator.java344
-rw-r--r--src/com/vaadin/data/validator/DateRangeValidator.java102
-rw-r--r--src/com/vaadin/data/validator/RangeValidator.java372
-rw-r--r--src/com/vaadin/event/FieldEvents.java500
-rw-r--r--src/com/vaadin/external/json/JSONException.java56
-rw-r--r--src/com/vaadin/external/json/JSONString.java42
-rw-r--r--src/com/vaadin/external/json/JSONStringer.java156
-rw-r--r--src/com/vaadin/external/json/JSONWriter.java710
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java9
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java42
-rw-r--r--src/com/vaadin/terminal/gwt/client/ComponentLocator.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/Container.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/DateTimeService.java878
-rw-r--r--src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java26
-rw-r--r--src/com/vaadin/terminal/gwt/client/LocaleService.java296
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java16
-rw-r--r--src/com/vaadin/terminal/gwt/client/VBrowserDetails.java712
-rw-r--r--src/com/vaadin/terminal/gwt/client/VDebugConsole.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintable.java154
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableMap.java816
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableWidget.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableWidgetContainer.java45
-rw-r--r--src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/WidgetSet.java43
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java254
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java198
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/TreeImages.java58
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java71
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java87
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java181
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java17
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java (renamed from src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java)155
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java143
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAccordion.java60
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java71
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java77
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VButton.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java3467
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java195
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java84
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java69
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java82
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java80
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java90
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateField.java96
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java240
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendarPaintable.java101
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java109
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java73
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java74
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java186
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VEmbeddedPaintable.java198
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java313
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java244
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VForm.java171
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java29
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java42
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java176
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java214
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java196
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java20
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java16
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java104
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VLink.java103
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VLinkPaintable.java100
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VListSelect.java22
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VListSelectPaintable.java21
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java221
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java322
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java3
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java9
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNativeSelectPaintable.java21
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VNotification.java834
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java100
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBasePaintable.java103
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VOptionGroupPaintable.java71
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPanel.java162
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java178
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java42
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPasswordFieldPaintable.java28
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java852
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java138
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupView.java92
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java107
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java51
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VProgressIndicatorPaintable.java65
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java139
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java514
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSlider.java1030
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java159
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java450
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java94
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java76
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java99
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java85
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java428
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextArea.java142
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextAreaPaintable.java38
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextField.java142
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextFieldPaintable.java124
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java56
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextualDatePaintable.java58
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTree.java331
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java231
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java46
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java202
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTwinColSelectPaintable.java34
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java37
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUnknownComponentPaintable.java52
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUpload.java73
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUploadPaintable.java62
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java20
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java15
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java79
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VView.java320
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java338
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VWindow.java301
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java299
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java142
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java86
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java84
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java78
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java79
-rw-r--r--src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java6
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java350
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java8
-rw-r--r--src/com/vaadin/ui/AbsoluteLayout.java4
-rw-r--r--src/com/vaadin/ui/AbstractOrderedLayout.java8
-rw-r--r--src/com/vaadin/ui/AbstractSplitPanel.java4
-rw-r--r--src/com/vaadin/ui/Accordion.java5
-rw-r--r--src/com/vaadin/ui/ComboBox.java259
-rw-r--r--src/com/vaadin/ui/CssLayout.java4
-rw-r--r--src/com/vaadin/ui/CustomComponent.java4
-rw-r--r--src/com/vaadin/ui/CustomField.java4
-rw-r--r--src/com/vaadin/ui/CustomLayout.java4
-rw-r--r--src/com/vaadin/ui/DateField.java4
-rw-r--r--src/com/vaadin/ui/DragAndDropWrapper.java3
-rw-r--r--src/com/vaadin/ui/Embedded.java6
-rw-r--r--src/com/vaadin/ui/Form.java5
-rw-r--r--src/com/vaadin/ui/FormLayout.java4
-rw-r--r--src/com/vaadin/ui/GridLayout.java4
-rw-r--r--src/com/vaadin/ui/HorizontalLayout.java4
-rw-r--r--src/com/vaadin/ui/HorizontalSplitPanel.java4
-rw-r--r--src/com/vaadin/ui/InlineDateField.java96
-rw-r--r--src/com/vaadin/ui/Link.java4
-rw-r--r--src/com/vaadin/ui/ListSelect.java4
-rw-r--r--src/com/vaadin/ui/NativeSelect.java4
-rw-r--r--src/com/vaadin/ui/OptionGroup.java3
-rw-r--r--src/com/vaadin/ui/Panel.java7
-rw-r--r--src/com/vaadin/ui/PasswordField.java4
-rw-r--r--src/com/vaadin/ui/PopupDateField.java160
-rw-r--r--src/com/vaadin/ui/PopupView.java4
-rw-r--r--src/com/vaadin/ui/ProgressIndicator.java4
-rw-r--r--src/com/vaadin/ui/RichTextArea.java4
-rw-r--r--src/com/vaadin/ui/Select.java4
-rw-r--r--src/com/vaadin/ui/SplitPanel.java114
-rw-r--r--src/com/vaadin/ui/TabSheet.java4
-rw-r--r--src/com/vaadin/ui/TextArea.java4
-rw-r--r--src/com/vaadin/ui/TextField.java4
-rw-r--r--src/com/vaadin/ui/Tree.java3
-rw-r--r--src/com/vaadin/ui/TwinColSelect.java3
-rw-r--r--src/com/vaadin/ui/Upload.java4
-rw-r--r--src/com/vaadin/ui/VerticalLayout.java4
-rw-r--r--src/com/vaadin/ui/VerticalSplitPanel.java4
-rw-r--r--src/com/vaadin/ui/Window.java4
200 files changed, 16069 insertions, 15262 deletions
diff --git a/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java b/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
index 3975bf73d8..6e9cc81f43 100644
--- a/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
+++ b/src/com/google/gwt/dom/client/VaadinDOMImplSafari.java
@@ -1,26 +1,26 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.google.gwt.dom.client;
-
-/**
- * Overridden to workaround GWT issue #6194. Remove this when updating to a
- * newer GWT that fixes the problem (2.3.0 possibly). Must be in this package as
- * the whole DOMImpl hierarchy is package private and I really did not want to
- * copy all the parent classes into this one...
- */
-class VaadinDOMImplSafari extends DOMImplSafari {
- @Override
- public int getAbsoluteLeft(Element elem) {
- // Chrome returns a float in certain cases (at least when zoom != 100%).
- // The |0 ensures it is converted to an int.
- return super.getAbsoluteLeft(elem) | 0;
- }
-
- @Override
- public int getAbsoluteTop(Element elem) {
- // Chrome returns a float in certain cases (at least when zoom != 100%).
- // The |0 ensures it is converted to an int.
- return super.getAbsoluteTop(elem) | 0;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.google.gwt.dom.client;
+
+/**
+ * Overridden to workaround GWT issue #6194. Remove this when updating to a
+ * newer GWT that fixes the problem (2.3.0 possibly). Must be in this package as
+ * the whole DOMImpl hierarchy is package private and I really did not want to
+ * copy all the parent classes into this one...
+ */
+class VaadinDOMImplSafari extends DOMImplSafari {
+ @Override
+ public int getAbsoluteLeft(Element elem) {
+ // Chrome returns a float in certain cases (at least when zoom != 100%).
+ // The |0 ensures it is converted to an int.
+ return super.getAbsoluteLeft(elem) | 0;
+ }
+
+ @Override
+ public int getAbsoluteTop(Element elem) {
+ // Chrome returns a float in certain cases (at least when zoom != 100%).
+ // The |0 ensures it is converted to an int.
+ return super.getAbsoluteTop(elem) | 0;
+ }
+}
diff --git a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 8ca6c95069..2584a4770b 100644
--- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -1,157 +1,157 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.reflect.Method;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.util.BeanItem;
-import com.vaadin.data.validator.BeanValidator;
-import com.vaadin.ui.Field;
-
-public class BeanFieldGroup<T> extends FieldGroup {
-
- private Class<T> beanType;
-
- private static Boolean beanValidationImplementationAvailable = null;
-
- public BeanFieldGroup(Class<T> beanType) {
- this.beanType = beanType;
- }
-
- @Override
- protected Class<?> getPropertyType(Object propertyId) {
- if (getItemDataSource() != null) {
- return super.getPropertyType(propertyId);
- } else {
- // Data source not set so we need to figure out the type manually
- /*
- * toString should never really be needed as propertyId should be of
- * form "fieldName" or "fieldName.subField[.subField2]" but the
- * method declaration comes from parent.
- */
- java.lang.reflect.Field f;
- try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
- }
- }
- }
-
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldError e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
- /**
- * Helper method for setting the data source directly using a bean. This
- * method wraps the bean in a {@link BeanItem} and calls
- * {@link #setItemDataSource(Item)}.
- *
- * @param bean
- * The bean to use as data source.
- */
- public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
- }
-
- @Override
- public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
- throw new RuntimeException(getClass().getSimpleName()
- + " only supports BeanItems as item data source");
- }
- super.setItemDataSource(item);
- }
-
- @Override
- public BeanItem<T> getItemDataSource() {
- return (BeanItem<T>) super.getItemDataSource();
- }
-
- @Override
- public void bind(Field field, Object propertyId) {
- if (getItemDataSource() != null) {
- // The data source is set so the property must be found in the item.
- // If it is not we try to add it.
- try {
- getItemProperty(propertyId);
- } catch (BindException e) {
- // Not found, try to add a nested property;
- // BeanItem property ids are always strings so this is safe
- getItemDataSource().addNestedProperty((String) propertyId);
- }
- }
-
- super.bind(field, propertyId);
- }
-
- @Override
- protected void configureField(Field<?> field) {
- super.configureField(field);
- // Add Bean validators if there are annotations
- if (isBeanValidationImplementationAvailable()) {
- BeanValidator validator = new BeanValidator(
- beanType, getPropertyId(field).toString());
- field.addValidator(validator);
- if (field.getLocale() != null) {
- validator.setLocale(field.getLocale());
- }
- }
- }
-
- /**
- * Checks whether a bean validation implementation (e.g. Hibernate Validator
- * or Apache Bean Validation) is available.
- *
- * TODO move this method to some more generic location
- *
- * @return true if a JSR-303 bean validation implementation is available
- */
- protected static boolean isBeanValidationImplementationAvailable() {
- if (beanValidationImplementationAvailable != null) {
- return beanValidationImplementationAvailable;
- }
- try {
- Class<?> validationClass = Class
- .forName("javax.validation.Validation");
- Method buildFactoryMethod = validationClass
- .getMethod("buildDefaultValidatorFactory");
- Object factory = buildFactoryMethod.invoke(null);
- beanValidationImplementationAvailable = (factory != null);
- } catch (Exception e) {
- // no bean validation implementation available
- beanValidationImplementationAvailable = false;
- }
- return beanValidationImplementationAvailable;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.ui.Field;
+
+public class BeanFieldGroup<T> extends FieldGroup {
+
+ private Class<T> beanType;
+
+ private static Boolean beanValidationImplementationAvailable = null;
+
+ public BeanFieldGroup(Class<T> beanType) {
+ this.beanType = beanType;
+ }
+
+ @Override
+ protected Class<?> getPropertyType(Object propertyId) {
+ if (getItemDataSource() != null) {
+ return super.getPropertyType(propertyId);
+ } else {
+ // Data source not set so we need to figure out the type manually
+ /*
+ * toString should never really be needed as propertyId should be of
+ * form "fieldName" or "fieldName.subField[.subField2]" but the
+ * method declaration comes from parent.
+ */
+ java.lang.reflect.Field f;
+ try {
+ f = getField(beanType, propertyId.toString());
+ return f.getType();
+ } catch (SecurityException e) {
+ throw new BindException("Cannot determine type of propertyId '"
+ + propertyId + "'.", e);
+ } catch (NoSuchFieldException e) {
+ throw new BindException("Cannot determine type of propertyId '"
+ + propertyId + "'. The propertyId was not found in "
+ + beanType.getName(), e);
+ }
+ }
+ }
+
+ private static java.lang.reflect.Field getField(Class<?> cls,
+ String propertyId) throws SecurityException, NoSuchFieldException {
+ if (propertyId.contains(".")) {
+ String[] parts = propertyId.split("\\.", 2);
+ // Get the type of the field in the "cls" class
+ java.lang.reflect.Field field1 = getField(cls, parts[0]);
+ // Find the rest from the sub type
+ return getField(field1.getType(), parts[1]);
+ } else {
+ try {
+ // Try to find the field directly in the given class
+ java.lang.reflect.Field field1 = cls
+ .getDeclaredField(propertyId);
+ return field1;
+ } catch (NoSuchFieldError e) {
+ // Try super classes until we reach Object
+ Class<?> superClass = cls.getSuperclass();
+ if (superClass != Object.class) {
+ return getField(superClass, propertyId);
+ } else {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method for setting the data source directly using a bean. This
+ * method wraps the bean in a {@link BeanItem} and calls
+ * {@link #setItemDataSource(Item)}.
+ *
+ * @param bean
+ * The bean to use as data source.
+ */
+ public void setItemDataSource(T bean) {
+ setItemDataSource(new BeanItem(bean));
+ }
+
+ @Override
+ public void setItemDataSource(Item item) {
+ if (!(item instanceof BeanItem)) {
+ throw new RuntimeException(getClass().getSimpleName()
+ + " only supports BeanItems as item data source");
+ }
+ super.setItemDataSource(item);
+ }
+
+ @Override
+ public BeanItem<T> getItemDataSource() {
+ return (BeanItem<T>) super.getItemDataSource();
+ }
+
+ @Override
+ public void bind(Field field, Object propertyId) {
+ if (getItemDataSource() != null) {
+ // The data source is set so the property must be found in the item.
+ // If it is not we try to add it.
+ try {
+ getItemProperty(propertyId);
+ } catch (BindException e) {
+ // Not found, try to add a nested property;
+ // BeanItem property ids are always strings so this is safe
+ getItemDataSource().addNestedProperty((String) propertyId);
+ }
+ }
+
+ super.bind(field, propertyId);
+ }
+
+ @Override
+ protected void configureField(Field<?> field) {
+ super.configureField(field);
+ // Add Bean validators if there are annotations
+ if (isBeanValidationImplementationAvailable()) {
+ BeanValidator validator = new BeanValidator(
+ beanType, getPropertyId(field).toString());
+ field.addValidator(validator);
+ if (field.getLocale() != null) {
+ validator.setLocale(field.getLocale());
+ }
+ }
+ }
+
+ /**
+ * Checks whether a bean validation implementation (e.g. Hibernate Validator
+ * or Apache Bean Validation) is available.
+ *
+ * TODO move this method to some more generic location
+ *
+ * @return true if a JSR-303 bean validation implementation is available
+ */
+ protected static boolean isBeanValidationImplementationAvailable() {
+ if (beanValidationImplementationAvailable != null) {
+ return beanValidationImplementationAvailable;
+ }
+ try {
+ Class<?> validationClass = Class
+ .forName("javax.validation.Validation");
+ Method buildFactoryMethod = validationClass
+ .getMethod("buildDefaultValidatorFactory");
+ Object factory = buildFactoryMethod.invoke(null);
+ beanValidationImplementationAvailable = (factory != null);
+ } catch (Exception e) {
+ // no bean validation implementation available
+ beanValidationImplementationAvailable = false;
+ }
+ return beanValidationImplementationAvailable;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/Caption.java b/src/com/vaadin/data/fieldgroup/Caption.java
index e9ae01a2d2..b990b720cd 100644
--- a/src/com/vaadin/data/fieldgroup/Caption.java
+++ b/src/com/vaadin/data/fieldgroup/Caption.java
@@ -1,15 +1,15 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Caption {
- String value();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Caption {
+ String value();
+}
diff --git a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
index 2fc7bc6b7e..569f643998 100644
--- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
@@ -1,156 +1,156 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.util.EnumSet;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.fieldgroup.FieldGroup.BindException;
-import com.vaadin.ui.AbstractSelect;
-import com.vaadin.ui.AbstractTextField;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.OptionGroup;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.TextField;
-
-public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
-
- public static final Object CAPTION_PROPERTY_ID = "Caption";
-
- public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
- if (Enum.class.isAssignableFrom(type)) {
- return createEnumField(type, fieldType);
- } else if (Boolean.class.isAssignableFrom(type)
- || boolean.class.isAssignableFrom(type)) {
- return createBooleanField(fieldType);
- }
- if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return fieldType.cast(createAbstractTextField(fieldType
- .asSubclass(AbstractTextField.class)));
- } else if (fieldType == RichTextArea.class) {
- return fieldType.cast(createRichTextArea());
- }
- return createDefaultField(type, fieldType);
- }
-
- protected RichTextArea createRichTextArea() {
- RichTextArea rta = new RichTextArea();
- rta.setImmediate(true);
-
- return rta;
- }
-
- private <T extends Field> T createEnumField(Class<?> type,
- Class<T> fieldType) {
- if (AbstractSelect.class.isAssignableFrom(fieldType)) {
- AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
- populateWithEnumData(s, (Class<? extends Enum>) type);
- return (T) s;
- }
-
- return null;
- }
-
- protected AbstractSelect createCompatibleSelect(
- Class<? extends AbstractSelect> fieldType) {
- AbstractSelect select;
- if (fieldType.isAssignableFrom(ListSelect.class)) {
- select = new ListSelect();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
- select = new NativeSelect();
- } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
- select = new OptionGroup();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(Table.class)) {
- Table t = new Table();
- t.setSelectable(true);
- select = t;
- } else {
- select = new ComboBox(null);
- }
- select.setImmediate(true);
- select.setNullSelectionAllowed(false);
-
- return select;
- }
-
- protected <T extends Field> T createBooleanField(Class<T> fieldType) {
- if (fieldType.isAssignableFrom(CheckBox.class)) {
- CheckBox cb = new CheckBox(null);
- cb.setImmediate(true);
- return (T) cb;
- } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
- }
-
- return null;
- }
-
- protected <T extends AbstractTextField> T createAbstractTextField(
- Class<T> fieldType) {
- if (fieldType == AbstractTextField.class) {
- fieldType = (Class<T>) TextField.class;
- }
- try {
- T field = fieldType.newInstance();
- field.setImmediate(true);
- return field;
- } catch (Exception e) {
- throw new BindException("Could not create a field of type "
- + fieldType, e);
- }
- }
-
- /**
- * Fallback when no specific field has been created. Typically returns a
- * TextField.
- *
- * @param <T>
- * The type of field to create
- * @param type
- * The type of data that should be edited
- * @param fieldType
- * The type of field to create
- * @return A field capable of editing the data or null if no field could be
- * created
- */
- protected <T extends Field> T createDefaultField(Class<?> type,
- Class<T> fieldType) {
- if (fieldType.isAssignableFrom(TextField.class)) {
- return fieldType.cast(createAbstractTextField(TextField.class));
- }
- return null;
- }
-
- /**
- * Populates the given select with all the enums in the given {@link Enum}
- * class. Uses {@link Enum}.toString() for caption.
- *
- * @param select
- * The select to populate
- * @param enumClass
- * The Enum class to use
- */
- protected void populateWithEnumData(AbstractSelect select,
- Class<? extends Enum> enumClass) {
- select.removeAllItems();
- for (Object p : select.getContainerPropertyIds()) {
- select.removeContainerProperty(p);
- }
- select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
- select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
- @SuppressWarnings("unchecked")
- EnumSet<?> enumSet = EnumSet.allOf(enumClass);
- for (Object r : enumSet) {
- Item newItem = select.addItem(r);
- newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.util.EnumSet;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.fieldgroup.FieldGroup.BindException;
+import com.vaadin.ui.AbstractSelect;
+import com.vaadin.ui.AbstractTextField;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.ListSelect;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.OptionGroup;
+import com.vaadin.ui.RichTextArea;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextField;
+
+public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
+
+ public static final Object CAPTION_PROPERTY_ID = "Caption";
+
+ public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
+ if (Enum.class.isAssignableFrom(type)) {
+ return createEnumField(type, fieldType);
+ } else if (Boolean.class.isAssignableFrom(type)
+ || boolean.class.isAssignableFrom(type)) {
+ return createBooleanField(fieldType);
+ }
+ if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return fieldType.cast(createAbstractTextField(fieldType
+ .asSubclass(AbstractTextField.class)));
+ } else if (fieldType == RichTextArea.class) {
+ return fieldType.cast(createRichTextArea());
+ }
+ return createDefaultField(type, fieldType);
+ }
+
+ protected RichTextArea createRichTextArea() {
+ RichTextArea rta = new RichTextArea();
+ rta.setImmediate(true);
+
+ return rta;
+ }
+
+ private <T extends Field> T createEnumField(Class<?> type,
+ Class<T> fieldType) {
+ if (AbstractSelect.class.isAssignableFrom(fieldType)) {
+ AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
+ populateWithEnumData(s, (Class<? extends Enum>) type);
+ return (T) s;
+ }
+
+ return null;
+ }
+
+ protected AbstractSelect createCompatibleSelect(
+ Class<? extends AbstractSelect> fieldType) {
+ AbstractSelect select;
+ if (fieldType.isAssignableFrom(ListSelect.class)) {
+ select = new ListSelect();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
+ select = new NativeSelect();
+ } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
+ select = new OptionGroup();
+ select.setMultiSelect(false);
+ } else if (fieldType.isAssignableFrom(Table.class)) {
+ Table t = new Table();
+ t.setSelectable(true);
+ select = t;
+ } else {
+ select = new ComboBox(null);
+ }
+ select.setImmediate(true);
+ select.setNullSelectionAllowed(false);
+
+ return select;
+ }
+
+ protected <T extends Field> T createBooleanField(Class<T> fieldType) {
+ if (fieldType.isAssignableFrom(CheckBox.class)) {
+ CheckBox cb = new CheckBox(null);
+ cb.setImmediate(true);
+ return (T) cb;
+ } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
+ return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
+ }
+
+ return null;
+ }
+
+ protected <T extends AbstractTextField> T createAbstractTextField(
+ Class<T> fieldType) {
+ if (fieldType == AbstractTextField.class) {
+ fieldType = (Class<T>) TextField.class;
+ }
+ try {
+ T field = fieldType.newInstance();
+ field.setImmediate(true);
+ return field;
+ } catch (Exception e) {
+ throw new BindException("Could not create a field of type "
+ + fieldType, e);
+ }
+ }
+
+ /**
+ * Fallback when no specific field has been created. Typically returns a
+ * TextField.
+ *
+ * @param <T>
+ * The type of field to create
+ * @param type
+ * The type of data that should be edited
+ * @param fieldType
+ * The type of field to create
+ * @return A field capable of editing the data or null if no field could be
+ * created
+ */
+ protected <T extends Field> T createDefaultField(Class<?> type,
+ Class<T> fieldType) {
+ if (fieldType.isAssignableFrom(TextField.class)) {
+ return fieldType.cast(createAbstractTextField(TextField.class));
+ }
+ return null;
+ }
+
+ /**
+ * Populates the given select with all the enums in the given {@link Enum}
+ * class. Uses {@link Enum}.toString() for caption.
+ *
+ * @param select
+ * The select to populate
+ * @param enumClass
+ * The Enum class to use
+ */
+ protected void populateWithEnumData(AbstractSelect select,
+ Class<? extends Enum> enumClass) {
+ select.removeAllItems();
+ for (Object p : select.getContainerPropertyIds()) {
+ select.removeContainerProperty(p);
+ }
+ select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
+ select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
+ @SuppressWarnings("unchecked")
+ EnumSet<?> enumSet = EnumSet.allOf(enumClass);
+ for (Object r : enumSet) {
+ Item newItem = select.addItem(r);
+ newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
+ }
+ }
+}
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroup.java b/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 381f4fef3f..3df19f5bc9 100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -1,978 +1,978 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.TransactionalPropertyWrapper;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.DefaultFieldFactory;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Form;
-
-/**
- * FieldGroup provides an easy way of binding fields to data and handling
- * commits of these fields.
- * <p>
- * The functionality of FieldGroup is similar to {@link Form} but
- * {@link FieldGroup} does not handle layouts in any way. The typical use case
- * is to create a layout outside the FieldGroup and then use FieldGroup to bind
- * the fields to a data source.
- * </p>
- * <p>
- * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
- * Using the buildAndBind methods {@link FieldGroup} can create fields for you
- * using a FieldGroupFieldFactory but you still have to add them to the correct
- * position in your layout.
- * </p>
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- */
-public class FieldGroup implements Serializable {
-
- private static final Logger logger = Logger.getLogger(FieldGroup.class
- .getName());
-
- private Item itemDataSource;
- private boolean buffered = true;
-
- private boolean enabled = true;
- private boolean readOnly = false;
-
- private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
- private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
- private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
-
- /**
- * The field factory used by builder methods.
- */
- private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
-
- /**
- * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
- * data source for the field binder.
- *
- */
- public FieldGroup() {
-
- }
-
- /**
- * Constructs a field binder that uses the given data source.
- *
- * @param itemDataSource
- * The data source to bind the fields to
- */
- public FieldGroup(Item itemDataSource) {
- setItemDataSource(itemDataSource);
- }
-
- /**
- * Updates the item that is used by this FieldBinder. Rebinds all fields to
- * the properties in the new item.
- *
- * @param itemDataSource
- * The new item to use
- */
- public void setItemDataSource(Item itemDataSource) {
- this.itemDataSource = itemDataSource;
-
- for (Field<?> f : fieldToPropertyId.keySet()) {
- bind(f, fieldToPropertyId.get(f));
- }
- }
-
- /**
- * Gets the item used by this FieldBinder. Note that you must call
- * {@link #commit()} for the item to be updated unless buffered mode has
- * been switched off.
- *
- * @see #setBuffered(boolean)
- * @see #commit()
- *
- * @return The item used by this FieldBinder
- */
- public Item getItemDataSource() {
- return itemDataSource;
- }
-
- /**
- * Checks the buffered mode for the bound fields.
- * <p>
- *
- * @see #setBuffered(boolean) for more details on buffered mode
- *
- * @see Field#isBuffered()
- * @return true if buffered mode is on, false otherwise
- *
- */
- public boolean isBuffered() {
- return buffered;
- }
-
- /**
- * Sets the buffered mode for the bound fields.
- * <p>
- * When buffered mode is on the item will not be updated until
- * {@link #commit()} is called. If buffered mode is off the item will be
- * updated once the fields are updated.
- * </p>
- * <p>
- * The default is to use buffered mode.
- * </p>
- *
- * @see Field#setBuffered(boolean)
- * @param buffered
- * true to turn on buffered mode, false otherwise
- */
- public void setBuffered(boolean buffered) {
- if (buffered == this.buffered) {
- return;
- }
-
- this.buffered = buffered;
- for (Field<?> field : getFields()) {
- field.setBuffered(buffered);
- }
- }
-
- /**
- * Returns the enabled status for the fields.
- * <p>
- * Note that this will not accurately represent the enabled status of all
- * fields if you change the enabled status of the fields through some other
- * method than {@link #setEnabled(boolean)}.
- *
- * @return true if the fields are enabled, false otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Updates the enabled state of all bound fields.
- *
- * @param fieldsEnabled
- * true to enable all bound fields, false to disable them
- */
- public void setEnabled(boolean fieldsEnabled) {
- enabled = fieldsEnabled;
- for (Field<?> field : getFields()) {
- field.setEnabled(fieldsEnabled);
- }
- }
-
- /**
- * Returns the read only status for the fields.
- * <p>
- * Note that this will not accurately represent the read only status of all
- * fields if you change the read only status of the fields through some
- * other method than {@link #setReadOnly(boolean)}.
- *
- * @return true if the fields are set to read only, false otherwise
- */
- public boolean isReadOnly() {
- return readOnly;
- }
-
- /**
- * Updates the read only state of all bound fields.
- *
- * @param fieldsReadOnly
- * true to set all bound fields to read only, false to set them
- * to read write
- */
- public void setReadOnly(boolean fieldsReadOnly) {
- readOnly = fieldsReadOnly;
- }
-
- /**
- * Returns a collection of all fields that have been bound.
- * <p>
- * The fields are not returned in any specific order.
- * </p>
- *
- * @return A collection with all bound Fields
- */
- public Collection<Field<?>> getFields() {
- return fieldToPropertyId.keySet();
- }
-
- /**
- * Binds the field with the given propertyId from the current item. If an
- * item has not been set then the binding is postponed until the item is set
- * using {@link #setItemDataSource(Item)}.
- * <p>
- * This method also adds validators when applicable.
- * </p>
- *
- * @param field
- * The field to bind
- * @param propertyId
- * The propertyId to bind to the field
- * @throws BindException
- * If the property id is already bound to another field by this
- * field binder
- */
- public void bind(Field<?> field, Object propertyId) throws BindException {
- if (propertyIdToField.containsKey(propertyId)
- && propertyIdToField.get(propertyId) != field) {
- throw new BindException("Property id " + propertyId
- + " is already bound to another field");
- }
- fieldToPropertyId.put(field, propertyId);
- propertyIdToField.put(propertyId, field);
- if (itemDataSource == null) {
- // Will be bound when data source is set
- return;
- }
-
- field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
- configureField(field);
- }
-
- private <T> Property.Transactional<T> wrapInTransactionalProperty(
- Property<T> itemProperty) {
- return new TransactionalPropertyWrapper<T>(itemProperty);
- }
-
- /**
- * Gets the property with the given property id from the item.
- *
- * @param propertyId
- * The id if the property to find
- * @return The property with the given id from the item
- * @throws BindException
- * If the property was not found in the item or no item has been
- * set
- */
- protected Property<?> getItemProperty(Object propertyId)
- throws BindException {
- Item item = getItemDataSource();
- if (item == null) {
- throw new BindException("Could not lookup property with id "
- + propertyId + " as no item has been set");
- }
- Property<?> p = item.getItemProperty(propertyId);
- if (p == null) {
- throw new BindException("A property with id " + propertyId
- + " was not found in the item");
- }
- return p;
- }
-
- /**
- * Detaches the field from its property id and removes it from this
- * FieldBinder.
- * <p>
- * Note that the field is not detached from its property data source if it
- * is no longer connected to the same property id it was bound to using this
- * FieldBinder.
- *
- * @param field
- * The field to detach
- * @throws BindException
- * If the field is not bound by this field binder or not bound
- * to the correct property id
- */
- public void unbind(Field<?> field) throws BindException {
- Object propertyId = fieldToPropertyId.get(field);
- if (propertyId == null) {
- throw new BindException(
- "The given field is not part of this FieldBinder");
- }
-
- Property fieldDataSource = field.getPropertyDataSource();
- if (fieldDataSource instanceof TransactionalPropertyWrapper) {
- fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
- .getWrappedProperty();
- }
- if (fieldDataSource == getItemProperty(propertyId)) {
- field.setPropertyDataSource(null);
- }
- fieldToPropertyId.remove(field);
- propertyIdToField.remove(propertyId);
- }
-
- /**
- * Configures a field with the settings set for this FieldBinder.
- * <p>
- * By default this updates the buffered, read only and enabled state of the
- * field. Also adds validators when applicable.
- *
- * @param field
- * The field to update
- */
- protected void configureField(Field<?> field) {
- field.setBuffered(isBuffered());
-
- field.setEnabled(isEnabled());
- field.setReadOnly(isReadOnly());
- }
-
- /**
- * Gets the type of the property with the given property id.
- *
- * @param propertyId
- * The propertyId. Must be find
- * @return The type of the property
- */
- protected Class<?> getPropertyType(Object propertyId) throws BindException {
- if (getItemDataSource() == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No item data source has been set.");
- }
- Property<?> p = getItemDataSource().getItemProperty(propertyId);
- if (p == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No property with that id was found.");
- }
-
- return p.getType();
- }
-
- /**
- * Returns a collection of all property ids that have been bound to fields.
- * <p>
- * Note that this will return property ids even before the item has been
- * set. In that case it returns the property ids that will be bound once the
- * item is set.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of bound property ids
- */
- public Collection<Object> getBoundPropertyIds() {
- return Collections.unmodifiableCollection(propertyIdToField.keySet());
- }
-
- /**
- * Returns a collection of all property ids that exist in the item set using
- * {@link #setItemDataSource(Item)} but have not been bound to fields.
- * <p>
- * Will always return an empty collection before an item has been set using
- * {@link #setItemDataSource(Item)}.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of property ids that have not been bound to fields
- */
- public Collection<Object> getUnboundPropertyIds() {
- if (getItemDataSource() == null) {
- return new ArrayList<Object>();
- }
- List<Object> unboundPropertyIds = new ArrayList<Object>();
- unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
- unboundPropertyIds.removeAll(propertyIdToField.keySet());
- return unboundPropertyIds;
- }
-
- /**
- * Commits all changes done to the bound fields.
- * <p>
- * Calls all {@link CommitHandler}s before and after committing the field
- * changes to the item data source. The whole commit is aborted and state is
- * restored to what it was before commit was called if any
- * {@link CommitHandler} throws a CommitException or there is a problem
- * committing the fields
- *
- * @throws CommitException
- * If the commit was aborted
- */
- public void commit() throws CommitException {
- if (!isBuffered()) {
- // Not using buffered mode, nothing to do
- return;
- }
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .startTransaction();
- }
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
-
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
-
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
- }
-
- throw new CommitException("Commit failed", e);
- }
-
- }
-
- /**
- * Sends a preCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePreCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.preCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Sends a postCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePostCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.postCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Discards all changes done to the bound fields.
- * <p>
- * Only has effect if buffered mode is used.
- *
- */
- public void discard() {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- f.discard();
- } catch (Exception e) {
- // TODO: handle exception
- // What can we do if discard fails other than try to discard all
- // other fields?
- }
- }
- }
-
- /**
- * Returns the field that is bound to the given property id
- *
- * @param propertyId
- * The property id to use to lookup the field
- * @return The field that is bound to the property id or null if no field is
- * bound to that property id
- */
- public Field<?> getField(Object propertyId) {
- return propertyIdToField.get(propertyId);
- }
-
- /**
- * Returns the property id that is bound to the given field
- *
- * @param field
- * The field to use to lookup the property id
- * @return The property id that is bound to the field or null if the field
- * is not bound to any property id by this FieldBinder
- */
- public Object getPropertyId(Field<?> field) {
- return fieldToPropertyId.get(field);
- }
-
- /**
- * Adds a commit handler.
- * <p>
- * The commit handler is called before the field values are committed to the
- * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
- * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
- * {@link CommitHandler} throws a CommitException the whole commit is
- * aborted and the fields retain their old values.
- *
- * @param commitHandler
- * The commit handler to add
- */
- public void addCommitHandler(CommitHandler commitHandler) {
- commitHandlers.add(commitHandler);
- }
-
- /**
- * Removes the given commit handler.
- *
- * @see #addCommitHandler(CommitHandler)
- *
- * @param commitHandler
- * The commit handler to remove
- */
- public void removeCommitHandler(CommitHandler commitHandler) {
- commitHandlers.remove(commitHandler);
- }
-
- /**
- * Returns a list of all commit handlers for this {@link FieldGroup}.
- * <p>
- * Use {@link #addCommitHandler(CommitHandler)} and
- * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
- * commit handler.
- *
- * @return A collection of commit handlers
- */
- protected Collection<CommitHandler> getCommitHandlers() {
- return Collections.unmodifiableCollection(commitHandlers);
- }
-
- /**
- * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
- * commit transactions. CommitHandlers can perform custom operations as part
- * of the commit and cause the commit to be aborted by throwing a
- * {@link CommitException}.
- */
- public interface CommitHandler extends Serializable {
- /**
- * Called before changes are committed to the field and the item is
- * updated.
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void preCommit(CommitEvent commitEvent) throws CommitException;
-
- /**
- * Called after changes are committed to the fields and the item is
- * updated..
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void postCommit(CommitEvent commitEvent) throws CommitException;
- }
-
- /**
- * FIXME javadoc
- *
- */
- public static class CommitEvent implements Serializable {
- private FieldGroup fieldBinder;
-
- private CommitEvent(FieldGroup fieldBinder) {
- this.fieldBinder = fieldBinder;
- }
-
- /**
- * Returns the field binder that this commit relates to
- *
- * @return The FieldBinder that is being committed.
- */
- public FieldGroup getFieldBinder() {
- return fieldBinder;
- }
-
- }
-
- /**
- * Checks the validity of the bound fields.
- * <p>
- * Call the {@link Field#validate()} for the fields to get the individual
- * error messages.
- *
- * @return true if all bound fields are valid, false otherwise.
- */
- public boolean isValid() {
- try {
- for (Field<?> field : getFields()) {
- field.validate();
- }
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks if any bound field has been modified.
- *
- * @return true if at least on field has been modified, false otherwise
- */
- public boolean isModified() {
- for (Field<?> field : getFields()) {
- if (field.isModified()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @return The field factory in use
- *
- */
- public FieldGroupFieldFactory getFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Sets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @param fieldFactory
- * The field factory to use
- */
- public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
- }
-
- /**
- * Binds member fields found in the given object.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age = new TextField("Age"); ... }
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.bindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and the age TextField to a "age"
- * property.
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to bind
- * @throws BindException
- * If there is a problem binding a field
- */
- public void bindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, false);
- }
-
- /**
- * Binds member fields found in the given object and builds member fields
- * that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age;
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.buildAndBindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * <p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and builds an age TextField using
- * the field factory and then binds it to the "age" property.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- public void buildAndBindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, true);
- }
-
- /**
- * Binds member fields found in the given object and optionally builds
- * member fields that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory is buildFields is true. All non-null fields for
- * which a property id can be determined are bound to the property id.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- protected void buildAndBindMemberFields(Object objectWithMemberFields,
- boolean buildFields) throws BindException {
- Class<?> objectClass = objectWithMemberFields.getClass();
-
- for (java.lang.reflect.Field memberField : objectClass
- .getDeclaredFields()) {
-
- if (!Field.class.isAssignableFrom(memberField.getType())) {
- // Process next field
- continue;
- }
-
- PropertyId propertyIdAnnotation = memberField
- .getAnnotation(PropertyId.class);
-
- Class<? extends Field> fieldType = (Class<? extends Field>) memberField
- .getType();
-
- Object propertyId = null;
- if (propertyIdAnnotation != null) {
- // @PropertyId(propertyId) always overrides property id
- propertyId = propertyIdAnnotation.value();
- } else {
- propertyId = memberField.getName();
- }
-
- // Ensure that the property id exists
- Class<?> propertyType;
-
- try {
- propertyType = getPropertyType(propertyId);
- } catch (BindException e) {
- // Property id was not found, skip this field
- continue;
- }
-
- Field<?> field;
- try {
- // Get the field from the object
- field = (Field<?>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField);
- } catch (Exception e) {
- // If we cannot determine the value, just skip the field and try
- // the next one
- continue;
- }
-
- if (field == null && buildFields) {
- Caption captionAnnotation = memberField
- .getAnnotation(Caption.class);
- String caption;
- if (captionAnnotation != null) {
- caption = captionAnnotation.value();
- } else {
- caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- }
-
- // Create the component (Field)
- field = build(caption, propertyType, fieldType);
-
- // Store it in the field
- try {
- ReflectTools.setJavaFieldValue(objectWithMemberFields,
- memberField, field);
- } catch (IllegalArgumentException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (IllegalAccessException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (InvocationTargetException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- }
- }
-
- if (field != null) {
- // Bind it to the property id
- bind(field, propertyId);
- }
- }
- }
-
- public static class CommitException extends Exception {
-
- public CommitException() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- }
-
- public static class BindException extends RuntimeException {
-
- public BindException(String message) {
- super(message);
- }
-
- public BindException(String message, Throwable t) {
- super(message, t);
- }
-
- }
-
- /**
- * Builds a field and binds it to the given property id using the field
- * binder.
- *
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field
- */
- public Field<?> buildAndBind(Object propertyId) throws BindException {
- String caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- return buildAndBind(caption, propertyId);
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field. Can be any type of {@link Field}.
- */
- public Field<?> buildAndBind(String caption, Object propertyId)
- throws BindException {
- Class<?> type = getPropertyType(propertyId);
- return buildAndBind(caption, propertyId, Field.class);
-
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder. Ensures the new field is of the given type.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If the field could not be created
- * @return The created and bound field. Can be any type of {@link Field}.
- */
-
- public <T extends Field> T buildAndBind(String caption, Object propertyId,
- Class<T> fieldType) throws BindException {
- Class<?> type = getPropertyType(propertyId);
-
- T field = build(caption, type, fieldType);
- bind(field, propertyId);
-
- return field;
- }
-
- /**
- * Creates a field based on the given data type.
- * <p>
- * The data type is the type that we want to edit using the field. The field
- * type is the type of field we want to create, can be {@link Field} if any
- * Field is good.
- * </p>
- *
- * @param caption
- * The caption for the new field
- * @param dataType
- * The data model type that we want to edit using the field
- * @param fieldType
- * The type of field that we want to create
- * @return A Field capable of editing the given type
- * @throws BindException
- * If the field could not be created
- */
- protected <T extends Field> T build(String caption, Class<?> dataType,
- Class<T> fieldType) throws BindException {
- T field = getFieldFactory().createField(dataType, fieldType);
- if (field == null) {
- throw new BindException("Unable to build a field of type "
- + fieldType.getName() + " for editing "
- + dataType.getName());
- }
-
- field.setCaption(caption);
- return field;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.TransactionalPropertyWrapper;
+import com.vaadin.tools.ReflectTools;
+import com.vaadin.ui.DefaultFieldFactory;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Form;
+
+/**
+ * FieldGroup provides an easy way of binding fields to data and handling
+ * commits of these fields.
+ * <p>
+ * The functionality of FieldGroup is similar to {@link Form} but
+ * {@link FieldGroup} does not handle layouts in any way. The typical use case
+ * is to create a layout outside the FieldGroup and then use FieldGroup to bind
+ * the fields to a data source.
+ * </p>
+ * <p>
+ * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
+ * Using the buildAndBind methods {@link FieldGroup} can create fields for you
+ * using a FieldGroupFieldFactory but you still have to add them to the correct
+ * position in your layout.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version @version@
+ * @since 7.0
+ */
+public class FieldGroup implements Serializable {
+
+ private static final Logger logger = Logger.getLogger(FieldGroup.class
+ .getName());
+
+ private Item itemDataSource;
+ private boolean buffered = true;
+
+ private boolean enabled = true;
+ private boolean readOnly = false;
+
+ private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
+ private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
+ private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
+
+ /**
+ * The field factory used by builder methods.
+ */
+ private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
+
+ /**
+ * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
+ * data source for the field binder.
+ *
+ */
+ public FieldGroup() {
+
+ }
+
+ /**
+ * Constructs a field binder that uses the given data source.
+ *
+ * @param itemDataSource
+ * The data source to bind the fields to
+ */
+ public FieldGroup(Item itemDataSource) {
+ setItemDataSource(itemDataSource);
+ }
+
+ /**
+ * Updates the item that is used by this FieldBinder. Rebinds all fields to
+ * the properties in the new item.
+ *
+ * @param itemDataSource
+ * The new item to use
+ */
+ public void setItemDataSource(Item itemDataSource) {
+ this.itemDataSource = itemDataSource;
+
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ bind(f, fieldToPropertyId.get(f));
+ }
+ }
+
+ /**
+ * Gets the item used by this FieldBinder. Note that you must call
+ * {@link #commit()} for the item to be updated unless buffered mode has
+ * been switched off.
+ *
+ * @see #setBuffered(boolean)
+ * @see #commit()
+ *
+ * @return The item used by this FieldBinder
+ */
+ public Item getItemDataSource() {
+ return itemDataSource;
+ }
+
+ /**
+ * Checks the buffered mode for the bound fields.
+ * <p>
+ *
+ * @see #setBuffered(boolean) for more details on buffered mode
+ *
+ * @see Field#isBuffered()
+ * @return true if buffered mode is on, false otherwise
+ *
+ */
+ public boolean isBuffered() {
+ return buffered;
+ }
+
+ /**
+ * Sets the buffered mode for the bound fields.
+ * <p>
+ * When buffered mode is on the item will not be updated until
+ * {@link #commit()} is called. If buffered mode is off the item will be
+ * updated once the fields are updated.
+ * </p>
+ * <p>
+ * The default is to use buffered mode.
+ * </p>
+ *
+ * @see Field#setBuffered(boolean)
+ * @param buffered
+ * true to turn on buffered mode, false otherwise
+ */
+ public void setBuffered(boolean buffered) {
+ if (buffered == this.buffered) {
+ return;
+ }
+
+ this.buffered = buffered;
+ for (Field<?> field : getFields()) {
+ field.setBuffered(buffered);
+ }
+ }
+
+ /**
+ * Returns the enabled status for the fields.
+ * <p>
+ * Note that this will not accurately represent the enabled status of all
+ * fields if you change the enabled status of the fields through some other
+ * method than {@link #setEnabled(boolean)}.
+ *
+ * @return true if the fields are enabled, false otherwise
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Updates the enabled state of all bound fields.
+ *
+ * @param fieldsEnabled
+ * true to enable all bound fields, false to disable them
+ */
+ public void setEnabled(boolean fieldsEnabled) {
+ enabled = fieldsEnabled;
+ for (Field<?> field : getFields()) {
+ field.setEnabled(fieldsEnabled);
+ }
+ }
+
+ /**
+ * Returns the read only status for the fields.
+ * <p>
+ * Note that this will not accurately represent the read only status of all
+ * fields if you change the read only status of the fields through some
+ * other method than {@link #setReadOnly(boolean)}.
+ *
+ * @return true if the fields are set to read only, false otherwise
+ */
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * Updates the read only state of all bound fields.
+ *
+ * @param fieldsReadOnly
+ * true to set all bound fields to read only, false to set them
+ * to read write
+ */
+ public void setReadOnly(boolean fieldsReadOnly) {
+ readOnly = fieldsReadOnly;
+ }
+
+ /**
+ * Returns a collection of all fields that have been bound.
+ * <p>
+ * The fields are not returned in any specific order.
+ * </p>
+ *
+ * @return A collection with all bound Fields
+ */
+ public Collection<Field<?>> getFields() {
+ return fieldToPropertyId.keySet();
+ }
+
+ /**
+ * Binds the field with the given propertyId from the current item. If an
+ * item has not been set then the binding is postponed until the item is set
+ * using {@link #setItemDataSource(Item)}.
+ * <p>
+ * This method also adds validators when applicable.
+ * </p>
+ *
+ * @param field
+ * The field to bind
+ * @param propertyId
+ * The propertyId to bind to the field
+ * @throws BindException
+ * If the property id is already bound to another field by this
+ * field binder
+ */
+ public void bind(Field<?> field, Object propertyId) throws BindException {
+ if (propertyIdToField.containsKey(propertyId)
+ && propertyIdToField.get(propertyId) != field) {
+ throw new BindException("Property id " + propertyId
+ + " is already bound to another field");
+ }
+ fieldToPropertyId.put(field, propertyId);
+ propertyIdToField.put(propertyId, field);
+ if (itemDataSource == null) {
+ // Will be bound when data source is set
+ return;
+ }
+
+ field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
+ configureField(field);
+ }
+
+ private <T> Property.Transactional<T> wrapInTransactionalProperty(
+ Property<T> itemProperty) {
+ return new TransactionalPropertyWrapper<T>(itemProperty);
+ }
+
+ /**
+ * Gets the property with the given property id from the item.
+ *
+ * @param propertyId
+ * The id if the property to find
+ * @return The property with the given id from the item
+ * @throws BindException
+ * If the property was not found in the item or no item has been
+ * set
+ */
+ protected Property<?> getItemProperty(Object propertyId)
+ throws BindException {
+ Item item = getItemDataSource();
+ if (item == null) {
+ throw new BindException("Could not lookup property with id "
+ + propertyId + " as no item has been set");
+ }
+ Property<?> p = item.getItemProperty(propertyId);
+ if (p == null) {
+ throw new BindException("A property with id " + propertyId
+ + " was not found in the item");
+ }
+ return p;
+ }
+
+ /**
+ * Detaches the field from its property id and removes it from this
+ * FieldBinder.
+ * <p>
+ * Note that the field is not detached from its property data source if it
+ * is no longer connected to the same property id it was bound to using this
+ * FieldBinder.
+ *
+ * @param field
+ * The field to detach
+ * @throws BindException
+ * If the field is not bound by this field binder or not bound
+ * to the correct property id
+ */
+ public void unbind(Field<?> field) throws BindException {
+ Object propertyId = fieldToPropertyId.get(field);
+ if (propertyId == null) {
+ throw new BindException(
+ "The given field is not part of this FieldBinder");
+ }
+
+ Property fieldDataSource = field.getPropertyDataSource();
+ if (fieldDataSource instanceof TransactionalPropertyWrapper) {
+ fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
+ .getWrappedProperty();
+ }
+ if (fieldDataSource == getItemProperty(propertyId)) {
+ field.setPropertyDataSource(null);
+ }
+ fieldToPropertyId.remove(field);
+ propertyIdToField.remove(propertyId);
+ }
+
+ /**
+ * Configures a field with the settings set for this FieldBinder.
+ * <p>
+ * By default this updates the buffered, read only and enabled state of the
+ * field. Also adds validators when applicable.
+ *
+ * @param field
+ * The field to update
+ */
+ protected void configureField(Field<?> field) {
+ field.setBuffered(isBuffered());
+
+ field.setEnabled(isEnabled());
+ field.setReadOnly(isReadOnly());
+ }
+
+ /**
+ * Gets the type of the property with the given property id.
+ *
+ * @param propertyId
+ * The propertyId. Must be find
+ * @return The type of the property
+ */
+ protected Class<?> getPropertyType(Object propertyId) throws BindException {
+ if (getItemDataSource() == null) {
+ throw new BindException(
+ "Property type for '"
+ + propertyId
+ + "' could not be determined. No item data source has been set.");
+ }
+ Property<?> p = getItemDataSource().getItemProperty(propertyId);
+ if (p == null) {
+ throw new BindException(
+ "Property type for '"
+ + propertyId
+ + "' could not be determined. No property with that id was found.");
+ }
+
+ return p.getType();
+ }
+
+ /**
+ * Returns a collection of all property ids that have been bound to fields.
+ * <p>
+ * Note that this will return property ids even before the item has been
+ * set. In that case it returns the property ids that will be bound once the
+ * item is set.
+ * </p>
+ * <p>
+ * No guarantee is given for the order of the property ids
+ * </p>
+ *
+ * @return A collection of bound property ids
+ */
+ public Collection<Object> getBoundPropertyIds() {
+ return Collections.unmodifiableCollection(propertyIdToField.keySet());
+ }
+
+ /**
+ * Returns a collection of all property ids that exist in the item set using
+ * {@link #setItemDataSource(Item)} but have not been bound to fields.
+ * <p>
+ * Will always return an empty collection before an item has been set using
+ * {@link #setItemDataSource(Item)}.
+ * </p>
+ * <p>
+ * No guarantee is given for the order of the property ids
+ * </p>
+ *
+ * @return A collection of property ids that have not been bound to fields
+ */
+ public Collection<Object> getUnboundPropertyIds() {
+ if (getItemDataSource() == null) {
+ return new ArrayList<Object>();
+ }
+ List<Object> unboundPropertyIds = new ArrayList<Object>();
+ unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
+ unboundPropertyIds.removeAll(propertyIdToField.keySet());
+ return unboundPropertyIds;
+ }
+
+ /**
+ * Commits all changes done to the bound fields.
+ * <p>
+ * Calls all {@link CommitHandler}s before and after committing the field
+ * changes to the item data source. The whole commit is aborted and state is
+ * restored to what it was before commit was called if any
+ * {@link CommitHandler} throws a CommitException or there is a problem
+ * committing the fields
+ *
+ * @throws CommitException
+ * If the commit was aborted
+ */
+ public void commit() throws CommitException {
+ if (!isBuffered()) {
+ // Not using buffered mode, nothing to do
+ return;
+ }
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .startTransaction();
+ }
+ try {
+ firePreCommitEvent();
+ // Commit the field values to the properties
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ f.commit();
+ }
+ firePostCommitEvent();
+
+ // Commit the properties
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .commit();
+ }
+
+ } catch (Exception e) {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .rollback();
+ } catch (Exception rollbackException) {
+ // FIXME: What to do ?
+ }
+ }
+
+ throw new CommitException("Commit failed", e);
+ }
+
+ }
+
+ /**
+ * Sends a preCommit event to all registered commit handlers
+ *
+ * @throws CommitException
+ * If the commit should be aborted
+ */
+ private void firePreCommitEvent() throws CommitException {
+ CommitHandler[] handlers = commitHandlers
+ .toArray(new CommitHandler[commitHandlers.size()]);
+
+ for (CommitHandler handler : handlers) {
+ handler.preCommit(new CommitEvent(this));
+ }
+ }
+
+ /**
+ * Sends a postCommit event to all registered commit handlers
+ *
+ * @throws CommitException
+ * If the commit should be aborted
+ */
+ private void firePostCommitEvent() throws CommitException {
+ CommitHandler[] handlers = commitHandlers
+ .toArray(new CommitHandler[commitHandlers.size()]);
+
+ for (CommitHandler handler : handlers) {
+ handler.postCommit(new CommitEvent(this));
+ }
+ }
+
+ /**
+ * Discards all changes done to the bound fields.
+ * <p>
+ * Only has effect if buffered mode is used.
+ *
+ */
+ public void discard() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ f.discard();
+ } catch (Exception e) {
+ // TODO: handle exception
+ // What can we do if discard fails other than try to discard all
+ // other fields?
+ }
+ }
+ }
+
+ /**
+ * Returns the field that is bound to the given property id
+ *
+ * @param propertyId
+ * The property id to use to lookup the field
+ * @return The field that is bound to the property id or null if no field is
+ * bound to that property id
+ */
+ public Field<?> getField(Object propertyId) {
+ return propertyIdToField.get(propertyId);
+ }
+
+ /**
+ * Returns the property id that is bound to the given field
+ *
+ * @param field
+ * The field to use to lookup the property id
+ * @return The property id that is bound to the field or null if the field
+ * is not bound to any property id by this FieldBinder
+ */
+ public Object getPropertyId(Field<?> field) {
+ return fieldToPropertyId.get(field);
+ }
+
+ /**
+ * Adds a commit handler.
+ * <p>
+ * The commit handler is called before the field values are committed to the
+ * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
+ * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
+ * {@link CommitHandler} throws a CommitException the whole commit is
+ * aborted and the fields retain their old values.
+ *
+ * @param commitHandler
+ * The commit handler to add
+ */
+ public void addCommitHandler(CommitHandler commitHandler) {
+ commitHandlers.add(commitHandler);
+ }
+
+ /**
+ * Removes the given commit handler.
+ *
+ * @see #addCommitHandler(CommitHandler)
+ *
+ * @param commitHandler
+ * The commit handler to remove
+ */
+ public void removeCommitHandler(CommitHandler commitHandler) {
+ commitHandlers.remove(commitHandler);
+ }
+
+ /**
+ * Returns a list of all commit handlers for this {@link FieldGroup}.
+ * <p>
+ * Use {@link #addCommitHandler(CommitHandler)} and
+ * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
+ * commit handler.
+ *
+ * @return A collection of commit handlers
+ */
+ protected Collection<CommitHandler> getCommitHandlers() {
+ return Collections.unmodifiableCollection(commitHandlers);
+ }
+
+ /**
+ * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
+ * commit transactions. CommitHandlers can perform custom operations as part
+ * of the commit and cause the commit to be aborted by throwing a
+ * {@link CommitException}.
+ */
+ public interface CommitHandler extends Serializable {
+ /**
+ * Called before changes are committed to the field and the item is
+ * updated.
+ * <p>
+ * Throw a {@link CommitException} to abort the commit.
+ *
+ * @param commitEvent
+ * An event containing information regarding the commit
+ * @throws CommitException
+ * if the commit should be aborted
+ */
+ public void preCommit(CommitEvent commitEvent) throws CommitException;
+
+ /**
+ * Called after changes are committed to the fields and the item is
+ * updated..
+ * <p>
+ * Throw a {@link CommitException} to abort the commit.
+ *
+ * @param commitEvent
+ * An event containing information regarding the commit
+ * @throws CommitException
+ * if the commit should be aborted
+ */
+ public void postCommit(CommitEvent commitEvent) throws CommitException;
+ }
+
+ /**
+ * FIXME javadoc
+ *
+ */
+ public static class CommitEvent implements Serializable {
+ private FieldGroup fieldBinder;
+
+ private CommitEvent(FieldGroup fieldBinder) {
+ this.fieldBinder = fieldBinder;
+ }
+
+ /**
+ * Returns the field binder that this commit relates to
+ *
+ * @return The FieldBinder that is being committed.
+ */
+ public FieldGroup getFieldBinder() {
+ return fieldBinder;
+ }
+
+ }
+
+ /**
+ * Checks the validity of the bound fields.
+ * <p>
+ * Call the {@link Field#validate()} for the fields to get the individual
+ * error messages.
+ *
+ * @return true if all bound fields are valid, false otherwise.
+ */
+ public boolean isValid() {
+ try {
+ for (Field<?> field : getFields()) {
+ field.validate();
+ }
+ return true;
+ } catch (InvalidValueException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if any bound field has been modified.
+ *
+ * @return true if at least on field has been modified, false otherwise
+ */
+ public boolean isModified() {
+ for (Field<?> field : getFields()) {
+ if (field.isModified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the field factory for the {@link FieldGroup}. The field factory is
+ * only used when {@link FieldGroup} creates a new field.
+ *
+ * @return The field factory in use
+ *
+ */
+ public FieldGroupFieldFactory getFieldFactory() {
+ return fieldFactory;
+ }
+
+ /**
+ * Sets the field factory for the {@link FieldGroup}. The field factory is
+ * only used when {@link FieldGroup} creates a new field.
+ *
+ * @param fieldFactory
+ * The field factory to use
+ */
+ public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
+ this.fieldFactory = fieldFactory;
+ }
+
+ /**
+ * Binds member fields found in the given object.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. All non-null fields for which a property id can
+ * be determined are bound to the property id.
+ * </p>
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class MyForm extends VerticalLayout {
+ * private TextField firstName = new TextField("First name");
+ * @PropertyId("last")
+ * private TextField lastName = new TextField("Last name");
+ * private TextField age = new TextField("Age"); ... }
+ *
+ * MyForm myForm = new MyForm();
+ * ...
+ * fieldGroup.bindMemberFields(myForm);
+ * </pre>
+ *
+ * </p>
+ * This binds the firstName TextField to a "firstName" property in the item,
+ * lastName TextField to a "last" property and the age TextField to a "age"
+ * property.
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to bind
+ * @throws BindException
+ * If there is a problem binding a field
+ */
+ public void bindMemberFields(Object objectWithMemberFields)
+ throws BindException {
+ buildAndBindMemberFields(objectWithMemberFields, false);
+ }
+
+ /**
+ * Binds member fields found in the given object and builds member fields
+ * that have not been initialized.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. Fields that are not initialized (null) are built
+ * using the field factory. All non-null fields for which a property id can
+ * be determined are bound to the property id.
+ * </p>
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class MyForm extends VerticalLayout {
+ * private TextField firstName = new TextField("First name");
+ * @PropertyId("last")
+ * private TextField lastName = new TextField("Last name");
+ * private TextField age;
+ *
+ * MyForm myForm = new MyForm();
+ * ...
+ * fieldGroup.buildAndBindMemberFields(myForm);
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * This binds the firstName TextField to a "firstName" property in the item,
+ * lastName TextField to a "last" property and builds an age TextField using
+ * the field factory and then binds it to the "age" property.
+ * </p>
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to build and
+ * bind
+ * @throws BindException
+ * If there is a problem binding or building a field
+ */
+ public void buildAndBindMemberFields(Object objectWithMemberFields)
+ throws BindException {
+ buildAndBindMemberFields(objectWithMemberFields, true);
+ }
+
+ /**
+ * Binds member fields found in the given object and optionally builds
+ * member fields that have not been initialized.
+ * <p>
+ * This method processes all (Java) member fields whose type extends
+ * {@link Field} and that can be mapped to a property id. Property id
+ * mapping is done based on the field name or on a @{@link PropertyId}
+ * annotation on the field. Fields that are not initialized (null) are built
+ * using the field factory is buildFields is true. All non-null fields for
+ * which a property id can be determined are bound to the property id.
+ * </p>
+ *
+ * @param objectWithMemberFields
+ * The object that contains (Java) member fields to build and
+ * bind
+ * @throws BindException
+ * If there is a problem binding or building a field
+ */
+ protected void buildAndBindMemberFields(Object objectWithMemberFields,
+ boolean buildFields) throws BindException {
+ Class<?> objectClass = objectWithMemberFields.getClass();
+
+ for (java.lang.reflect.Field memberField : objectClass
+ .getDeclaredFields()) {
+
+ if (!Field.class.isAssignableFrom(memberField.getType())) {
+ // Process next field
+ continue;
+ }
+
+ PropertyId propertyIdAnnotation = memberField
+ .getAnnotation(PropertyId.class);
+
+ Class<? extends Field> fieldType = (Class<? extends Field>) memberField
+ .getType();
+
+ Object propertyId = null;
+ if (propertyIdAnnotation != null) {
+ // @PropertyId(propertyId) always overrides property id
+ propertyId = propertyIdAnnotation.value();
+ } else {
+ propertyId = memberField.getName();
+ }
+
+ // Ensure that the property id exists
+ Class<?> propertyType;
+
+ try {
+ propertyType = getPropertyType(propertyId);
+ } catch (BindException e) {
+ // Property id was not found, skip this field
+ continue;
+ }
+
+ Field<?> field;
+ try {
+ // Get the field from the object
+ field = (Field<?>) ReflectTools.getJavaFieldValue(
+ objectWithMemberFields, memberField);
+ } catch (Exception e) {
+ // If we cannot determine the value, just skip the field and try
+ // the next one
+ continue;
+ }
+
+ if (field == null && buildFields) {
+ Caption captionAnnotation = memberField
+ .getAnnotation(Caption.class);
+ String caption;
+ if (captionAnnotation != null) {
+ caption = captionAnnotation.value();
+ } else {
+ caption = DefaultFieldFactory
+ .createCaptionByPropertyId(propertyId);
+ }
+
+ // Create the component (Field)
+ field = build(caption, propertyType, fieldType);
+
+ // Store it in the field
+ try {
+ ReflectTools.setJavaFieldValue(objectWithMemberFields,
+ memberField, field);
+ } catch (IllegalArgumentException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ } catch (IllegalAccessException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ } catch (InvocationTargetException e) {
+ throw new BindException("Could not assign value to field '"
+ + memberField.getName() + "'", e);
+ }
+ }
+
+ if (field != null) {
+ // Bind it to the property id
+ bind(field, propertyId);
+ }
+ }
+ }
+
+ public static class CommitException extends Exception {
+
+ public CommitException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CommitException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ }
+
+ public static class BindException extends RuntimeException {
+
+ public BindException(String message) {
+ super(message);
+ }
+
+ public BindException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ }
+
+ /**
+ * Builds a field and binds it to the given property id using the field
+ * binder.
+ *
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If there is a problem while building or binding
+ * @return The created and bound field
+ */
+ public Field<?> buildAndBind(Object propertyId) throws BindException {
+ String caption = DefaultFieldFactory
+ .createCaptionByPropertyId(propertyId);
+ return buildAndBind(caption, propertyId);
+ }
+
+ /**
+ * Builds a field using the given caption and binds it to the given property
+ * id using the field binder.
+ *
+ * @param caption
+ * The caption for the field
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If there is a problem while building or binding
+ * @return The created and bound field. Can be any type of {@link Field}.
+ */
+ public Field<?> buildAndBind(String caption, Object propertyId)
+ throws BindException {
+ Class<?> type = getPropertyType(propertyId);
+ return buildAndBind(caption, propertyId, Field.class);
+
+ }
+
+ /**
+ * Builds a field using the given caption and binds it to the given property
+ * id using the field binder. Ensures the new field is of the given type.
+ *
+ * @param caption
+ * The caption for the field
+ * @param propertyId
+ * The property id to bind to. Must be present in the field
+ * finder.
+ * @throws BindException
+ * If the field could not be created
+ * @return The created and bound field. Can be any type of {@link Field}.
+ */
+
+ public <T extends Field> T buildAndBind(String caption, Object propertyId,
+ Class<T> fieldType) throws BindException {
+ Class<?> type = getPropertyType(propertyId);
+
+ T field = build(caption, type, fieldType);
+ bind(field, propertyId);
+
+ return field;
+ }
+
+ /**
+ * Creates a field based on the given data type.
+ * <p>
+ * The data type is the type that we want to edit using the field. The field
+ * type is the type of field we want to create, can be {@link Field} if any
+ * Field is good.
+ * </p>
+ *
+ * @param caption
+ * The caption for the new field
+ * @param dataType
+ * The data model type that we want to edit using the field
+ * @param fieldType
+ * The type of field that we want to create
+ * @return A Field capable of editing the given type
+ * @throws BindException
+ * If the field could not be created
+ */
+ protected <T extends Field> T build(String caption, Class<?> dataType,
+ Class<T> fieldType) throws BindException {
+ T field = getFieldFactory().createField(dataType, fieldType);
+ if (field == null) {
+ throw new BindException("Unable to build a field of type "
+ + fieldType.getName() + " for editing "
+ + dataType.getName());
+ }
+
+ field.setCaption(caption);
+ return field;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
index 6945a492bd..80c012cbdc 100644
--- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
@@ -1,31 +1,31 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Field;
-
-/**
- * Factory interface for creating new Field-instances based on the data type
- * that should be edited.
- *
- * @author Vaadin Ltd.
- * @version @version@
- * @since 7.0
- */
-public interface FieldGroupFieldFactory extends Serializable {
- /**
- * Creates a field based on the data type that we want to edit
- *
- * @param dataType
- * The type that we want to edit using the field
- * @param fieldType
- * The type of field we want to create. If set to {@link Field}
- * then any type of field is accepted
- * @return A field that can be assigned to the given fieldType and that is
- * capable of editing the given type of data
- */
- <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.io.Serializable;
+
+import com.vaadin.ui.Field;
+
+/**
+ * Factory interface for creating new Field-instances based on the data type
+ * that should be edited.
+ *
+ * @author Vaadin Ltd.
+ * @version @version@
+ * @since 7.0
+ */
+public interface FieldGroupFieldFactory extends Serializable {
+ /**
+ * Creates a field based on the data type that we want to edit
+ *
+ * @param dataType
+ * The type that we want to edit using the field
+ * @param fieldType
+ * The type of field we want to create. If set to {@link Field}
+ * then any type of field is accepted
+ * @return A field that can be assigned to the given fieldType and that is
+ * capable of editing the given type of data
+ */
+ <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
+}
diff --git a/src/com/vaadin/data/fieldgroup/PropertyId.java b/src/com/vaadin/data/fieldgroup/PropertyId.java
index 588fdc3020..268047401d 100644
--- a/src/com/vaadin/data/fieldgroup/PropertyId.java
+++ b/src/com/vaadin/data/fieldgroup/PropertyId.java
@@ -1,15 +1,15 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface PropertyId {
- String value();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.fieldgroup;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PropertyId {
+ String value();
+}
diff --git a/src/com/vaadin/data/util/TextFileProperty.java b/src/com/vaadin/data/util/TextFileProperty.java
index 77325e141d..5ebba98062 100644
--- a/src/com/vaadin/data/util/TextFileProperty.java
+++ b/src/com/vaadin/data/util/TextFileProperty.java
@@ -1,141 +1,141 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * Property implementation for wrapping a text file.
- *
- * Supports reading and writing of a File from/to String.
- *
- * {@link ValueChangeListener}s are supported, but only fire when
- * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
- * are supported but only fire when setReadOnly(boolean) is explicitly called.
- *
- */
-@SuppressWarnings("serial")
-public class TextFileProperty extends AbstractProperty<String> {
-
- private File file;
- private Charset charset = null;
-
- /**
- * Wrap given file with property interface.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- */
- public TextFileProperty(File file) {
- this.file = file;
- }
-
- /**
- * Wrap the given file with the property interface and specify character
- * set.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- * @param charset
- * Charset to be used for reading and writing the file.
- */
- public TextFileProperty(File file, Charset charset) {
- this.file = file;
- this.charset = charset;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getType()
- */
- public Class<String> getType() {
- return String.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getValue()
- */
- public String getValue() {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- InputStreamReader isr = charset == null ? new InputStreamReader(fis)
- : new InputStreamReader(fis, charset);
- BufferedReader r = new BufferedReader(isr);
- StringBuilder b = new StringBuilder();
- char buf[] = new char[8 * 1024];
- int len;
- while ((len = r.read(buf)) != -1) {
- b.append(buf, 0, len);
- }
- r.close();
- isr.close();
- fis.close();
- return b.toString();
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return file == null || super.isReadOnly() || !file.canWrite();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setValue(java.lang.Object)
- */
- public void setValue(Object newValue) throws ReadOnlyException {
- if (isReadOnly()) {
- throw new ReadOnlyException();
- }
- if (file == null) {
- return;
- }
-
- try {
- FileOutputStream fos = new FileOutputStream(file);
- OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
- fos) : new OutputStreamWriter(fos, charset);
- BufferedWriter w = new BufferedWriter(osw);
- w.append(newValue.toString());
- w.flush();
- w.close();
- osw.close();
- fos.close();
- fireValueChange();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+
+/**
+ * Property implementation for wrapping a text file.
+ *
+ * Supports reading and writing of a File from/to String.
+ *
+ * {@link ValueChangeListener}s are supported, but only fire when
+ * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
+ * are supported but only fire when setReadOnly(boolean) is explicitly called.
+ *
+ */
+@SuppressWarnings("serial")
+public class TextFileProperty extends AbstractProperty<String> {
+
+ private File file;
+ private Charset charset = null;
+
+ /**
+ * Wrap given file with property interface.
+ *
+ * Setting the file to null works, but getValue() will return null.
+ *
+ * @param file
+ * File to be wrapped.
+ */
+ public TextFileProperty(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Wrap the given file with the property interface and specify character
+ * set.
+ *
+ * Setting the file to null works, but getValue() will return null.
+ *
+ * @param file
+ * File to be wrapped.
+ * @param charset
+ * Charset to be used for reading and writing the file.
+ */
+ public TextFileProperty(File file, Charset charset) {
+ this.file = file;
+ this.charset = charset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#getType()
+ */
+ public Class<String> getType() {
+ return String.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#getValue()
+ */
+ public String getValue() {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ InputStreamReader isr = charset == null ? new InputStreamReader(fis)
+ : new InputStreamReader(fis, charset);
+ BufferedReader r = new BufferedReader(isr);
+ StringBuilder b = new StringBuilder();
+ char buf[] = new char[8 * 1024];
+ int len;
+ while ((len = r.read(buf)) != -1) {
+ b.append(buf, 0, len);
+ }
+ r.close();
+ isr.close();
+ fis.close();
+ return b.toString();
+ } catch (FileNotFoundException e) {
+ return null;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#isReadOnly()
+ */
+ @Override
+ public boolean isReadOnly() {
+ return file == null || super.isReadOnly() || !file.canWrite();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Property#setValue(java.lang.Object)
+ */
+ public void setValue(Object newValue) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ if (file == null) {
+ return;
+ }
+
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
+ fos) : new OutputStreamWriter(fos, charset);
+ BufferedWriter w = new BufferedWriter(osw);
+ w.append(newValue.toString());
+ w.flush();
+ w.close();
+ osw.close();
+ fos.close();
+ fireValueChange();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
index de44dbe544..06ec0935c3 100644
--- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
@@ -1,107 +1,107 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.Property.ValueChangeEvent;
-import com.vaadin.data.Property.ValueChangeNotifier;
-
-/**
- * Wrapper class that helps implement two-phase commit for a non-transactional
- * property.
- *
- * When accessing the property through the wrapper, getting and setting the
- * property value take place immediately. However, the wrapper keeps track of
- * the old value of the property so that it can be set for the property in case
- * of a roll-back. This can result in the underlying property value changing
- * multiple times (first based on modifications made by the application, then
- * back upon roll-back).
- *
- * Value change events on the {@link TransactionalPropertyWrapper} are only
- * fired at the end of a successful transaction, whereas listeners attached to
- * the underlying property may receive multiple value change events.
- *
- * @see com.vaadin.data.Property.Transactional
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- *
- * @param <T>
- */
-public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
- implements ValueChangeNotifier, Property.Transactional<T> {
-
- private Property<T> wrappedProperty;
- private boolean inTransaction = false;
- private boolean valueChangePending;
- private T valueBeforeTransaction;
-
- public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
- this.wrappedProperty = wrappedProperty;
- if (wrappedProperty instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) wrappedProperty)
- .addListener(new ValueChangeListener() {
-
- public void valueChange(ValueChangeEvent event) {
- fireValueChange();
- }
- });
- }
- }
-
- public Class getType() {
- return wrappedProperty.getType();
- }
-
- public T getValue() {
- return wrappedProperty.getValue();
- }
-
- public void setValue(Object newValue) throws ReadOnlyException {
- // Causes a value change to be sent to this listener which in turn fires
- // a new value change event for this property
- wrappedProperty.setValue(newValue);
- }
-
- public void startTransaction() {
- inTransaction = true;
- valueBeforeTransaction = getValue();
- }
-
- public void commit() {
- endTransaction();
- }
-
- public void rollback() {
- try {
- wrappedProperty.setValue(valueBeforeTransaction);
- } finally {
- valueChangePending = false;
- endTransaction();
- }
- }
-
- protected void endTransaction() {
- inTransaction = false;
- valueBeforeTransaction = null;
- if (valueChangePending) {
- fireValueChange();
- }
- }
-
- @Override
- protected void fireValueChange() {
- if (inTransaction) {
- valueChangePending = true;
- } else {
- super.fireValueChange();
- }
- }
-
- public Property<T> getWrappedProperty() {
- return wrappedProperty;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeNotifier;
+
+/**
+ * Wrapper class that helps implement two-phase commit for a non-transactional
+ * property.
+ *
+ * When accessing the property through the wrapper, getting and setting the
+ * property value take place immediately. However, the wrapper keeps track of
+ * the old value of the property so that it can be set for the property in case
+ * of a roll-back. This can result in the underlying property value changing
+ * multiple times (first based on modifications made by the application, then
+ * back upon roll-back).
+ *
+ * Value change events on the {@link TransactionalPropertyWrapper} are only
+ * fired at the end of a successful transaction, whereas listeners attached to
+ * the underlying property may receive multiple value change events.
+ *
+ * @see com.vaadin.data.Property.Transactional
+ *
+ * @author Vaadin Ltd
+ * @version @version@
+ * @since 7.0
+ *
+ * @param <T>
+ */
+public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
+ implements ValueChangeNotifier, Property.Transactional<T> {
+
+ private Property<T> wrappedProperty;
+ private boolean inTransaction = false;
+ private boolean valueChangePending;
+ private T valueBeforeTransaction;
+
+ public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
+ this.wrappedProperty = wrappedProperty;
+ if (wrappedProperty instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) wrappedProperty)
+ .addListener(new ValueChangeListener() {
+
+ public void valueChange(ValueChangeEvent event) {
+ fireValueChange();
+ }
+ });
+ }
+ }
+
+ public Class getType() {
+ return wrappedProperty.getType();
+ }
+
+ public T getValue() {
+ return wrappedProperty.getValue();
+ }
+
+ public void setValue(Object newValue) throws ReadOnlyException {
+ // Causes a value change to be sent to this listener which in turn fires
+ // a new value change event for this property
+ wrappedProperty.setValue(newValue);
+ }
+
+ public void startTransaction() {
+ inTransaction = true;
+ valueBeforeTransaction = getValue();
+ }
+
+ public void commit() {
+ endTransaction();
+ }
+
+ public void rollback() {
+ try {
+ wrappedProperty.setValue(valueBeforeTransaction);
+ } finally {
+ valueChangePending = false;
+ endTransaction();
+ }
+ }
+
+ protected void endTransaction() {
+ inTransaction = false;
+ valueBeforeTransaction = null;
+ if (valueChangePending) {
+ fireValueChange();
+ }
+ }
+
+ @Override
+ protected void fireValueChange() {
+ if (inTransaction) {
+ valueChangePending = true;
+ } else {
+ super.fireValueChange();
+ }
+ }
+
+ public Property<T> getWrappedProperty() {
+ return wrappedProperty;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/Converter.java b/src/com/vaadin/data/util/converter/Converter.java
index 065d06b071..b8c15e8cdc 100644
--- a/src/com/vaadin/data/util/converter/Converter.java
+++ b/src/com/vaadin/data/util/converter/Converter.java
@@ -1,159 +1,159 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-/**
- * Interface that implements conversion between a model and a presentation type.
- * <p>
- * Typically {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
- * these together returns the original result for all input but this is not a
- * requirement.
- * </p>
- * <p>
- * Converters must not have any side effects (never update UI from inside a
- * converter).
- * </p>
- * <p>
- * All Converters must be stateless and thread safe.
- * </p>
- * <p>
- * If conversion of a value fails, a {@link ConversionException} is thrown.
- * </p>
- *
- * @param <MODEL>
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
- * @param <PRESENTATION>
- * The presentation type. Must be compatible with what
- * {@link #getPresentationType()} returns.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public interface Converter<PRESENTATION, MODEL> extends Serializable {
-
- /**
- * Converts the given value from target type to source type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws ConversionException;
-
- /**
- * Converts the given value from source type to target type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws ConversionException;
-
- /**
- * The source type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToPresentation(Object, Locale)}.
- *
- * @return The source type
- */
- public Class<MODEL> getModelType();
-
- /**
- * The target type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToModel(Object, Locale)}.
- *
- * @return The target type
- */
- public Class<PRESENTATION> getPresentationType();
-
- /**
- * An exception that signals that the value passed to
- * {@link Converter#convertToPresentation(Object, Locale)} or
- * {@link Converter#convertToModel(Object, Locale)} could not be converted.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public static class ConversionException extends RuntimeException {
-
- /**
- * Constructs a new <code>ConversionException</code> without a detail
- * message.
- */
- public ConversionException() {
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public ConversionException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new {@code ConversionException} with the specified
- * cause.
- *
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message and cause.
- *
- * @param message
- * the detail message
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Interface that implements conversion between a model and a presentation type.
+ * <p>
+ * Typically {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
+ * these together returns the original result for all input but this is not a
+ * requirement.
+ * </p>
+ * <p>
+ * Converters must not have any side effects (never update UI from inside a
+ * converter).
+ * </p>
+ * <p>
+ * All Converters must be stateless and thread safe.
+ * </p>
+ * <p>
+ * If conversion of a value fails, a {@link ConversionException} is thrown.
+ * </p>
+ *
+ * @param <MODEL>
+ * The model type. Must be compatible with what
+ * {@link #getModelType()} returns.
+ * @param <PRESENTATION>
+ * The presentation type. Must be compatible with what
+ * {@link #getPresentationType()} returns.
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public interface Converter<PRESENTATION, MODEL> extends Serializable {
+
+ /**
+ * Converts the given value from target type to source type.
+ * <p>
+ * A converter can optionally use locale to do the conversion.
+ * </p>
+ * A converter should in most cases be symmetric so chaining
+ * {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should return the original value.
+ *
+ * @param value
+ * The value to convert, compatible with the target type. Can be
+ * null
+ * @param locale
+ * The locale to use for conversion. Can be null.
+ * @return The converted value compatible with the source type
+ * @throws ConversionException
+ * If the value could not be converted
+ */
+ public MODEL convertToModel(PRESENTATION value, Locale locale)
+ throws ConversionException;
+
+ /**
+ * Converts the given value from source type to target type.
+ * <p>
+ * A converter can optionally use locale to do the conversion.
+ * </p>
+ * A converter should in most cases be symmetric so chaining
+ * {@link #convertToPresentation(Object, Locale)} and
+ * {@link #convertToModel(Object, Locale)} should return the original value.
+ *
+ * @param value
+ * The value to convert, compatible with the target type. Can be
+ * null
+ * @param locale
+ * The locale to use for conversion. Can be null.
+ * @return The converted value compatible with the source type
+ * @throws ConversionException
+ * If the value could not be converted
+ */
+ public PRESENTATION convertToPresentation(MODEL value, Locale locale)
+ throws ConversionException;
+
+ /**
+ * The source type of the converter.
+ *
+ * Values of this type can be passed to
+ * {@link #convertToPresentation(Object, Locale)}.
+ *
+ * @return The source type
+ */
+ public Class<MODEL> getModelType();
+
+ /**
+ * The target type of the converter.
+ *
+ * Values of this type can be passed to
+ * {@link #convertToModel(Object, Locale)}.
+ *
+ * @return The target type
+ */
+ public Class<PRESENTATION> getPresentationType();
+
+ /**
+ * An exception that signals that the value passed to
+ * {@link Converter#convertToPresentation(Object, Locale)} or
+ * {@link Converter#convertToModel(Object, Locale)} could not be converted.
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+ public static class ConversionException extends RuntimeException {
+
+ /**
+ * Constructs a new <code>ConversionException</code> without a detail
+ * message.
+ */
+ public ConversionException() {
+ }
+
+ /**
+ * Constructs a new <code>ConversionException</code> with the specified
+ * detail message.
+ *
+ * @param msg
+ * the detail message
+ */
+ public ConversionException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a new {@code ConversionException} with the specified
+ * cause.
+ *
+ * @param cause
+ * The cause of the the exception
+ */
+ public ConversionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new <code>ConversionException</code> with the specified
+ * detail message and cause.
+ *
+ * @param message
+ * the detail message
+ * @param cause
+ * The cause of the the exception
+ */
+ public ConversionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/ConverterFactory.java b/src/com/vaadin/data/util/converter/ConverterFactory.java
index 451f84185d..ed4ab41ac0 100644
--- a/src/com/vaadin/data/util/converter/ConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/ConverterFactory.java
@@ -1,23 +1,23 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-
-/**
- * Factory interface for providing Converters based on a presentation type and a
- * model type.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- *
- */
-public interface ConverterFactory extends Serializable {
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType);
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.io.Serializable;
+
+/**
+ * Factory interface for providing Converters based on a presentation type and a
+ * model type.
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ *
+ */
+public interface ConverterFactory extends Serializable {
+ public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType);
+
+}
diff --git a/src/com/vaadin/data/util/converter/DateToLongConverter.java b/src/com/vaadin/data/util/converter/DateToLongConverter.java
index d66adece06..537800f617 100644
--- a/src/com/vaadin/data/util/converter/DateToLongConverter.java
+++ b/src/com/vaadin/data/util/converter/DateToLongConverter.java
@@ -1,68 +1,68 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Long} to {@link Date} and back.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateToLongConverter implements Converter<Date, Long> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Long convertToModel(Date value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return value.getTime();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public Date convertToPresentation(Long value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return new Date(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Long> getModelType() {
- return Long.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<Date> getPresentationType() {
- return Date.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Long} to {@link Date} and back.
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DateToLongConverter implements Converter<Date, Long> {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Long convertToModel(Date value, Locale locale) {
+ if (value == null) {
+ return null;
+ }
+
+ return value.getTime();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public Date convertToPresentation(Long value, Locale locale) {
+ if (value == null) {
+ return null;
+ }
+
+ return new Date(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Long> getModelType() {
+ return Long.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<Date> getPresentationType() {
+ return Date.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 9233624819..3ad7b6a85b 100644
--- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@ -1,100 +1,100 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.logging.Logger;
-
-import com.vaadin.Application;
-
-/**
- * Default implementation of {@link ConverterFactory}. Provides converters for
- * standard types like {@link String}, {@link Double} and {@link Date}. </p>
- * <p>
- * Custom converters can be provided by extending this class and using
- * {@link Application#setConverterFactory(ConverterFactory)}.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DefaultConverterFactory implements ConverterFactory {
-
- private final static Logger log = Logger
- .getLogger(DefaultConverterFactory.class.getName());
-
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- Converter<PRESENTATION, MODEL> converter = findConverter(
- presentationType, modelType);
- if (converter != null) {
- log.finest(getClass().getName() + " created a "
- + converter.getClass());
- return converter;
- }
-
- // Try to find a reverse converter
- Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
- modelType, presentationType);
- if (reverseConverter != null) {
- log.finest(getClass().getName() + " created a reverse "
- + reverseConverter.getClass());
- return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
- }
-
- log.finest(getClass().getName() + " could not find a converter for "
- + presentationType.getName() + " to " + modelType.getName()
- + " conversion");
- return null;
-
- }
-
- protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- if (presentationType == String.class) {
- // TextField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
- if (converter != null) {
- return converter;
- }
- } else if (presentationType == Date.class) {
- // DateField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
- if (converter != null) {
- return converter;
- }
- }
-
- return null;
-
- }
-
- protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
- if (Long.class.isAssignableFrom(sourceType)) {
- return new DateToLongConverter();
- } else {
- return null;
- }
- }
-
- protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
- if (Double.class.isAssignableFrom(sourceType)) {
- return new StringToDoubleConverter();
- } else if (Integer.class.isAssignableFrom(sourceType)) {
- return new StringToIntegerConverter();
- } else if (Boolean.class.isAssignableFrom(sourceType)) {
- return new StringToBooleanConverter();
- } else if (Number.class.isAssignableFrom(sourceType)) {
- return new StringToNumberConverter();
- } else if (Date.class.isAssignableFrom(sourceType)) {
- return new StringToDateConverter();
- } else {
- return null;
- }
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Date;
+import java.util.logging.Logger;
+
+import com.vaadin.Application;
+
+/**
+ * Default implementation of {@link ConverterFactory}. Provides converters for
+ * standard types like {@link String}, {@link Double} and {@link Date}. </p>
+ * <p>
+ * Custom converters can be provided by extending this class and using
+ * {@link Application#setConverterFactory(ConverterFactory)}.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DefaultConverterFactory implements ConverterFactory {
+
+ private final static Logger log = Logger
+ .getLogger(DefaultConverterFactory.class.getName());
+
+ public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
+ Converter<PRESENTATION, MODEL> converter = findConverter(
+ presentationType, modelType);
+ if (converter != null) {
+ log.finest(getClass().getName() + " created a "
+ + converter.getClass());
+ return converter;
+ }
+
+ // Try to find a reverse converter
+ Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
+ modelType, presentationType);
+ if (reverseConverter != null) {
+ log.finest(getClass().getName() + " created a reverse "
+ + reverseConverter.getClass());
+ return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
+ }
+
+ log.finest(getClass().getName() + " could not find a converter for "
+ + presentationType.getName() + " to " + modelType.getName()
+ + " conversion");
+ return null;
+
+ }
+
+ protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
+ if (presentationType == String.class) {
+ // TextField converters and more
+ Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
+ if (converter != null) {
+ return converter;
+ }
+ } else if (presentationType == Date.class) {
+ // DateField converters and more
+ Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
+ if (converter != null) {
+ return converter;
+ }
+ }
+
+ return null;
+
+ }
+
+ protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
+ if (Long.class.isAssignableFrom(sourceType)) {
+ return new DateToLongConverter();
+ } else {
+ return null;
+ }
+ }
+
+ protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
+ if (Double.class.isAssignableFrom(sourceType)) {
+ return new StringToDoubleConverter();
+ } else if (Integer.class.isAssignableFrom(sourceType)) {
+ return new StringToIntegerConverter();
+ } else if (Boolean.class.isAssignableFrom(sourceType)) {
+ return new StringToBooleanConverter();
+ } else if (Number.class.isAssignableFrom(sourceType)) {
+ return new StringToNumberConverter();
+ } else if (Date.class.isAssignableFrom(sourceType)) {
+ return new StringToDateConverter();
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/ReverseConverter.java b/src/com/vaadin/data/util/converter/ReverseConverter.java
index b191d1ca0b..1c561f29e8 100644
--- a/src/com/vaadin/data/util/converter/ReverseConverter.java
+++ b/src/com/vaadin/data/util/converter/ReverseConverter.java
@@ -1,80 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that wraps another {@link Converter} and reverses source and
- * target types.
- *
- * @param <MODEL>
- * The source type
- * @param <PRESENTATION>
- * The target type
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class ReverseConverter<PRESENTATION, MODEL> implements
- Converter<PRESENTATION, MODEL> {
-
- private Converter<MODEL, PRESENTATION> realConverter;
-
- /**
- * Creates a converter from source to target based on a converter that
- * converts from target to source.
- *
- * @param converter
- * The converter to use in a reverse fashion
- */
- public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
- this.realConverter = converter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#convertToModel(java
- * .lang.Object, java.util.Locale)
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToPresentation(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToModel(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getSourceType()
- */
- public Class<MODEL> getModelType() {
- return realConverter.getPresentationType();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getTargetType()
- */
- public Class<PRESENTATION> getPresentationType() {
- return realConverter.getModelType();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Locale;
+
+/**
+ * A converter that wraps another {@link Converter} and reverses source and
+ * target types.
+ *
+ * @param <MODEL>
+ * The source type
+ * @param <PRESENTATION>
+ * The target type
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class ReverseConverter<PRESENTATION, MODEL> implements
+ Converter<PRESENTATION, MODEL> {
+
+ private Converter<MODEL, PRESENTATION> realConverter;
+
+ /**
+ * Creates a converter from source to target based on a converter that
+ * converts from target to source.
+ *
+ * @param converter
+ * The converter to use in a reverse fashion
+ */
+ public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
+ this.realConverter = converter;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#convertToModel(java
+ * .lang.Object, java.util.Locale)
+ */
+ public MODEL convertToModel(PRESENTATION value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return realConverter.convertToPresentation(value, locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public PRESENTATION convertToPresentation(MODEL value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ return realConverter.convertToModel(value, locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getSourceType()
+ */
+ public Class<MODEL> getModelType() {
+ return realConverter.getPresentationType();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getTargetType()
+ */
+ public Class<PRESENTATION> getPresentationType() {
+ return realConverter.getModelType();
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
index 3b2034a361..96a3a3d071 100644
--- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
@@ -1,104 +1,104 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Boolean} and back.
- * The String representation is given by Boolean.toString().
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToBooleanConverter implements Converter<String, Boolean> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Boolean convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- if (getTrueString().equals(value)) {
- return true;
- } else if (getFalseString().equals(value)) {
- return false;
- } else {
- throw new ConversionException("Cannot convert " + value + " to "
- + getModelType().getName());
- }
- }
-
- /**
- * Gets the string representation for true. Default is "true".
- *
- * @return the string representation for true
- */
- protected String getTrueString() {
- return Boolean.TRUE.toString();
- }
-
- /**
- * Gets the string representation for false. Default is "false".
- *
- * @return the string representation for false
- */
- protected String getFalseString() {
- return Boolean.FALSE.toString();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Boolean value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
- if (value) {
- return getTrueString();
- } else {
- return getFalseString();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Boolean> getModelType() {
- return Boolean.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Boolean} and back.
+ * The String representation is given by Boolean.toString().
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToBooleanConverter implements Converter<String, Boolean> {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Boolean convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ if (getTrueString().equals(value)) {
+ return true;
+ } else if (getFalseString().equals(value)) {
+ return false;
+ } else {
+ throw new ConversionException("Cannot convert " + value + " to "
+ + getModelType().getName());
+ }
+ }
+
+ /**
+ * Gets the string representation for true. Default is "true".
+ *
+ * @return the string representation for true
+ */
+ protected String getTrueString() {
+ return Boolean.TRUE.toString();
+ }
+
+ /**
+ * Gets the string representation for false. Default is "false".
+ *
+ * @return the string representation for false
+ */
+ protected String getFalseString() {
+ return Boolean.FALSE.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Boolean value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+ if (value) {
+ return getTrueString();
+ } else {
+ return getFalseString();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Boolean> getModelType() {
+ return Boolean.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToDateConverter.java b/src/com/vaadin/data/util/converter/StringToDateConverter.java
index 2aa9395532..6f3c2e47f6 100644
--- a/src/com/vaadin/data/util/converter/StringToDateConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDateConverter.java
@@ -1,108 +1,108 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.DateFormat;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Date} to {@link String} and back. Uses
- * the given locale and {@link DateFormat} for formatting and parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDateConverter implements Converter<String, Date> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Date, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A DateFormat instance
- */
- protected DateFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
- DateFormat.MEDIUM, locale);
- f.setLenient(false);
- return f;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Date convertToModel(String value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Date parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Date value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Date> getModelType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Date} to {@link String} and back. Uses
+ * the given locale and {@link DateFormat} for formatting and parsing.
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToDateConverter implements Converter<String, Date> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Date, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A DateFormat instance
+ */
+ protected DateFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
+ DateFormat.MEDIUM, locale);
+ f.setLenient(false);
+ return f;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Date convertToModel(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ ParsePosition parsePosition = new ParsePosition(0);
+ Date parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ return parsedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Date value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Date> getModelType() {
+ return Date.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
index 29c6329451..60a38f4127 100644
--- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
@@ -1,103 +1,103 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Double} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDoubleConverter implements Converter<String, Double> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Double, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Double convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- return parsedValue.doubleValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Double value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Double> getModelType() {
- return Double.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Double} and back.
+ * Uses the given locale and a {@link NumberFormat} instance for formatting and
+ * parsing.
+ * <p>
+ * Leading and trailing white spaces are ignored when converting from a String.
+ * </p>
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToDoubleConverter implements Converter<String, Double> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Double, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ return NumberFormat.getNumberInstance(locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Double convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+ return parsedValue.doubleValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Double value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Double> getModelType() {
+ return Double.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+}
diff --git a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
index 7fa4458c51..e55feec3b6 100644
--- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
@@ -1,84 +1,84 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Integer} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToIntegerConverter implements Converter<String, Integer> {
-
- /**
- * Returns the format used by
- * {@link #convertToPresentation(Integer, Locale)} and
- * {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
- return NumberFormat.getIntegerInstance(locale);
- }
-
- public Integer convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue.intValue();
- }
-
- public String convertToPresentation(Integer value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- public Class<Integer> getModelType() {
- return Integer.class;
- }
-
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to {@link Integer} and back.
+ * Uses the given locale and a {@link NumberFormat} instance for formatting and
+ * parsing.
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToIntegerConverter implements Converter<String, Integer> {
+
+ /**
+ * Returns the format used by
+ * {@link #convertToPresentation(Integer, Locale)} and
+ * {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+ return NumberFormat.getIntegerInstance(locale);
+ }
+
+ public Integer convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ // Parse and detect errors. If the full string was not used, it is
+ // an error.
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ if (parsedValue == null) {
+ // Convert "" to null
+ return null;
+ }
+ return parsedValue.intValue();
+ }
+
+ public String convertToPresentation(Integer value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ public Class<Integer> getModelType() {
+ return Integer.class;
+ }
+
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
index 64944a434c..d1816007e7 100644
--- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java
+++ b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
@@ -1,107 +1,107 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Number} to {@link String} and back.
- * Uses the given locale and {@link NumberFormat} for formatting and parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToNumberConverter implements Converter<String, Number> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Number, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Number convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Number value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Number> getModelType() {
- return Number.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.util.converter;
+
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link Number} to {@link String} and back.
+ * Uses the given locale and {@link NumberFormat} for formatting and parsing.
+ * <p>
+ * Override and overwrite {@link #getFormat(Locale)} to use a different format.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class StringToNumberConverter implements Converter<String, Number> {
+
+ /**
+ * Returns the format used by {@link #convertToPresentation(Number, Locale)}
+ * and {@link #convertToModel(String, Locale)}.
+ *
+ * @param locale
+ * The locale to use
+ * @return A NumberFormat instance
+ */
+ protected NumberFormat getFormat(Locale locale) {
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+
+ return NumberFormat.getNumberInstance(locale);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
+ * java.util.Locale)
+ */
+ public Number convertToModel(String value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ // Remove leading and trailing white space
+ value = value.trim();
+
+ // Parse and detect errors. If the full string was not used, it is
+ // an error.
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ if (parsePosition.getIndex() != value.length()) {
+ throw new ConversionException("Could not convert '" + value
+ + "' to " + getModelType().getName());
+ }
+
+ if (parsedValue == null) {
+ // Convert "" to null
+ return null;
+ }
+ return parsedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
+ * .Object, java.util.Locale)
+ */
+ public String convertToPresentation(Number value, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return getFormat(locale).format(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getModelType()
+ */
+ public Class<Number> getModelType() {
+ return Number.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.util.converter.Converter#getPresentationType()
+ */
+ public Class<String> getPresentationType() {
+ return String.class;
+ }
+
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
index ac6efaa49b..788966048d 100644
--- a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
+++ b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
@@ -1,92 +1,92 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-
-/**
- * CacheFlushNotifier is a simple static notification mechanism to inform other
- * SQLContainers that the contents of their caches may have become stale.
- */
-class CacheFlushNotifier implements Serializable {
- /*
- * SQLContainer instance reference list and dead reference queue. Used for
- * the cache flush notification feature.
- */
- private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
- private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
-
- /**
- * Adds the given SQLContainer to the cache flush notification receiver list
- *
- * @param c
- * Container to add
- */
- public static void addInstance(SQLContainer c) {
- removeDeadReferences();
- if (c != null) {
- allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
- }
- }
-
- /**
- * Removes dead references from instance list
- */
- private static void removeDeadReferences() {
- java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
- .poll();
- while (dead != null) {
- allInstances.remove(dead);
- dead = deadInstances.poll();
- }
- }
-
- /**
- * Iterates through the instances and notifies containers which are
- * connected to the same table or are using the same query string.
- *
- * @param c
- * SQLContainer that issued the cache flush notification
- */
- public static void notifyOfCacheFlush(SQLContainer c) {
- removeDeadReferences();
- for (WeakReference<SQLContainer> wr : allInstances) {
- if (wr.get() != null) {
- SQLContainer wrc = wr.get();
- if (wrc == null) {
- continue;
- }
- /*
- * If the reference points to the container sending the
- * notification, do nothing.
- */
- if (wrc.equals(c)) {
- continue;
- }
- /* Compare QueryDelegate types and tableName/queryString */
- QueryDelegate wrQd = wrc.getQueryDelegate();
- QueryDelegate qd = c.getQueryDelegate();
- if (wrQd instanceof TableQuery
- && qd instanceof TableQuery
- && ((TableQuery) wrQd).getTableName().equals(
- ((TableQuery) qd).getTableName())) {
- wrc.refresh();
- } else if (wrQd instanceof FreeformQuery
- && qd instanceof FreeformQuery
- && ((FreeformQuery) wrQd).getQueryString().equals(
- ((FreeformQuery) qd).getQueryString())) {
- wrc.refresh();
- }
- }
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
+import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+
+/**
+ * CacheFlushNotifier is a simple static notification mechanism to inform other
+ * SQLContainers that the contents of their caches may have become stale.
+ */
+class CacheFlushNotifier implements Serializable {
+ /*
+ * SQLContainer instance reference list and dead reference queue. Used for
+ * the cache flush notification feature.
+ */
+ private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
+ private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
+
+ /**
+ * Adds the given SQLContainer to the cache flush notification receiver list
+ *
+ * @param c
+ * Container to add
+ */
+ public static void addInstance(SQLContainer c) {
+ removeDeadReferences();
+ if (c != null) {
+ allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
+ }
+ }
+
+ /**
+ * Removes dead references from instance list
+ */
+ private static void removeDeadReferences() {
+ java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
+ .poll();
+ while (dead != null) {
+ allInstances.remove(dead);
+ dead = deadInstances.poll();
+ }
+ }
+
+ /**
+ * Iterates through the instances and notifies containers which are
+ * connected to the same table or are using the same query string.
+ *
+ * @param c
+ * SQLContainer that issued the cache flush notification
+ */
+ public static void notifyOfCacheFlush(SQLContainer c) {
+ removeDeadReferences();
+ for (WeakReference<SQLContainer> wr : allInstances) {
+ if (wr.get() != null) {
+ SQLContainer wrc = wr.get();
+ if (wrc == null) {
+ continue;
+ }
+ /*
+ * If the reference points to the container sending the
+ * notification, do nothing.
+ */
+ if (wrc.equals(c)) {
+ continue;
+ }
+ /* Compare QueryDelegate types and tableName/queryString */
+ QueryDelegate wrQd = wrc.getQueryDelegate();
+ QueryDelegate qd = c.getQueryDelegate();
+ if (wrQd instanceof TableQuery
+ && qd instanceof TableQuery
+ && ((TableQuery) wrQd).getTableName().equals(
+ ((TableQuery) qd).getTableName())) {
+ wrc.refresh();
+ } else if (wrQd instanceof FreeformQuery
+ && qd instanceof FreeformQuery
+ && ((FreeformQuery) wrQd).getQueryString().equals(
+ ((FreeformQuery) qd).getQueryString())) {
+ wrc.refresh();
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
index 44921dd12d..839fceb3c2 100644
--- a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
+++ b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
@@ -1,31 +1,31 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
- * number of items. In SQLContainer this is used for RowItem -cache. Cache size
- * will be two times the page length parameter of the container.
- */
-class CacheMap<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = 679999766473555231L;
- private int cacheLimit = SQLContainer.CACHE_RATIO
- * SQLContainer.DEFAULT_PAGE_LENGTH;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
- return size() > cacheLimit;
- }
-
- void setCacheLimit(int limit) {
- cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
- }
-
- int getCacheLimit() {
- return cacheLimit;
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
+ * number of items. In SQLContainer this is used for RowItem -cache. Cache size
+ * will be two times the page length parameter of the container.
+ */
+class CacheMap<K, V> extends LinkedHashMap<K, V> {
+ private static final long serialVersionUID = 679999766473555231L;
+ private int cacheLimit = SQLContainer.CACHE_RATIO
+ * SQLContainer.DEFAULT_PAGE_LENGTH;
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+ return size() > cacheLimit;
+ }
+
+ void setCacheLimit(int limit) {
+ cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
+ }
+
+ int getCacheLimit() {
+ return cacheLimit;
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/Reference.java b/src/com/vaadin/data/util/sqlcontainer/Reference.java
index 6e863fa040..dea1aa87c0 100644
--- a/src/com/vaadin/data/util/sqlcontainer/Reference.java
+++ b/src/com/vaadin/data/util/sqlcontainer/Reference.java
@@ -1,56 +1,56 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * The reference class represents a simple [usually foreign key] reference to
- * another SQLContainer. Actual foreign key reference in the database is not
- * required, but it is recommended to make sure that certain constraints are
- * followed.
- */
-@SuppressWarnings("serial")
-class Reference implements Serializable {
-
- /**
- * The SQLContainer that this reference points to.
- */
- private SQLContainer referencedContainer;
-
- /**
- * The column ID/name in the referencing SQLContainer that contains the key
- * used for the reference.
- */
- private String referencingColumn;
-
- /**
- * The column ID/name in the referenced SQLContainer that contains the key
- * used for the reference.
- */
- private String referencedColumn;
-
- /**
- * Constructs a new reference to be used within the SQLContainer to
- * reference another SQLContainer.
- */
- Reference(SQLContainer referencedContainer, String referencingColumn,
- String referencedColumn) {
- this.referencedContainer = referencedContainer;
- this.referencingColumn = referencingColumn;
- this.referencedColumn = referencedColumn;
- }
-
- SQLContainer getReferencedContainer() {
- return referencedContainer;
- }
-
- String getReferencingColumn() {
- return referencingColumn;
- }
-
- String getReferencedColumn() {
- return referencedColumn;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+
+/**
+ * The reference class represents a simple [usually foreign key] reference to
+ * another SQLContainer. Actual foreign key reference in the database is not
+ * required, but it is recommended to make sure that certain constraints are
+ * followed.
+ */
+@SuppressWarnings("serial")
+class Reference implements Serializable {
+
+ /**
+ * The SQLContainer that this reference points to.
+ */
+ private SQLContainer referencedContainer;
+
+ /**
+ * The column ID/name in the referencing SQLContainer that contains the key
+ * used for the reference.
+ */
+ private String referencingColumn;
+
+ /**
+ * The column ID/name in the referenced SQLContainer that contains the key
+ * used for the reference.
+ */
+ private String referencedColumn;
+
+ /**
+ * Constructs a new reference to be used within the SQLContainer to
+ * reference another SQLContainer.
+ */
+ Reference(SQLContainer referencedContainer, String referencingColumn,
+ String referencedColumn) {
+ this.referencedContainer = referencedContainer;
+ this.referencingColumn = referencingColumn;
+ this.referencedColumn = referencedColumn;
+ }
+
+ SQLContainer getReferencedContainer() {
+ return referencedContainer;
+ }
+
+ String getReferencingColumn() {
+ return referencingColumn;
+ }
+
+ String getReferencedColumn() {
+ return referencedColumn;
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/RowId.java b/src/com/vaadin/data/util/sqlcontainer/RowId.java
index ed01b72e06..925325134a 100644
--- a/src/com/vaadin/data/util/sqlcontainer/RowId.java
+++ b/src/com/vaadin/data/util/sqlcontainer/RowId.java
@@ -1,81 +1,81 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * RowId represents identifiers of a single database result set row.
- *
- * The data structure of a RowId is an Object array which contains the values of
- * the primary key columns of the identified row. This allows easy equals()
- * -comparison of RowItems.
- */
-public class RowId implements Serializable {
- private static final long serialVersionUID = -3161778404698901258L;
- protected Object[] id;
-
- /**
- * Prevent instantiation without required parameters.
- */
- protected RowId() {
- }
-
- public RowId(Object[] id) {
- if (id == null) {
- throw new IllegalArgumentException("id parameter must not be null!");
- }
- this.id = id;
- }
-
- public Object[] getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- int result = 31;
- if (id != null) {
- for (Object o : id) {
- if (o != null) {
- result += o.hashCode();
- }
- }
- }
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RowId)) {
- return false;
- }
- Object[] compId = ((RowId) obj).getId();
- if (id == null && compId == null) {
- return true;
- }
- if (id.length != compId.length) {
- return false;
- }
- for (int i = 0; i < id.length; i++) {
- if ((id[i] == null && compId[i] != null)
- || (id[i] != null && !id[i].equals(compId[i]))) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- StringBuffer s = new StringBuffer();
- for (int i = 0; i < id.length; i++) {
- s.append(id[i]);
- if (i < id.length - 1) {
- s.append("/");
- }
- }
- return s.toString();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer;
+
+import java.io.Serializable;
+
+/**
+ * RowId represents identifiers of a single database result set row.
+ *
+ * The data structure of a RowId is an Object array which contains the values of
+ * the primary key columns of the identified row. This allows easy equals()
+ * -comparison of RowItems.
+ */
+public class RowId implements Serializable {
+ private static final long serialVersionUID = -3161778404698901258L;
+ protected Object[] id;
+
+ /**
+ * Prevent instantiation without required parameters.
+ */
+ protected RowId() {
+ }
+
+ public RowId(Object[] id) {
+ if (id == null) {
+ throw new IllegalArgumentException("id parameter must not be null!");
+ }
+ this.id = id;
+ }
+
+ public Object[] getId() {
+ return id;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 31;
+ if (id != null) {
+ for (Object o : id) {
+ if (o != null) {
+ result += o.hashCode();
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof RowId)) {
+ return false;
+ }
+ Object[] compId = ((RowId) obj).getId();
+ if (id == null && compId == null) {
+ return true;
+ }
+ if (id.length != compId.length) {
+ return false;
+ }
+ for (int i = 0; i < id.length; i++) {
+ if ((id[i] == null && compId[i] != null)
+ || (id[i] != null && !id[i].equals(compId[i]))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ for (int i = 0; i < id.length; i++) {
+ s.append(id[i]);
+ if (i < id.length - 1) {
+ s.append("/");
+ }
+ }
+ return s.toString();
+ }
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
index c1a7c61eab..2a1068e786 100644
--- a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
+++ b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
@@ -1,165 +1,165 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Simple implementation of the JDBCConnectionPool interface. Handles loading
- * the JDBC driver, setting up the connections and ensuring they are still
- * usable upon release.
- */
-@SuppressWarnings("serial")
-public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
-
- private int initialConnections = 5;
- private int maxConnections = 20;
-
- private String driverName;
- private String connectionUri;
- private String userName;
- private String password;
-
- private transient Set<Connection> availableConnections;
- private transient Set<Connection> reservedConnections;
-
- private boolean initialized;
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password) throws SQLException {
- if (driverName == null) {
- throw new IllegalArgumentException(
- "JDBC driver class name must be given.");
- }
- if (connectionUri == null) {
- throw new IllegalArgumentException(
- "Database connection URI must be given.");
- }
- if (userName == null) {
- throw new IllegalArgumentException(
- "Database username must be given.");
- }
- if (password == null) {
- throw new IllegalArgumentException(
- "Database password must be given.");
- }
- this.driverName = driverName;
- this.connectionUri = connectionUri;
- this.userName = userName;
- this.password = password;
-
- /* Initialize JDBC driver */
- try {
- Class.forName(driverName).newInstance();
- } catch (Exception ex) {
- throw new RuntimeException("Specified JDBC Driver: " + driverName
- + " - initialization failed.", ex);
- }
- }
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password, int initialConnections,
- int maxConnections) throws SQLException {
- this(driverName, connectionUri, userName, password);
- this.initialConnections = initialConnections;
- this.maxConnections = maxConnections;
- }
-
- private void initializeConnections() throws SQLException {
- availableConnections = new HashSet<Connection>(initialConnections);
- reservedConnections = new HashSet<Connection>(initialConnections);
- for (int i = 0; i < initialConnections; i++) {
- availableConnections.add(createConnection());
- }
- initialized = true;
- }
-
- public synchronized Connection reserveConnection() throws SQLException {
- if (!initialized) {
- initializeConnections();
- }
- if (availableConnections.isEmpty()) {
- if (reservedConnections.size() < maxConnections) {
- availableConnections.add(createConnection());
- } else {
- throw new SQLException("Connection limit has been reached.");
- }
- }
-
- Connection c = availableConnections.iterator().next();
- availableConnections.remove(c);
- reservedConnections.add(c);
-
- return c;
- }
-
- public synchronized void releaseConnection(Connection conn) {
- if (conn == null || !initialized) {
- return;
- }
- /* Try to roll back if necessary */
- try {
- if (!conn.getAutoCommit()) {
- conn.rollback();
- }
- } catch (SQLException e) {
- /* Roll back failed, close and discard connection */
- try {
- conn.close();
- } catch (SQLException e1) {
- /* Nothing needs to be done */
- }
- reservedConnections.remove(conn);
- return;
- }
- reservedConnections.remove(conn);
- availableConnections.add(conn);
- }
-
- private Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(connectionUri, userName,
- password);
- c.setAutoCommit(false);
- if (driverName.toLowerCase().contains("mysql")) {
- try {
- Statement s = c.createStatement();
- s.execute("SET SESSION sql_mode = 'ANSI'");
- s.close();
- } catch (Exception e) {
- // Failed to set ansi mode; continue
- }
- }
- return c;
- }
-
- public void destroy() {
- for (Connection c : availableConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
- for (Connection c : reservedConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
-
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- initialized = false;
- out.defaultWriteObject();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.connection;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple implementation of the JDBCConnectionPool interface. Handles loading
+ * the JDBC driver, setting up the connections and ensuring they are still
+ * usable upon release.
+ */
+@SuppressWarnings("serial")
+public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
+
+ private int initialConnections = 5;
+ private int maxConnections = 20;
+
+ private String driverName;
+ private String connectionUri;
+ private String userName;
+ private String password;
+
+ private transient Set<Connection> availableConnections;
+ private transient Set<Connection> reservedConnections;
+
+ private boolean initialized;
+
+ public SimpleJDBCConnectionPool(String driverName, String connectionUri,
+ String userName, String password) throws SQLException {
+ if (driverName == null) {
+ throw new IllegalArgumentException(
+ "JDBC driver class name must be given.");
+ }
+ if (connectionUri == null) {
+ throw new IllegalArgumentException(
+ "Database connection URI must be given.");
+ }
+ if (userName == null) {
+ throw new IllegalArgumentException(
+ "Database username must be given.");
+ }
+ if (password == null) {
+ throw new IllegalArgumentException(
+ "Database password must be given.");
+ }
+ this.driverName = driverName;
+ this.connectionUri = connectionUri;
+ this.userName = userName;
+ this.password = password;
+
+ /* Initialize JDBC driver */
+ try {
+ Class.forName(driverName).newInstance();
+ } catch (Exception ex) {
+ throw new RuntimeException("Specified JDBC Driver: " + driverName
+ + " - initialization failed.", ex);
+ }
+ }
+
+ public SimpleJDBCConnectionPool(String driverName, String connectionUri,
+ String userName, String password, int initialConnections,
+ int maxConnections) throws SQLException {
+ this(driverName, connectionUri, userName, password);
+ this.initialConnections = initialConnections;
+ this.maxConnections = maxConnections;
+ }
+
+ private void initializeConnections() throws SQLException {
+ availableConnections = new HashSet<Connection>(initialConnections);
+ reservedConnections = new HashSet<Connection>(initialConnections);
+ for (int i = 0; i < initialConnections; i++) {
+ availableConnections.add(createConnection());
+ }
+ initialized = true;
+ }
+
+ public synchronized Connection reserveConnection() throws SQLException {
+ if (!initialized) {
+ initializeConnections();
+ }
+ if (availableConnections.isEmpty()) {
+ if (reservedConnections.size() < maxConnections) {
+ availableConnections.add(createConnection());
+ } else {
+ throw new SQLException("Connection limit has been reached.");
+ }
+ }
+
+ Connection c = availableConnections.iterator().next();
+ availableConnections.remove(c);
+ reservedConnections.add(c);
+
+ return c;
+ }
+
+ public synchronized void releaseConnection(Connection conn) {
+ if (conn == null || !initialized) {
+ return;
+ }
+ /* Try to roll back if necessary */
+ try {
+ if (!conn.getAutoCommit()) {
+ conn.rollback();
+ }
+ } catch (SQLException e) {
+ /* Roll back failed, close and discard connection */
+ try {
+ conn.close();
+ } catch (SQLException e1) {
+ /* Nothing needs to be done */
+ }
+ reservedConnections.remove(conn);
+ return;
+ }
+ reservedConnections.remove(conn);
+ availableConnections.add(conn);
+ }
+
+ private Connection createConnection() throws SQLException {
+ Connection c = DriverManager.getConnection(connectionUri, userName,
+ password);
+ c.setAutoCommit(false);
+ if (driverName.toLowerCase().contains("mysql")) {
+ try {
+ Statement s = c.createStatement();
+ s.execute("SET SESSION sql_mode = 'ANSI'");
+ s.close();
+ } catch (Exception e) {
+ // Failed to set ansi mode; continue
+ }
+ }
+ return c;
+ }
+
+ public void destroy() {
+ for (Connection c : availableConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) {
+ // No need to do anything
+ }
+ }
+ for (Connection c : reservedConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) {
+ // No need to do anything
+ }
+ }
+
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ initialized = false;
+ out.defaultWriteObject();
+ }
+
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
index 2ea151c578..95521c5019 100644
--- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
+++ b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
@@ -1,57 +1,57 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-/**
- * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
- * provides definitions for methods that produce StatementHelper objects instead
- * of basic query strings. This allows the FreeformQuery query delegate to use
- * PreparedStatements instead of regular Statement when accessing the database.
- *
- * Due to the injection protection and other benefits of prepared statements, it
- * is advisable to implement this interface instead of the FreeformQueryDelegate
- * whenever possible.
- */
-public interface FreeformStatementDelegate extends FreeformQueryDelegate {
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement. This
- * method is responsible for gluing together the select query from the
- * filters and the order by conditions if these are supported.
- *
- * @param offset
- * the first record (row) to fetch.
- * @param pagelength
- * the number of records (rows) to fetch. 0 means all records
- * starting from offset.
- */
- public StatementHelper getQueryStatement(int offset, int limit)
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement that
- * will fetch the row count from the DB. Row count should be fetched using
- * filters that are currently set to the QueryDelegate.
- */
- public StatementHelper getCountStatement()
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement used
- * by the FreeformQuery.containsRowWithKeys() method. This is useful for
- * cases when the default logic in said method is not enough to support more
- * complex free form queries.
- *
- * @param keys
- * the values of the primary keys
- * @throws UnsupportedOperationException
- * to use the default logic in FreeformQuery
- */
- public StatementHelper getContainsRowQueryStatement(Object... keys)
- throws UnsupportedOperationException;
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.query;
+
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
+
+/**
+ * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
+ * provides definitions for methods that produce StatementHelper objects instead
+ * of basic query strings. This allows the FreeformQuery query delegate to use
+ * PreparedStatements instead of regular Statement when accessing the database.
+ *
+ * Due to the injection protection and other benefits of prepared statements, it
+ * is advisable to implement this interface instead of the FreeformQueryDelegate
+ * whenever possible.
+ */
+public interface FreeformStatementDelegate extends FreeformQueryDelegate {
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement. This
+ * method is responsible for gluing together the select query from the
+ * filters and the order by conditions if these are supported.
+ *
+ * @param offset
+ * the first record (row) to fetch.
+ * @param pagelength
+ * the number of records (rows) to fetch. 0 means all records
+ * starting from offset.
+ */
+ public StatementHelper getQueryStatement(int offset, int limit)
+ throws UnsupportedOperationException;
+
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement that
+ * will fetch the row count from the DB. Row count should be fetched using
+ * filters that are currently set to the QueryDelegate.
+ */
+ public StatementHelper getCountStatement()
+ throws UnsupportedOperationException;
+
+ /**
+ * Should return a new instance of StatementHelper that contains the query
+ * string and parameter values required to create a PreparedStatement used
+ * by the FreeformQuery.containsRowWithKeys() method. This is useful for
+ * cases when the default logic in said method is not enough to support more
+ * complex free form queries.
+ *
+ * @param keys
+ * the values of the primary keys
+ * @throws UnsupportedOperationException
+ * to use the default logic in FreeformQuery
+ */
+ public StatementHelper getContainsRowQueryStatement(Object... keys)
+ throws UnsupportedOperationException;
+}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
index 888f1ec501..3fd92e920d 100644
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
+++ b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
@@ -1,135 +1,135 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * StatementHelper is a simple helper class that assists TableQuery and the
- * query generators in filling a PreparedStatement. The actual statement is
- * generated by the query generator methods, but the resulting statement and all
- * the parameter values are stored in an instance of StatementHelper.
- *
- * This class will also fill the values with correct setters into the
- * PreparedStatement on request.
- */
-public class StatementHelper implements Serializable {
-
- private String queryString;
-
- private List<Object> parameters = new ArrayList<Object>();
- private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
-
- public StatementHelper() {
- }
-
- public void setQueryString(String queryString) {
- this.queryString = queryString;
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public void addParameterValue(Object parameter) {
- if (parameter != null) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, parameter.getClass());
- }
- }
-
- public void addParameterValue(Object parameter, Class<?> type) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, type);
- }
-
- public void setParameterValuesToStatement(PreparedStatement pstmt)
- throws SQLException {
- for (int i = 0; i < parameters.size(); i++) {
- if (parameters.get(i) == null) {
- handleNullValue(i, pstmt);
- } else {
- pstmt.setObject(i + 1, parameters.get(i));
- }
- }
-
- /*
- * The following list contains the data types supported by
- * PreparedStatement but not supported by SQLContainer:
- *
- * [The list is provided as PreparedStatement method signatures]
- *
- * setNCharacterStream(int parameterIndex, Reader value)
- *
- * setNClob(int parameterIndex, NClob value)
- *
- * setNString(int parameterIndex, String value)
- *
- * setRef(int parameterIndex, Ref x)
- *
- * setRowId(int parameterIndex, RowId x)
- *
- * setSQLXML(int parameterIndex, SQLXML xmlObject)
- *
- * setBytes(int parameterIndex, byte[] x)
- *
- * setCharacterStream(int parameterIndex, Reader reader)
- *
- * setClob(int parameterIndex, Clob x)
- *
- * setURL(int parameterIndex, URL x)
- *
- * setArray(int parameterIndex, Array x)
- *
- * setAsciiStream(int parameterIndex, InputStream x)
- *
- * setBinaryStream(int parameterIndex, InputStream x)
- *
- * setBlob(int parameterIndex, Blob x)
- */
- }
-
- private void handleNullValue(int i, PreparedStatement pstmt)
- throws SQLException {
- if (BigDecimal.class.equals(dataTypes.get(i))) {
- pstmt.setBigDecimal(i + 1, null);
- } else if (Boolean.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BOOLEAN);
- } else if (Byte.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (Date.class.equals(dataTypes.get(i))) {
- pstmt.setDate(i + 1, null);
- } else if (Double.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.DOUBLE);
- } else if (Float.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.FLOAT);
- } else if (Integer.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.INTEGER);
- } else if (Long.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BIGINT);
- } else if (Short.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (String.class.equals(dataTypes.get(i))) {
- pstmt.setString(i + 1, null);
- } else if (Time.class.equals(dataTypes.get(i))) {
- pstmt.setTime(i + 1, null);
- } else if (Timestamp.class.equals(dataTypes.get(i))) {
- pstmt.setTimestamp(i + 1, null);
- } else {
- throw new SQLException("Data type not supported by SQLContainer: "
- + parameters.get(i).getClass().toString());
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.util.sqlcontainer.query.generator;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * StatementHelper is a simple helper class that assists TableQuery and the
+ * query generators in filling a PreparedStatement. The actual statement is
+ * generated by the query generator methods, but the resulting statement and all
+ * the parameter values are stored in an instance of StatementHelper.
+ *
+ * This class will also fill the values with correct setters into the
+ * PreparedStatement on request.
+ */
+public class StatementHelper implements Serializable {
+
+ private String queryString;
+
+ private List<Object> parameters = new ArrayList<Object>();
+ private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
+
+ public StatementHelper() {
+ }
+
+ public void setQueryString(String queryString) {
+ this.queryString = queryString;
+ }
+
+ public String getQueryString() {
+ return queryString;
+ }
+
+ public void addParameterValue(Object parameter) {
+ if (parameter != null) {
+ parameters.add(parameter);
+ dataTypes.put(parameters.size() - 1, parameter.getClass());
+ }
+ }
+
+ public void addParameterValue(Object parameter, Class<?> type) {
+ parameters.add(parameter);
+ dataTypes.put(parameters.size() - 1, type);
+ }
+
+ public void setParameterValuesToStatement(PreparedStatement pstmt)
+ throws SQLException {
+ for (int i = 0; i < parameters.size(); i++) {
+ if (parameters.get(i) == null) {
+ handleNullValue(i, pstmt);
+ } else {
+ pstmt.setObject(i + 1, parameters.get(i));
+ }
+ }
+
+ /*
+ * The following list contains the data types supported by
+ * PreparedStatement but not supported by SQLContainer:
+ *
+ * [The list is provided as PreparedStatement method signatures]
+ *
+ * setNCharacterStream(int parameterIndex, Reader value)
+ *
+ * setNClob(int parameterIndex, NClob value)
+ *
+ * setNString(int parameterIndex, String value)
+ *
+ * setRef(int parameterIndex, Ref x)
+ *
+ * setRowId(int parameterIndex, RowId x)
+ *
+ * setSQLXML(int parameterIndex, SQLXML xmlObject)
+ *
+ * setBytes(int parameterIndex, byte[] x)
+ *
+ * setCharacterStream(int parameterIndex, Reader reader)
+ *
+ * setClob(int parameterIndex, Clob x)
+ *
+ * setURL(int parameterIndex, URL x)
+ *
+ * setArray(int parameterIndex, Array x)
+ *
+ * setAsciiStream(int parameterIndex, InputStream x)
+ *
+ * setBinaryStream(int parameterIndex, InputStream x)
+ *
+ * setBlob(int parameterIndex, Blob x)
+ */
+ }
+
+ private void handleNullValue(int i, PreparedStatement pstmt)
+ throws SQLException {
+ if (BigDecimal.class.equals(dataTypes.get(i))) {
+ pstmt.setBigDecimal(i + 1, null);
+ } else if (Boolean.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.BOOLEAN);
+ } else if (Byte.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.SMALLINT);
+ } else if (Date.class.equals(dataTypes.get(i))) {
+ pstmt.setDate(i + 1, null);
+ } else if (Double.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.DOUBLE);
+ } else if (Float.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.FLOAT);
+ } else if (Integer.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.INTEGER);
+ } else if (Long.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.BIGINT);
+ } else if (Short.class.equals(dataTypes.get(i))) {
+ pstmt.setNull(i + 1, Types.SMALLINT);
+ } else if (String.class.equals(dataTypes.get(i))) {
+ pstmt.setString(i + 1, null);
+ } else if (Time.class.equals(dataTypes.get(i))) {
+ pstmt.setTime(i + 1, null);
+ } else if (Timestamp.class.equals(dataTypes.get(i))) {
+ pstmt.setTimestamp(i + 1, null);
+ } else {
+ throw new SQLException("Data type not supported by SQLContainer: "
+ + parameters.get(i).getClass().toString());
+ }
+ }
+}
diff --git a/src/com/vaadin/data/validator/BeanValidator.java b/src/com/vaadin/data/validator/BeanValidator.java
index 939fd2e9c4..817df85248 100644
--- a/src/com/vaadin/data/validator/BeanValidator.java
+++ b/src/com/vaadin/data/validator/BeanValidator.java
@@ -1,173 +1,173 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.MessageInterpolator.Context;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.metadata.ConstraintDescriptor;
-
-import com.vaadin.data.Validator;
-
-/**
- * Vaadin {@link Validator} using the JSR-303 (javax.validation)
- * annotation-based bean validation.
- *
- * The annotations of the fields of the beans are used to determine the
- * validation to perform.
- *
- * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
- * Validation - formerly agimatec validation) must be present on the project
- * classpath when using bean validation.
- *
- * @since 7.0
- *
- * @author Petri Hakala
- * @author Henri Sara
- */
-public class BeanValidator implements Validator {
-
- private static final long serialVersionUID = 1L;
- private static ValidatorFactory factory;
-
- private transient javax.validation.Validator javaxBeanValidator;
- private String propertyName;
- private Class<?> beanClass;
- private Locale locale;
-
- /**
- * Simple implementation of a message interpolator context that returns
- * fixed values.
- */
- protected static class SimpleContext implements Context, Serializable {
-
- private final Object value;
- private final ConstraintDescriptor<?> descriptor;
-
- /**
- * Create a simple immutable message interpolator context.
- *
- * @param value
- * value being validated
- * @param descriptor
- * ConstraintDescriptor corresponding to the constraint being
- * validated
- */
- public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
- this.value = value;
- this.descriptor = descriptor;
- }
-
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return descriptor;
- }
-
- public Object getValidatedValue() {
- return value;
- }
-
- }
-
- /**
- * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
- *
- * @param beanClass
- * bean class based on which the validation should be performed
- * @param propertyName
- * property to validate
- */
- public BeanValidator(Class<?> beanClass, String propertyName) {
- this.beanClass = beanClass;
- this.propertyName = propertyName;
- locale = Locale.getDefault();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Validator#validate(java.lang.Object)
- */
- public void validate(final Object value) throws InvalidValueException {
- Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
- propertyName, value);
- if (violations.size() > 0) {
- List<String> exceptions = new ArrayList<String>();
- for (Object v : violations) {
- final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
- String msg = getJavaxBeanValidatorFactory()
- .getMessageInterpolator().interpolate(
- violation.getMessageTemplate(),
- new SimpleContext(value, violation
- .getConstraintDescriptor()), locale);
- exceptions.add(msg);
- }
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < exceptions.size(); i++) {
- if (i != 0) {
- b.append("<br/>");
- }
- b.append(exceptions.get(i));
- }
- throw new InvalidValueException(b.toString());
- }
- }
-
- /**
- * Sets the locale used for validation error messages.
- *
- * Revalidation is not automatically triggered by setting the locale.
- *
- * @param locale
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Gets the locale used for validation error messages.
- *
- * @return locale used for validation
- */
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Returns the underlying JSR-303 bean validator factory used. A factory is
- * created using {@link Validation} if necessary.
- *
- * @return {@link ValidatorFactory} to use
- */
- protected static ValidatorFactory getJavaxBeanValidatorFactory() {
- if (factory == null) {
- factory = Validation.buildDefaultValidatorFactory();
- }
-
- return factory;
- }
-
- /**
- * Returns a shared Validator instance to use. An instance is created using
- * the validator factory if necessary and thereafter reused by the
- * {@link BeanValidator} instance.
- *
- * @return the JSR-303 {@link javax.validation.Validator} to use
- */
- protected javax.validation.Validator getJavaxBeanValidator() {
- if (javaxBeanValidator == null) {
- javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
- }
-
- return javaxBeanValidator;
- }
-
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.data.validator;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.MessageInterpolator.Context;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.metadata.ConstraintDescriptor;
+
+import com.vaadin.data.Validator;
+
+/**
+ * Vaadin {@link Validator} using the JSR-303 (javax.validation)
+ * annotation-based bean validation.
+ *
+ * The annotations of the fields of the beans are used to determine the
+ * validation to perform.
+ *
+ * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
+ * Validation - formerly agimatec validation) must be present on the project
+ * classpath when using bean validation.
+ *
+ * @since 7.0
+ *
+ * @author Petri Hakala
+ * @author Henri Sara
+ */
+public class BeanValidator implements Validator {
+
+ private static final long serialVersionUID = 1L;
+ private static ValidatorFactory factory;
+
+ private transient javax.validation.Validator javaxBeanValidator;
+ private String propertyName;
+ private Class<?> beanClass;
+ private Locale locale;
+
+ /**
+ * Simple implementation of a message interpolator context that returns
+ * fixed values.
+ */
+ protected static class SimpleContext implements Context, Serializable {
+
+ private final Object value;
+ private final ConstraintDescriptor<?> descriptor;
+
+ /**
+ * Create a simple immutable message interpolator context.
+ *
+ * @param value
+ * value being validated
+ * @param descriptor
+ * ConstraintDescriptor corresponding to the constraint being
+ * validated
+ */
+ public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
+ this.value = value;
+ this.descriptor = descriptor;
+ }
+
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return descriptor;
+ }
+
+ public Object getValidatedValue() {
+ return value;
+ }
+
+ }
+
+ /**
+ * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
+ *
+ * @param beanClass
+ * bean class based on which the validation should be performed
+ * @param propertyName
+ * property to validate
+ */
+ public BeanValidator(Class<?> beanClass, String propertyName) {
+ this.beanClass = beanClass;
+ this.propertyName = propertyName;
+ locale = Locale.getDefault();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.Validator#validate(java.lang.Object)
+ */
+ public void validate(final Object value) throws InvalidValueException {
+ Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
+ propertyName, value);
+ if (violations.size() > 0) {
+ List<String> exceptions = new ArrayList<String>();
+ for (Object v : violations) {
+ final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
+ String msg = getJavaxBeanValidatorFactory()
+ .getMessageInterpolator().interpolate(
+ violation.getMessageTemplate(),
+ new SimpleContext(value, violation
+ .getConstraintDescriptor()), locale);
+ exceptions.add(msg);
+ }
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; i < exceptions.size(); i++) {
+ if (i != 0) {
+ b.append("<br/>");
+ }
+ b.append(exceptions.get(i));
+ }
+ throw new InvalidValueException(b.toString());
+ }
+ }
+
+ /**
+ * Sets the locale used for validation error messages.
+ *
+ * Revalidation is not automatically triggered by setting the locale.
+ *
+ * @param locale
+ */
+ public void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
+ /**
+ * Gets the locale used for validation error messages.
+ *
+ * @return locale used for validation
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Returns the underlying JSR-303 bean validator factory used. A factory is
+ * created using {@link Validation} if necessary.
+ *
+ * @return {@link ValidatorFactory} to use
+ */
+ protected static ValidatorFactory getJavaxBeanValidatorFactory() {
+ if (factory == null) {
+ factory = Validation.buildDefaultValidatorFactory();
+ }
+
+ return factory;
+ }
+
+ /**
+ * Returns a shared Validator instance to use. An instance is created using
+ * the validator factory if necessary and thereafter reused by the
+ * {@link BeanValidator} instance.
+ *
+ * @return the JSR-303 {@link javax.validation.Validator} to use
+ */
+ protected javax.validation.Validator getJavaxBeanValidator() {
+ if (javaxBeanValidator == null) {
+ javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
+ }
+
+ return javaxBeanValidator;
+ }
+
} \ No newline at end of file
diff --git a/src/com/vaadin/data/validator/DateRangeValidator.java b/src/com/vaadin/data/validator/DateRangeValidator.java
index 42f5a224ed..24f3d3ce10 100644
--- a/src/com/vaadin/data/validator/DateRangeValidator.java
+++ b/src/com/vaadin/data/validator/DateRangeValidator.java
@@ -1,51 +1,51 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import java.util.Date;
-
-import com.vaadin.ui.DateField.Resolution;
-
-/**
- * Validator for validating that a Date is inside a given range.
- *
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateRangeValidator extends RangeValidator<Date> {
-
- /**
- * Creates a validator for checking that an Date is within a given range.
- * <p>
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- * </p>
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public DateRangeValidator(String errorMessage, Date minValue,
- Date maxValue, Resolution resolution) {
- super(errorMessage, Date.class, minValue, maxValue);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.validator;
+
+import java.util.Date;
+
+import com.vaadin.ui.DateField.Resolution;
+
+/**
+ * Validator for validating that a Date is inside a given range.
+ *
+ * <p>
+ * Note that the comparison is done directly on the Date object so take care
+ * that the hours/minutes/seconds/milliseconds of the min/max values are
+ * properly set.
+ * </p>
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class DateRangeValidator extends RangeValidator<Date> {
+
+ /**
+ * Creates a validator for checking that an Date is within a given range.
+ * <p>
+ * By default the range is inclusive i.e. both minValue and maxValue are
+ * valid values. Use {@link #setMinValueIncluded(boolean)} or
+ * {@link #setMaxValueIncluded(boolean)} to change it.
+ * </p>
+ * <p>
+ * Note that the comparison is done directly on the Date object so take care
+ * that the hours/minutes/seconds/milliseconds of the min/max values are
+ * properly set.
+ * </p>
+ *
+ * @param errorMessage
+ * the message to display in case the value does not validate.
+ * @param minValue
+ * The minimum value to accept or null for no limit
+ * @param maxValue
+ * The maximum value to accept or null for no limit
+ */
+ public DateRangeValidator(String errorMessage, Date minValue,
+ Date maxValue, Resolution resolution) {
+ super(errorMessage, Date.class, minValue, maxValue);
+ }
+
+}
diff --git a/src/com/vaadin/data/validator/RangeValidator.java b/src/com/vaadin/data/validator/RangeValidator.java
index 457f046360..433271274f 100644
--- a/src/com/vaadin/data/validator/RangeValidator.java
+++ b/src/com/vaadin/data/validator/RangeValidator.java
@@ -1,186 +1,186 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * An base implementation for validating any objects that implement
- * {@link Comparable}.
- *
- * Verifies that the value is of the given type and within the (optionally)
- * given limits. Typically you want to use a sub class of this like
- * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
- * {@link DateRangeValidator} in applications.
- * <p>
- * Note that {@link RangeValidator} always accept null values. Make a field
- * required to ensure that no empty values are accepted or override
- * {@link #isValidValue(Comparable)}.
- * </p>
- *
- * @param <T>
- * The type of Number to validate. Must implement Comparable so that
- * minimum and maximum checks work.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
-
- private T minValue = null;
- private boolean minValueIncluded = true;
- private T maxValue = null;
- private boolean maxValueIncluded = true;
- private Class<T> type;
-
- /**
- * Creates a new range validator of the given type.
- *
- * @param errorMessage
- * The error message to use if validation fails
- * @param type
- * The type of object the validator can validate.
- * @param minValue
- * The minimum value that should be accepted or null for no limit
- * @param maxValue
- * The maximum value that should be accepted or null for no limit
- */
- public RangeValidator(String errorMessage, Class<T> type, T minValue,
- T maxValue) {
- super(errorMessage);
- this.type = type;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-
- /**
- * Checks if the minimum value is part of the accepted range
- *
- * @return true if the minimum value is part of the range, false otherwise
- */
- public boolean isMinValueIncluded() {
- return minValueIncluded;
- }
-
- /**
- * Sets if the minimum value is part of the accepted range
- *
- * @param minValueIncluded
- * true if the minimum value should be part of the range, false
- * otherwise
- */
- public void setMinValueIncluded(boolean minValueIncluded) {
- this.minValueIncluded = minValueIncluded;
- }
-
- /**
- * Checks if the maximum value is part of the accepted range
- *
- * @return true if the maximum value is part of the range, false otherwise
- */
- public boolean isMaxValueIncluded() {
- return maxValueIncluded;
- }
-
- /**
- * Sets if the maximum value is part of the accepted range
- *
- * @param maxValueIncluded
- * true if the maximum value should be part of the range, false
- * otherwise
- */
- public void setMaxValueIncluded(boolean maxValueIncluded) {
- this.maxValueIncluded = maxValueIncluded;
- }
-
- /**
- * Gets the minimum value of the range
- *
- * @return the minimum value
- */
- public T getMinValue() {
- return minValue;
- }
-
- /**
- * Sets the minimum value of the range. Use
- * {@link #setMinValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param minValue
- * the minimum value
- */
- public void setMinValue(T minValue) {
- this.minValue = minValue;
- }
-
- /**
- * Gets the maximum value of the range
- *
- * @return the maximum value
- */
- public T getMaxValue() {
- return maxValue;
- }
-
- /**
- * Sets the maximum value of the range. Use
- * {@link #setMaxValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param maxValue
- * the maximum value
- */
- public void setMaxValue(T maxValue) {
- this.maxValue = maxValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
- * )
- */
- @Override
- protected boolean isValidValue(T value) {
- if (value == null) {
- return true;
- }
-
- if (getMinValue() != null) {
- // Ensure that the min limit is ok
- int result = value.compareTo(getMinValue());
- if (result < 0) {
- // value less than min value
- return false;
- } else if (result == 0 && !isMinValueIncluded()) {
- // values equal and min value not included
- return false;
- }
- }
- if (getMaxValue() != null) {
- // Ensure that the Max limit is ok
- int result = value.compareTo(getMaxValue());
- if (result > 0) {
- // value greater than max value
- return false;
- } else if (result == 0 && !isMaxValueIncluded()) {
- // values equal and max value not included
- return false;
- }
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.validator.AbstractValidator#getType()
- */
- @Override
- public Class<T> getType() {
- return type;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.data.validator;
+
+/**
+ * An base implementation for validating any objects that implement
+ * {@link Comparable}.
+ *
+ * Verifies that the value is of the given type and within the (optionally)
+ * given limits. Typically you want to use a sub class of this like
+ * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
+ * {@link DateRangeValidator} in applications.
+ * <p>
+ * Note that {@link RangeValidator} always accept null values. Make a field
+ * required to ensure that no empty values are accepted or override
+ * {@link #isValidValue(Comparable)}.
+ * </p>
+ *
+ * @param <T>
+ * The type of Number to validate. Must implement Comparable so that
+ * minimum and maximum checks work.
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
+
+ private T minValue = null;
+ private boolean minValueIncluded = true;
+ private T maxValue = null;
+ private boolean maxValueIncluded = true;
+ private Class<T> type;
+
+ /**
+ * Creates a new range validator of the given type.
+ *
+ * @param errorMessage
+ * The error message to use if validation fails
+ * @param type
+ * The type of object the validator can validate.
+ * @param minValue
+ * The minimum value that should be accepted or null for no limit
+ * @param maxValue
+ * The maximum value that should be accepted or null for no limit
+ */
+ public RangeValidator(String errorMessage, Class<T> type, T minValue,
+ T maxValue) {
+ super(errorMessage);
+ this.type = type;
+ this.minValue = minValue;
+ this.maxValue = maxValue;
+ }
+
+ /**
+ * Checks if the minimum value is part of the accepted range
+ *
+ * @return true if the minimum value is part of the range, false otherwise
+ */
+ public boolean isMinValueIncluded() {
+ return minValueIncluded;
+ }
+
+ /**
+ * Sets if the minimum value is part of the accepted range
+ *
+ * @param minValueIncluded
+ * true if the minimum value should be part of the range, false
+ * otherwise
+ */
+ public void setMinValueIncluded(boolean minValueIncluded) {
+ this.minValueIncluded = minValueIncluded;
+ }
+
+ /**
+ * Checks if the maximum value is part of the accepted range
+ *
+ * @return true if the maximum value is part of the range, false otherwise
+ */
+ public boolean isMaxValueIncluded() {
+ return maxValueIncluded;
+ }
+
+ /**
+ * Sets if the maximum value is part of the accepted range
+ *
+ * @param maxValueIncluded
+ * true if the maximum value should be part of the range, false
+ * otherwise
+ */
+ public void setMaxValueIncluded(boolean maxValueIncluded) {
+ this.maxValueIncluded = maxValueIncluded;
+ }
+
+ /**
+ * Gets the minimum value of the range
+ *
+ * @return the minimum value
+ */
+ public T getMinValue() {
+ return minValue;
+ }
+
+ /**
+ * Sets the minimum value of the range. Use
+ * {@link #setMinValueIncluded(boolean)} to control whether this value is
+ * part of the range or not.
+ *
+ * @param minValue
+ * the minimum value
+ */
+ public void setMinValue(T minValue) {
+ this.minValue = minValue;
+ }
+
+ /**
+ * Gets the maximum value of the range
+ *
+ * @return the maximum value
+ */
+ public T getMaxValue() {
+ return maxValue;
+ }
+
+ /**
+ * Sets the maximum value of the range. Use
+ * {@link #setMaxValueIncluded(boolean)} to control whether this value is
+ * part of the range or not.
+ *
+ * @param maxValue
+ * the maximum value
+ */
+ public void setMaxValue(T maxValue) {
+ this.maxValue = maxValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
+ * )
+ */
+ @Override
+ protected boolean isValidValue(T value) {
+ if (value == null) {
+ return true;
+ }
+
+ if (getMinValue() != null) {
+ // Ensure that the min limit is ok
+ int result = value.compareTo(getMinValue());
+ if (result < 0) {
+ // value less than min value
+ return false;
+ } else if (result == 0 && !isMinValueIncluded()) {
+ // values equal and min value not included
+ return false;
+ }
+ }
+ if (getMaxValue() != null) {
+ // Ensure that the Max limit is ok
+ int result = value.compareTo(getMaxValue());
+ if (result > 0) {
+ // value greater than max value
+ return false;
+ } else if (result == 0 && !isMaxValueIncluded()) {
+ // values equal and max value not included
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.data.validator.AbstractValidator#getType()
+ */
+ @Override
+ public Class<T> getType() {
+ return type;
+ }
+
+}
diff --git a/src/com/vaadin/event/FieldEvents.java b/src/com/vaadin/event/FieldEvents.java
index 202abba078..28fd6bb4f7 100644
--- a/src/com/vaadin/event/FieldEvents.java
+++ b/src/com/vaadin/event/FieldEvents.java
@@ -1,250 +1,250 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Field.ValueChangeEvent;
-import com.vaadin.ui.TextField;
-
-/**
- * Interface that serves as a wrapper for {@link Field} related events.
- */
-public interface FieldEvents {
-
- /**
- * The interface for adding and removing <code>FocusEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>FocusEvent</code> when it receives keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see FocusListener
- * @see FocusEvent
- */
- public interface FocusNotifier extends Serializable {
- /**
- * Adds a <code>FocusListener</code> to the Component which gets fired
- * when a <code>Field</code> receives keyboard focus.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void addListener(FocusListener listener);
-
- /**
- * Removes a <code>FocusListener</code> from the Component.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void removeListener(FocusListener listener);
- }
-
- /**
- * The interface for adding and removing <code>BlurEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>BlurEvent</code> when it loses keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see BlurListener
- * @see BlurEvent
- */
- public interface BlurNotifier extends Serializable {
- /**
- * Adds a <code>BlurListener</code> to the Component which gets fired
- * when a <code>Field</code> loses keyboard focus.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void addListener(BlurListener listener);
-
- /**
- * Removes a <code>BlurListener</code> from the Component.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void removeListener(BlurListener listener);
- }
-
- /**
- * <code>FocusEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> receives keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class FocusEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.FOCUS;
-
- public FocusEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>FocusListener</code> interface for listening for
- * <code>FocusEvent</code> fired by a <code>Field</code>.
- *
- * @see FocusEvent
- * @since 6.2
- */
- public interface FocusListener extends ComponentEventListener {
-
- public static final Method focusMethod = ReflectTools.findMethod(
- FocusListener.class, "focus", FocusEvent.class);
-
- /**
- * Component has been focused
- *
- * @param event
- * Component focus event.
- */
- public void focus(FocusEvent event);
- }
-
- /**
- * <code>BlurEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> loses keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class BlurEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.BLUR;
-
- public BlurEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>BlurListener</code> interface for listening for
- * <code>BlurEvent</code> fired by a <code>Field</code>.
- *
- * @see BlurEvent
- * @since 6.2
- */
- public interface BlurListener extends ComponentEventListener {
-
- public static final Method blurMethod = ReflectTools.findMethod(
- BlurListener.class, "blur", BlurEvent.class);
-
- /**
- * Component has been blurred
- *
- * @param event
- * Component blur event.
- */
- public void blur(BlurEvent event);
- }
-
- /**
- * TextChangeEvents are fired when the user is editing the text content of a
- * field. Most commonly text change events are triggered by typing text with
- * keyboard, but e.g. pasting content from clip board to a text field also
- * triggers an event.
- * <p>
- * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are
- * triggered repeatedly while the end user is filling the field.
- * ValueChangeEvents are not fired until the user for example hits enter or
- * focuses another field. Also note the difference that TextChangeEvents are
- * only fired if the change is triggered from the user, while
- * ValueChangeEvents are also fired if the field value is set by the
- * application code.
- * <p>
- * The {@link TextChangeNotifier}s implementation may decide when exactly
- * TextChangeEvents are fired. TextChangeEvents are not necessary fire for
- * example on each key press, but buffered with a small delay. The
- * {@link TextField} component supports different modes for triggering
- * TextChangeEvents.
- *
- * @see TextChangeListener
- * @see TextChangeNotifier
- * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode)
- * @since 6.5
- */
- public static abstract class TextChangeEvent extends Component.Event {
- public TextChangeEvent(Component source) {
- super(source);
- }
-
- /**
- * @return the text content of the field after the
- * {@link TextChangeEvent}
- */
- public abstract String getText();
-
- /**
- * @return the cursor position during after the {@link TextChangeEvent}
- */
- public abstract int getCursorPosition();
- }
-
- /**
- * A listener for {@link TextChangeEvent}s.
- *
- * @since 6.5
- */
- public interface TextChangeListener extends ComponentEventListener {
-
- public static String EVENT_ID = "ie";
- public static Method EVENT_METHOD = ReflectTools.findMethod(
- TextChangeListener.class, "textChange", TextChangeEvent.class);
-
- /**
- * This method is called repeatedly while the text is edited by a user.
- *
- * @param event
- * the event providing details of the text change
- */
- public void textChange(TextChangeEvent event);
- }
-
- /**
- * An interface implemented by a {@link Field} supporting
- * {@link TextChangeEvent}s. An example a {@link TextField} supports
- * {@link TextChangeListener}s.
- */
- public interface TextChangeNotifier extends Serializable {
- public void addListener(TextChangeListener listener);
-
- public void removeListener(TextChangeListener listener);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.event;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.tools.ReflectTools;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.Field.ValueChangeEvent;
+import com.vaadin.ui.TextField;
+
+/**
+ * Interface that serves as a wrapper for {@link Field} related events.
+ */
+public interface FieldEvents {
+
+ /**
+ * The interface for adding and removing <code>FocusEvent</code> listeners.
+ * By implementing this interface a class explicitly announces that it will
+ * generate a <code>FocusEvent</code> when it receives keyboard focus.
+ * <p>
+ * Note: The general Java convention is not to explicitly declare that a
+ * class generates events, but to directly define the
+ * <code>addListener</code> and <code>removeListener</code> methods. That
+ * way the caller of these methods has no real way of finding out if the
+ * class really will send the events, or if it just defines the methods to
+ * be able to implement an interface.
+ * </p>
+ *
+ * @since 6.2
+ * @see FocusListener
+ * @see FocusEvent
+ */
+ public interface FocusNotifier extends Serializable {
+ /**
+ * Adds a <code>FocusListener</code> to the Component which gets fired
+ * when a <code>Field</code> receives keyboard focus.
+ *
+ * @param listener
+ * @see FocusListener
+ * @since 6.2
+ */
+ public void addListener(FocusListener listener);
+
+ /**
+ * Removes a <code>FocusListener</code> from the Component.
+ *
+ * @param listener
+ * @see FocusListener
+ * @since 6.2
+ */
+ public void removeListener(FocusListener listener);
+ }
+
+ /**
+ * The interface for adding and removing <code>BlurEvent</code> listeners.
+ * By implementing this interface a class explicitly announces that it will
+ * generate a <code>BlurEvent</code> when it loses keyboard focus.
+ * <p>
+ * Note: The general Java convention is not to explicitly declare that a
+ * class generates events, but to directly define the
+ * <code>addListener</code> and <code>removeListener</code> methods. That
+ * way the caller of these methods has no real way of finding out if the
+ * class really will send the events, or if it just defines the methods to
+ * be able to implement an interface.
+ * </p>
+ *
+ * @since 6.2
+ * @see BlurListener
+ * @see BlurEvent
+ */
+ public interface BlurNotifier extends Serializable {
+ /**
+ * Adds a <code>BlurListener</code> to the Component which gets fired
+ * when a <code>Field</code> loses keyboard focus.
+ *
+ * @param listener
+ * @see BlurListener
+ * @since 6.2
+ */
+ public void addListener(BlurListener listener);
+
+ /**
+ * Removes a <code>BlurListener</code> from the Component.
+ *
+ * @param listener
+ * @see BlurListener
+ * @since 6.2
+ */
+ public void removeListener(BlurListener listener);
+ }
+
+ /**
+ * <code>FocusEvent</code> class for holding additional event information.
+ * Fired when a <code>Field</code> receives keyboard focus.
+ *
+ * @since 6.2
+ */
+ @SuppressWarnings("serial")
+ public class FocusEvent extends Component.Event {
+
+ /**
+ * Identifier for event that can be used in {@link EventRouter}
+ */
+ public static final String EVENT_ID = EventId.FOCUS;
+
+ public FocusEvent(Component source) {
+ super(source);
+ }
+ }
+
+ /**
+ * <code>FocusListener</code> interface for listening for
+ * <code>FocusEvent</code> fired by a <code>Field</code>.
+ *
+ * @see FocusEvent
+ * @since 6.2
+ */
+ public interface FocusListener extends ComponentEventListener {
+
+ public static final Method focusMethod = ReflectTools.findMethod(
+ FocusListener.class, "focus", FocusEvent.class);
+
+ /**
+ * Component has been focused
+ *
+ * @param event
+ * Component focus event.
+ */
+ public void focus(FocusEvent event);
+ }
+
+ /**
+ * <code>BlurEvent</code> class for holding additional event information.
+ * Fired when a <code>Field</code> loses keyboard focus.
+ *
+ * @since 6.2
+ */
+ @SuppressWarnings("serial")
+ public class BlurEvent extends Component.Event {
+
+ /**
+ * Identifier for event that can be used in {@link EventRouter}
+ */
+ public static final String EVENT_ID = EventId.BLUR;
+
+ public BlurEvent(Component source) {
+ super(source);
+ }
+ }
+
+ /**
+ * <code>BlurListener</code> interface for listening for
+ * <code>BlurEvent</code> fired by a <code>Field</code>.
+ *
+ * @see BlurEvent
+ * @since 6.2
+ */
+ public interface BlurListener extends ComponentEventListener {
+
+ public static final Method blurMethod = ReflectTools.findMethod(
+ BlurListener.class, "blur", BlurEvent.class);
+
+ /**
+ * Component has been blurred
+ *
+ * @param event
+ * Component blur event.
+ */
+ public void blur(BlurEvent event);
+ }
+
+ /**
+ * TextChangeEvents are fired when the user is editing the text content of a
+ * field. Most commonly text change events are triggered by typing text with
+ * keyboard, but e.g. pasting content from clip board to a text field also
+ * triggers an event.
+ * <p>
+ * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are
+ * triggered repeatedly while the end user is filling the field.
+ * ValueChangeEvents are not fired until the user for example hits enter or
+ * focuses another field. Also note the difference that TextChangeEvents are
+ * only fired if the change is triggered from the user, while
+ * ValueChangeEvents are also fired if the field value is set by the
+ * application code.
+ * <p>
+ * The {@link TextChangeNotifier}s implementation may decide when exactly
+ * TextChangeEvents are fired. TextChangeEvents are not necessary fire for
+ * example on each key press, but buffered with a small delay. The
+ * {@link TextField} component supports different modes for triggering
+ * TextChangeEvents.
+ *
+ * @see TextChangeListener
+ * @see TextChangeNotifier
+ * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode)
+ * @since 6.5
+ */
+ public static abstract class TextChangeEvent extends Component.Event {
+ public TextChangeEvent(Component source) {
+ super(source);
+ }
+
+ /**
+ * @return the text content of the field after the
+ * {@link TextChangeEvent}
+ */
+ public abstract String getText();
+
+ /**
+ * @return the cursor position during after the {@link TextChangeEvent}
+ */
+ public abstract int getCursorPosition();
+ }
+
+ /**
+ * A listener for {@link TextChangeEvent}s.
+ *
+ * @since 6.5
+ */
+ public interface TextChangeListener extends ComponentEventListener {
+
+ public static String EVENT_ID = "ie";
+ public static Method EVENT_METHOD = ReflectTools.findMethod(
+ TextChangeListener.class, "textChange", TextChangeEvent.class);
+
+ /**
+ * This method is called repeatedly while the text is edited by a user.
+ *
+ * @param event
+ * the event providing details of the text change
+ */
+ public void textChange(TextChangeEvent event);
+ }
+
+ /**
+ * An interface implemented by a {@link Field} supporting
+ * {@link TextChangeEvent}s. An example a {@link TextField} supports
+ * {@link TextChangeListener}s.
+ */
+ public interface TextChangeNotifier extends Serializable {
+ public void addListener(TextChangeListener listener);
+
+ public void removeListener(TextChangeListener listener);
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONException.java b/src/com/vaadin/external/json/JSONException.java
index 9d97a32d7d..d799021506 100644
--- a/src/com/vaadin/external/json/JSONException.java
+++ b/src/com/vaadin/external/json/JSONException.java
@@ -1,28 +1,28 @@
-package com.vaadin.external.json;
-
-/**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
- * @author JSON.org
- * @version 2010-12-24
- */
-public class JSONException extends Exception {
- private static final long serialVersionUID = 0;
- private Throwable cause;
-
- /**
- * Constructs a JSONException with an explanatory message.
- * @param message Detail about the reason for the exception.
- */
- public JSONException(String message) {
- super(message);
- }
-
- public JSONException(Throwable cause) {
- super(cause.getMessage());
- this.cause = cause;
- }
-
- public Throwable getCause() {
- return this.cause;
- }
-}
+package com.vaadin.external.json;
+
+/**
+ * The JSONException is thrown by the JSON.org classes when things are amiss.
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class JSONException extends Exception {
+ private static final long serialVersionUID = 0;
+ private Throwable cause;
+
+ /**
+ * Constructs a JSONException with an explanatory message.
+ * @param message Detail about the reason for the exception.
+ */
+ public JSONException(String message) {
+ super(message);
+ }
+
+ public JSONException(Throwable cause) {
+ super(cause.getMessage());
+ this.cause = cause;
+ }
+
+ public Throwable getCause() {
+ return this.cause;
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONString.java b/src/com/vaadin/external/json/JSONString.java
index 7b574d1915..cc7e4d8c07 100644
--- a/src/com/vaadin/external/json/JSONString.java
+++ b/src/com/vaadin/external/json/JSONString.java
@@ -1,21 +1,21 @@
-package com.vaadin.external.json;
-
-import java.io.Serializable;
-
-/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
- * method so that a class can change the behavior of
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
- * <code>JSONWriter.value(</code>Object<code>)</code>. The
- * <code>toJSONString</code> method will be used instead of the default behavior
- * of using the Object's <code>toString()</code> method and quoting the result.
- */
-public interface JSONString extends Serializable {
- /**
- * The <code>toJSONString</code> method allows a class to produce its own
- * JSON serialization.
- *
- * @return A strictly syntactically correct JSON text.
- */
- public String toJSONString();
-}
+package com.vaadin.external.json;
+
+import java.io.Serializable;
+
+/**
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
+ * method so that a class can change the behavior of
+ * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
+ * <code>JSONWriter.value(</code>Object<code>)</code>. The
+ * <code>toJSONString</code> method will be used instead of the default behavior
+ * of using the Object's <code>toString()</code> method and quoting the result.
+ */
+public interface JSONString extends Serializable {
+ /**
+ * The <code>toJSONString</code> method allows a class to produce its own
+ * JSON serialization.
+ *
+ * @return A strictly syntactically correct JSON text.
+ */
+ public String toJSONString();
+}
diff --git a/src/com/vaadin/external/json/JSONStringer.java b/src/com/vaadin/external/json/JSONStringer.java
index c4a1af600a..465f27aaab 100644
--- a/src/com/vaadin/external/json/JSONStringer.java
+++ b/src/com/vaadin/external/json/JSONStringer.java
@@ -1,78 +1,78 @@
-package com.vaadin.external.json;
-
-/*
-Copyright (c) 2006 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.io.StringWriter;
-
-/**
- * JSONStringer provides a quick and convenient way of producing JSON text.
- * The texts produced strictly conform to JSON syntax rules. No whitespace is
- * added, so the results are ready for transmission or storage. Each instance of
- * JSONStringer can produce one JSON text.
- * <p>
- * A JSONStringer instance provides a <code>value</code> method for appending
- * values to the
- * text, and a <code>key</code>
- * method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound
- * object values. All of these methods return the JSONWriter instance,
- * permitting cascade style. For example, <pre>
- * myString = new JSONStringer()
- * .object()
- * .key("JSON")
- * .value("Hello, World!")
- * .endObject()
- * .toString();</pre> which produces the string <pre>
- * {"JSON":"Hello, World!"}</pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONStringer adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * @author JSON.org
- * @version 2008-09-18
- */
-public class JSONStringer extends JSONWriter {
- /**
- * Make a fresh JSONStringer. It can be used to build one JSON text.
- */
- public JSONStringer() {
- super(new StringWriter());
- }
-
- /**
- * Return the JSON text. This method is used to obtain the product of the
- * JSONStringer instance. It will return <code>null</code> if there was a
- * problem in the construction of the JSON text (such as the calls to
- * <code>array</code> were not properly balanced with calls to
- * <code>endArray</code>).
- * @return The JSON text.
- */
- public String toString() {
- return this.mode == 'd' ? this.writer.toString() : null;
- }
-}
+package com.vaadin.external.json;
+
+/*
+Copyright (c) 2006 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+import java.io.StringWriter;
+
+/**
+ * JSONStringer provides a quick and convenient way of producing JSON text.
+ * The texts produced strictly conform to JSON syntax rules. No whitespace is
+ * added, so the results are ready for transmission or storage. Each instance of
+ * JSONStringer can produce one JSON text.
+ * <p>
+ * A JSONStringer instance provides a <code>value</code> method for appending
+ * values to the
+ * text, and a <code>key</code>
+ * method for adding keys before values in objects. There are <code>array</code>
+ * and <code>endArray</code> methods that make and bound array values, and
+ * <code>object</code> and <code>endObject</code> methods which make and bound
+ * object values. All of these methods return the JSONWriter instance,
+ * permitting cascade style. For example, <pre>
+ * myString = new JSONStringer()
+ * .object()
+ * .key("JSON")
+ * .value("Hello, World!")
+ * .endObject()
+ * .toString();</pre> which produces the string <pre>
+ * {"JSON":"Hello, World!"}</pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONStringer adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ * @author JSON.org
+ * @version 2008-09-18
+ */
+public class JSONStringer extends JSONWriter {
+ /**
+ * Make a fresh JSONStringer. It can be used to build one JSON text.
+ */
+ public JSONStringer() {
+ super(new StringWriter());
+ }
+
+ /**
+ * Return the JSON text. This method is used to obtain the product of the
+ * JSONStringer instance. It will return <code>null</code> if there was a
+ * problem in the construction of the JSON text (such as the calls to
+ * <code>array</code> were not properly balanced with calls to
+ * <code>endArray</code>).
+ * @return The JSON text.
+ */
+ public String toString() {
+ return this.mode == 'd' ? this.writer.toString() : null;
+ }
+}
diff --git a/src/com/vaadin/external/json/JSONWriter.java b/src/com/vaadin/external/json/JSONWriter.java
index 438721b7b2..5f9ddeeae2 100644
--- a/src/com/vaadin/external/json/JSONWriter.java
+++ b/src/com/vaadin/external/json/JSONWriter.java
@@ -1,355 +1,355 @@
-package com.vaadin.external.json;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-
-/*
- Copyright (c) 2006 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONWriter provides a quick and convenient way of producing JSON text. The
- * texts produced strictly conform to JSON syntax rules. No whitespace is added,
- * so the results are ready for transmission or storage. Each instance of
- * JSONWriter can produce one JSON text.
- * <p>
- * A JSONWriter instance provides a <code>value</code> method for appending
- * values to the text, and a <code>key</code> method for adding keys before
- * values in objects. There are <code>array</code> and <code>endArray</code>
- * methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting a cascade style. For
- * example,
- *
- * <pre>
- * new JSONWriter(myWriter).object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
- * .endObject();
- * </pre>
- *
- * which writes
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONWriter adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- *
- * @author JSON.org
- * @version 2011-11-14
- */
-public class JSONWriter implements Serializable {
- private static final int maxdepth = 200;
-
- /**
- * The comma flag determines if a comma should be output before the next
- * value.
- */
- private boolean comma;
-
- /**
- * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k'
- * (key), 'o' (object).
- */
- protected char mode;
-
- /**
- * The object/array stack.
- */
- private final JSONObject stack[];
-
- /**
- * The stack top index. A value of 0 indicates that the stack is empty.
- */
- private int top;
-
- /**
- * The writer that will receive the output.
- */
- protected Writer writer;
-
- /**
- * Make a fresh JSONWriter. It can be used to build one JSON text.
- */
- public JSONWriter(Writer w) {
- comma = false;
- mode = 'i';
- stack = new JSONObject[maxdepth];
- top = 0;
- writer = w;
- }
-
- /**
- * Append a value.
- *
- * @param string
- * A string value.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- private JSONWriter append(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null pointer");
- }
- if (mode == 'o' || mode == 'a') {
- try {
- if (comma && mode == 'a') {
- writer.write(',');
- }
- writer.write(string);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- if (mode == 'o') {
- mode = 'k';
- }
- comma = true;
- return this;
- }
- throw new JSONException("Value out of sequence.");
- }
-
- /**
- * Begin appending a new array. All values until the balancing
- * <code>endArray</code> will be appended to this array. The
- * <code>endArray</code> method must be called to mark the array's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter array() throws JSONException {
- if (mode == 'i' || mode == 'o' || mode == 'a') {
- push(null);
- append("[");
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced array.");
- }
-
- /**
- * End something.
- *
- * @param mode
- * Mode
- * @param c
- * Closing character
- * @return this
- * @throws JSONException
- * If unbalanced.
- */
- private JSONWriter end(char mode, char c) throws JSONException {
- if (this.mode != mode) {
- throw new JSONException(mode == 'a' ? "Misplaced endArray."
- : "Misplaced endObject.");
- }
- pop(mode);
- try {
- writer.write(c);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- comma = true;
- return this;
- }
-
- /**
- * End an array. This method most be called to balance calls to
- * <code>array</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endArray() throws JSONException {
- return end('a', ']');
- }
-
- /**
- * End an object. This method most be called to balance calls to
- * <code>object</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endObject() throws JSONException {
- return end('k', '}');
- }
-
- /**
- * Append a key. The key will be associated with the next value. In an
- * object, every value must be preceded by a key.
- *
- * @param string
- * A key string.
- * @return this
- * @throws JSONException
- * If the key is out of place. For example, keys do not belong
- * in arrays or if the key is null.
- */
- public JSONWriter key(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null key.");
- }
- if (mode == 'k') {
- try {
- stack[top - 1].putOnce(string, Boolean.TRUE);
- if (comma) {
- writer.write(',');
- }
- writer.write(JSONObject.quote(string));
- writer.write(':');
- comma = false;
- mode = 'o';
- return this;
- } catch (IOException e) {
- throw new JSONException(e);
- }
- }
- throw new JSONException("Misplaced key.");
- }
-
- /**
- * Begin appending a new object. All keys and values until the balancing
- * <code>endObject</code> will be appended to this object. The
- * <code>endObject</code> method must be called to mark the object's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter object() throws JSONException {
- if (mode == 'i') {
- mode = 'o';
- }
- if (mode == 'o' || mode == 'a') {
- append("{");
- push(new JSONObject());
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced object.");
-
- }
-
- /**
- * Pop an array or object scope.
- *
- * @param c
- * The scope to close.
- * @throws JSONException
- * If nesting is wrong.
- */
- private void pop(char c) throws JSONException {
- if (top <= 0) {
- throw new JSONException("Nesting error.");
- }
- char m = stack[top - 1] == null ? 'a' : 'k';
- if (m != c) {
- throw new JSONException("Nesting error.");
- }
- top -= 1;
- mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
- }
-
- /**
- * Push an array or object scope.
- *
- * @param c
- * The scope to open.
- * @throws JSONException
- * If nesting is too deep.
- */
- private void push(JSONObject jo) throws JSONException {
- if (top >= maxdepth) {
- throw new JSONException("Nesting too deep.");
- }
- stack[top] = jo;
- mode = jo == null ? 'a' : 'k';
- top += 1;
- }
-
- /**
- * Append either the value <code>true</code> or the value <code>false</code>
- * .
- *
- * @param b
- * A boolean.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(boolean b) throws JSONException {
- return append(b ? "true" : "false");
- }
-
- /**
- * Append a double value.
- *
- * @param d
- * A double.
- * @return this
- * @throws JSONException
- * If the number is not finite.
- */
- public JSONWriter value(double d) throws JSONException {
- return this.value(new Double(d));
- }
-
- /**
- * Append a long value.
- *
- * @param l
- * A long.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(long l) throws JSONException {
- return append(Long.toString(l));
- }
-
- /**
- * Append an object value.
- *
- * @param object
- * The object to append. It can be null, or a Boolean, Number,
- * String, JSONObject, or JSONArray, or an object that implements
- * JSONString.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- public JSONWriter value(Object object) throws JSONException {
- return append(JSONObject.valueToString(object));
- }
-}
+package com.vaadin.external.json;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+
+/*
+ Copyright (c) 2006 JSON.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ The Software shall be used for Good, not Evil.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+
+/**
+ * JSONWriter provides a quick and convenient way of producing JSON text. The
+ * texts produced strictly conform to JSON syntax rules. No whitespace is added,
+ * so the results are ready for transmission or storage. Each instance of
+ * JSONWriter can produce one JSON text.
+ * <p>
+ * A JSONWriter instance provides a <code>value</code> method for appending
+ * values to the text, and a <code>key</code> method for adding keys before
+ * values in objects. There are <code>array</code> and <code>endArray</code>
+ * methods that make and bound array values, and <code>object</code> and
+ * <code>endObject</code> methods which make and bound object values. All of
+ * these methods return the JSONWriter instance, permitting a cascade style. For
+ * example,
+ *
+ * <pre>
+ * new JSONWriter(myWriter).object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
+ * .endObject();
+ * </pre>
+ *
+ * which writes
+ *
+ * <pre>
+ * {"JSON":"Hello, World!"}
+ * </pre>
+ * <p>
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONWriter adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
+ * <p>
+ * This can sometimes be easier than using a JSONObject to build a string.
+ *
+ * @author JSON.org
+ * @version 2011-11-14
+ */
+public class JSONWriter implements Serializable {
+ private static final int maxdepth = 200;
+
+ /**
+ * The comma flag determines if a comma should be output before the next
+ * value.
+ */
+ private boolean comma;
+
+ /**
+ * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k'
+ * (key), 'o' (object).
+ */
+ protected char mode;
+
+ /**
+ * The object/array stack.
+ */
+ private final JSONObject stack[];
+
+ /**
+ * The stack top index. A value of 0 indicates that the stack is empty.
+ */
+ private int top;
+
+ /**
+ * The writer that will receive the output.
+ */
+ protected Writer writer;
+
+ /**
+ * Make a fresh JSONWriter. It can be used to build one JSON text.
+ */
+ public JSONWriter(Writer w) {
+ comma = false;
+ mode = 'i';
+ stack = new JSONObject[maxdepth];
+ top = 0;
+ writer = w;
+ }
+
+ /**
+ * Append a value.
+ *
+ * @param string
+ * A string value.
+ * @return this
+ * @throws JSONException
+ * If the value is out of sequence.
+ */
+ private JSONWriter append(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null pointer");
+ }
+ if (mode == 'o' || mode == 'a') {
+ try {
+ if (comma && mode == 'a') {
+ writer.write(',');
+ }
+ writer.write(string);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ if (mode == 'o') {
+ mode = 'k';
+ }
+ comma = true;
+ return this;
+ }
+ throw new JSONException("Value out of sequence.");
+ }
+
+ /**
+ * Begin appending a new array. All values until the balancing
+ * <code>endArray</code> will be appended to this array. The
+ * <code>endArray</code> method must be called to mark the array's end.
+ *
+ * @return this
+ * @throws JSONException
+ * If the nesting is too deep, or if the object is started in
+ * the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter array() throws JSONException {
+ if (mode == 'i' || mode == 'o' || mode == 'a') {
+ push(null);
+ append("[");
+ comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced array.");
+ }
+
+ /**
+ * End something.
+ *
+ * @param mode
+ * Mode
+ * @param c
+ * Closing character
+ * @return this
+ * @throws JSONException
+ * If unbalanced.
+ */
+ private JSONWriter end(char mode, char c) throws JSONException {
+ if (this.mode != mode) {
+ throw new JSONException(mode == 'a' ? "Misplaced endArray."
+ : "Misplaced endObject.");
+ }
+ pop(mode);
+ try {
+ writer.write(c);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ comma = true;
+ return this;
+ }
+
+ /**
+ * End an array. This method most be called to balance calls to
+ * <code>array</code>.
+ *
+ * @return this
+ * @throws JSONException
+ * If incorrectly nested.
+ */
+ public JSONWriter endArray() throws JSONException {
+ return end('a', ']');
+ }
+
+ /**
+ * End an object. This method most be called to balance calls to
+ * <code>object</code>.
+ *
+ * @return this
+ * @throws JSONException
+ * If incorrectly nested.
+ */
+ public JSONWriter endObject() throws JSONException {
+ return end('k', '}');
+ }
+
+ /**
+ * Append a key. The key will be associated with the next value. In an
+ * object, every value must be preceded by a key.
+ *
+ * @param string
+ * A key string.
+ * @return this
+ * @throws JSONException
+ * If the key is out of place. For example, keys do not belong
+ * in arrays or if the key is null.
+ */
+ public JSONWriter key(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null key.");
+ }
+ if (mode == 'k') {
+ try {
+ stack[top - 1].putOnce(string, Boolean.TRUE);
+ if (comma) {
+ writer.write(',');
+ }
+ writer.write(JSONObject.quote(string));
+ writer.write(':');
+ comma = false;
+ mode = 'o';
+ return this;
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ }
+ throw new JSONException("Misplaced key.");
+ }
+
+ /**
+ * Begin appending a new object. All keys and values until the balancing
+ * <code>endObject</code> will be appended to this object. The
+ * <code>endObject</code> method must be called to mark the object's end.
+ *
+ * @return this
+ * @throws JSONException
+ * If the nesting is too deep, or if the object is started in
+ * the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter object() throws JSONException {
+ if (mode == 'i') {
+ mode = 'o';
+ }
+ if (mode == 'o' || mode == 'a') {
+ append("{");
+ push(new JSONObject());
+ comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced object.");
+
+ }
+
+ /**
+ * Pop an array or object scope.
+ *
+ * @param c
+ * The scope to close.
+ * @throws JSONException
+ * If nesting is wrong.
+ */
+ private void pop(char c) throws JSONException {
+ if (top <= 0) {
+ throw new JSONException("Nesting error.");
+ }
+ char m = stack[top - 1] == null ? 'a' : 'k';
+ if (m != c) {
+ throw new JSONException("Nesting error.");
+ }
+ top -= 1;
+ mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
+ }
+
+ /**
+ * Push an array or object scope.
+ *
+ * @param c
+ * The scope to open.
+ * @throws JSONException
+ * If nesting is too deep.
+ */
+ private void push(JSONObject jo) throws JSONException {
+ if (top >= maxdepth) {
+ throw new JSONException("Nesting too deep.");
+ }
+ stack[top] = jo;
+ mode = jo == null ? 'a' : 'k';
+ top += 1;
+ }
+
+ /**
+ * Append either the value <code>true</code> or the value <code>false</code>
+ * .
+ *
+ * @param b
+ * A boolean.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(boolean b) throws JSONException {
+ return append(b ? "true" : "false");
+ }
+
+ /**
+ * Append a double value.
+ *
+ * @param d
+ * A double.
+ * @return this
+ * @throws JSONException
+ * If the number is not finite.
+ */
+ public JSONWriter value(double d) throws JSONException {
+ return this.value(new Double(d));
+ }
+
+ /**
+ * Append a long value.
+ *
+ * @param l
+ * A long.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(long l) throws JSONException {
+ return append(Long.toString(l));
+ }
+
+ /**
+ * Append an object value.
+ *
+ * @param object
+ * The object to append. It can be null, or a Boolean, Number,
+ * String, JSONObject, or JSONArray, or an object that implements
+ * JSONString.
+ * @return this
+ * @throws JSONException
+ * If the value is out of sequence.
+ */
+ public JSONWriter value(Object object) throws JSONException {
+ return append(JSONObject.valueToString(object));
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
index 169934024b..f9be8bf019 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
@@ -17,7 +17,7 @@ import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
-import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
+import com.vaadin.terminal.gwt.client.ui.VUnknownComponentPaintable;
public class ApplicationConfiguration implements EntryPoint {
@@ -381,13 +381,14 @@ public class ApplicationConfiguration implements EntryPoint {
return useDebugIdInDom;
}
- public Class<? extends VPaintableWidget> getWidgetClassByEncodedTag(String tag) {
+ public Class<? extends VPaintableWidget> getWidgetClassByEncodedTag(
+ String tag) {
try {
int parseInt = Integer.parseInt(tag);
return classes[parseInt];
} catch (Exception e) {
// component was not present in mappings
- return VUnknownComponent.class;
+ return VUnknownComponentPaintable.class;
}
}
@@ -397,7 +398,7 @@ public class ApplicationConfiguration implements EntryPoint {
String key = keyArray.get(i).intern();
int value = valueMap.getInt(key);
classes[value] = widgetSet.getImplementationByClassName(key);
- if (classes[value] == VUnknownComponent.class) {
+ if (classes[value] == VUnknownComponentPaintable.class) {
if (unknownComponents == null) {
unknownComponents = new HashMap<String, String>();
}
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 064c2404ad..f20243d959 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -38,11 +38,10 @@ import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage;
import com.vaadin.terminal.gwt.client.ui.Field;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.VContextMenu;
import com.vaadin.terminal.gwt.client.ui.VNotification;
import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent;
-import com.vaadin.terminal.gwt.client.ui.VView;
+import com.vaadin.terminal.gwt.client.ui.VViewPaintable;
import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager;
import com.vaadin.terminal.gwt.server.AbstractCommunicationManager;
@@ -140,7 +139,7 @@ public class ApplicationConnection {
private Timer loadTimer3;
private Element loadElement;
- private final VView view;
+ private final VViewPaintable view;
protected boolean applicationRunning = false;
@@ -171,7 +170,8 @@ public class ApplicationConnection {
private Set<VPaintableWidget> zeroHeightComponents = null;
public ApplicationConnection() {
- view = GWT.create(VView.class);
+ view = GWT.create(VViewPaintable.class);
+ view.setConnection(this);
}
public void init(WidgetSet widgetSet, ApplicationConfiguration cnf) {
@@ -829,7 +829,8 @@ public class ApplicationConnection {
if (loadElement == null) {
loadElement = DOM.createDiv();
DOM.setStyleAttribute(loadElement, "position", "absolute");
- DOM.appendChild(view.getElement(), loadElement);
+ DOM.appendChild(view.getWidgetForPaintable().getElement(),
+ loadElement);
VConsole.log("inserting load indicator");
}
DOM.setElementProperty(loadElement, "className", "v-loading-indicator");
@@ -970,7 +971,7 @@ public class ApplicationConnection {
meta = json.getValueMap("meta");
if (meta.containsKey("repaintAll")) {
repaintAll = true;
- view.clear();
+ view.getWidgetForPaintable().clear();
getPaintableMap().clear();
if (meta.containsKey("invalidLayouts")) {
validatingLayouts = true;
@@ -1643,11 +1644,7 @@ public class ApplicationConnection {
// Changed invisibile <-> visible
if (wasVisible && manageCaption) {
// Must hide caption when component is hidden
- final Container parent = Util.getLayout(component);
- if (parent != null) {
- parent.updateCaption(paintable, uidl);
- }
-
+ paintable.getParent().updateCaption(paintable, uidl);
}
}
@@ -1692,10 +1689,7 @@ public class ApplicationConnection {
// Set captions
if (manageCaption) {
- final Container parent = Util.getLayout(component);
- if (parent != null) {
- parent.updateCaption(paintable, uidl);
- }
+ paintable.getParent().updateCaption(paintable, uidl);
}
// add error classname to components w/ error
@@ -1705,13 +1699,6 @@ public class ApplicationConnection {
tooltipInfo.setErrorUidl(null);
}
- // Set captions
- if (manageCaption) {
- final Container parent = Util.getLayout(component);
- if (parent != null) {
- parent.updateCaption(paintable, uidl);
- }
- }
/*
* updateComponentSize need to be after caption update so caption can be
* taken into account
@@ -1915,10 +1902,9 @@ public class ApplicationConnection {
if (!paintableMap.hasPaintable(pid)) {
// Create and register a new paintable if no old was found
VPaintableWidget p = widgetSet.createWidget(uidl, configuration);
- if (p instanceof VAbstractPaintableWidget) {
- ((VAbstractPaintableWidget) p).setConnection(this);
- ((VAbstractPaintableWidget) p).init();
- }
+ p.setConnection(this);
+ p.setId(pid);
+ p.init();
paintableMap.registerPaintable(pid, p);
}
return (VPaintableWidget) paintableMap.getPaintable(pid);
@@ -2077,7 +2063,7 @@ public class ApplicationConnection {
@Override
public void run() {
VConsole.log("Running re-layout of " + view.getClass().getName());
- runDescendentsLayout(view);
+ runDescendentsLayout(view.getWidgetForPaintable());
isPending = false;
}
};
@@ -2112,7 +2098,7 @@ public class ApplicationConnection {
*
* @return the main view
*/
- public VView getView() {
+ public VViewPaintable getView() {
return view;
}
diff --git a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java
index b03bc708e2..f49f99a477 100644
--- a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java
+++ b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java
@@ -375,7 +375,7 @@ public class ComponentLocator {
} else if (w instanceof VWindow) {
VWindow win = (VWindow) w;
ArrayList<VWindow> subWindowList = client.getView()
- .getSubWindowList();
+ .getWidgetForPaintable().getSubWindowList();
int indexOfSubWindow = subWindowList.indexOf(win);
return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]";
} else if (w instanceof RootPanel) {
@@ -435,7 +435,7 @@ public class ComponentLocator {
if (part.equals(ROOT_ID)) {
w = RootPanel.get();
} else if (part.equals("")) {
- w = client.getView();
+ w = client.getView().getWidgetForPaintable();
} else if (w == null) {
// Must be static pid (PID_S*)
w = ((VPaintableWidget) VPaintableMap.get(client).getPaintable(
@@ -465,7 +465,8 @@ public class ComponentLocator {
* compatibility
*/
if (widgetClassName.equals("VWindow")) {
- iterator = client.getView().getSubWindowList().iterator();
+ iterator = client.getView().getWidgetForPaintable()
+ .getSubWindowList().iterator();
} else if (widgetClassName.equals("VContextMenu")) {
return client.getContextMenu();
} else {
diff --git a/src/com/vaadin/terminal/gwt/client/Container.java b/src/com/vaadin/terminal/gwt/client/Container.java
index db6bbf0ee4..b573fd934e 100644
--- a/src/com/vaadin/terminal/gwt/client/Container.java
+++ b/src/com/vaadin/terminal/gwt/client/Container.java
@@ -8,7 +8,11 @@ import java.util.Set;
import com.google.gwt.user.client.ui.Widget;
-public interface Container extends VPaintableWidget {
+/**
+ * @deprecated To be removed before 7.0.0
+ */
+@Deprecated
+public interface Container {
/**
* Replace child of this layout with another component.
@@ -33,23 +37,6 @@ public interface Container extends VPaintableWidget {
boolean hasChildComponent(Widget component);
/**
- * Update child components caption, description and error message.
- *
- * <p>
- * Each component is responsible for maintaining its caption, description
- * and error message. In most cases components doesn't want to do that and
- * those elements reside outside of the component. Because of this layouts
- * must provide service for it's childen to show those elements for them.
- * </p>
- *
- * @param paintable
- * Child component for which service is requested.
- * @param uidl
- * UIDL of the child component.
- */
- void updateCaption(VPaintableWidget paintable, UIDL uidl);
-
- /**
* Called when a child components size has been updated in the rendering
* phase.
*
diff --git a/src/com/vaadin/terminal/gwt/client/DateTimeService.java b/src/com/vaadin/terminal/gwt/client/DateTimeService.java
index d368d655af..c0151d2819 100644
--- a/src/com/vaadin/terminal/gwt/client/DateTimeService.java
+++ b/src/com/vaadin/terminal/gwt/client/DateTimeService.java
@@ -1,439 +1,439 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.Date;
-
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.i18n.client.LocaleInfo;
-import com.vaadin.terminal.gwt.client.ui.VDateField;
-
-/**
- * This class provides date/time parsing services to all components on the
- * client side.
- *
- * @author Vaadin Ltd.
- *
- */
-@SuppressWarnings("deprecation")
-public class DateTimeService {
-
- private String currentLocale;
-
- private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
- 31, 30, 31 };
-
- /**
- * Creates a new date time service with the application default locale.
- */
- public DateTimeService() {
- currentLocale = LocaleService.getDefaultLocale();
- }
-
- /**
- * Creates a new date time service with a given locale.
- *
- * @param locale
- * e.g. fi, en etc.
- * @throws LocaleNotLoadedException
- */
- public DateTimeService(String locale) throws LocaleNotLoadedException {
- setLocale(locale);
- }
-
- public void setLocale(String locale) throws LocaleNotLoadedException {
- if (LocaleService.getAvailableLocales().contains(locale)) {
- currentLocale = locale;
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public String getLocale() {
- return currentLocale;
- }
-
- public String getMonth(int month) {
- try {
- return LocaleService.getMonthNames(currentLocale)[month];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getShortMonth(int month) {
- try {
- return LocaleService.getShortMonthNames(currentLocale)[month];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getDay(int day) {
- try {
- return LocaleService.getDayNames(currentLocale)[day];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public String getShortDay(int day) {
- try {
- return LocaleService.getShortDayNames(currentLocale)[day];
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return null;
- }
- }
-
- public int getFirstDayOfWeek() {
- try {
- return LocaleService.getFirstDayOfWeek(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return 0;
- }
- }
-
- public boolean isTwelveHourClock() {
- try {
- return LocaleService.isTwelveHourClock(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return false;
- }
- }
-
- public String getClockDelimeter() {
- try {
- return LocaleService.getClockDelimiter(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error(e);
- return ":";
- }
- }
-
- private static final String[] DEFAULT_AMPM_STRINGS = { "AM", "PM" };
-
- public String[] getAmPmStrings() {
- try {
- return LocaleService.getAmPmStrings(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- // TODO can this practically even happen? Should die instead?
- VConsole.error("Locale not loaded, using fallback : AM/PM");
- VConsole.error(e);
- return DEFAULT_AMPM_STRINGS;
- }
- }
-
- public int getStartWeekDay(Date date) {
- final Date dateForFirstOfThisMonth = new Date(date.getYear(),
- date.getMonth(), 1);
- int firstDay;
- try {
- firstDay = LocaleService.getFirstDayOfWeek(currentLocale);
- } catch (final LocaleNotLoadedException e) {
- VConsole.error("Locale not loaded, using fallback 0");
- VConsole.error(e);
- firstDay = 0;
- }
- int start = dateForFirstOfThisMonth.getDay() - firstDay;
- if (start < 0) {
- start = 6;
- }
- return start;
- }
-
- public static void setMilliseconds(Date date, int ms) {
- date.setTime(date.getTime() / 1000 * 1000 + ms);
- }
-
- public static int getMilliseconds(Date date) {
- if (date == null) {
- return 0;
- }
-
- return (int) (date.getTime() - date.getTime() / 1000 * 1000);
- }
-
- public static int getNumberOfDaysInMonth(Date date) {
- final int month = date.getMonth();
- if (month == 1 && true == isLeapYear(date)) {
- return 29;
- }
- return maxDaysInMonth[month];
- }
-
- public static boolean isLeapYear(Date date) {
- // Instantiate the date for 1st March of that year
- final Date firstMarch = new Date(date.getYear(), 2, 1);
-
- // Go back 1 day
- final long firstMarchTime = firstMarch.getTime();
- final long lastDayTimeFeb = firstMarchTime - (24 * 60 * 60 * 1000); // NUM_MILLISECS_A_DAY
-
- // Instantiate new Date with this time
- final Date febLastDay = new Date(lastDayTimeFeb);
-
- // Check for date in this new instance
- return (29 == febLastDay.getDate()) ? true : false;
- }
-
- public static boolean isSameDay(Date d1, Date d2) {
- return (getDayInt(d1) == getDayInt(d2));
- }
-
- public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,
- int resolution) {
- Date s;
- Date e;
- if (rangeStart.after(rangeEnd)) {
- s = rangeEnd;
- e = rangeStart;
- } else {
- e = rangeEnd;
- s = rangeStart;
- }
- long start = s.getYear() * 10000000000l;
- long end = e.getYear() * 10000000000l;
- long target = date.getYear() * 10000000000l;
-
- if (resolution == VDateField.RESOLUTION_YEAR) {
- return (start <= target && end >= target);
- }
- start += s.getMonth() * 100000000l;
- end += e.getMonth() * 100000000l;
- target += date.getMonth() * 100000000l;
- if (resolution == VDateField.RESOLUTION_MONTH) {
- return (start <= target && end >= target);
- }
- start += s.getDate() * 1000000l;
- end += e.getDate() * 1000000l;
- target += date.getDate() * 1000000l;
- if (resolution == VDateField.RESOLUTION_DAY) {
- return (start <= target && end >= target);
- }
- start += s.getHours() * 10000l;
- end += e.getHours() * 10000l;
- target += date.getHours() * 10000l;
- if (resolution == VDateField.RESOLUTION_HOUR) {
- return (start <= target && end >= target);
- }
- start += s.getMinutes() * 100l;
- end += e.getMinutes() * 100l;
- target += date.getMinutes() * 100l;
- if (resolution == VDateField.RESOLUTION_MIN) {
- return (start <= target && end >= target);
- }
- start += s.getSeconds();
- end += e.getSeconds();
- target += date.getSeconds();
- return (start <= target && end >= target);
-
- }
-
- private static int getDayInt(Date date) {
- final int y = date.getYear();
- final int m = date.getMonth();
- final int d = date.getDate();
-
- return ((y + 1900) * 10000 + m * 100 + d) * 1000000000;
- }
-
- /**
- * Returns the ISO-8601 week number of the given date.
- *
- * @param date
- * The date for which the week number should be resolved
- * @return The ISO-8601 week number for {@literal date}
- */
- public static int getISOWeekNumber(Date date) {
- final long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
- int dayOfWeek = date.getDay(); // 0 == sunday
-
- // ISO 8601 use weeks that start on monday so we use
- // mon=1,tue=2,...sun=7;
- if (dayOfWeek == 0) {
- dayOfWeek = 7;
- }
- // Find nearest thursday (defines the week in ISO 8601). The week number
- // for the nearest thursday is the same as for the target date.
- int nearestThursdayDiff = 4 - dayOfWeek; // 4 is thursday
- Date nearestThursday = new Date(date.getTime() + nearestThursdayDiff
- * MILLISECONDS_PER_DAY);
-
- Date firstOfJanuary = new Date(nearestThursday.getYear(), 0, 1);
- long timeDiff = nearestThursday.getTime() - firstOfJanuary.getTime();
- int daysSinceFirstOfJanuary = (int) (timeDiff / MILLISECONDS_PER_DAY);
-
- int weekNumber = (daysSinceFirstOfJanuary) / 7 + 1;
-
- return weekNumber;
- }
-
- /**
- * Check if format contains the month name. If it does we manually convert
- * it to the month name since DateTimeFormat.format always uses the current
- * locale and will replace the month name wrong if current locale is
- * different from the locale set for the DateField.
- *
- * MMMM is converted into long month name, MMM is converted into short month
- * name. '' are added around the name to avoid that DateTimeFormat parses
- * the month name as a pattern.
- *
- * @param date
- * The date to convert
- * @param formatStr
- * The format string that might contain MMM or MMMM
- * @param dateTimeService
- * Reference to the Vaadin DateTimeService
- * @return
- */
- public String formatDate(Date date, String formatStr) {
- /*
- * Format month names separately when locale for the DateTimeService is
- * not the same as the browser locale
- */
- formatStr = formatMonthNames(date, formatStr);
-
- // Format uses the browser locale
- DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
-
- String result = format.format(date);
-
- return result;
- }
-
- private String formatMonthNames(Date date, String formatStr) {
- if (formatStr.contains("MMMM")) {
- String monthName = getMonth(date.getMonth());
-
- if (monthName != null) {
- /*
- * Replace 4 or more M:s with the quoted month name. Also
- * concatenate generated string with any other string prepending
- * or following the MMMM pattern, i.e. 'MMMM'ta ' becomes
- * 'MONTHta ' and not 'MONTH''ta ', 'ab'MMMM becomes 'abMONTH',
- * 'x'MMMM'y' becomes 'xMONTHy'.
- */
- formatStr = formatStr.replaceAll("'([M]{4,})'", monthName);
- formatStr = formatStr.replaceAll("([M]{4,})'", "'" + monthName);
- formatStr = formatStr.replaceAll("'([M]{4,})", monthName + "'");
- formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName
- + "'");
- }
- }
-
- if (formatStr.contains("MMM")) {
-
- String monthName = getShortMonth(date.getMonth());
-
- if (monthName != null) {
- /*
- * Replace 3 or more M:s with the quoted month name. Also
- * concatenate generated string with any other string prepending
- * or following the MMM pattern, i.e. 'MMM'ta ' becomes 'MONTHta
- * ' and not 'MONTH''ta ', 'ab'MMM becomes 'abMONTH', 'x'MMM'y'
- * becomes 'xMONTHy'.
- */
- formatStr = formatStr.replaceAll("'([M]{3,})'", monthName);
- formatStr = formatStr.replaceAll("([M]{3,})'", "'" + monthName);
- formatStr = formatStr.replaceAll("'([M]{3,})", monthName + "'");
- formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName
- + "'");
- }
- }
-
- return formatStr;
- }
-
- /**
- * Replaces month names in the entered date with the name in the current
- * browser locale.
- *
- * @param enteredDate
- * Date string e.g. "5 May 2010"
- * @param formatString
- * Format string e.g. "d M yyyy"
- * @return The date string where the month names have been replaced by the
- * browser locale version
- */
- private String parseMonthName(String enteredDate, String formatString) {
- LocaleInfo browserLocale = LocaleInfo.getCurrentLocale();
- if (browserLocale.getLocaleName().equals(getLocale())) {
- // No conversion needs to be done when locales match
- return enteredDate;
- }
- String[] browserMonthNames = browserLocale.getDateTimeConstants()
- .months();
- String[] browserShortMonthNames = browserLocale.getDateTimeConstants()
- .shortMonths();
-
- if (formatString.contains("MMMM")) {
- // Full month name
- for (int i = 0; i < 12; i++) {
- enteredDate = enteredDate.replaceAll(getMonth(i),
- browserMonthNames[i]);
- }
- }
- if (formatString.contains("MMM")) {
- // Short month name
- for (int i = 0; i < 12; i++) {
- enteredDate = enteredDate.replaceAll(getShortMonth(i),
- browserShortMonthNames[i]);
- }
- }
-
- return enteredDate;
- }
-
- /**
- * Parses the given date string using the given format string and the locale
- * set in this DateTimeService instance.
- *
- * @param dateString
- * Date string e.g. "1 February 2010"
- * @param formatString
- * Format string e.g. "d MMMM yyyy"
- * @param lenient
- * true to use lenient parsing, false to use strict parsing
- * @return A Date object representing the dateString. Never returns null.
- * @throws IllegalArgumentException
- * if the parsing fails
- *
- */
- public Date parseDate(String dateString, String formatString,
- boolean lenient) throws IllegalArgumentException {
- /* DateTimeFormat uses the browser's locale */
- DateTimeFormat format = DateTimeFormat.getFormat(formatString);
-
- /*
- * Parse month names separately when locale for the DateTimeService is
- * not the same as the browser locale
- */
- dateString = parseMonthName(dateString, formatString);
-
- Date date;
-
- if (lenient) {
- date = format.parse(dateString);
- } else {
- date = format.parseStrict(dateString);
- }
-
- // Some version of Firefox sets the timestamp to 0 if parsing fails.
- if (date != null && date.getTime() == 0) {
- throw new IllegalArgumentException("Parsing of '" + dateString
- + "' failed");
- }
-
- return date;
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.Date;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.LocaleInfo;
+import com.vaadin.terminal.gwt.client.ui.VDateField;
+
+/**
+ * This class provides date/time parsing services to all components on the
+ * client side.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+@SuppressWarnings("deprecation")
+public class DateTimeService {
+
+ private String currentLocale;
+
+ private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
+ 31, 30, 31 };
+
+ /**
+ * Creates a new date time service with the application default locale.
+ */
+ public DateTimeService() {
+ currentLocale = LocaleService.getDefaultLocale();
+ }
+
+ /**
+ * Creates a new date time service with a given locale.
+ *
+ * @param locale
+ * e.g. fi, en etc.
+ * @throws LocaleNotLoadedException
+ */
+ public DateTimeService(String locale) throws LocaleNotLoadedException {
+ setLocale(locale);
+ }
+
+ public void setLocale(String locale) throws LocaleNotLoadedException {
+ if (LocaleService.getAvailableLocales().contains(locale)) {
+ currentLocale = locale;
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public String getLocale() {
+ return currentLocale;
+ }
+
+ public String getMonth(int month) {
+ try {
+ return LocaleService.getMonthNames(currentLocale)[month];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getShortMonth(int month) {
+ try {
+ return LocaleService.getShortMonthNames(currentLocale)[month];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getDay(int day) {
+ try {
+ return LocaleService.getDayNames(currentLocale)[day];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public String getShortDay(int day) {
+ try {
+ return LocaleService.getShortDayNames(currentLocale)[day];
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return null;
+ }
+ }
+
+ public int getFirstDayOfWeek() {
+ try {
+ return LocaleService.getFirstDayOfWeek(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return 0;
+ }
+ }
+
+ public boolean isTwelveHourClock() {
+ try {
+ return LocaleService.isTwelveHourClock(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return false;
+ }
+ }
+
+ public String getClockDelimeter() {
+ try {
+ return LocaleService.getClockDelimiter(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error(e);
+ return ":";
+ }
+ }
+
+ private static final String[] DEFAULT_AMPM_STRINGS = { "AM", "PM" };
+
+ public String[] getAmPmStrings() {
+ try {
+ return LocaleService.getAmPmStrings(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ // TODO can this practically even happen? Should die instead?
+ VConsole.error("Locale not loaded, using fallback : AM/PM");
+ VConsole.error(e);
+ return DEFAULT_AMPM_STRINGS;
+ }
+ }
+
+ public int getStartWeekDay(Date date) {
+ final Date dateForFirstOfThisMonth = new Date(date.getYear(),
+ date.getMonth(), 1);
+ int firstDay;
+ try {
+ firstDay = LocaleService.getFirstDayOfWeek(currentLocale);
+ } catch (final LocaleNotLoadedException e) {
+ VConsole.error("Locale not loaded, using fallback 0");
+ VConsole.error(e);
+ firstDay = 0;
+ }
+ int start = dateForFirstOfThisMonth.getDay() - firstDay;
+ if (start < 0) {
+ start = 6;
+ }
+ return start;
+ }
+
+ public static void setMilliseconds(Date date, int ms) {
+ date.setTime(date.getTime() / 1000 * 1000 + ms);
+ }
+
+ public static int getMilliseconds(Date date) {
+ if (date == null) {
+ return 0;
+ }
+
+ return (int) (date.getTime() - date.getTime() / 1000 * 1000);
+ }
+
+ public static int getNumberOfDaysInMonth(Date date) {
+ final int month = date.getMonth();
+ if (month == 1 && true == isLeapYear(date)) {
+ return 29;
+ }
+ return maxDaysInMonth[month];
+ }
+
+ public static boolean isLeapYear(Date date) {
+ // Instantiate the date for 1st March of that year
+ final Date firstMarch = new Date(date.getYear(), 2, 1);
+
+ // Go back 1 day
+ final long firstMarchTime = firstMarch.getTime();
+ final long lastDayTimeFeb = firstMarchTime - (24 * 60 * 60 * 1000); // NUM_MILLISECS_A_DAY
+
+ // Instantiate new Date with this time
+ final Date febLastDay = new Date(lastDayTimeFeb);
+
+ // Check for date in this new instance
+ return (29 == febLastDay.getDate()) ? true : false;
+ }
+
+ public static boolean isSameDay(Date d1, Date d2) {
+ return (getDayInt(d1) == getDayInt(d2));
+ }
+
+ public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,
+ int resolution) {
+ Date s;
+ Date e;
+ if (rangeStart.after(rangeEnd)) {
+ s = rangeEnd;
+ e = rangeStart;
+ } else {
+ e = rangeEnd;
+ s = rangeStart;
+ }
+ long start = s.getYear() * 10000000000l;
+ long end = e.getYear() * 10000000000l;
+ long target = date.getYear() * 10000000000l;
+
+ if (resolution == VDateField.RESOLUTION_YEAR) {
+ return (start <= target && end >= target);
+ }
+ start += s.getMonth() * 100000000l;
+ end += e.getMonth() * 100000000l;
+ target += date.getMonth() * 100000000l;
+ if (resolution == VDateField.RESOLUTION_MONTH) {
+ return (start <= target && end >= target);
+ }
+ start += s.getDate() * 1000000l;
+ end += e.getDate() * 1000000l;
+ target += date.getDate() * 1000000l;
+ if (resolution == VDateField.RESOLUTION_DAY) {
+ return (start <= target && end >= target);
+ }
+ start += s.getHours() * 10000l;
+ end += e.getHours() * 10000l;
+ target += date.getHours() * 10000l;
+ if (resolution == VDateField.RESOLUTION_HOUR) {
+ return (start <= target && end >= target);
+ }
+ start += s.getMinutes() * 100l;
+ end += e.getMinutes() * 100l;
+ target += date.getMinutes() * 100l;
+ if (resolution == VDateField.RESOLUTION_MIN) {
+ return (start <= target && end >= target);
+ }
+ start += s.getSeconds();
+ end += e.getSeconds();
+ target += date.getSeconds();
+ return (start <= target && end >= target);
+
+ }
+
+ private static int getDayInt(Date date) {
+ final int y = date.getYear();
+ final int m = date.getMonth();
+ final int d = date.getDate();
+
+ return ((y + 1900) * 10000 + m * 100 + d) * 1000000000;
+ }
+
+ /**
+ * Returns the ISO-8601 week number of the given date.
+ *
+ * @param date
+ * The date for which the week number should be resolved
+ * @return The ISO-8601 week number for {@literal date}
+ */
+ public static int getISOWeekNumber(Date date) {
+ final long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
+ int dayOfWeek = date.getDay(); // 0 == sunday
+
+ // ISO 8601 use weeks that start on monday so we use
+ // mon=1,tue=2,...sun=7;
+ if (dayOfWeek == 0) {
+ dayOfWeek = 7;
+ }
+ // Find nearest thursday (defines the week in ISO 8601). The week number
+ // for the nearest thursday is the same as for the target date.
+ int nearestThursdayDiff = 4 - dayOfWeek; // 4 is thursday
+ Date nearestThursday = new Date(date.getTime() + nearestThursdayDiff
+ * MILLISECONDS_PER_DAY);
+
+ Date firstOfJanuary = new Date(nearestThursday.getYear(), 0, 1);
+ long timeDiff = nearestThursday.getTime() - firstOfJanuary.getTime();
+ int daysSinceFirstOfJanuary = (int) (timeDiff / MILLISECONDS_PER_DAY);
+
+ int weekNumber = (daysSinceFirstOfJanuary) / 7 + 1;
+
+ return weekNumber;
+ }
+
+ /**
+ * Check if format contains the month name. If it does we manually convert
+ * it to the month name since DateTimeFormat.format always uses the current
+ * locale and will replace the month name wrong if current locale is
+ * different from the locale set for the DateField.
+ *
+ * MMMM is converted into long month name, MMM is converted into short month
+ * name. '' are added around the name to avoid that DateTimeFormat parses
+ * the month name as a pattern.
+ *
+ * @param date
+ * The date to convert
+ * @param formatStr
+ * The format string that might contain MMM or MMMM
+ * @param dateTimeService
+ * Reference to the Vaadin DateTimeService
+ * @return
+ */
+ public String formatDate(Date date, String formatStr) {
+ /*
+ * Format month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ formatStr = formatMonthNames(date, formatStr);
+
+ // Format uses the browser locale
+ DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
+
+ String result = format.format(date);
+
+ return result;
+ }
+
+ private String formatMonthNames(Date date, String formatStr) {
+ if (formatStr.contains("MMMM")) {
+ String monthName = getMonth(date.getMonth());
+
+ if (monthName != null) {
+ /*
+ * Replace 4 or more M:s with the quoted month name. Also
+ * concatenate generated string with any other string prepending
+ * or following the MMMM pattern, i.e. 'MMMM'ta ' becomes
+ * 'MONTHta ' and not 'MONTH''ta ', 'ab'MMMM becomes 'abMONTH',
+ * 'x'MMMM'y' becomes 'xMONTHy'.
+ */
+ formatStr = formatStr.replaceAll("'([M]{4,})'", monthName);
+ formatStr = formatStr.replaceAll("([M]{4,})'", "'" + monthName);
+ formatStr = formatStr.replaceAll("'([M]{4,})", monthName + "'");
+ formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ if (formatStr.contains("MMM")) {
+
+ String monthName = getShortMonth(date.getMonth());
+
+ if (monthName != null) {
+ /*
+ * Replace 3 or more M:s with the quoted month name. Also
+ * concatenate generated string with any other string prepending
+ * or following the MMM pattern, i.e. 'MMM'ta ' becomes 'MONTHta
+ * ' and not 'MONTH''ta ', 'ab'MMM becomes 'abMONTH', 'x'MMM'y'
+ * becomes 'xMONTHy'.
+ */
+ formatStr = formatStr.replaceAll("'([M]{3,})'", monthName);
+ formatStr = formatStr.replaceAll("([M]{3,})'", "'" + monthName);
+ formatStr = formatStr.replaceAll("'([M]{3,})", monthName + "'");
+ formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ return formatStr;
+ }
+
+ /**
+ * Replaces month names in the entered date with the name in the current
+ * browser locale.
+ *
+ * @param enteredDate
+ * Date string e.g. "5 May 2010"
+ * @param formatString
+ * Format string e.g. "d M yyyy"
+ * @return The date string where the month names have been replaced by the
+ * browser locale version
+ */
+ private String parseMonthName(String enteredDate, String formatString) {
+ LocaleInfo browserLocale = LocaleInfo.getCurrentLocale();
+ if (browserLocale.getLocaleName().equals(getLocale())) {
+ // No conversion needs to be done when locales match
+ return enteredDate;
+ }
+ String[] browserMonthNames = browserLocale.getDateTimeConstants()
+ .months();
+ String[] browserShortMonthNames = browserLocale.getDateTimeConstants()
+ .shortMonths();
+
+ if (formatString.contains("MMMM")) {
+ // Full month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getMonth(i),
+ browserMonthNames[i]);
+ }
+ }
+ if (formatString.contains("MMM")) {
+ // Short month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getShortMonth(i),
+ browserShortMonthNames[i]);
+ }
+ }
+
+ return enteredDate;
+ }
+
+ /**
+ * Parses the given date string using the given format string and the locale
+ * set in this DateTimeService instance.
+ *
+ * @param dateString
+ * Date string e.g. "1 February 2010"
+ * @param formatString
+ * Format string e.g. "d MMMM yyyy"
+ * @param lenient
+ * true to use lenient parsing, false to use strict parsing
+ * @return A Date object representing the dateString. Never returns null.
+ * @throws IllegalArgumentException
+ * if the parsing fails
+ *
+ */
+ public Date parseDate(String dateString, String formatString,
+ boolean lenient) throws IllegalArgumentException {
+ /* DateTimeFormat uses the browser's locale */
+ DateTimeFormat format = DateTimeFormat.getFormat(formatString);
+
+ /*
+ * Parse month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ dateString = parseMonthName(dateString, formatString);
+
+ Date date;
+
+ if (lenient) {
+ date = format.parse(dateString);
+ } else {
+ date = format.parseStrict(dateString);
+ }
+
+ // Some version of Firefox sets the timestamp to 0 if parsing fails.
+ if (date != null && date.getTime() == 0) {
+ throw new IllegalArgumentException("Parsing of '" + dateString
+ + "' failed");
+ }
+
+ return date;
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java b/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
index 4d0a9faf97..871495c79e 100644
--- a/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
+++ b/src/com/vaadin/terminal/gwt/client/LocaleNotLoadedException.java
@@ -1,13 +1,13 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-@SuppressWarnings("serial")
-public class LocaleNotLoadedException extends Exception {
-
- public LocaleNotLoadedException(String locale) {
- super(locale);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+@SuppressWarnings("serial")
+public class LocaleNotLoadedException extends Exception {
+
+ public LocaleNotLoadedException(String locale) {
+ super(locale);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/LocaleService.java b/src/com/vaadin/terminal/gwt/client/LocaleService.java
index 9ae1b04118..0f22ae705b 100644
--- a/src/com/vaadin/terminal/gwt/client/LocaleService.java
+++ b/src/com/vaadin/terminal/gwt/client/LocaleService.java
@@ -1,148 +1,148 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import com.google.gwt.core.client.JsArray;
-
-/**
- * Date / time etc. localisation service for all widgets. Caches all loaded
- * locales as JSONObjects.
- *
- * @author Vaadin Ltd.
- *
- */
-public class LocaleService {
-
- private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
- private static String defaultLocale;
-
- public static void addLocale(ValueMap valueMap) {
-
- final String key = valueMap.getString("name");
- if (cache.containsKey(key)) {
- cache.remove(key);
- }
- cache.put(key, valueMap);
- if (cache.size() == 1) {
- setDefaultLocale(key);
- }
- }
-
- public static void setDefaultLocale(String locale) {
- defaultLocale = locale;
- }
-
- public static String getDefaultLocale() {
- return defaultLocale;
- }
-
- public static Set<String> getAvailableLocales() {
- return cache.keySet();
- }
-
- public static String[] getMonthNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("mn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getShortMonthNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("smn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getDayNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("dn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getShortDayNames(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("sdn");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static int getFirstDayOfWeek(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getInt("fdow");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String getDateFormat(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("df");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static boolean isTwelveHourClock(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getBoolean("thc");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String getClockDelimiter(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getString("hmd");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
- }
-
- public static String[] getAmPmStrings(String locale)
- throws LocaleNotLoadedException {
- if (cache.containsKey(locale)) {
- final ValueMap l = cache.get(locale);
- return l.getStringArray("ampm");
- } else {
- throw new LocaleNotLoadedException(locale);
- }
-
- }
-
- public static void addLocales(JsArray<ValueMap> valueMapArray) {
- for (int i = 0; i < valueMapArray.length(); i++) {
- addLocale(valueMapArray.get(i));
-
- }
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.client.JsArray;
+
+/**
+ * Date / time etc. localisation service for all widgets. Caches all loaded
+ * locales as JSONObjects.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class LocaleService {
+
+ private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
+ private static String defaultLocale;
+
+ public static void addLocale(ValueMap valueMap) {
+
+ final String key = valueMap.getString("name");
+ if (cache.containsKey(key)) {
+ cache.remove(key);
+ }
+ cache.put(key, valueMap);
+ if (cache.size() == 1) {
+ setDefaultLocale(key);
+ }
+ }
+
+ public static void setDefaultLocale(String locale) {
+ defaultLocale = locale;
+ }
+
+ public static String getDefaultLocale() {
+ return defaultLocale;
+ }
+
+ public static Set<String> getAvailableLocales() {
+ return cache.keySet();
+ }
+
+ public static String[] getMonthNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("mn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getShortMonthNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("smn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getDayNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("dn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getShortDayNames(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("sdn");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static int getFirstDayOfWeek(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getInt("fdow");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String getDateFormat(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getString("df");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static boolean isTwelveHourClock(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getBoolean("thc");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String getClockDelimiter(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getString("hmd");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+ }
+
+ public static String[] getAmPmStrings(String locale)
+ throws LocaleNotLoadedException {
+ if (cache.containsKey(locale)) {
+ final ValueMap l = cache.get(locale);
+ return l.getStringArray("ampm");
+ } else {
+ throw new LocaleNotLoadedException(locale);
+ }
+
+ }
+
+ public static void addLocales(JsArray<ValueMap> valueMapArray) {
+ for (int i = 0; i < valueMapArray.length(); i++) {
+ addLocale(valueMapArray.get(i));
+
+ }
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index 39b44a506c..67339c984a 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -678,7 +678,7 @@ public class Util {
*/
public static VPaintableWidget getChildPaintableForElement(
ApplicationConnection client, Container parent, Element element) {
- Element rootElement = parent.getWidgetForPaintable().getElement();
+ Element rootElement = ((Widget) parent).getElement();
while (element != null && element != rootElement) {
VPaintableWidget paintable = VPaintableMap.get(client)
.getPaintable(element);
@@ -1145,4 +1145,18 @@ public class Util {
cur = cur.parentNode;
}
}-*/;
+
+ /**
+ * Checks if the given event is either a touch event or caused by the left
+ * mouse button
+ *
+ * @param event
+ * @return true if the event is a touch event or caused by the left mouse
+ * button, false otherwise
+ */
+ public static boolean isTouchEventOrLeftMouseButton(Event event) {
+ int eventType = event.getTypeInt();
+ boolean touchEvent = Util.isTouchEvent(event);
+ return touchEvent || event.getButton() == Event.BUTTON_LEFT;
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
index d9ca56be05..89e106f063 100644
--- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
+++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
@@ -1,356 +1,356 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.gwt.server.WebBrowser;
-
-/**
- * Class that parses the user agent string from the browser and provides
- * information about the browser. Used internally by {@link BrowserInfo} and
- * {@link WebBrowser}. Should not be used directly.
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- * @since 6.3
- */
-public class VBrowserDetails implements Serializable {
-
- private boolean isGecko = false;
- private boolean isWebKit = false;
- private boolean isPresto = false;
-
- private boolean isChromeFrameCapable = false;
- private boolean isChromeFrame = false;
-
- private boolean isSafari = false;
- private boolean isChrome = false;
- private boolean isFirefox = false;
- private boolean isOpera = false;
- private boolean isIE = false;
-
- private boolean isWindows = false;
- private boolean isMacOSX = false;
- private boolean isLinux = false;
-
- private float browserEngineVersion = -1;
- private int browserMajorVersion = -1;
- private int browserMinorVersion = -1;
-
- /**
- * Create an instance based on the given user agent.
- *
- * @param userAgent
- * User agent as provided by the browser.
- */
- public VBrowserDetails(String userAgent) {
- userAgent = userAgent.toLowerCase();
-
- // browser engine name
- isGecko = userAgent.indexOf("gecko") != -1
- && userAgent.indexOf("webkit") == -1;
- isWebKit = userAgent.indexOf("applewebkit") != -1;
- isPresto = userAgent.indexOf(" presto/") != -1;
-
- // browser name
- isChrome = userAgent.indexOf(" chrome/") != -1;
- isSafari = !isChrome && userAgent.indexOf("safari") != -1;
- isOpera = userAgent.indexOf("opera") != -1;
- isIE = userAgent.indexOf("msie") != -1 && !isOpera
- && (userAgent.indexOf("webtv") == -1);
- isFirefox = userAgent.indexOf(" firefox/") != -1;
-
- // chromeframe
- isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
- isChromeFrame = isChromeFrameCapable && !isChrome;
-
- // Rendering engine version
- try {
- if (isGecko) {
- int rvPos = userAgent.indexOf("rv:");
- if (rvPos >= 0) {
- String tmp = userAgent.substring(rvPos + 3);
- tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
- browserEngineVersion = Float.parseFloat(tmp);
- }
- } else if (isWebKit) {
- String tmp = userAgent
- .substring(userAgent.indexOf("webkit/") + 7);
- tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1");
- browserEngineVersion = Float.parseFloat(tmp);
- }
- } catch (Exception e) {
- // Browser engine version parsing failed
- System.err.println("Browser engine version parsing failed for: "
- + userAgent);
- }
-
- // Browser version
- try {
- if (isIE) {
- String ieVersionString = userAgent.substring(userAgent
- .indexOf("msie ") + 5);
- ieVersionString = safeSubstring(ieVersionString, 0,
- ieVersionString.indexOf(";"));
- parseVersionString(ieVersionString);
- } else if (isFirefox) {
- int i = userAgent.indexOf(" firefox/") + 9;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isChrome) {
- int i = userAgent.indexOf(" chrome/") + 8;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isSafari) {
- int i = userAgent.indexOf(" version/") + 9;
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- } else if (isOpera) {
- int i = userAgent.indexOf(" version/");
- if (i != -1) {
- // Version present in Opera 10 and newer
- i += 9; // " version/".length
- } else {
- i = userAgent.indexOf("opera/") + 6;
- }
- parseVersionString(safeSubstring(userAgent, i, i + 5));
- }
- } catch (Exception e) {
- // Browser version parsing failed
- System.err.println("Browser version parsing failed for: "
- + userAgent);
- }
-
- // Operating system
- if (userAgent.contains("windows ")) {
- isWindows = true;
- } else if (userAgent.contains("linux")) {
- isLinux = true;
- } else if (userAgent.contains("macintosh")
- || userAgent.contains("mac osx")
- || userAgent.contains("mac os x")) {
- isMacOSX = true;
- }
- }
-
- private void parseVersionString(String versionString) {
- int idx = versionString.indexOf('.');
- if (idx < 0) {
- idx = versionString.length();
- }
- browserMajorVersion = Integer.parseInt(safeSubstring(versionString, 0,
- idx));
-
- int idx2 = versionString.indexOf('.', idx + 1);
- if (idx2 < 0) {
- idx2 = versionString.length();
- }
- try {
- browserMinorVersion = Integer.parseInt(safeSubstring(versionString,
- idx + 1, idx2).replaceAll("[^0-9].*", ""));
- } catch (NumberFormatException e) {
- // leave the minor version unmodified (-1 = unknown)
- }
- }
-
- private String safeSubstring(String string, int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- beginIndex = 0;
- }
- if (endIndex < 0 || endIndex > string.length()) {
- endIndex = string.length();
- }
- return string.substring(beginIndex, endIndex);
- }
-
- /**
- * Tests if the browser is Firefox.
- *
- * @return true if it is Firefox, false otherwise
- */
- public boolean isFirefox() {
- return isFirefox;
- }
-
- /**
- * Tests if the browser is using the Gecko engine
- *
- * @return true if it is Gecko, false otherwise
- */
- public boolean isGecko() {
- return isGecko;
- }
-
- /**
- * Tests if the browser is using the WebKit engine
- *
- * @return true if it is WebKit, false otherwise
- */
- public boolean isWebKit() {
- return isWebKit;
- }
-
- /**
- * Tests if the browser is using the Presto engine
- *
- * @return true if it is Presto, false otherwise
- */
- public boolean isPresto() {
- return isPresto;
- }
-
- /**
- * Tests if the browser is Safari.
- *
- * @return true if it is Safari, false otherwise
- */
- public boolean isSafari() {
- return isSafari;
- }
-
- /**
- * Tests if the browser is Chrome.
- *
- * @return true if it is Chrome, false otherwise
- */
- public boolean isChrome() {
- return isChrome;
- }
-
- /**
- * Tests if the browser is capable of running ChromeFrame.
- *
- * @return true if it has ChromeFrame, false otherwise
- */
- public boolean isChromeFrameCapable() {
- return isChromeFrameCapable;
- }
-
- /**
- * Tests if the browser is running ChromeFrame.
- *
- * @return true if it is ChromeFrame, false otherwise
- */
- public boolean isChromeFrame() {
- return isChromeFrame;
- }
-
- /**
- * Tests if the browser is Opera.
- *
- * @return true if it is Opera, false otherwise
- */
- public boolean isOpera() {
- return isOpera;
- }
-
- /**
- * Tests if the browser is Internet Explorer.
- *
- * @return true if it is Internet Explorer, false otherwise
- */
- public boolean isIE() {
- return isIE;
- }
-
- /**
- * Returns the version of the browser engine. For WebKit this is an integer
- * e.g., 532.0. For gecko it is a float e.g., 1.8 or 1.9.
- *
- * @return The version of the browser engine
- */
- public float getBrowserEngineVersion() {
- return browserEngineVersion;
- }
-
- /**
- * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
- * 4, 8 for Internet Explorer 8.
- * <p>
- * Note that Internet Explorer 8 and newer will return the document mode so
- * IE8 rendering as IE7 will return 7.
- * </p>
- *
- * @return The major version of the browser.
- */
- public final int getBrowserMajorVersion() {
- return browserMajorVersion;
- }
-
- /**
- * Returns the browser minor version e.g., 5 for Firefox 3.5.
- *
- * @see #getBrowserMajorVersion()
- *
- * @return The minor version of the browser, or -1 if not known/parsed.
- */
- public final int getBrowserMinorVersion() {
- return browserMinorVersion;
- }
-
- /**
- * Sets the version for IE based on the documentMode. This is used to return
- * the correct the correct IE version when the version from the user agent
- * string and the value of the documentMode property do not match.
- *
- * @param documentMode
- * The current document mode
- */
- public void setIEMode(int documentMode) {
- browserMajorVersion = documentMode;
- browserMinorVersion = 0;
- }
-
- /**
- * Tests if the browser is run on Windows.
- *
- * @return true if run on Windows, false otherwise
- */
- public boolean isWindows() {
- return isWindows;
- }
-
- /**
- * Tests if the browser is run on Mac OSX.
- *
- * @return true if run on Mac OSX, false otherwise
- */
- public boolean isMacOSX() {
- return isMacOSX;
- }
-
- /**
- * Tests if the browser is run on Linux.
- *
- * @return true if run on Linux, false otherwise
- */
- public boolean isLinux() {
- return isLinux;
- }
-
- /**
- * Checks if the browser is so old that it simply won't work with a Vaadin
- * application. NOTE that the browser might still be capable of running
- * Crome Frame, so you might still want to check
- * {@link #isChromeFrameCapable()} if this returns true.
- *
- * @return true if the browser won't work, false if not the browser is
- * supported or might work
- */
- public boolean isTooOldToFunctionProperly() {
- if (isIE() && getBrowserMajorVersion() < 8) {
- return true;
- }
- if (isSafari() && getBrowserMajorVersion() < 5) {
- return true;
- }
- if (isFirefox() && getBrowserMajorVersion() < 4) {
- return true;
- }
- if (isOpera() && getBrowserMajorVersion() < 11) {
- return true;
- }
-
- return false;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import java.io.Serializable;
+
+import com.vaadin.terminal.gwt.server.WebBrowser;
+
+/**
+ * Class that parses the user agent string from the browser and provides
+ * information about the browser. Used internally by {@link BrowserInfo} and
+ * {@link WebBrowser}. Should not be used directly.
+ *
+ * @author Vaadin Ltd.
+ * @version @VERSION@
+ * @since 6.3
+ */
+public class VBrowserDetails implements Serializable {
+
+ private boolean isGecko = false;
+ private boolean isWebKit = false;
+ private boolean isPresto = false;
+
+ private boolean isChromeFrameCapable = false;
+ private boolean isChromeFrame = false;
+
+ private boolean isSafari = false;
+ private boolean isChrome = false;
+ private boolean isFirefox = false;
+ private boolean isOpera = false;
+ private boolean isIE = false;
+
+ private boolean isWindows = false;
+ private boolean isMacOSX = false;
+ private boolean isLinux = false;
+
+ private float browserEngineVersion = -1;
+ private int browserMajorVersion = -1;
+ private int browserMinorVersion = -1;
+
+ /**
+ * Create an instance based on the given user agent.
+ *
+ * @param userAgent
+ * User agent as provided by the browser.
+ */
+ public VBrowserDetails(String userAgent) {
+ userAgent = userAgent.toLowerCase();
+
+ // browser engine name
+ isGecko = userAgent.indexOf("gecko") != -1
+ && userAgent.indexOf("webkit") == -1;
+ isWebKit = userAgent.indexOf("applewebkit") != -1;
+ isPresto = userAgent.indexOf(" presto/") != -1;
+
+ // browser name
+ isChrome = userAgent.indexOf(" chrome/") != -1;
+ isSafari = !isChrome && userAgent.indexOf("safari") != -1;
+ isOpera = userAgent.indexOf("opera") != -1;
+ isIE = userAgent.indexOf("msie") != -1 && !isOpera
+ && (userAgent.indexOf("webtv") == -1);
+ isFirefox = userAgent.indexOf(" firefox/") != -1;
+
+ // chromeframe
+ isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
+ isChromeFrame = isChromeFrameCapable && !isChrome;
+
+ // Rendering engine version
+ try {
+ if (isGecko) {
+ int rvPos = userAgent.indexOf("rv:");
+ if (rvPos >= 0) {
+ String tmp = userAgent.substring(rvPos + 3);
+ tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
+ browserEngineVersion = Float.parseFloat(tmp);
+ }
+ } else if (isWebKit) {
+ String tmp = userAgent
+ .substring(userAgent.indexOf("webkit/") + 7);
+ tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1");
+ browserEngineVersion = Float.parseFloat(tmp);
+ }
+ } catch (Exception e) {
+ // Browser engine version parsing failed
+ System.err.println("Browser engine version parsing failed for: "
+ + userAgent);
+ }
+
+ // Browser version
+ try {
+ if (isIE) {
+ String ieVersionString = userAgent.substring(userAgent
+ .indexOf("msie ") + 5);
+ ieVersionString = safeSubstring(ieVersionString, 0,
+ ieVersionString.indexOf(";"));
+ parseVersionString(ieVersionString);
+ } else if (isFirefox) {
+ int i = userAgent.indexOf(" firefox/") + 9;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isChrome) {
+ int i = userAgent.indexOf(" chrome/") + 8;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isSafari) {
+ int i = userAgent.indexOf(" version/") + 9;
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ } else if (isOpera) {
+ int i = userAgent.indexOf(" version/");
+ if (i != -1) {
+ // Version present in Opera 10 and newer
+ i += 9; // " version/".length
+ } else {
+ i = userAgent.indexOf("opera/") + 6;
+ }
+ parseVersionString(safeSubstring(userAgent, i, i + 5));
+ }
+ } catch (Exception e) {
+ // Browser version parsing failed
+ System.err.println("Browser version parsing failed for: "
+ + userAgent);
+ }
+
+ // Operating system
+ if (userAgent.contains("windows ")) {
+ isWindows = true;
+ } else if (userAgent.contains("linux")) {
+ isLinux = true;
+ } else if (userAgent.contains("macintosh")
+ || userAgent.contains("mac osx")
+ || userAgent.contains("mac os x")) {
+ isMacOSX = true;
+ }
+ }
+
+ private void parseVersionString(String versionString) {
+ int idx = versionString.indexOf('.');
+ if (idx < 0) {
+ idx = versionString.length();
+ }
+ browserMajorVersion = Integer.parseInt(safeSubstring(versionString, 0,
+ idx));
+
+ int idx2 = versionString.indexOf('.', idx + 1);
+ if (idx2 < 0) {
+ idx2 = versionString.length();
+ }
+ try {
+ browserMinorVersion = Integer.parseInt(safeSubstring(versionString,
+ idx + 1, idx2).replaceAll("[^0-9].*", ""));
+ } catch (NumberFormatException e) {
+ // leave the minor version unmodified (-1 = unknown)
+ }
+ }
+
+ private String safeSubstring(String string, int beginIndex, int endIndex) {
+ if (beginIndex < 0) {
+ beginIndex = 0;
+ }
+ if (endIndex < 0 || endIndex > string.length()) {
+ endIndex = string.length();
+ }
+ return string.substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Tests if the browser is Firefox.
+ *
+ * @return true if it is Firefox, false otherwise
+ */
+ public boolean isFirefox() {
+ return isFirefox;
+ }
+
+ /**
+ * Tests if the browser is using the Gecko engine
+ *
+ * @return true if it is Gecko, false otherwise
+ */
+ public boolean isGecko() {
+ return isGecko;
+ }
+
+ /**
+ * Tests if the browser is using the WebKit engine
+ *
+ * @return true if it is WebKit, false otherwise
+ */
+ public boolean isWebKit() {
+ return isWebKit;
+ }
+
+ /**
+ * Tests if the browser is using the Presto engine
+ *
+ * @return true if it is Presto, false otherwise
+ */
+ public boolean isPresto() {
+ return isPresto;
+ }
+
+ /**
+ * Tests if the browser is Safari.
+ *
+ * @return true if it is Safari, false otherwise
+ */
+ public boolean isSafari() {
+ return isSafari;
+ }
+
+ /**
+ * Tests if the browser is Chrome.
+ *
+ * @return true if it is Chrome, false otherwise
+ */
+ public boolean isChrome() {
+ return isChrome;
+ }
+
+ /**
+ * Tests if the browser is capable of running ChromeFrame.
+ *
+ * @return true if it has ChromeFrame, false otherwise
+ */
+ public boolean isChromeFrameCapable() {
+ return isChromeFrameCapable;
+ }
+
+ /**
+ * Tests if the browser is running ChromeFrame.
+ *
+ * @return true if it is ChromeFrame, false otherwise
+ */
+ public boolean isChromeFrame() {
+ return isChromeFrame;
+ }
+
+ /**
+ * Tests if the browser is Opera.
+ *
+ * @return true if it is Opera, false otherwise
+ */
+ public boolean isOpera() {
+ return isOpera;
+ }
+
+ /**
+ * Tests if the browser is Internet Explorer.
+ *
+ * @return true if it is Internet Explorer, false otherwise
+ */
+ public boolean isIE() {
+ return isIE;
+ }
+
+ /**
+ * Returns the version of the browser engine. For WebKit this is an integer
+ * e.g., 532.0. For gecko it is a float e.g., 1.8 or 1.9.
+ *
+ * @return The version of the browser engine
+ */
+ public float getBrowserEngineVersion() {
+ return browserEngineVersion;
+ }
+
+ /**
+ * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
+ * 4, 8 for Internet Explorer 8.
+ * <p>
+ * Note that Internet Explorer 8 and newer will return the document mode so
+ * IE8 rendering as IE7 will return 7.
+ * </p>
+ *
+ * @return The major version of the browser.
+ */
+ public final int getBrowserMajorVersion() {
+ return browserMajorVersion;
+ }
+
+ /**
+ * Returns the browser minor version e.g., 5 for Firefox 3.5.
+ *
+ * @see #getBrowserMajorVersion()
+ *
+ * @return The minor version of the browser, or -1 if not known/parsed.
+ */
+ public final int getBrowserMinorVersion() {
+ return browserMinorVersion;
+ }
+
+ /**
+ * Sets the version for IE based on the documentMode. This is used to return
+ * the correct the correct IE version when the version from the user agent
+ * string and the value of the documentMode property do not match.
+ *
+ * @param documentMode
+ * The current document mode
+ */
+ public void setIEMode(int documentMode) {
+ browserMajorVersion = documentMode;
+ browserMinorVersion = 0;
+ }
+
+ /**
+ * Tests if the browser is run on Windows.
+ *
+ * @return true if run on Windows, false otherwise
+ */
+ public boolean isWindows() {
+ return isWindows;
+ }
+
+ /**
+ * Tests if the browser is run on Mac OSX.
+ *
+ * @return true if run on Mac OSX, false otherwise
+ */
+ public boolean isMacOSX() {
+ return isMacOSX;
+ }
+
+ /**
+ * Tests if the browser is run on Linux.
+ *
+ * @return true if run on Linux, false otherwise
+ */
+ public boolean isLinux() {
+ return isLinux;
+ }
+
+ /**
+ * Checks if the browser is so old that it simply won't work with a Vaadin
+ * application. NOTE that the browser might still be capable of running
+ * Crome Frame, so you might still want to check
+ * {@link #isChromeFrameCapable()} if this returns true.
+ *
+ * @return true if the browser won't work, false if not the browser is
+ * supported or might work
+ */
+ public boolean isTooOldToFunctionProperly() {
+ if (isIE() && getBrowserMajorVersion() < 8) {
+ return true;
+ }
+ if (isSafari() && getBrowserMajorVersion() < 5) {
+ return true;
+ }
+ if (isFirefox() && getBrowserMajorVersion() < 4) {
+ return true;
+ }
+ if (isOpera() && getBrowserMajorVersion() < 11) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
index fdaf944b9f..76c312676a 100644
--- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
+++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
@@ -91,7 +91,7 @@ public class VDebugConsole extends VOverlay implements Console {
for (ApplicationConnection a : ApplicationConfiguration
.getRunningApplications()) {
VPaintableWidget paintable = Util.getPaintableForElement(a,
- a.getView(), eventTarget);
+ a.getView().getWidgetForPaintable(), eventTarget);
if (paintable == null) {
paintable = Util.getPaintableForElement(a,
RootPanel.get(), eventTarget);
@@ -120,7 +120,7 @@ public class VDebugConsole extends VOverlay implements Console {
for (ApplicationConnection a : ApplicationConfiguration
.getRunningApplications()) {
VPaintableWidget paintable = Util.getPaintableForElement(a,
- a.getView(), eventTarget);
+ a.getView().getWidgetForPaintable(), eventTarget);
if (paintable == null) {
paintable = Util.getPaintableForElement(a,
RootPanel.get(), eventTarget);
@@ -534,8 +534,7 @@ public class VDebugConsole extends VOverlay implements Console {
emphasisInUi.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if (paintable != null) {
- Element element2 = layout.getWidgetForPaintable()
- .getElement();
+ Element element2 = ((Widget) layout).getElement();
Widget.setStyleName(element2, "invalidlayout",
emphasisInUi.getValue());
}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintable.java b/src/com/vaadin/terminal/gwt/client/VPaintable.java
index d85c6d33e2..032058b8d5 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintable.java
@@ -1,74 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-/**
- * Interface implemented by all client side classes that can be communicate with
- * the server. Classes implementing this interface are initialized by the
- * framework when needed and have the ability to communicate with the server.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public interface VPaintable {
- /**
- * TODO
- *
- * @param uidl
- * @param client
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
-
- // /**
- // * Returns the id for this VPaintable. This must always be what has been
- // set
- // * using {@link #setId(String)}.
- // *
- // * @return The id for the VPaintable.
- // */
- // public String getId();
- //
- // /**
- // * Sets the id for the VPaintable. This method is called once by the
- // * framework when the VPaintable is initialized and should never be called
- // * otherwise.
- // * <p>
- // * The VPaintable id is used to map the server and the client paintables
- // * together. It is unique in this root and assigned by the framework.
- // * </p>
- // *
- // * @param id
- // * The id of the paintable.
- // */
- // public void setId(String id);
-
- /**
- * Gets ApplicationConnection instance that created this VPaintable.
- *
- * @return The ApplicationConnection as set by
- * {@link #setConnection(ApplicationConnection)}
- */
- // public ApplicationConnection getConnection();
-
- /**
- * Sets the reference to ApplicationConnection. This method is called by the
- * framework when the VPaintable is created and should never be called
- * otherwise.
- *
- * @param connection
- * The ApplicationConnection that created this VPaintable
- */
- // public void setConnection(ApplicationConnection connection);
-
- /**
- * Tests whether the component is enabled or not. A user can not interact
- * with disabled components. Disabled components are rendered in a style
- * that indicates the status, usually in gray color. Children of a disabled
- * component are also disabled.
- *
- * @return true if the component is enabled, false otherwise
- */
- // public boolean isEnabled();
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+/**
+ * Interface implemented by all client side classes that can be communicate with
+ * the server. Classes implementing this interface are initialized by the
+ * framework when needed and have the ability to communicate with the server.
+ *
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.0
+ */
+public interface VPaintable {
+ /**
+ * TODO
+ *
+ * @param uidl
+ * @param client
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
+
+ /**
+ * Returns the id for this VPaintable. This must always be what has been set
+ * using {@link #setId(String)}.
+ *
+ * @return The id for the VPaintable.
+ */
+ public String getId();
+
+ /**
+ * Sets the id for the VPaintable. This method is called once by the
+ * framework when the VPaintable is initialized and should never be called
+ * otherwise.
+ * <p>
+ * The VPaintable id is used to map the server and the client paintables
+ * together. It is unique in this root and assigned by the framework.
+ * </p>
+ *
+ * @param id
+ * The id of the paintable.
+ */
+ public void setId(String id);
+
+ /**
+ * Gets ApplicationConnection instance that created this VPaintable.
+ *
+ * @return The ApplicationConnection as set by
+ * {@link #setConnection(ApplicationConnection)}
+ */
+ public ApplicationConnection getConnection();
+
+ /**
+ * Sets the reference to ApplicationConnection. This method is called by the
+ * framework when the VPaintable is created and should never be called
+ * otherwise.
+ *
+ * @param connection
+ * The ApplicationConnection that created this VPaintable
+ */
+ public void setConnection(ApplicationConnection connection);
+
+ /**
+ * Tests whether the component is enabled or not. A user can not interact
+ * with disabled components. Disabled components are rendered in a style
+ * that indicates the status, usually in gray color. Children of a disabled
+ * component are also disabled.
+ *
+ * @return true if the component is enabled, false otherwise
+ */
+ // public boolean isEnabled();
+
+ /**
+ *
+ * Called once when the connection and id has been set
+ */
+ public void init();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
index 31aec87aa0..309c527e7a 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
@@ -1,408 +1,408 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import java.util.ArrayList;
-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.MeasureManager.MeasuredSize;
-import com.vaadin.terminal.gwt.client.RenderInformation.Size;
-
-public class VPaintableMap {
-
- private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();
- private Map<VPaintable, String> paintableToId = new HashMap<VPaintable, String>();
-
- public static VPaintableMap get(ApplicationConnection applicationConnection) {
- return applicationConnection.getPaintableMap();
- }
-
- @Deprecated
- private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
- .create();
-
- private Set<String> unregistryBag = new HashSet<String>();
-
- /**
- * Returns a Paintable by its paintable id
- *
- * @param id
- * The Paintable id
- */
- public VPaintable getPaintable(String pid) {
- return idToPaintable.get(pid);
- }
-
- /**
- * Returns a Paintable element by its root element
- *
- * @param element
- * Root element of the paintable
- */
- public VPaintableWidget getPaintable(Element element) {
- return (VPaintableWidget) getPaintable(getPid(element));
- }
-
- /**
- * FIXME: What does this even do and why?
- *
- * @param pid
- * @return
- */
- public boolean isDragAndDropPaintable(String pid) {
- return (pid.startsWith("DD"));
- }
-
- /**
- * Checks if a paintable with the given paintable id has been registered.
- *
- * @param pid
- * The paintable id to check for
- * @return true if a paintable has been registered with the given paintable
- * id, false otherwise
- */
- public boolean hasPaintable(String pid) {
- return idToPaintable.containsKey(pid);
- }
-
- /**
- * Removes all registered paintable ids
- */
- public void clear() {
- idToPaintable.clear();
- paintableToId.clear();
- idToComponentDetail.clear();
- }
-
- @Deprecated
- public Widget getWidget(VPaintableWidget paintable) {
- return paintable.getWidgetForPaintable();
- }
-
- @Deprecated
- public VPaintableWidget getPaintable(Widget widget) {
- return getPaintable(widget.getElement());
- }
-
- public void registerPaintable(String pid, VPaintable paintable) {
- ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
- idToComponentDetail.put(pid, componentDetail);
- idToPaintable.put(pid, paintable);
- paintableToId.put(paintable, pid);
- if (paintable instanceof VPaintableWidget) {
- VPaintableWidget pw = (VPaintableWidget) paintable;
- setPid(pw.getWidgetForPaintable().getElement(), pid);
- }
- }
-
- private native void setPid(Element el, String pid)
- /*-{
- el.tkPid = pid;
- }-*/;
-
- /**
- * Gets the paintableId for a specific paintable.
- * <p>
- * The paintableId is used in the UIDL to identify a specific widget
- * instance, effectively linking the widget with it's server side Component.
- * </p>
- *
- * @param paintable
- * the paintable who's id is needed
- * @return the id for the given paintable or null if the paintable could not
- * be found
- */
- public String getPid(VPaintable paintable) {
- if (paintable == null) {
- return null;
- }
- return paintableToId.get(paintable);
- }
-
- @Deprecated
- public String getPid(Widget widget) {
- return getPid(widget.getElement());
- }
-
- /**
- * Gets the paintableId using a DOM element - the element should be the main
- * element for a paintable otherwise no id will be found. Use
- * {@link #getPid(Paintable)} instead whenever possible.
- *
- * @see #getPid(Paintable)
- * @param el
- * element of the paintable whose pid is desired
- * @return the pid of the element's paintable, if it's a paintable
- */
- native String getPid(Element el)
- /*-{
- return el.tkPid;
- }-*/;
-
- /**
- * Gets the main element for the paintable with the given id. The revers of
- * {@link #getPid(Element)}.
- *
- * @param pid
- * the pid of the widget whose element is desired
- * @return the element for the paintable corresponding to the pid
- */
- public Element getElement(String pid) {
- VPaintable p = getPaintable(pid);
- if (p instanceof VPaintableWidget) {
- return ((VPaintableWidget) p).getWidgetForPaintable().getElement();
- }
-
- return null;
- }
-
- /**
- * Unregisters the given paintable; always use after removing a paintable.
- * This method does not remove the paintable from the DOM, but marks the
- * paintable so that ApplicationConnection may clean up its references to
- * it. Removing the widget from DOM is component containers responsibility.
- *
- * @param p
- * the paintable to remove
- */
- public void unregisterPaintable(VPaintable p) {
-
- // add to unregistry que
-
- if (p == null) {
- VConsole.error("WARN: Trying to unregister null paintable");
- return;
- }
- String id = getPid(p);
- Widget widget = null;
- if (p instanceof VPaintableWidget) {
- widget = ((VPaintableWidget) p).getWidgetForPaintable();
- }
-
- if (id == null) {
- /*
- * Uncomment the following to debug unregistring components. No
- * paintables with null id should end here. At least one exception
- * is our VScrollTableRow, that is hacked to fake it self as a
- * Paintable to build support for sizing easier.
- */
- // if (!(p instanceof VScrollTableRow)) {
- // VConsole.log("Trying to unregister Paintable not created by Application Connection.");
- // }
- } else {
- unregistryBag.add(id);
- }
- if (widget != null && widget instanceof HasWidgets) {
- unregisterChildPaintables((HasWidgets) widget);
- }
-
- }
-
- public VPaintableWidget[] getRegisteredPaintableWidgets() {
- ArrayList<VPaintableWidget> result = new ArrayList<VPaintableWidget>();
-
- for (VPaintable paintable : getPaintables()) {
- if (paintable instanceof VPaintableWidget) {
- VPaintableWidget paintableWidget = (VPaintableWidget) paintable;
- if (!unregistryBag.contains(getPid(paintable))) {
- result.add(paintableWidget);
- }
- }
- }
-
- return result.toArray(new VPaintableWidget[result.size()]);
- }
-
- 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<Widget> it = container.iterator();
- while (it.hasNext()) {
- final Widget w = it.next();
- VPaintableWidget p = getPaintable(w);
- if (p != null) {
- // This will unregister the paintable and all its children
- unregisterPaintable(p);
- } else if (w instanceof HasWidgets) {
- // For normal widget containers, unregister the children
- unregisterChildPaintables((HasWidgets) w);
- }
- }
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param pid
- * @param uidl
- */
- @Deprecated
- public void registerEventListenersFromUIDL(String pid, UIDL uidl) {
- ComponentDetail cd = idToComponentDetail.get(pid);
- if (cd == null) {
- throw new IllegalArgumentException("Pid must not be null");
- }
-
- cd.registerEventListenersFromUIDL(uidl);
-
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public Size getOffsetSize(VPaintableWidget paintable) {
- return getComponentDetail(paintable).getOffsetSize();
- }
-
- /**
- * FIXME: Should not be here
- *
- * @param paintable
- * @return
- */
- @Deprecated
- public void setOffsetSize(VPaintableWidget paintable, Size newSize) {
- getComponentDetail(paintable).setOffsetSize(newSize);
- }
-
- 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;
- }
-
- /**
- * FIXME: Should not be here
- */
- @Deprecated
- public MeasuredSize getMeasuredSize(VPaintableWidget paintable) {
- ComponentDetail componentDetail = getComponentDetail(paintable);
- if (componentDetail == null) {
- return null;
- }
-
- return componentDetail.getMeasuredSize();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import java.util.ArrayList;
+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.MeasureManager.MeasuredSize;
+import com.vaadin.terminal.gwt.client.RenderInformation.Size;
+
+public class VPaintableMap {
+
+ private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();
+ private Map<VPaintable, String> paintableToId = new HashMap<VPaintable, String>();
+
+ public static VPaintableMap get(ApplicationConnection applicationConnection) {
+ return applicationConnection.getPaintableMap();
+ }
+
+ @Deprecated
+ private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
+ .create();
+
+ private Set<String> unregistryBag = new HashSet<String>();
+
+ /**
+ * Returns a Paintable by its paintable id
+ *
+ * @param id
+ * The Paintable id
+ */
+ public VPaintable getPaintable(String pid) {
+ return idToPaintable.get(pid);
+ }
+
+ /**
+ * Returns a Paintable element by its root element
+ *
+ * @param element
+ * Root element of the paintable
+ */
+ public VPaintableWidget getPaintable(Element element) {
+ return (VPaintableWidget) getPaintable(getPid(element));
+ }
+
+ /**
+ * FIXME: What does this even do and why?
+ *
+ * @param pid
+ * @return
+ */
+ public boolean isDragAndDropPaintable(String pid) {
+ return (pid.startsWith("DD"));
+ }
+
+ /**
+ * Checks if a paintable with the given paintable id has been registered.
+ *
+ * @param pid
+ * The paintable id to check for
+ * @return true if a paintable has been registered with the given paintable
+ * id, false otherwise
+ */
+ public boolean hasPaintable(String pid) {
+ return idToPaintable.containsKey(pid);
+ }
+
+ /**
+ * Removes all registered paintable ids
+ */
+ public void clear() {
+ idToPaintable.clear();
+ paintableToId.clear();
+ idToComponentDetail.clear();
+ }
+
+ @Deprecated
+ public Widget getWidget(VPaintableWidget paintable) {
+ return paintable.getWidgetForPaintable();
+ }
+
+ @Deprecated
+ public VPaintableWidget getPaintable(Widget widget) {
+ return getPaintable(widget.getElement());
+ }
+
+ public void registerPaintable(String pid, VPaintable paintable) {
+ ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
+ idToComponentDetail.put(pid, componentDetail);
+ idToPaintable.put(pid, paintable);
+ paintableToId.put(paintable, pid);
+ if (paintable instanceof VPaintableWidget) {
+ VPaintableWidget pw = (VPaintableWidget) paintable;
+ setPid(pw.getWidgetForPaintable().getElement(), pid);
+ }
+ }
+
+ private native void setPid(Element el, String pid)
+ /*-{
+ el.tkPid = pid;
+ }-*/;
+
+ /**
+ * Gets the paintableId for a specific paintable.
+ * <p>
+ * The paintableId is used in the UIDL to identify a specific widget
+ * instance, effectively linking the widget with it's server side Component.
+ * </p>
+ *
+ * @param paintable
+ * the paintable who's id is needed
+ * @return the id for the given paintable or null if the paintable could not
+ * be found
+ */
+ public String getPid(VPaintable paintable) {
+ if (paintable == null) {
+ return null;
+ }
+ return paintableToId.get(paintable);
+ }
+
+ @Deprecated
+ public String getPid(Widget widget) {
+ return getPid(widget.getElement());
+ }
+
+ /**
+ * Gets the paintableId using a DOM element - the element should be the main
+ * element for a paintable otherwise no id will be found. Use
+ * {@link #getPid(Paintable)} instead whenever possible.
+ *
+ * @see #getPid(Paintable)
+ * @param el
+ * element of the paintable whose pid is desired
+ * @return the pid of the element's paintable, if it's a paintable
+ */
+ native String getPid(Element el)
+ /*-{
+ return el.tkPid;
+ }-*/;
+
+ /**
+ * Gets the main element for the paintable with the given id. The revers of
+ * {@link #getPid(Element)}.
+ *
+ * @param pid
+ * the pid of the widget whose element is desired
+ * @return the element for the paintable corresponding to the pid
+ */
+ public Element getElement(String pid) {
+ VPaintable p = getPaintable(pid);
+ if (p instanceof VPaintableWidget) {
+ return ((VPaintableWidget) p).getWidgetForPaintable().getElement();
+ }
+
+ return null;
+ }
+
+ /**
+ * Unregisters the given paintable; always use after removing a paintable.
+ * This method does not remove the paintable from the DOM, but marks the
+ * paintable so that ApplicationConnection may clean up its references to
+ * it. Removing the widget from DOM is component containers responsibility.
+ *
+ * @param p
+ * the paintable to remove
+ */
+ public void unregisterPaintable(VPaintable p) {
+
+ // add to unregistry que
+
+ if (p == null) {
+ VConsole.error("WARN: Trying to unregister null paintable");
+ return;
+ }
+ String id = getPid(p);
+ Widget widget = null;
+ if (p instanceof VPaintableWidget) {
+ widget = ((VPaintableWidget) p).getWidgetForPaintable();
+ }
+
+ if (id == null) {
+ /*
+ * Uncomment the following to debug unregistring components. No
+ * paintables with null id should end here. At least one exception
+ * is our VScrollTableRow, that is hacked to fake it self as a
+ * Paintable to build support for sizing easier.
+ */
+ // if (!(p instanceof VScrollTableRow)) {
+ // VConsole.log("Trying to unregister Paintable not created by Application Connection.");
+ // }
+ } else {
+ unregistryBag.add(id);
+ }
+ if (widget != null && widget instanceof HasWidgets) {
+ unregisterChildPaintables((HasWidgets) widget);
+ }
+
+ }
+
+ public VPaintableWidget[] getRegisteredPaintableWidgets() {
+ ArrayList<VPaintableWidget> result = new ArrayList<VPaintableWidget>();
+
+ for (VPaintable paintable : getPaintables()) {
+ if (paintable instanceof VPaintableWidget) {
+ VPaintableWidget paintableWidget = (VPaintableWidget) paintable;
+ if (!unregistryBag.contains(getPid(paintable))) {
+ result.add(paintableWidget);
+ }
+ }
+ }
+
+ return result.toArray(new VPaintableWidget[result.size()]);
+ }
+
+ 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<Widget> it = container.iterator();
+ while (it.hasNext()) {
+ final Widget w = it.next();
+ VPaintableWidget p = getPaintable(w);
+ if (p != null) {
+ // This will unregister the paintable and all its children
+ unregisterPaintable(p);
+ } else if (w instanceof HasWidgets) {
+ // For normal widget containers, unregister the children
+ unregisterChildPaintables((HasWidgets) w);
+ }
+ }
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param pid
+ * @param uidl
+ */
+ @Deprecated
+ public void registerEventListenersFromUIDL(String pid, UIDL uidl) {
+ ComponentDetail cd = idToComponentDetail.get(pid);
+ if (cd == null) {
+ throw new IllegalArgumentException("Pid must not be null");
+ }
+
+ cd.registerEventListenersFromUIDL(uidl);
+
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public Size getOffsetSize(VPaintableWidget paintable) {
+ return getComponentDetail(paintable).getOffsetSize();
+ }
+
+ /**
+ * FIXME: Should not be here
+ *
+ * @param paintable
+ * @return
+ */
+ @Deprecated
+ public void setOffsetSize(VPaintableWidget paintable, Size newSize) {
+ getComponentDetail(paintable).setOffsetSize(newSize);
+ }
+
+ 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;
+ }
+
+ /**
+ * FIXME: Should not be here
+ */
+ @Deprecated
+ public MeasuredSize getMeasuredSize(VPaintableWidget paintable) {
+ ComponentDetail componentDetail = getComponentDetail(paintable);
+ if (componentDetail == null) {
+ return null;
+ }
+
+ return componentDetail.getMeasuredSize();
+ }
+
+} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
index 2f0cae1cc1..4b8720b132 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
@@ -21,4 +21,11 @@ public interface VPaintableWidget extends VPaintable {
*/
public Widget getWidgetForPaintable();
+ /**
+ * Returns the parent {@link VPaintableWidgetContainer}
+ *
+ * @return
+ */
+ // FIXME: Rename to getParent()
+ public VPaintableWidgetContainer getParent();
}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableWidgetContainer.java b/src/com/vaadin/terminal/gwt/client/VPaintableWidgetContainer.java
new file mode 100644
index 0000000000..baf266546d
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidgetContainer.java
@@ -0,0 +1,45 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.HasWidgets;
+
+/**
+ * An interface used by client-side paintables whose widget is a component
+ * container (implements {@link HasWidgets}).
+ */
+public interface VPaintableWidgetContainer extends VPaintableWidget {
+
+ /**
+ * Update child components caption, description and error message.
+ *
+ * <p>
+ * Each component is responsible for maintaining its caption, description
+ * and error message. In most cases components doesn't want to do that and
+ * those elements reside outside of the component. Because of this layouts
+ * must provide service for it's childen to show those elements for them.
+ * </p>
+ *
+ * @param paintable
+ * Child component for which service is requested.
+ * @param uidl
+ * UIDL of the child component.
+ */
+ void updateCaption(VPaintableWidget paintable, UIDL uidl);
+
+ /**
+ * Returns the children for this paintable.
+ * <p>
+ * The children for this paintable are defined as all
+ * {@link VPaintableWidget}s whose parent is this
+ * {@link VPaintableWidgetContainer}.
+ * </p>
+ *
+ * @return A collection of children for this paintable. An empty collection
+ * if there are no children.
+ */
+ // public Collection<VPaintableWidget> getChildren();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java b/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
index 6bef0c409c..65d5d6a9a2 100644
--- a/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
+++ b/src/com/vaadin/terminal/gwt/client/VSchedulerImpl.java
@@ -1,32 +1,32 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import com.google.gwt.core.client.impl.SchedulerImpl;
-
-public class VSchedulerImpl extends SchedulerImpl {
-
- /**
- * Keeps track of if there are deferred commands that are being executed. 0
- * == no deferred commands currently in progress, > 0 otherwise.
- */
- private int deferredCommandTrackers = 0;
-
- @Override
- public void scheduleDeferred(ScheduledCommand cmd) {
- deferredCommandTrackers++;
- super.scheduleDeferred(cmd);
- super.scheduleDeferred(new ScheduledCommand() {
-
- public void execute() {
- deferredCommandTrackers--;
- }
- });
- }
-
- public boolean hasWorkQueued() {
- boolean hasWorkQueued = (deferredCommandTrackers != 0);
- return hasWorkQueued;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.core.client.impl.SchedulerImpl;
+
+public class VSchedulerImpl extends SchedulerImpl {
+
+ /**
+ * Keeps track of if there are deferred commands that are being executed. 0
+ * == no deferred commands currently in progress, > 0 otherwise.
+ */
+ private int deferredCommandTrackers = 0;
+
+ @Override
+ public void scheduleDeferred(ScheduledCommand cmd) {
+ deferredCommandTrackers++;
+ super.scheduleDeferred(cmd);
+ super.scheduleDeferred(new ScheduledCommand() {
+
+ public void execute() {
+ deferredCommandTrackers--;
+ }
+ });
+ }
+
+ public boolean hasWorkQueued() {
+ boolean hasWorkQueued = (deferredCommandTrackers != 0);
+ return hasWorkQueued;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
index bcf7f14a9d..e63bcf98d9 100644
--- a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
+++ b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java
@@ -24,7 +24,7 @@ import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
+import com.vaadin.terminal.gwt.client.ui.VUnknownComponentPaintable;
import com.vaadin.terminal.gwt.client.ui.VWindow;
public class VUIDLBrowser extends SimpleTree {
@@ -99,7 +99,7 @@ public class VUIDLBrowser extends SimpleTree {
String name) {
Class<? extends VPaintableWidget> widgetClassByDecodedTag = conf
.getWidgetClassByEncodedTag(name);
- if (widgetClassByDecodedTag == VUnknownComponent.class) {
+ if (widgetClassByDecodedTag == VUnknownComponentPaintable.class) {
return conf.getUnknownServerClassNameByEncodedTagName(name)
+ "(NO CLIENT IMPLEMENTATION FOUND)";
} else {
diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java
index b78091950b..390d79ce17 100644
--- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java
+++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java
@@ -6,13 +6,9 @@ package com.vaadin.terminal.gwt.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
-import com.vaadin.terminal.gwt.client.ui.VListSelect;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
-import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
-import com.vaadin.terminal.gwt.client.ui.VView;
-import com.vaadin.terminal.gwt.client.ui.VWindow;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelectPaintable;
+import com.vaadin.terminal.gwt.client.ui.VListSelectPaintable;
+import com.vaadin.terminal.gwt.client.ui.VUnknownComponentPaintable;
public class WidgetSet {
@@ -25,7 +21,8 @@ public class WidgetSet {
/**
* Create an uninitialized component that best matches given UIDL. The
- * component must be a {@link Widget} that implements {@link VPaintableWidget}.
+ * component must be a {@link Widget} that implements
+ * {@link VPaintableWidget}.
*
* @param uidl
* UIDL to be painted with returned component.
@@ -35,7 +32,8 @@ public class WidgetSet {
* @return New uninitialized and unregistered component that can paint given
* UIDL.
*/
- public VPaintableWidget createWidget(UIDL uidl, ApplicationConfiguration conf) {
+ public VPaintableWidget createWidget(UIDL uidl,
+ ApplicationConfiguration conf) {
/*
* Yes, this (including the generated code in WidgetMap) may look very
* odd code, but due the nature of GWT, we cannot do this any cleaner.
@@ -46,16 +44,15 @@ public class WidgetSet {
* TODO should try to get rid of these exceptions here
*/
- final Class<? extends VPaintableWidget> classType = resolveWidgetType(uidl,
- conf);
- if (classType == null || classType == VUnknownComponent.class) {
+ final Class<? extends VPaintableWidget> classType = resolveWidgetType(
+ uidl, conf);
+ if (classType == null || classType == VUnknownComponentPaintable.class) {
String serverSideName = conf
.getUnknownServerClassNameByEncodedTagName(uidl.getTag());
- VUnknownComponent c = GWT.create(VUnknownComponent.class);
+ VUnknownComponentPaintable c = GWT
+ .create(VUnknownComponentPaintable.class);
c.setServerSideClassName(serverSideName);
return c;
- } else if (VWindow.class == classType) {
- return GWT.create(VWindow.class);
} else {
/*
* let the auto generated code instantiate this type
@@ -74,20 +71,14 @@ public class WidgetSet {
// add our historical quirks
- if (widgetClass == VView.class && uidl.hasAttribute("sub")) {
- return VWindow.class;
- } else if (widgetClass == VFilterSelect.class) {
+ if (widgetClass == VFilterSelectPaintable.class) {
if (uidl.hasAttribute("type")) {
final String type = uidl.getStringAttribute("type").intern();
if ("legacy-multi" == type) {
- return VListSelect.class;
+ return VListSelectPaintable.class;
}
}
- } else if (widgetClass == VSplitPanelHorizontal.class
- && uidl.hasAttribute("vertical")) {
- return VSplitPanelVertical.class;
}
-
return widgetClass;
}
@@ -119,7 +110,7 @@ public class WidgetSet {
public Class<? extends VPaintableWidget> getImplementationByClassName(
String fullyqualifiedName) {
if (fullyqualifiedName == null) {
- return VUnknownComponent.class;
+ return VUnknownComponentPaintable.class;
}
Class<? extends VPaintableWidget> implementationByServerSideClassName = widgetMap
.getImplementationByServerSideClassName(fullyqualifiedName);
@@ -131,9 +122,7 @@ public class WidgetSet {
* *actually* be VListSelect, when the annotation says VFilterSelect
*/
if (fullyqualifiedName.equals("com.vaadin.ui.Select")) {
- loadImplementation(VListSelect.class);
- } else if (fullyqualifiedName.equals("com.vaadin.ui.SplitPanel")) {
- loadImplementation(VSplitPanelVertical.class);
+ loadImplementation(VListSelectPaintable.class);
}
return implementationByServerSideClassName;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java b/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
index cf18c693c6..1577d60ab7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/CalendarEntry.java
@@ -1,128 +1,128 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.vaadin.terminal.gwt.client.DateTimeService;
-
-public class CalendarEntry {
- private final String styleName;
- private Date start;
- private Date end;
- private String title;
- private String description;
- private boolean notime;
-
- @SuppressWarnings("deprecation")
- public CalendarEntry(String styleName, Date start, Date end, String title,
- String description, boolean notime) {
- this.styleName = styleName;
- if (notime) {
- Date d = new Date(start.getTime());
- d.setSeconds(0);
- d.setMinutes(0);
- this.start = d;
- if (end != null) {
- d = new Date(end.getTime());
- d.setSeconds(0);
- d.setMinutes(0);
- this.end = d;
- } else {
- end = start;
- }
- } else {
- this.start = start;
- this.end = end;
- }
- this.title = title;
- this.description = description;
- this.notime = notime;
- }
-
- public CalendarEntry(String styleName, Date start, Date end, String title,
- String description) {
- this(styleName, start, end, title, description, false);
- }
-
- public String getStyleName() {
- return styleName;
- }
-
- public Date getStart() {
- return start;
- }
-
- public void setStart(Date start) {
- this.start = start;
- }
-
- public Date getEnd() {
- return end;
- }
-
- public void setEnd(Date end) {
- this.end = end;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public boolean isNotime() {
- return notime;
- }
-
- public void setNotime(boolean notime) {
- this.notime = notime;
- }
-
- @SuppressWarnings("deprecation")
- public String getStringForDate(Date d) {
- // TODO format from DateTimeService
- String s = "";
- if (!notime) {
- if (!DateTimeService.isSameDay(d, start)) {
- s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)
- + "." + start.getDate() + " ";
- }
- int i = start.getHours();
- s += (i < 10 ? "0" : "") + i;
- s += ":";
- i = start.getMinutes();
- s += (i < 10 ? "0" : "") + i;
- if (!start.equals(end)) {
- s += " - ";
- if (!DateTimeService.isSameDay(start, end)) {
- s += (end.getYear() + 1900) + "." + (end.getMonth() + 1)
- + "." + end.getDate() + " ";
- }
- i = end.getHours();
- s += (i < 10 ? "0" : "") + i;
- s += ":";
- i = end.getMinutes();
- s += (i < 10 ? "0" : "") + i;
- }
- s += " ";
- }
- if (title != null) {
- s += title;
- }
- return s;
- }
-
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.vaadin.terminal.gwt.client.DateTimeService;
+
+public class CalendarEntry {
+ private final String styleName;
+ private Date start;
+ private Date end;
+ private String title;
+ private String description;
+ private boolean notime;
+
+ @SuppressWarnings("deprecation")
+ public CalendarEntry(String styleName, Date start, Date end, String title,
+ String description, boolean notime) {
+ this.styleName = styleName;
+ if (notime) {
+ Date d = new Date(start.getTime());
+ d.setSeconds(0);
+ d.setMinutes(0);
+ this.start = d;
+ if (end != null) {
+ d = new Date(end.getTime());
+ d.setSeconds(0);
+ d.setMinutes(0);
+ this.end = d;
+ } else {
+ end = start;
+ }
+ } else {
+ this.start = start;
+ this.end = end;
+ }
+ this.title = title;
+ this.description = description;
+ this.notime = notime;
+ }
+
+ public CalendarEntry(String styleName, Date start, Date end, String title,
+ String description) {
+ this(styleName, start, end, title, description, false);
+ }
+
+ public String getStyleName() {
+ return styleName;
+ }
+
+ public Date getStart() {
+ return start;
+ }
+
+ public void setStart(Date start) {
+ this.start = start;
+ }
+
+ public Date getEnd() {
+ return end;
+ }
+
+ public void setEnd(Date end) {
+ this.end = end;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public boolean isNotime() {
+ return notime;
+ }
+
+ public void setNotime(boolean notime) {
+ this.notime = notime;
+ }
+
+ @SuppressWarnings("deprecation")
+ public String getStringForDate(Date d) {
+ // TODO format from DateTimeService
+ String s = "";
+ if (!notime) {
+ if (!DateTimeService.isSameDay(d, start)) {
+ s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)
+ + "." + start.getDate() + " ";
+ }
+ int i = start.getHours();
+ s += (i < 10 ? "0" : "") + i;
+ s += ":";
+ i = start.getMinutes();
+ s += (i < 10 ? "0" : "") + i;
+ if (!start.equals(end)) {
+ s += " - ";
+ if (!DateTimeService.isSameDay(start, end)) {
+ s += (end.getYear() + 1900) + "." + (end.getMonth() + 1)
+ + "." + end.getDate() + " ";
+ }
+ i = end.getHours();
+ s += (i < 10 ? "0" : "") + i;
+ s += ":";
+ i = end.getMinutes();
+ s += (i < 10 ? "0" : "") + i;
+ }
+ s += " ";
+ }
+ if (title != null) {
+ s += title;
+ }
+ return s;
+ }
+
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
index 0ca97d2bf8..831add049b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableFlowPanel.java
@@ -1,100 +1,100 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.HasBlurHandlers;
-import com.google.gwt.event.dom.client.HasFocusHandlers;
-import com.google.gwt.event.dom.client.HasKeyDownHandlers;
-import com.google.gwt.event.dom.client.HasKeyPressHandlers;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.impl.FocusImpl;
-import com.vaadin.terminal.gwt.client.Focusable;
-
-public class FocusableFlowPanel extends FlowPanel implements HasFocusHandlers,
- HasBlurHandlers, HasKeyDownHandlers, HasKeyPressHandlers, Focusable {
-
- /**
- * Constructor
- */
- public FocusableFlowPanel() {
- // make focusable, as we don't need access key magic we don't need to
- // use FocusImpl.createFocusable
- getElement().setTabIndex(0);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.
- * google.gwt.event.dom.client.FocusHandler)
- */
- public HandlerRegistration addFocusHandler(FocusHandler handler) {
- return addDomHandler(handler, FocusEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasBlurHandlers#addBlurHandler(com.google
- * .gwt.event.dom.client.BlurHandler)
- */
- public HandlerRegistration addBlurHandler(BlurHandler handler) {
- return addDomHandler(handler, BlurEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasKeyDownHandlers#addKeyDownHandler(
- * com.google.gwt.event.dom.client.KeyDownHandler)
- */
- public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
- return addDomHandler(handler, KeyDownEvent.getType());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.HasKeyPressHandlers#addKeyPressHandler
- * (com.google.gwt.event.dom.client.KeyPressHandler)
- */
- public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
- return addDomHandler(handler, KeyPressEvent.getType());
- }
-
- /**
- * Sets/Removes the keyboard focus to the panel.
- *
- * @param focus
- * If set to true then the focus is moved to the panel, if set to
- * false the focus is removed
- */
- public void setFocus(boolean focus) {
- if (focus) {
- FocusImpl.getFocusImplForPanel().focus(getElement());
- } else {
- FocusImpl.getFocusImplForPanel().blur(getElement());
- }
- }
-
- /**
- * Focus the panel
- */
- public void focus() {
- setFocus(true);
- }
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.HasBlurHandlers;
+import com.google.gwt.event.dom.client.HasFocusHandlers;
+import com.google.gwt.event.dom.client.HasKeyDownHandlers;
+import com.google.gwt.event.dom.client.HasKeyPressHandlers;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.impl.FocusImpl;
+import com.vaadin.terminal.gwt.client.Focusable;
+
+public class FocusableFlowPanel extends FlowPanel implements HasFocusHandlers,
+ HasBlurHandlers, HasKeyDownHandlers, HasKeyPressHandlers, Focusable {
+
+ /**
+ * Constructor
+ */
+ public FocusableFlowPanel() {
+ // make focusable, as we don't need access key magic we don't need to
+ // use FocusImpl.createFocusable
+ getElement().setTabIndex(0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.
+ * google.gwt.event.dom.client.FocusHandler)
+ */
+ public HandlerRegistration addFocusHandler(FocusHandler handler) {
+ return addDomHandler(handler, FocusEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasBlurHandlers#addBlurHandler(com.google
+ * .gwt.event.dom.client.BlurHandler)
+ */
+ public HandlerRegistration addBlurHandler(BlurHandler handler) {
+ return addDomHandler(handler, BlurEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasKeyDownHandlers#addKeyDownHandler(
+ * com.google.gwt.event.dom.client.KeyDownHandler)
+ */
+ public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
+ return addDomHandler(handler, KeyDownEvent.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.HasKeyPressHandlers#addKeyPressHandler
+ * (com.google.gwt.event.dom.client.KeyPressHandler)
+ */
+ public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
+ return addDomHandler(handler, KeyPressEvent.getType());
+ }
+
+ /**
+ * Sets/Removes the keyboard focus to the panel.
+ *
+ * @param focus
+ * If set to true then the focus is moved to the panel, if set to
+ * false the focus is removed
+ */
+ public void setFocus(boolean focus) {
+ if (focus) {
+ FocusImpl.getFocusImplForPanel().focus(getElement());
+ } else {
+ FocusImpl.getFocusImplForPanel().blur(getElement());
+ }
+ }
+
+ /**
+ * Focus the panel
+ */
+ public void focus() {
+ setFocus(true);
+ }
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java b/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
index 8a153da98c..37f8889463 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/TreeImages.java
@@ -1,29 +1,29 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.ui.AbstractImagePrototype;
-
-public interface TreeImages extends com.google.gwt.user.client.ui.TreeImages {
-
- /**
- * An image indicating an open branch.
- *
- * @return a prototype of this image
- * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/expanded
- * .png
- */
- AbstractImagePrototype treeOpen();
-
- /**
- * An image indicating a closed branch.
- *
- * @return a prototype of this image
- * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/collapsed
- * .png
- */
- AbstractImagePrototype treeClosed();
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+
+public interface TreeImages extends com.google.gwt.user.client.ui.TreeImages {
+
+ /**
+ * An image indicating an open branch.
+ *
+ * @return a prototype of this image
+ * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/expanded
+ * .png
+ */
+ AbstractImagePrototype treeOpen();
+
+ /**
+ * An image indicating a closed branch.
+ *
+ * @return a prototype of this image
+ * @gwt.resource com/vaadin/terminal/gwt/public/default/tree/img/collapsed
+ * .png
+ */
+ AbstractImagePrototype treeClosed();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
index e5982b1078..7ac44bc4b7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
@@ -4,7 +4,6 @@
package com.vaadin.terminal.gwt.client.ui;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -13,9 +12,6 @@ import java.util.Set;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
@@ -23,7 +19,6 @@ import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
@@ -49,26 +44,11 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
private Object previousStyleName;
- private Map<String, AbsoluteWrapper> pidToComponentWrappper = new HashMap<String, AbsoluteWrapper>();
+ Map<String, AbsoluteWrapper> pidToComponentWrappper = new HashMap<String, AbsoluteWrapper>();
protected ApplicationConnection client;
- private boolean rendering;
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
+ boolean rendering;
public VAbsoluteLayout() {
setElement(Document.get().createDivElement());
@@ -137,46 +117,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
return true;
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- AbsoluteWrapper parent2 = (AbsoluteWrapper) (component
- .getWidgetForPaintable()).getParent();
- parent2.updateCaption(uidl);
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- this.client = client;
- // TODO margin handling
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- HashSet<String> unrenderedPids = new HashSet<String>(
- pidToComponentWrappper.keySet());
-
- for (Iterator<Object> childIterator = uidl.getChildIterator(); childIterator
- .hasNext();) {
- UIDL cc = (UIDL) childIterator.next();
- if (cc.getTag().equals("cc")) {
- UIDL componentUIDL = cc.getChildUIDL(0);
- unrenderedPids.remove(componentUIDL.getId());
- getWrapper(client, componentUIDL).updateFromUIDL(cc);
- }
- }
-
- for (String pid : unrenderedPids) {
- AbsoluteWrapper absoluteWrapper = pidToComponentWrappper.get(pid);
- pidToComponentWrappper.remove(pid);
- absoluteWrapper.destroy();
- }
- rendering = false;
- }
-
- private AbsoluteWrapper getWrapper(ApplicationConnection client,
- UIDL componentUIDL) {
+ AbsoluteWrapper getWrapper(ApplicationConnection client, UIDL componentUIDL) {
AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL
.getId());
if (wrapper == null) {
@@ -364,12 +305,8 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
* @return The Paintable which the element is a part of. Null if the element
* belongs to the layout and not to a child.
*/
- private VPaintableWidget getComponent(Element element) {
+ VPaintableWidget getComponent(Element element) {
return Util.getPaintableForElement(client, this, element);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
new file mode 100644
index 0000000000..9d73e75b09
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayoutPaintable.java
@@ -0,0 +1,87 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout.AbsoluteWrapper;
+
+public class VAbsoluteLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+ // TODO margin handling
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ HashSet<String> unrenderedPids = new HashSet<String>(
+ getWidgetForPaintable().pidToComponentWrappper.keySet());
+
+ for (Iterator<Object> childIterator = uidl.getChildIterator(); childIterator
+ .hasNext();) {
+ UIDL cc = (UIDL) childIterator.next();
+ if (cc.getTag().equals("cc")) {
+ UIDL componentUIDL = cc.getChildUIDL(0);
+ unrenderedPids.remove(componentUIDL.getId());
+ getWidgetForPaintable().getWrapper(client, componentUIDL)
+ .updateFromUIDL(cc);
+ }
+ }
+
+ for (String pid : unrenderedPids) {
+ AbsoluteWrapper absoluteWrapper = getWidgetForPaintable().pidToComponentWrappper
+ .get(pid);
+ getWidgetForPaintable().pidToComponentWrappper.remove(pid);
+ absoluteWrapper.destroy();
+ }
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ AbsoluteWrapper parent2 = (AbsoluteWrapper) (component
+ .getWidgetForPaintable()).getParent();
+ parent2.updateCaption(uidl);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAbsoluteLayout.class);
+ }
+
+ @Override
+ public VAbsoluteLayout getWidgetForPaintable() {
+ return (VAbsoluteLayout) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
index 9a2e728454..474e9c416d 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
@@ -1,75 +1,106 @@
-/*
-@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.VPaintableWidget;
-
-public abstract class VAbstractPaintableWidget implements VPaintableWidget {
-
- private Widget widget;
- private ApplicationConnection connection;
-
- /* 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;
- // }
-}
+/*
+@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;
+ private VPaintableWidgetContainer parent;
+
+ /* 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 getParent() {
+ if (parent != null)
+ return parent;
+
+ // FIXME: Hierarchy should be set by framework instead of looked up here
+ VPaintableMap paintableMap = VPaintableMap.get(getConnection());
+
+ Widget w = getWidgetForPaintable();
+ while (w != null) {
+ w = w.getParent();
+ if (paintableMap.isPaintable(w)) {
+ parent = (VPaintableWidgetContainer) paintableMap.getPaintable(w);
+ return parent;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
new file mode 100644
index 0000000000..1f78c02f58
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidgetContainer.java
@@ -0,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() {
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
index 0d44609bb0..f1a932b3a3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanel.java
@@ -6,9 +6,7 @@ package com.vaadin.terminal.gwt.client.ui;
import java.util.Set;
-import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Node;
-import com.google.gwt.event.dom.client.DomEvent.Type;
import com.google.gwt.event.dom.client.TouchCancelEvent;
import com.google.gwt.event.dom.client.TouchCancelHandler;
import com.google.gwt.event.dom.client.TouchEndEvent;
@@ -17,8 +15,6 @@ import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchMoveHandler;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.dom.client.TouchStartHandler;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -30,61 +26,16 @@ import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-public class VSplitPanel extends ComplexPanel implements Container,
+public class VAbstractSplitPanel extends ComplexPanel implements Container,
ContainerResizedListener {
private boolean enabled = false;
public static final String CLASSNAME = "v-splitpanel";
- public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";
-
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- SPLITTER_CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- if ((Event.getEventsSunk(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 addHandler(handler, type);
- } else {
- return addDomHandler(handler, type);
- }
- }
-
- @Override
- public void onContextMenu(
- com.google.gwt.event.dom.client.ContextMenuEvent event) {
- Element target = event.getNativeEvent().getEventTarget().cast();
- if (splitter.isOrHasChild(target)) {
- super.onContextMenu(event);
- }
- };
-
- @Override
- protected void fireClick(NativeEvent event) {
- Element target = event.getEventTarget().cast();
- if (splitter.isOrHasChild(target)) {
- super.fireClick(event);
- }
- }
-
- @Override
- protected Element getRelativeToElement() {
- return null;
- }
-
- };
-
public static final int ORIENTATION_HORIZONTAL = 0;
public static final int ORIENTATION_VERTICAL = 1;
@@ -93,9 +44,9 @@ public class VSplitPanel extends ComplexPanel implements Container,
private int orientation = ORIENTATION_HORIZONTAL;
- private Widget firstChild;
+ Widget firstChild;
- private Widget secondChild;
+ Widget secondChild;
private final Element wrapper = DOM.createDiv();
@@ -103,7 +54,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
private final Element secondContainer = DOM.createDiv();
- private final Element splitter = DOM.createDiv();
+ final Element splitter = DOM.createDiv();
private boolean resizing;
@@ -121,11 +72,11 @@ public class VSplitPanel extends ComplexPanel implements Container,
private boolean positionReversed = false;
- private String[] componentStyleNames;
+ String[] componentStyleNames;
private Element draggingCurtain;
- private ApplicationConnection client;
+ ApplicationConnection client;
private String width = "";
@@ -136,14 +87,14 @@ public class VSplitPanel extends ComplexPanel implements Container,
RenderInformation renderInformation = new RenderInformation();
- private String id;
+ String id;
- private boolean immediate;
+ boolean immediate;
- private boolean rendering = false;
+ boolean rendering = false;
/* The current position of the split handle in either percentages or pixels */
- private String position;
+ String position;
protected Element scrolledContainer;
@@ -151,11 +102,11 @@ public class VSplitPanel extends ComplexPanel implements Container,
private TouchScrollDelegate touchScrollDelegate;
- public VSplitPanel() {
+ public VAbstractSplitPanel() {
this(ORIENTATION_HORIZONTAL);
}
- public VSplitPanel(int orientation) {
+ public VAbstractSplitPanel(int orientation) {
setElement(DOM.createDiv());
switch (orientation) {
case ORIENTATION_HORIZONTAL:
@@ -255,69 +206,6 @@ public class VSplitPanel extends ComplexPanel implements Container,
+ "-second-container");
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- id = uidl.getId();
- rendering = true;
-
- immediate = uidl.hasAttribute("immediate");
-
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
- setEnabled(!uidl.getBooleanAttribute("disabled"));
-
- clickEventHandler.handleEventHandlerRegistration(client);
- if (uidl.hasAttribute("style")) {
- componentStyleNames = uidl.getStringAttribute("style").split(" ");
- } else {
- componentStyleNames = new String[0];
- }
-
- setLocked(uidl.getBooleanAttribute("locked"));
-
- setPositionReversed(uidl.getBooleanAttribute("reversed"));
-
- setStylenames();
-
- position = uidl.getStringAttribute("position");
- setSplitPosition(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 (firstChild != newFirstChild) {
- if (firstChild != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(firstChild));
- }
- setFirstWidget(newFirstChild);
- }
- if (secondChild != newSecondChild) {
- if (secondChild != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(secondChild));
- }
- setSecondWidget(newSecondChild);
- }
- newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
- newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
-
- renderInformation.updateSize(getElement());
-
- // This is needed at least for cases like #3458 to take
- // appearing/disappearing scrollbars into account.
- client.runDescendentsLayout(this);
-
- rendering = false;
-
- }
-
@Override
public boolean remove(Widget w) {
boolean removed = super.remove(w);
@@ -331,7 +219,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
return removed;
}
- private void setLocked(boolean newValue) {
+ void setLocked(boolean newValue) {
if (locked != newValue) {
locked = newValue;
splitterSize = -1;
@@ -339,7 +227,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
}
}
- private void setPositionReversed(boolean reversed) {
+ void setPositionReversed(boolean reversed) {
if (positionReversed != reversed) {
if (orientation == ORIENTATION_HORIZONTAL) {
DOM.setStyleAttribute(splitter, "right", "");
@@ -353,7 +241,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
}
}
- private void setSplitPosition(String pos) {
+ void setSplitPosition(String pos) {
if (pos == null) {
return;
}
@@ -473,7 +361,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
}
- private void setFirstWidget(Widget w) {
+ void setFirstWidget(Widget w) {
if (firstChild != null) {
firstChild.removeFromParent();
}
@@ -481,7 +369,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
firstChild = w;
}
- private void setSecondWidget(Widget w) {
+ void setSecondWidget(Widget w) {
if (secondChild != null) {
secondChild.removeFromParent();
}
@@ -791,10 +679,6 @@ public class VSplitPanel extends ComplexPanel implements Container,
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // TODO Implement caption handling
- }
-
/**
* Updates the new split position back to server.
*/
@@ -810,7 +694,7 @@ public class VSplitPanel extends ComplexPanel implements Container,
client.updateVariable(id, "position", pos, immediate);
}
- private void setStylenames() {
+ void setStylenames() {
final String splitterSuffix = (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter"
: "-vsplitter");
final String firstContainerSuffix = "-first-container";
@@ -846,7 +730,4 @@ public class VSplitPanel extends ComplexPanel implements Container,
return enabled;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
new file mode 100644
index 0000000000..9c7e5f04f9
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractSplitPanelPaintable.java
@@ -0,0 +1,143 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public abstract class VAbstractSplitPanelPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public static final String SPLITTER_CLICK_EVENT_IDENTIFIER = "sp_click";
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // TODO Implement caption handling
+ }
+
+ ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ SPLITTER_CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ if ((Event.getEventsSunk(getWidgetForPaintable().splitter) & Event
+ .getTypeInt(type.getName())) != 0) {
+ // If we are already sinking the event for the splitter we do
+ // not want to additionally sink it for the root element
+ return getWidgetForPaintable().addHandler(handler, type);
+ } else {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ }
+
+ @Override
+ public void onContextMenu(
+ com.google.gwt.event.dom.client.ContextMenuEvent event) {
+ Element target = event.getNativeEvent().getEventTarget().cast();
+ if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
+ super.onContextMenu(event);
+ }
+ };
+
+ @Override
+ protected void fireClick(NativeEvent event) {
+ Element target = event.getEventTarget().cast();
+ if (getWidgetForPaintable().splitter.isOrHasChild(target)) {
+ super.fireClick(event);
+ }
+ }
+
+ @Override
+ protected Element getRelativeToElement() {
+ return null;
+ }
+
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ getWidgetForPaintable().setEnabled(
+ !uidl.getBooleanAttribute("disabled"));
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+ if (uidl.hasAttribute("style")) {
+ getWidgetForPaintable().componentStyleNames = uidl
+ .getStringAttribute("style").split(" ");
+ } else {
+ getWidgetForPaintable().componentStyleNames = new String[0];
+ }
+
+ getWidgetForPaintable().setLocked(uidl.getBooleanAttribute("locked"));
+
+ getWidgetForPaintable().setPositionReversed(
+ uidl.getBooleanAttribute("reversed"));
+
+ getWidgetForPaintable().setStylenames();
+
+ getWidgetForPaintable().position = uidl.getStringAttribute("position");
+ getWidgetForPaintable().setSplitPosition(
+ getWidgetForPaintable().position);
+
+ final VPaintableWidget newFirstChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(0));
+ final VPaintableWidget newSecondChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(1));
+ Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();
+ Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();
+
+ if (getWidgetForPaintable().firstChild != newFirstChild) {
+ if (getWidgetForPaintable().firstChild != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().firstChild));
+ }
+ getWidgetForPaintable().setFirstWidget(newFirstChild);
+ }
+ if (getWidgetForPaintable().secondChild != newSecondChild) {
+ if (getWidgetForPaintable().secondChild != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().secondChild));
+ }
+ getWidgetForPaintable().setSecondWidget(newSecondChild);
+ }
+ newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
+ newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ // This is needed at least for cases like #3458 to take
+ // appearing/disappearing scrollbars into account.
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ @Override
+ public VAbstractSplitPanel getWidgetForPaintable() {
+ return (VAbstractSplitPanel) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected abstract VAbstractSplitPanel createWidget();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java
index 7fe87713c3..3e4f21477b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java
@@ -15,7 +15,6 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
@@ -36,58 +35,23 @@ public class VAccordion extends VTabsheetBase implements
private String width = "";
- private HashMap<StackItem, UIDL> lazyUpdateMap = new HashMap<StackItem, UIDL>();
+ HashMap<StackItem, UIDL> lazyUpdateMap = new HashMap<StackItem, UIDL>();
private RenderSpace renderSpace = new RenderSpace(0, 0, true);
- private StackItem openTab = null;
+ StackItem openTab = null;
- private boolean rendering = false;
+ boolean rendering = false;
- private int selectedUIDLItemIndex = -1;
+ int selectedUIDLItemIndex = -1;
- private RenderInformation renderInformation = new RenderInformation();
+ RenderInformation renderInformation = new RenderInformation();
public VAccordion() {
super(CLASSNAME);
}
@Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- selectedUIDLItemIndex = -1;
- super.updateFromUIDL(uidl, client);
- /*
- * Render content after all tabs have been created and we know how large
- * the content area is
- */
- if (selectedUIDLItemIndex >= 0) {
- StackItem selectedItem = getStackItem(selectedUIDLItemIndex);
- UIDL selectedTabUIDL = lazyUpdateMap.remove(selectedItem);
- open(selectedUIDLItemIndex);
-
- selectedItem.setContent(selectedTabUIDL);
- } else if (!uidl.getBooleanAttribute("cached") && openTab != null) {
- close(openTab);
- }
-
- iLayout();
- // finally render possible hidden tabs
- if (lazyUpdateMap.size() > 0) {
- for (Iterator iterator = lazyUpdateMap.keySet().iterator(); iterator
- .hasNext();) {
- StackItem item = (StackItem) iterator.next();
- item.setContent(lazyUpdateMap.get(item));
- }
- lazyUpdateMap.clear();
- }
-
- renderInformation.updateSize(getElement());
-
- rendering = false;
- }
-
- @Override
protected void renderTab(UIDL tabUidl, int index, boolean selected,
boolean hidden) {
StackItem item;
@@ -182,7 +146,7 @@ public class VAccordion extends VTabsheetBase implements
return item;
}
- private void open(int itemIndex) {
+ void open(int itemIndex) {
StackItem item = (StackItem) getWidget(itemIndex);
boolean alreadyOpen = false;
if (openTab != null) {
@@ -205,7 +169,7 @@ public class VAccordion extends VTabsheetBase implements
updateOpenTabSize();
}
- private void close(StackItem item) {
+ void close(StackItem item) {
if (!item.isOpen()) {
return;
}
@@ -581,10 +545,6 @@ public class VAccordion extends VTabsheetBase implements
}
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- /* Accordion does not render its children's captions */
- }
-
public boolean requestLayout(Set<Widget> children) {
if (!isDynamicHeight() && !isDynamicWidth()) {
/*
@@ -646,12 +606,8 @@ public class VAccordion extends VTabsheetBase implements
return null;
}
- private StackItem getStackItem(int index) {
+ StackItem getStackItem(int index) {
return (StackItem) getWidget(index);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
new file mode 100644
index 0000000000..6b03300a09
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordionPaintable.java
@@ -0,0 +1,71 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VAccordion.StackItem;
+
+public class VAccordionPaintable extends VTabsheetBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().selectedUIDLItemIndex = -1;
+ super.updateFromUIDL(uidl, client);
+ /*
+ * Render content after all tabs have been created and we know how large
+ * the content area is
+ */
+ if (getWidgetForPaintable().selectedUIDLItemIndex >= 0) {
+ StackItem selectedItem = getWidgetForPaintable().getStackItem(
+ getWidgetForPaintable().selectedUIDLItemIndex);
+ UIDL selectedTabUIDL = getWidgetForPaintable().lazyUpdateMap
+ .remove(selectedItem);
+ getWidgetForPaintable().open(
+ getWidgetForPaintable().selectedUIDLItemIndex);
+
+ selectedItem.setContent(selectedTabUIDL);
+ } else if (!uidl.getBooleanAttribute("cached")
+ && getWidgetForPaintable().openTab != null) {
+ getWidgetForPaintable().close(getWidgetForPaintable().openTab);
+ }
+
+ getWidgetForPaintable().iLayout();
+ // finally render possible hidden tabs
+ if (getWidgetForPaintable().lazyUpdateMap.size() > 0) {
+ for (Iterator iterator = getWidgetForPaintable().lazyUpdateMap
+ .keySet().iterator(); iterator.hasNext();) {
+ StackItem item = (StackItem) iterator.next();
+ item.setContent(getWidgetForPaintable().lazyUpdateMap.get(item));
+ }
+ getWidgetForPaintable().lazyUpdateMap.clear();
+ }
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ public VAccordion getWidgetForPaintable() {
+ return (VAccordion) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAccordion.class);
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ /* Accordion does not render its children's captions */
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
index e949d95104..a10c81861b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAudioPaintable.java
@@ -1,37 +1,40 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Style;
-import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VAudioPaintable extends VMediaBasePaintable {
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- super.updateFromUIDL(uidl, client);
- Style style = getWidgetForPaintable().getElement().getStyle();
-
- // Make sure that the controls are not clipped if visible.
- if (shouldShowControls(uidl)
- && (style.getHeight() == null || "".equals(style.getHeight()))) {
- if (BrowserInfo.get().isChrome()) {
- style.setHeight(32, Unit.PX);
- } else {
- style.setHeight(25, Unit.PX);
- }
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VAudio.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VAudioPaintable extends VMediaBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+ super.updateFromUIDL(uidl, client);
+ Style style = getWidgetForPaintable().getElement().getStyle();
+
+ // Make sure that the controls are not clipped if visible.
+ if (shouldShowControls(uidl)
+ && (style.getHeight() == null || "".equals(style.getHeight()))) {
+ if (BrowserInfo.get().isChrome()) {
+ style.setHeight(32, Unit.PX);
+ } else {
+ style.setHeight(25, Unit.PX);
+ }
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VAudio.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/VButton.java
index f8397d4a39..21b5d8bbe8 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VButton.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VButton.java
@@ -19,7 +19,6 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Accessibility;
import com.google.gwt.user.client.ui.FocusWidget;
-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;
@@ -450,9 +449,4 @@ public class VButton extends FocusWidget implements ClickHandler, FocusHandler,
public void onBlur(BlurEvent arg0) {
client.updateVariable(paintableId, EventId.BLUR, "", true);
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java
index 1367d412a8..98f2888700 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java
@@ -1,3 +1,7 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
package com.vaadin.terminal.gwt.client.ui;
import com.google.gwt.core.client.GWT;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
index b318fe0af3..2968e132c6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
@@ -1,1730 +1,1737 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-import java.util.Iterator;
-
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.dom.client.MouseDownEvent;
-import com.google.gwt.event.dom.client.MouseDownHandler;
-import com.google.gwt.event.dom.client.MouseOutEvent;
-import com.google.gwt.event.dom.client.MouseOutHandler;
-import com.google.gwt.event.dom.client.MouseUpEvent;
-import com.google.gwt.event.dom.client.MouseUpHandler;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.InlineHTML;
-import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.ui.label.VLabel;
-
-@SuppressWarnings("deprecation")
-public class VCalendarPanel extends FocusableFlexTable implements
- KeyDownHandler, KeyPressHandler, MouseOutHandler, MouseDownHandler,
- MouseUpHandler, BlurHandler, FocusHandler, SubPartAware {
-
- public interface SubmitListener {
-
- /**
- * Called when calendar user triggers a submitting operation in calendar
- * panel. Eg. clicking on day or hitting enter.
- */
- void onSubmit();
-
- /**
- * On eg. ESC key.
- */
- void onCancel();
- }
-
- /**
- * Blur listener that listens to blur event from the panel
- */
- public interface FocusOutListener {
- /**
- * @return true if the calendar panel is not used after focus moves out
- */
- boolean onFocusOut(DomEvent<?> event);
- }
-
- /**
- * FocusChangeListener is notified when the panel changes its _focused_
- * value. It can be set with
- */
- public interface FocusChangeListener {
- void focusChanged(Date focusedDate);
- }
-
- /**
- * Dispatches an event when the panel when time is changed
- */
- public interface TimeChangeListener {
-
- void changed(int hour, int min, int sec, int msec);
- }
-
- /**
- * Represents a Date button in the calendar
- */
- private class VEventButton extends Button {
- public VEventButton() {
- addMouseDownHandler(VCalendarPanel.this);
- addMouseOutHandler(VCalendarPanel.this);
- addMouseUpHandler(VCalendarPanel.this);
- }
- }
-
- private static final String CN_FOCUSED = "focused";
-
- private static final String CN_TODAY = "today";
-
- private static final String CN_SELECTED = "selected";
-
- private static final String CN_OFFMONTH = "offmonth";
-
- /**
- * Represents a click handler for when a user selects a value by using the
- * mouse
- */
- private ClickHandler dayClickHandler = new ClickHandler() {
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
- * .event.dom.client.ClickEvent)
- */
- public void onClick(ClickEvent event) {
- Day day = (Day) event.getSource();
- focusDay(day.getDate());
- selectFocused();
- onSubmit();
- }
- };
-
- private VEventButton prevYear;
-
- private VEventButton nextYear;
-
- private VEventButton prevMonth;
-
- private VEventButton nextMonth;
-
- private VTime time;
-
- private FlexTable days = new FlexTable();
-
- private int resolution = VDateField.RESOLUTION_YEAR;
-
- private int focusedRow;
-
- private Timer mouseTimer;
-
- private Date value;
-
- private boolean enabled = true;
-
- private boolean readonly = false;
-
- private DateTimeService dateTimeService;
-
- private boolean showISOWeekNumbers;
-
- private Date displayedMonth;
-
- private Date focusedDate;
-
- private Day selectedDay;
-
- private Day focusedDay;
-
- private FocusOutListener focusOutListener;
-
- private SubmitListener submitListener;
-
- private FocusChangeListener focusChangeListener;
-
- private TimeChangeListener timeChangeListener;
-
- private boolean hasFocus = false;
-
- public VCalendarPanel() {
-
- setStyleName(VDateField.CLASSNAME + "-calendarpanel");
-
- /*
- * Firefox auto-repeat works correctly only if we use a key press
- * handler, other browsers handle it correctly when using a key down
- * handler
- */
- if (BrowserInfo.get().isGecko()) {
- addKeyPressHandler(this);
- } else {
- addKeyDownHandler(this);
- }
- addFocusHandler(this);
- addBlurHandler(this);
-
- }
-
- /**
- * Sets the focus to given day of current time. Used when moving in the
- * calender with the keyboard.
- *
- * @param date
- * The day number from by Date.getDate()
- */
- private void focusDay(Date day) {
- // Only used when calender body is present
- if (resolution > VDateField.RESOLUTION_MONTH) {
- if (focusedDay != null) {
- focusedDay.removeStyleDependentName(CN_FOCUSED);
- }
-
- if (day != null && focusedDate != null) {
- focusedDate.setTime(day.getTime());
- int rowCount = days.getRowCount();
- for (int i = 0; i < rowCount; i++) {
- int cellCount = days.getCellCount(i);
- for (int j = 0; j < cellCount; j++) {
- Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
- Day curday = (Day) widget;
- if (curday.getDate().equals(day)) {
- curday.addStyleDependentName(CN_FOCUSED);
- focusedDay = curday;
- focusedRow = i;
- return;
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Sets the selection hightlight to a given date of current time
- *
- * @param date
- */
- private void selectDate(Date date) {
- if (selectedDay != null) {
- selectedDay.removeStyleDependentName(CN_SELECTED);
- }
-
- int rowCount = days.getRowCount();
- for (int i = 0; i < rowCount; i++) {
- int cellCount = days.getCellCount(i);
- for (int j = 0; j < cellCount; j++) {
- Widget widget = days.getWidget(i, j);
- if (widget != null && widget instanceof Day) {
- Day curday = (Day) widget;
- if (curday.getDate().equals(date)) {
- curday.addStyleDependentName(CN_SELECTED);
- selectedDay = curday;
- return;
- }
- }
- }
- }
- }
-
- /**
- * Updates year, month, day from focusedDate to value
- */
- private void selectFocused() {
- if (focusedDate != null) {
- if (value == null) {
- // No previously selected value (set to null on server side).
- // Create a new date using current date and time
- value = new Date();
- }
- /*
- * #5594 set Date (day) to 1 in order to prevent any kind of
- * wrapping of months when later setting the month. (e.g. 31 ->
- * month with 30 days -> wraps to the 1st of the following month,
- * e.g. 31st of May -> 31st of April = 1st of May)
- */
- value.setDate(1);
- if (value.getYear() != focusedDate.getYear()) {
- value.setYear(focusedDate.getYear());
- }
- if (value.getMonth() != focusedDate.getMonth()) {
- value.setMonth(focusedDate.getMonth());
- }
- if (value.getDate() != focusedDate.getDate()) {
- }
- // We always need to set the date, even if it hasn't changed, since
- // it was forced to 1 above.
- value.setDate(focusedDate.getDate());
-
- selectDate(focusedDate);
- } else {
- VConsole.log("Trying to select a the focused date which is NULL!");
- }
- }
-
- protected boolean onValueChange() {
- return false;
- }
-
- public int getResolution() {
- return resolution;
- }
-
- public void setResolution(int resolution) {
- this.resolution = resolution;
- if (time != null) {
- time.removeFromParent();
- time = null;
- }
- }
-
- private boolean isReadonly() {
- return readonly;
- }
-
- private boolean isEnabled() {
- return enabled;
- }
-
- private void clearCalendarBody(boolean remove) {
- if (!remove) {
- // Leave the cells in place but clear their contents
-
- // This has the side effect of ensuring that the calendar always
- // contain 7 rows.
- for (int row = 1; row < 7; row++) {
- for (int col = 0; col < 8; col++) {
- days.setHTML(row, col, "&nbsp;");
- }
- }
- } else if (getRowCount() > 1) {
- removeRow(1);
- days.clear();
- }
- }
-
- /**
- * Builds the top buttons and current month and year header.
- *
- * @param needsMonth
- * Should the month buttons be visible?
- */
- private void buildCalendarHeader(boolean needsMonth) {
-
- getRowFormatter().addStyleName(0,
- VDateField.CLASSNAME + "-calendarpanel-header");
-
- if (prevMonth == null && needsMonth) {
- prevMonth = new VEventButton();
- prevMonth.setHTML("&lsaquo;");
- prevMonth.setStyleName("v-button-prevmonth");
- prevMonth.setTabIndex(-1);
- nextMonth = new VEventButton();
- nextMonth.setHTML("&rsaquo;");
- nextMonth.setStyleName("v-button-nextmonth");
- nextMonth.setTabIndex(-1);
- getFlexCellFormatter().setStyleName(0, 3,
- VDateField.CLASSNAME + "-calendarpanel-nextmonth");
- getFlexCellFormatter().setStyleName(0, 1,
- VDateField.CLASSNAME + "-calendarpanel-prevmonth");
-
- setWidget(0, 3, nextMonth);
- setWidget(0, 1, prevMonth);
- } else if (prevMonth != null && !needsMonth) {
- // Remove month traverse buttons
- remove(prevMonth);
- remove(nextMonth);
- prevMonth = null;
- nextMonth = null;
- }
-
- if (prevYear == null) {
- prevYear = new VEventButton();
- prevYear.setHTML("&laquo;");
- prevYear.setStyleName("v-button-prevyear");
- prevYear.setTabIndex(-1);
- nextYear = new VEventButton();
- nextYear.setHTML("&raquo;");
- nextYear.setStyleName("v-button-nextyear");
- nextYear.setTabIndex(-1);
- setWidget(0, 0, prevYear);
- setWidget(0, 4, nextYear);
- getFlexCellFormatter().setStyleName(0, 0,
- VDateField.CLASSNAME + "-calendarpanel-prevyear");
- getFlexCellFormatter().setStyleName(0, 4,
- VDateField.CLASSNAME + "-calendarpanel-nextyear");
- }
-
- final String monthName = needsMonth ? getDateTimeService().getMonth(
- focusedDate.getMonth()) : "";
- final int year = focusedDate.getYear() + 1900;
- getFlexCellFormatter().setStyleName(0, 2,
- VDateField.CLASSNAME + "-calendarpanel-month");
- setHTML(0, 2, "<span class=\"" + VDateField.CLASSNAME
- + "-calendarpanel-month\">" + monthName + " " + year
- + "</span>");
- }
-
- private DateTimeService getDateTimeService() {
- return dateTimeService;
- }
-
- public void setDateTimeService(DateTimeService dateTimeService) {
- this.dateTimeService = dateTimeService;
- }
-
- /**
- * Returns whether ISO 8601 week numbers should be shown in the value
- * selector or not. ISO 8601 defines that a week always starts with a Monday
- * so the week numbers are only shown if this is the case.
- *
- * @return true if week number should be shown, false otherwise
- */
- public boolean isShowISOWeekNumbers() {
- return showISOWeekNumbers;
- }
-
- public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
- this.showISOWeekNumbers = showISOWeekNumbers;
- }
-
- /**
- * Builds the day and time selectors of the calendar.
- */
- private void buildCalendarBody() {
-
- final int weekColumn = 0;
- final int firstWeekdayColumn = 1;
- final int headerRow = 0;
-
- setWidget(1, 0, days);
- setCellPadding(0);
- setCellSpacing(0);
- getFlexCellFormatter().setColSpan(1, 0, 5);
- getFlexCellFormatter().setStyleName(1, 0,
- VDateField.CLASSNAME + "-calendarpanel-body");
-
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
- "v-week");
- days.setHTML(headerRow, weekColumn, "<strong></strong>");
- // Hide the week column if week numbers are not to be displayed.
- days.getFlexCellFormatter().setVisible(headerRow, weekColumn,
- isShowISOWeekNumbers());
-
- days.getRowFormatter().setStyleName(headerRow,
- VDateField.CLASSNAME + "-calendarpanel-weekdays");
-
- if (isShowISOWeekNumbers()) {
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
- "v-first");
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn, "");
- days.getRowFormatter().addStyleName(headerRow,
- VDateField.CLASSNAME + "-calendarpanel-weeknumbers");
- } else {
- days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "");
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn, "v-first");
- }
-
- days.getFlexCellFormatter().setStyleName(headerRow,
- firstWeekdayColumn + 6, "v-last");
-
- // Print weekday names
- final int firstDay = getDateTimeService().getFirstDayOfWeek();
- for (int i = 0; i < 7; i++) {
- int day = i + firstDay;
- if (day > 6) {
- day = 0;
- }
- if (getResolution() > VDateField.RESOLUTION_MONTH) {
- days.setHTML(headerRow, firstWeekdayColumn + i, "<strong>"
- + getDateTimeService().getShortDay(day) + "</strong>");
- } else {
- days.setHTML(headerRow, firstWeekdayColumn + i, "");
- }
- }
-
- // today must have zeroed hours, minutes, seconds, and milliseconds
- final Date tmp = new Date();
- final Date today = new Date(tmp.getYear(), tmp.getMonth(),
- tmp.getDate());
-
- final int startWeekDay = getDateTimeService().getStartWeekDay(
- focusedDate);
- final Date curr = (Date) focusedDate.clone();
- // Start from the first day of the week that at least partially belongs
- // to the current month
- curr.setDate(-startWeekDay);
-
- // No month has more than 6 weeks so 6 is a safe maximum for rows.
- for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {
- for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
-
- // Actually write the day of month
- Day day = new Day((Date) curr.clone());
-
- if (curr.equals(value)) {
- day.addStyleDependentName(CN_SELECTED);
- selectedDay = day;
- }
- if (curr.equals(today)) {
- day.addStyleDependentName(CN_TODAY);
- }
- if (curr.equals(focusedDate)) {
- focusedDay = day;
- focusedRow = weekOfMonth;
- if (hasFocus) {
- day.addStyleDependentName(CN_FOCUSED);
- }
- }
- if (curr.getMonth() != focusedDate.getMonth()) {
- day.addStyleDependentName(CN_OFFMONTH);
- }
-
- days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);
-
- // ISO week numbers if requested
- days.getCellFormatter().setVisible(weekOfMonth, weekColumn,
- isShowISOWeekNumbers());
- if (isShowISOWeekNumbers()) {
- final String baseCssClass = VDateField.CLASSNAME
- + "-calendarpanel-weeknumber";
- String weekCssClass = baseCssClass;
-
- int weekNumber = DateTimeService.getISOWeekNumber(curr);
-
- days.setHTML(weekOfMonth, 0, "<span class=\""
- + weekCssClass + "\"" + ">" + weekNumber
- + "</span>");
- }
- curr.setDate(curr.getDate() + 1);
- }
- }
- }
-
- /**
- * Do we need the time selector
- *
- * @return True if it is required
- */
- private boolean isTimeSelectorNeeded() {
- return getResolution() > VDateField.RESOLUTION_DAY;
- }
-
- /**
- * Updates the calendar and text field with the selected dates.
- */
- public void renderCalendar() {
- if (focusedDate == null) {
- focusedDate = new Date();
- }
-
- if (getResolution() <= VDateField.RESOLUTION_MONTH
- && focusChangeListener != null) {
- focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
- }
-
- final boolean needsMonth = getResolution() > VDateField.RESOLUTION_YEAR;
- boolean needsBody = getResolution() >= VDateField.RESOLUTION_DAY;
- buildCalendarHeader(needsMonth);
- clearCalendarBody(!needsBody);
- if (needsBody) {
- buildCalendarBody();
- }
-
- if (isTimeSelectorNeeded() && time == null) {
- time = new VTime();
- setWidget(2, 0, time);
- getFlexCellFormatter().setColSpan(2, 0, 5);
- getFlexCellFormatter().setStyleName(2, 0,
- VDateField.CLASSNAME + "-calendarpanel-time");
- } else if (isTimeSelectorNeeded()) {
- time.updateTimes();
- } else if (time != null) {
- remove(time);
- }
-
- }
-
- /**
- * Selects the next month
- */
- private void focusNextMonth() {
-
- int currentMonth = focusedDate.getMonth();
- focusedDate.setMonth(currentMonth + 1);
- int requestedMonth = (currentMonth + 1) % 12;
-
- /*
- * If the selected value was e.g. 31.3 the new value would be 31.4 but
- * this value is invalid so the new value will be 1.5. This is taken
- * care of by decreasing the value until we have the correct month.
- */
- while (focusedDate.getMonth() != requestedMonth) {
- focusedDate.setDate(focusedDate.getDate() - 1);
- }
- displayedMonth.setMonth(displayedMonth.getMonth() + 1);
-
- renderCalendar();
- }
-
- /**
- * Selects the previous month
- */
- private void focusPreviousMonth() {
- int currentMonth = focusedDate.getMonth();
- focusedDate.setMonth(currentMonth - 1);
-
- /*
- * If the selected value was e.g. 31.12 the new value would be 31.11 but
- * this value is invalid so the new value will be 1.12. This is taken
- * care of by decreasing the value until we have the correct month.
- */
- while (focusedDate.getMonth() == currentMonth) {
- focusedDate.setDate(focusedDate.getDate() - 1);
- }
- displayedMonth.setMonth(displayedMonth.getMonth() - 1);
-
- renderCalendar();
- }
-
- /**
- * Selects the previous year
- */
- private void focusPreviousYear(int years) {
- focusedDate.setYear(focusedDate.getYear() - years);
- displayedMonth.setYear(displayedMonth.getYear() - years);
- renderCalendar();
- }
-
- /**
- * Selects the next year
- */
- private void focusNextYear(int years) {
- focusedDate.setYear(focusedDate.getYear() + years);
- displayedMonth.setYear(displayedMonth.getYear() + years);
- renderCalendar();
- }
-
- /**
- * Handles a user click on the component
- *
- * @param sender
- * The component that was clicked
- * @param updateVariable
- * Should the value field be updated
- *
- */
- private void processClickEvent(Widget sender) {
- if (!isEnabled() || isReadonly()) {
- return;
- }
- if (sender == prevYear) {
- focusPreviousYear(1);
- } else if (sender == nextYear) {
- focusNextYear(1);
- } else if (sender == prevMonth) {
- focusPreviousMonth();
- } else if (sender == nextMonth) {
- focusNextMonth();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
- * .event.dom.client.KeyDownEvent)
- */
- public void onKeyDown(KeyDownEvent event) {
- handleKeyPress(event);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google
- * .gwt.event.dom.client.KeyPressEvent)
- */
- public void onKeyPress(KeyPressEvent event) {
- handleKeyPress(event);
- }
-
- /**
- * Handles the keypress from both the onKeyPress event and the onKeyDown
- * event
- *
- * @param event
- * The keydown/keypress event
- */
- private void handleKeyPress(DomEvent<?> event) {
- if (time != null
- && time.getElement().isOrHasChild(
- (Node) event.getNativeEvent().getEventTarget().cast())) {
- int nativeKeyCode = event.getNativeEvent().getKeyCode();
- if (nativeKeyCode == getSelectKey()) {
- onSubmit(); // submit happens if enter key hit down on listboxes
- event.preventDefault();
- event.stopPropagation();
- }
- return;
- }
-
- // Check tabs
- int keycode = event.getNativeEvent().getKeyCode();
- if (keycode == KeyCodes.KEY_TAB && event.getNativeEvent().getShiftKey()) {
- if (onTabOut(event)) {
- return;
- }
- }
-
- // Handle the navigation
- if (handleNavigation(keycode, event.getNativeEvent().getCtrlKey()
- || event.getNativeEvent().getMetaKey(), event.getNativeEvent()
- .getShiftKey())) {
- event.preventDefault();
- }
-
- }
-
- /**
- * Notifies submit-listeners of a submit event
- */
- private void onSubmit() {
- if (getSubmitListener() != null) {
- getSubmitListener().onSubmit();
- }
- }
-
- /**
- * Notifies submit-listeners of a cancel event
- */
- private void onCancel() {
- if (getSubmitListener() != null) {
- getSubmitListener().onCancel();
- }
- }
-
- /**
- * Handles the keyboard navigation when the resolution is set to years.
- *
- * @param keycode
- * The keycode to process
- * @param ctrl
- * Is ctrl pressed?
- * @param shift
- * is shift pressed
- * @return Returns true if the keycode was processed, else false
- */
- protected boolean handleNavigationYearMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl and Shift selection not supported
- if (ctrl || shift) {
- return false;
- }
-
- else if (keycode == getPreviousKey()) {
- focusNextYear(10); // Add 10 years
- return true;
- }
-
- else if (keycode == getForwardKey()) {
- focusNextYear(1); // Add 1 year
- return true;
- }
-
- else if (keycode == getNextKey()) {
- focusPreviousYear(10); // Subtract 10 years
- return true;
- }
-
- else if (keycode == getBackwardKey()) {
- focusPreviousYear(1); // Subtract 1 year
- return true;
-
- } else if (keycode == getSelectKey()) {
- value = (Date) focusedDate.clone();
- onSubmit();
- return true;
-
- } else if (keycode == getResetKey()) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
-
- } else if (keycode == getCloseKey()) {
- // TODO fire listener, on users responsibility??
-
- return true;
- }
- return false;
- }
-
- /**
- * Handle the keyboard navigation when the resolution is set to MONTH
- *
- * @param keycode
- * The keycode to handle
- * @param ctrl
- * Was the ctrl key pressed?
- * @param shift
- * Was the shift key pressed?
- * @return
- */
- protected boolean handleNavigationMonthMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl selection not supported
- if (ctrl) {
- return false;
-
- } else if (keycode == getPreviousKey()) {
- focusNextYear(1); // Add 1 year
- return true;
-
- } else if (keycode == getForwardKey()) {
- focusNextMonth(); // Add 1 month
- return true;
-
- } else if (keycode == getNextKey()) {
- focusPreviousYear(1); // Subtract 1 year
- return true;
-
- } else if (keycode == getBackwardKey()) {
- focusPreviousMonth(); // Subtract 1 month
- return true;
-
- } else if (keycode == getSelectKey()) {
- value = (Date) focusedDate.clone();
- onSubmit();
- return true;
-
- } else if (keycode == getResetKey()) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
-
- } else if (keycode == getCloseKey() || keycode == KeyCodes.KEY_TAB) {
-
- // TODO fire close event
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Handle keyboard navigation what the resolution is set to DAY
- *
- * @param keycode
- * The keycode to handle
- * @param ctrl
- * Was the ctrl key pressed?
- * @param shift
- * Was the shift key pressed?
- * @return Return true if the key press was handled by the method, else
- * return false.
- */
- protected boolean handleNavigationDayMode(int keycode, boolean ctrl,
- boolean shift) {
-
- // Ctrl key is not in use
- if (ctrl) {
- return false;
- }
-
- /*
- * Jumps to the next day.
- */
- if (keycode == getForwardKey() && !shift) {
- // Calculate new showing value
-
- Date newCurrentDate = (Date) focusedDate.clone();
-
- newCurrentDate.setDate(newCurrentDate.getDate() + 1);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() + 1);
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps to the previous day
- */
- } else if (keycode == getBackwardKey() && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() - 1);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() - 1);
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps one week back in the calendar
- */
- } else if (keycode == getPreviousKey() && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() - 7);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()
- && focusedRow > 1) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate = newCurrentDate;
- renderCalendar();
- }
-
- return true;
-
- /*
- * Jumps one week forward in the calendar
- */
- } else if (keycode == getNextKey() && !ctrl && !shift) {
- // Calculate new showing value
- Date newCurrentDate = (Date) focusedDate.clone();
- newCurrentDate.setDate(newCurrentDate.getDate() + 7);
-
- if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
- // Month did not change, only move the selection
- focusDay(newCurrentDate);
- } else {
- // If the month changed we need to re-render the calendar
- focusedDate = newCurrentDate;
- renderCalendar();
-
- }
-
- return true;
-
- /*
- * Selects the value that is chosen
- */
- } else if (keycode == getSelectKey() && !shift) {
- selectFocused();
- onSubmit(); // submit
- return true;
- } else if (keycode == getCloseKey()) {
- onCancel();
- // TODO close event
-
- return true;
-
- /*
- * Jumps to the next month
- */
- } else if (shift && keycode == getForwardKey()) {
- focusNextMonth();
- return true;
-
- /*
- * Jumps to the previous month
- */
- } else if (shift && keycode == getBackwardKey()) {
- focusPreviousMonth();
- return true;
-
- /*
- * Jumps to the next year
- */
- } else if (shift && keycode == getPreviousKey()) {
- focusNextYear(1);
- return true;
-
- /*
- * Jumps to the previous year
- */
- } else if (shift && keycode == getNextKey()) {
- focusPreviousYear(1);
- return true;
-
- /*
- * Resets the selection
- */
- } else if (keycode == getResetKey() && !shift) {
- // Restore showing value the selected value
- focusedDate.setTime(value.getTime());
- renderCalendar();
- return true;
- }
-
- return false;
- }
-
- /**
- * Handles the keyboard navigation
- *
- * @param keycode
- * The key code that was pressed
- * @param ctrl
- * Was the ctrl key pressed
- * @param shift
- * Was the shift key pressed
- * @return Return true if key press was handled by the component, else
- * return false
- */
- protected boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
- if (!isEnabled() || isReadonly()) {
- return false;
- }
-
- else if (resolution == VDateField.RESOLUTION_YEAR) {
- return handleNavigationYearMode(keycode, ctrl, shift);
- }
-
- else if (resolution == VDateField.RESOLUTION_MONTH) {
- return handleNavigationMonthMode(keycode, ctrl, shift);
- }
-
- else if (resolution == VDateField.RESOLUTION_DAY) {
- return handleNavigationDayMode(keycode, ctrl, shift);
- }
-
- else {
- return handleNavigationDayMode(keycode, ctrl, shift);
- }
-
- }
-
- /**
- * Returns the reset key which will reset the calendar to the previous
- * selection. By default this is backspace but it can be overriden to change
- * the key to whatever you want.
- *
- * @return
- */
- protected int getResetKey() {
- return KeyCodes.KEY_BACKSPACE;
- }
-
- /**
- * Returns the select key which selects the value. By default this is the
- * enter key but it can be changed to whatever you like by overriding this
- * method.
- *
- * @return
- */
- protected int getSelectKey() {
- return KeyCodes.KEY_ENTER;
- }
-
- /**
- * Returns the key that closes the popup window if this is a VPopopCalendar.
- * Else this does nothing. By default this is the Escape key but you can
- * change the key to whatever you want by overriding this method.
- *
- * @return
- */
- protected int getCloseKey() {
- return KeyCodes.KEY_ESCAPE;
- }
-
- /**
- * The key that selects the next day in the calendar. By default this is the
- * right arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getForwardKey() {
- return KeyCodes.KEY_RIGHT;
- }
-
- /**
- * The key that selects the previous day in the calendar. By default this is
- * the left arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getBackwardKey() {
- return KeyCodes.KEY_LEFT;
- }
-
- /**
- * The key that selects the next week in the calendar. By default this is
- * the down arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getNextKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * The key that selects the previous week in the calendar. By default this
- * is the up arrow key but by overriding this method it can be changed to
- * whatever you like.
- *
- * @return
- */
- protected int getPreviousKey() {
- return KeyCodes.KEY_UP;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google
- * .gwt.event.dom.client.MouseOutEvent)
- */
- public void onMouseOut(MouseOutEvent event) {
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
- * .gwt.event.dom.client.MouseDownEvent)
- */
- public void onMouseDown(MouseDownEvent event) {
- // Allow user to click-n-hold for fast-forward or fast-rewind.
- // Timer is first used for a 500ms delay after mousedown. After that has
- // elapsed, another timer is triggered to go off every 150ms. Both
- // timers are cancelled on mouseup or mouseout.
- if (event.getSource() instanceof VEventButton) {
- final VEventButton sender = (VEventButton) event.getSource();
- processClickEvent(sender);
- mouseTimer = new Timer() {
- @Override
- public void run() {
- mouseTimer = new Timer() {
- @Override
- public void run() {
- processClickEvent(sender);
- }
- };
- mouseTimer.scheduleRepeating(150);
- }
- };
- mouseTimer.schedule(500);
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt
- * .event.dom.client.MouseUpEvent)
- */
- public void onMouseUp(MouseUpEvent event) {
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-
- /**
- * Sets the data of the Panel.
- *
- * @param currentDate
- * The date to set
- */
- public void setDate(Date currentDate) {
-
- // Check that we are not re-rendering an already active date
- if (currentDate == value && currentDate != null) {
- return;
- }
-
- Date oldDisplayedMonth = displayedMonth;
- value = currentDate;
-
- if (value == null) {
- focusedDate = displayedMonth = null;
- } else {
- focusedDate = (Date) value.clone();
- displayedMonth = (Date) value.clone();
- }
-
- // Re-render calendar if month or year of focused date has changed
- if (oldDisplayedMonth == null || value == null
- || oldDisplayedMonth.getYear() != value.getYear()
- || oldDisplayedMonth.getMonth() != value.getMonth()) {
- renderCalendar();
- } else {
- focusDay(currentDate);
- selectFocused();
- }
-
- if (!hasFocus) {
- focusDay((Date) null);
- }
- }
-
- /**
- * TimeSelector is a widget consisting of list boxes that modifie the Date
- * object that is given for.
- *
- */
- public class VTime extends FlowPanel implements ChangeHandler {
-
- private ListBox hours;
-
- private ListBox mins;
-
- private ListBox sec;
-
- private ListBox ampm;
-
- /**
- * Constructor
- */
- public VTime() {
- super();
- setStyleName(VDateField.CLASSNAME + "-time");
- buildTime();
- }
-
- private ListBox createListBox() {
- ListBox lb = new ListBox();
- lb.setStyleName(VNativeSelect.CLASSNAME);
- lb.addChangeHandler(this);
- lb.addBlurHandler(VCalendarPanel.this);
- lb.addFocusHandler(VCalendarPanel.this);
- return lb;
- }
-
- /**
- * Constructs the ListBoxes and updates their value
- *
- * @param redraw
- * Should new instances of the listboxes be created
- */
- private void buildTime() {
- clear();
-
- hours = createListBox();
- if (getDateTimeService().isTwelveHourClock()) {
- hours.addItem("12");
- for (int i = 1; i < 12; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
- }
- } else {
- for (int i = 0; i < 24; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
- }
- }
-
- hours.addChangeHandler(this);
- if (getDateTimeService().isTwelveHourClock()) {
- ampm = createListBox();
- final String[] ampmText = getDateTimeService().getAmPmStrings();
- ampm.addItem(ampmText[0]);
- ampm.addItem(ampmText[1]);
- ampm.addChangeHandler(this);
- }
-
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- mins = createListBox();
- for (int i = 0; i < 60; i++) {
- mins.addItem((i < 10) ? "0" + i : "" + i);
- }
- mins.addChangeHandler(this);
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- sec = createListBox();
- for (int i = 0; i < 60; i++) {
- sec.addItem((i < 10) ? "0" + i : "" + i);
- }
- sec.addChangeHandler(this);
- }
-
- final String delimiter = getDateTimeService().getClockDelimeter();
- if (isReadonly()) {
- int h = 0;
- if (value != null) {
- h = value.getHours();
- }
- if (getDateTimeService().isTwelveHourClock()) {
- h -= h < 12 ? 0 : 12;
- }
- add(new VLabel(h < 10 ? "0" + h : "" + h));
- } else {
- add(hours);
- }
-
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- add(new VLabel(delimiter));
- if (isReadonly()) {
- final int m = mins.getSelectedIndex();
- add(new VLabel(m < 10 ? "0" + m : "" + m));
- } else {
- add(mins);
- }
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- add(new VLabel(delimiter));
- if (isReadonly()) {
- final int s = sec.getSelectedIndex();
- add(new VLabel(s < 10 ? "0" + s : "" + s));
- } else {
- add(sec);
- }
- }
- if (getResolution() == VDateField.RESOLUTION_HOUR) {
- add(new VLabel(delimiter + "00")); // o'clock
- }
- if (getDateTimeService().isTwelveHourClock()) {
- add(new VLabel("&nbsp;"));
- if (isReadonly()) {
- int i = 0;
- if (value != null) {
- i = (value.getHours() < 12) ? 0 : 1;
- }
- add(new VLabel(ampm.getItemText(i)));
- } else {
- add(ampm);
- }
- }
-
- if (isReadonly()) {
- return;
- }
-
- // Update times
- updateTimes();
-
- ListBox lastDropDown = getLastDropDown();
- lastDropDown.addKeyDownHandler(new KeyDownHandler() {
- public void onKeyDown(KeyDownEvent event) {
- boolean shiftKey = event.getNativeEvent().getShiftKey();
- if (shiftKey) {
- return;
- } else {
- int nativeKeyCode = event.getNativeKeyCode();
- if (nativeKeyCode == KeyCodes.KEY_TAB) {
- onTabOut(event);
- }
- }
- }
- });
-
- }
-
- private ListBox getLastDropDown() {
- int i = getWidgetCount() - 1;
- while (i >= 0) {
- Widget widget = getWidget(i);
- if (widget instanceof ListBox) {
- return (ListBox) widget;
- }
- i--;
- }
- return null;
- }
-
- /**
- * Updates the valus to correspond to the values in value
- */
- public void updateTimes() {
- boolean selected = true;
- if (value == null) {
- value = new Date();
- selected = false;
- }
- if (getDateTimeService().isTwelveHourClock()) {
- int h = value.getHours();
- ampm.setSelectedIndex(h < 12 ? 0 : 1);
- h -= ampm.getSelectedIndex() * 12;
- hours.setSelectedIndex(h);
- } else {
- hours.setSelectedIndex(value.getHours());
- }
- if (getResolution() >= VDateField.RESOLUTION_MIN) {
- mins.setSelectedIndex(value.getMinutes());
- }
- if (getResolution() >= VDateField.RESOLUTION_SEC) {
- sec.setSelectedIndex(value.getSeconds());
- }
- if (getDateTimeService().isTwelveHourClock()) {
- ampm.setSelectedIndex(value.getHours() < 12 ? 0 : 1);
- }
-
- hours.setEnabled(isEnabled());
- if (mins != null) {
- mins.setEnabled(isEnabled());
- }
- if (sec != null) {
- sec.setEnabled(isEnabled());
- }
- if (ampm != null) {
- ampm.setEnabled(isEnabled());
- }
-
- }
-
- private int getMilliseconds() {
- return DateTimeService.getMilliseconds(value);
- }
-
- private DateTimeService getDateTimeService() {
- if (dateTimeService == null) {
- dateTimeService = new DateTimeService();
- }
- return dateTimeService;
- }
-
- /*
- * (non-Javadoc) VT
- *
- * @see
- * com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt
- * .event.dom.client.ChangeEvent)
- */
- public void onChange(ChangeEvent event) {
- /*
- * Value from dropdowns gets always set for the value. Like year and
- * month when resolution is month or year.
- */
- if (event.getSource() == hours) {
- int h = hours.getSelectedIndex();
- if (getDateTimeService().isTwelveHourClock()) {
- h = h + ampm.getSelectedIndex() * 12;
- }
- value.setHours(h);
- if (timeChangeListener != null) {
- timeChangeListener.changed(h, value.getMinutes(),
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == mins) {
- final int m = mins.getSelectedIndex();
- value.setMinutes(m);
- if (timeChangeListener != null) {
- timeChangeListener.changed(value.getHours(), m,
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == sec) {
- final int s = sec.getSelectedIndex();
- value.setSeconds(s);
- if (timeChangeListener != null) {
- timeChangeListener.changed(value.getHours(),
- value.getMinutes(), s,
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- } else if (event.getSource() == ampm) {
- final int h = hours.getSelectedIndex()
- + (ampm.getSelectedIndex() * 12);
- value.setHours(h);
- if (timeChangeListener != null) {
- timeChangeListener.changed(h, value.getMinutes(),
- value.getSeconds(),
- DateTimeService.getMilliseconds(value));
- }
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- }
-
- private class Day extends InlineHTML {
- private static final String BASECLASS = VDateField.CLASSNAME
- + "-calendarpanel-day";
- private final Date date;
-
- Day(Date date) {
- super("" + date.getDate());
- setStyleName(BASECLASS);
- this.date = date;
- addClickHandler(dayClickHandler);
- }
-
- public Date getDate() {
- return date;
- }
- }
-
- public Date getDate() {
- return value;
- }
-
- /**
- * If true should be returned if the panel will not be used after this
- * event.
- *
- * @param event
- * @return
- */
- protected boolean onTabOut(DomEvent<?> event) {
- if (focusOutListener != null) {
- return focusOutListener.onFocusOut(event);
- }
- return false;
- }
-
- /**
- * A focus out listener is triggered when the panel loosed focus. This can
- * happen either after a user clicks outside the panel or tabs out.
- *
- * @param listener
- * The listener to trigger
- */
- public void setFocusOutListener(FocusOutListener listener) {
- focusOutListener = listener;
- }
-
- /**
- * The submit listener is called when the user selects a value from the
- * calender either by clicking the day or selects it by keyboard.
- *
- * @param submitListener
- * The listener to trigger
- */
- public void setSubmitListener(SubmitListener submitListener) {
- this.submitListener = submitListener;
- }
-
- /**
- * The given FocusChangeListener is notified when the focused date changes
- * by user either clicking on a new date or by using the keyboard.
- *
- * @param listener
- * The FocusChangeListener to be notified
- */
- public void setFocusChangeListener(FocusChangeListener listener) {
- focusChangeListener = listener;
- }
-
- /**
- * The time change listener is triggered when the user changes the time.
- *
- * @param listener
- */
- public void setTimeChangeListener(TimeChangeListener listener) {
- timeChangeListener = listener;
- }
-
- /**
- * Returns the submit listener that listens to selection made from the panel
- *
- * @return The listener or NULL if no listener has been set
- */
- public SubmitListener getSubmitListener() {
- return submitListener;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
- * .dom.client.BlurEvent)
- */
- public void onBlur(final BlurEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
- hasFocus = false;
- focusDay(null);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event
- * .dom.client.FocusEvent)
- */
- public void onFocus(FocusEvent event) {
- if (event.getSource() instanceof VCalendarPanel) {
- hasFocus = true;
-
- // Focuses the current day if the calendar shows the days
- if (focusedDay != null) {
- focusDay(focusedDate);
- }
- }
- }
-
- private static final String SUBPART_NEXT_MONTH = "nextmon";
- private static final String SUBPART_PREV_MONTH = "prevmon";
-
- private static final String SUBPART_NEXT_YEAR = "nexty";
- private static final String SUBPART_PREV_YEAR = "prevy";
- private static final String SUBPART_HOUR_SELECT = "h";
- private static final String SUBPART_MINUTE_SELECT = "m";
- private static final String SUBPART_SECS_SELECT = "s";
- private static final String SUBPART_MSECS_SELECT = "ms";
- private static final String SUBPART_AMPM_SELECT = "ampm";
- private static final String SUBPART_DAY = "day";
- private static final String SUBPART_MONTH_YEAR_HEADER = "header";
-
- public String getSubPartName(Element subElement) {
- if (contains(nextMonth, subElement)) {
- return SUBPART_NEXT_MONTH;
- } else if (contains(prevMonth, subElement)) {
- return SUBPART_PREV_MONTH;
- } else if (contains(nextYear, subElement)) {
- return SUBPART_NEXT_YEAR;
- } else if (contains(prevYear, subElement)) {
- return SUBPART_PREV_YEAR;
- } else if (contains(days, subElement)) {
- // Day, find out which dayOfMonth and use that as the identifier
- Day day = Util.findWidget(subElement, Day.class);
- if (day != null) {
- Date date = day.getDate();
- int id = date.getDate();
- if (date.getMonth() < displayedMonth.getMonth()) {
- id -= DateTimeService.getNumberOfDaysInMonth(date);
- } else if (date.getMonth() > displayedMonth.getMonth()) {
- id += DateTimeService
- .getNumberOfDaysInMonth(displayedMonth);
- }
- return SUBPART_DAY + id;
- }
- } else if (time != null) {
- if (contains(time.hours, subElement)) {
- return SUBPART_HOUR_SELECT;
- } else if (contains(time.mins, subElement)) {
- return SUBPART_MINUTE_SELECT;
- } else if (contains(time.sec, subElement)) {
- return SUBPART_SECS_SELECT;
- } else if (contains(time.ampm, subElement)) {
- return SUBPART_AMPM_SELECT;
-
- }
- } else if (getCellFormatter().getElement(0, 2).isOrHasChild(subElement)) {
- return SUBPART_MONTH_YEAR_HEADER;
- }
-
- return null;
- }
-
- /**
- * Checks if subElement is inside the widget DOM hierarchy.
- *
- * @param w
- * @param subElement
- * @return true if {@code w} is a parent of subElement, false otherwise.
- */
- private boolean contains(Widget w, Element subElement) {
- if (w == null || w.getElement() == null) {
- return false;
- }
-
- return w.getElement().isOrHasChild(subElement);
- }
-
- public Element getSubPartElement(String subPart) {
- if (SUBPART_NEXT_MONTH.equals(subPart)) {
- return nextMonth.getElement();
- }
- if (SUBPART_PREV_MONTH.equals(subPart)) {
- return prevMonth.getElement();
- }
- if (SUBPART_NEXT_YEAR.equals(subPart)) {
- return nextYear.getElement();
- }
- if (SUBPART_PREV_YEAR.equals(subPart)) {
- return prevYear.getElement();
- }
- if (SUBPART_HOUR_SELECT.equals(subPart)) {
- return time.hours.getElement();
- }
- if (SUBPART_MINUTE_SELECT.equals(subPart)) {
- return time.mins.getElement();
- }
- if (SUBPART_SECS_SELECT.equals(subPart)) {
- return time.sec.getElement();
- }
- if (SUBPART_AMPM_SELECT.equals(subPart)) {
- return time.ampm.getElement();
- }
- if (subPart.startsWith(SUBPART_DAY)) {
- // can be less than 1 or greater than the number of days in the current month
- // these map to the "off-month" days
- int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY
- .length()));
- Date date = new Date(displayedMonth.getYear(),
- displayedMonth.getMonth(), dayOfMonth);
- Iterator<Widget> iter = days.iterator();
- while (iter.hasNext()) {
- Widget w = iter.next();
- if (w instanceof Day) {
- Day day = (Day) w;
- if (day.getDate().equals(date)) {
- return day.getElement();
- }
- }
- }
- }
-
- if (SUBPART_MONTH_YEAR_HEADER.equals(subPart)) {
- return (Element) getCellFormatter().getElement(0, 2).getChild(0);
- }
- return null;
- }
-
- @Override
- protected void onDetach() {
- super.onDetach();
- if (mouseTimer != null) {
- mouseTimer.cancel();
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+import java.util.Iterator;
+
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseUpEvent;
+import com.google.gwt.event.dom.client.MouseUpHandler;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.InlineHTML;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.ui.label.VLabel;
+
+@SuppressWarnings("deprecation")
+public class VCalendarPanel extends FocusableFlexTable implements
+ KeyDownHandler, KeyPressHandler, MouseOutHandler, MouseDownHandler,
+ MouseUpHandler, BlurHandler, FocusHandler, SubPartAware {
+
+ public interface SubmitListener {
+
+ /**
+ * Called when calendar user triggers a submitting operation in calendar
+ * panel. Eg. clicking on day or hitting enter.
+ */
+ void onSubmit();
+
+ /**
+ * On eg. ESC key.
+ */
+ void onCancel();
+ }
+
+ /**
+ * Blur listener that listens to blur event from the panel
+ */
+ public interface FocusOutListener {
+ /**
+ * @return true if the calendar panel is not used after focus moves out
+ */
+ boolean onFocusOut(DomEvent<?> event);
+ }
+
+ /**
+ * FocusChangeListener is notified when the panel changes its _focused_
+ * value.
+ */
+ public interface FocusChangeListener {
+ void focusChanged(Date focusedDate);
+ }
+
+ /**
+ * Dispatches an event when the panel when time is changed
+ */
+ public interface TimeChangeListener {
+
+ void changed(int hour, int min, int sec, int msec);
+ }
+
+ /**
+ * Represents a Date button in the calendar
+ */
+ private class VEventButton extends Button {
+ public VEventButton() {
+ addMouseDownHandler(VCalendarPanel.this);
+ addMouseOutHandler(VCalendarPanel.this);
+ addMouseUpHandler(VCalendarPanel.this);
+ }
+ }
+
+ private static final String CN_FOCUSED = "focused";
+
+ private static final String CN_TODAY = "today";
+
+ private static final String CN_SELECTED = "selected";
+
+ private static final String CN_OFFMONTH = "offmonth";
+
+ /**
+ * Represents a click handler for when a user selects a value by using the
+ * mouse
+ */
+ private ClickHandler dayClickHandler = new ClickHandler() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
+ * .event.dom.client.ClickEvent)
+ */
+ public void onClick(ClickEvent event) {
+ Day day = (Day) event.getSource();
+ focusDay(day.getDate());
+ selectFocused();
+ onSubmit();
+ }
+ };
+
+ private VEventButton prevYear;
+
+ private VEventButton nextYear;
+
+ private VEventButton prevMonth;
+
+ private VEventButton nextMonth;
+
+ private VTime time;
+
+ private FlexTable days = new FlexTable();
+
+ private int resolution = VDateField.RESOLUTION_YEAR;
+
+ private int focusedRow;
+
+ private Timer mouseTimer;
+
+ private Date value;
+
+ private boolean enabled = true;
+
+ private boolean readonly = false;
+
+ private DateTimeService dateTimeService;
+
+ private boolean showISOWeekNumbers;
+
+ private Date displayedMonth;
+
+ private Date focusedDate;
+
+ private Day selectedDay;
+
+ private Day focusedDay;
+
+ private FocusOutListener focusOutListener;
+
+ private SubmitListener submitListener;
+
+ private FocusChangeListener focusChangeListener;
+
+ private TimeChangeListener timeChangeListener;
+
+ private boolean hasFocus = false;
+
+ public VCalendarPanel() {
+
+ setStyleName(VDateField.CLASSNAME + "-calendarpanel");
+
+ /*
+ * Firefox auto-repeat works correctly only if we use a key press
+ * handler, other browsers handle it correctly when using a key down
+ * handler
+ */
+ if (BrowserInfo.get().isGecko()) {
+ addKeyPressHandler(this);
+ } else {
+ addKeyDownHandler(this);
+ }
+ addFocusHandler(this);
+ addBlurHandler(this);
+
+ }
+
+ /**
+ * Sets the focus to given date in the current view. Used when moving in the
+ * calendar with the keyboard.
+ *
+ * @param date
+ * A Date representing the day of month to be focused. Must be
+ * one of the days currently visible.
+ */
+ private void focusDay(Date date) {
+ // Only used when calender body is present
+ if (resolution > VDateField.RESOLUTION_MONTH) {
+ if (focusedDay != null) {
+ focusedDay.removeStyleDependentName(CN_FOCUSED);
+ }
+
+ if (date != null && focusedDate != null) {
+ focusedDate.setTime(date.getTime());
+ int rowCount = days.getRowCount();
+ for (int i = 0; i < rowCount; i++) {
+ int cellCount = days.getCellCount(i);
+ for (int j = 0; j < cellCount; j++) {
+ Widget widget = days.getWidget(i, j);
+ if (widget != null && widget instanceof Day) {
+ Day curday = (Day) widget;
+ if (curday.getDate().equals(date)) {
+ curday.addStyleDependentName(CN_FOCUSED);
+ focusedDay = curday;
+ focusedRow = i;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the selection highlight to a given day in the current view
+ *
+ * @param date
+ * A Date representing the day of month to be selected. Must be
+ * one of the days currently visible.
+ *
+ */
+ private void selectDate(Date date) {
+ if (selectedDay != null) {
+ selectedDay.removeStyleDependentName(CN_SELECTED);
+ }
+
+ int rowCount = days.getRowCount();
+ for (int i = 0; i < rowCount; i++) {
+ int cellCount = days.getCellCount(i);
+ for (int j = 0; j < cellCount; j++) {
+ Widget widget = days.getWidget(i, j);
+ if (widget != null && widget instanceof Day) {
+ Day curday = (Day) widget;
+ if (curday.getDate().equals(date)) {
+ curday.addStyleDependentName(CN_SELECTED);
+ selectedDay = curday;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates year, month, day from focusedDate to value
+ */
+ private void selectFocused() {
+ if (focusedDate != null) {
+ if (value == null) {
+ // No previously selected value (set to null on server side).
+ // Create a new date using current date and time
+ value = new Date();
+ }
+ /*
+ * #5594 set Date (day) to 1 in order to prevent any kind of
+ * wrapping of months when later setting the month. (e.g. 31 ->
+ * month with 30 days -> wraps to the 1st of the following month,
+ * e.g. 31st of May -> 31st of April = 1st of May)
+ */
+ value.setDate(1);
+ if (value.getYear() != focusedDate.getYear()) {
+ value.setYear(focusedDate.getYear());
+ }
+ if (value.getMonth() != focusedDate.getMonth()) {
+ value.setMonth(focusedDate.getMonth());
+ }
+ if (value.getDate() != focusedDate.getDate()) {
+ }
+ // We always need to set the date, even if it hasn't changed, since
+ // it was forced to 1 above.
+ value.setDate(focusedDate.getDate());
+
+ selectDate(focusedDate);
+ } else {
+ VConsole.log("Trying to select a the focused date which is NULL!");
+ }
+ }
+
+ protected boolean onValueChange() {
+ return false;
+ }
+
+ public int getResolution() {
+ return resolution;
+ }
+
+ public void setResolution(int resolution) {
+ this.resolution = resolution;
+ if (time != null) {
+ time.removeFromParent();
+ time = null;
+ }
+ }
+
+ private boolean isReadonly() {
+ return readonly;
+ }
+
+ private boolean isEnabled() {
+ return enabled;
+ }
+
+ private void clearCalendarBody(boolean remove) {
+ if (!remove) {
+ // Leave the cells in place but clear their contents
+
+ // This has the side effect of ensuring that the calendar always
+ // contain 7 rows.
+ for (int row = 1; row < 7; row++) {
+ for (int col = 0; col < 8; col++) {
+ days.setHTML(row, col, "&nbsp;");
+ }
+ }
+ } else if (getRowCount() > 1) {
+ removeRow(1);
+ days.clear();
+ }
+ }
+
+ /**
+ * Builds the top buttons and current month and year header.
+ *
+ * @param needsMonth
+ * Should the month buttons be visible?
+ */
+ private void buildCalendarHeader(boolean needsMonth) {
+
+ getRowFormatter().addStyleName(0,
+ VDateField.CLASSNAME + "-calendarpanel-header");
+
+ if (prevMonth == null && needsMonth) {
+ prevMonth = new VEventButton();
+ prevMonth.setHTML("&lsaquo;");
+ prevMonth.setStyleName("v-button-prevmonth");
+ prevMonth.setTabIndex(-1);
+ nextMonth = new VEventButton();
+ nextMonth.setHTML("&rsaquo;");
+ nextMonth.setStyleName("v-button-nextmonth");
+ nextMonth.setTabIndex(-1);
+ getFlexCellFormatter().setStyleName(0, 3,
+ VDateField.CLASSNAME + "-calendarpanel-nextmonth");
+ getFlexCellFormatter().setStyleName(0, 1,
+ VDateField.CLASSNAME + "-calendarpanel-prevmonth");
+
+ setWidget(0, 3, nextMonth);
+ setWidget(0, 1, prevMonth);
+ } else if (prevMonth != null && !needsMonth) {
+ // Remove month traverse buttons
+ remove(prevMonth);
+ remove(nextMonth);
+ prevMonth = null;
+ nextMonth = null;
+ }
+
+ if (prevYear == null) {
+ prevYear = new VEventButton();
+ prevYear.setHTML("&laquo;");
+ prevYear.setStyleName("v-button-prevyear");
+ prevYear.setTabIndex(-1);
+ nextYear = new VEventButton();
+ nextYear.setHTML("&raquo;");
+ nextYear.setStyleName("v-button-nextyear");
+ nextYear.setTabIndex(-1);
+ setWidget(0, 0, prevYear);
+ setWidget(0, 4, nextYear);
+ getFlexCellFormatter().setStyleName(0, 0,
+ VDateField.CLASSNAME + "-calendarpanel-prevyear");
+ getFlexCellFormatter().setStyleName(0, 4,
+ VDateField.CLASSNAME + "-calendarpanel-nextyear");
+ }
+
+ final String monthName = needsMonth ? getDateTimeService().getMonth(
+ focusedDate.getMonth()) : "";
+ final int year = focusedDate.getYear() + 1900;
+ getFlexCellFormatter().setStyleName(0, 2,
+ VDateField.CLASSNAME + "-calendarpanel-month");
+ setHTML(0, 2, "<span class=\"" + VDateField.CLASSNAME
+ + "-calendarpanel-month\">" + monthName + " " + year
+ + "</span>");
+ }
+
+ private DateTimeService getDateTimeService() {
+ return dateTimeService;
+ }
+
+ public void setDateTimeService(DateTimeService dateTimeService) {
+ this.dateTimeService = dateTimeService;
+ }
+
+ /**
+ * Returns whether ISO 8601 week numbers should be shown in the value
+ * selector or not. ISO 8601 defines that a week always starts with a Monday
+ * so the week numbers are only shown if this is the case.
+ *
+ * @return true if week number should be shown, false otherwise
+ */
+ public boolean isShowISOWeekNumbers() {
+ return showISOWeekNumbers;
+ }
+
+ public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
+ this.showISOWeekNumbers = showISOWeekNumbers;
+ }
+
+ /**
+ * Builds the day and time selectors of the calendar.
+ */
+ private void buildCalendarBody() {
+
+ final int weekColumn = 0;
+ final int firstWeekdayColumn = 1;
+ final int headerRow = 0;
+
+ setWidget(1, 0, days);
+ setCellPadding(0);
+ setCellSpacing(0);
+ getFlexCellFormatter().setColSpan(1, 0, 5);
+ getFlexCellFormatter().setStyleName(1, 0,
+ VDateField.CLASSNAME + "-calendarpanel-body");
+
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
+ "v-week");
+ days.setHTML(headerRow, weekColumn, "<strong></strong>");
+ // Hide the week column if week numbers are not to be displayed.
+ days.getFlexCellFormatter().setVisible(headerRow, weekColumn,
+ isShowISOWeekNumbers());
+
+ days.getRowFormatter().setStyleName(headerRow,
+ VDateField.CLASSNAME + "-calendarpanel-weekdays");
+
+ if (isShowISOWeekNumbers()) {
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
+ "v-first");
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn, "");
+ days.getRowFormatter().addStyleName(headerRow,
+ VDateField.CLASSNAME + "-calendarpanel-weeknumbers");
+ } else {
+ days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "");
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn, "v-first");
+ }
+
+ days.getFlexCellFormatter().setStyleName(headerRow,
+ firstWeekdayColumn + 6, "v-last");
+
+ // Print weekday names
+ final int firstDay = getDateTimeService().getFirstDayOfWeek();
+ for (int i = 0; i < 7; i++) {
+ int day = i + firstDay;
+ if (day > 6) {
+ day = 0;
+ }
+ if (getResolution() > VDateField.RESOLUTION_MONTH) {
+ days.setHTML(headerRow, firstWeekdayColumn + i, "<strong>"
+ + getDateTimeService().getShortDay(day) + "</strong>");
+ } else {
+ days.setHTML(headerRow, firstWeekdayColumn + i, "");
+ }
+ }
+
+ // Zero out hours, minutes, seconds, and milliseconds to compare dates
+ // without time part
+ final Date tmp = new Date();
+ final Date today = new Date(tmp.getYear(), tmp.getMonth(),
+ tmp.getDate());
+
+ final Date selectedDate = value == null ? null : new Date(
+ value.getYear(), value.getMonth(), value.getDate());
+
+ final int startWeekDay = getDateTimeService().getStartWeekDay(
+ displayedMonth);
+ final Date curr = (Date) displayedMonth.clone();
+ // Start from the first day of the week that at least partially belongs
+ // to the current month
+ curr.setDate(1 - startWeekDay);
+
+ // No month has more than 6 weeks so 6 is a safe maximum for rows.
+ for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {
+ for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
+
+ // Actually write the day of month
+ Day day = new Day((Date) curr.clone());
+
+ if (curr.equals(selectedDate)) {
+ day.addStyleDependentName(CN_SELECTED);
+ selectedDay = day;
+ }
+ if (curr.equals(today)) {
+ day.addStyleDependentName(CN_TODAY);
+ }
+ if (curr.equals(focusedDate)) {
+ focusedDay = day;
+ focusedRow = weekOfMonth;
+ if (hasFocus) {
+ day.addStyleDependentName(CN_FOCUSED);
+ }
+ }
+ if (curr.getMonth() != displayedMonth.getMonth()) {
+ day.addStyleDependentName(CN_OFFMONTH);
+ }
+
+ days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);
+
+ // ISO week numbers if requested
+ days.getCellFormatter().setVisible(weekOfMonth, weekColumn,
+ isShowISOWeekNumbers());
+ if (isShowISOWeekNumbers()) {
+ final String baseCssClass = VDateField.CLASSNAME
+ + "-calendarpanel-weeknumber";
+ String weekCssClass = baseCssClass;
+
+ int weekNumber = DateTimeService.getISOWeekNumber(curr);
+
+ days.setHTML(weekOfMonth, 0, "<span class=\""
+ + weekCssClass + "\"" + ">" + weekNumber
+ + "</span>");
+ }
+ curr.setDate(curr.getDate() + 1);
+ }
+ }
+ }
+
+ /**
+ * Do we need the time selector
+ *
+ * @return True if it is required
+ */
+ private boolean isTimeSelectorNeeded() {
+ return getResolution() > VDateField.RESOLUTION_DAY;
+ }
+
+ /**
+ * Updates the calendar and text field with the selected dates.
+ */
+ public void renderCalendar() {
+ if (focusedDate == null) {
+ Date now = new Date();
+ // focusedDate must have zero hours, mins, secs, millisecs
+ focusedDate = new Date(now.getYear(), now.getMonth(), now.getDate());
+ displayedMonth = new Date(now.getYear(), now.getMonth(), 1);
+ }
+
+ if (getResolution() <= VDateField.RESOLUTION_MONTH
+ && focusChangeListener != null) {
+ focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
+ }
+
+ final boolean needsMonth = getResolution() > VDateField.RESOLUTION_YEAR;
+ boolean needsBody = getResolution() >= VDateField.RESOLUTION_DAY;
+ buildCalendarHeader(needsMonth);
+ clearCalendarBody(!needsBody);
+ if (needsBody) {
+ buildCalendarBody();
+ }
+
+ if (isTimeSelectorNeeded() && time == null) {
+ time = new VTime();
+ setWidget(2, 0, time);
+ getFlexCellFormatter().setColSpan(2, 0, 5);
+ getFlexCellFormatter().setStyleName(2, 0,
+ VDateField.CLASSNAME + "-calendarpanel-time");
+ } else if (isTimeSelectorNeeded()) {
+ time.updateTimes();
+ } else if (time != null) {
+ remove(time);
+ }
+ }
+
+ /**
+ * Moves the focus forward the given number of days.
+ */
+ private void focusNextDay(int days) {
+ int oldMonth = focusedDate.getMonth();
+ focusedDate.setDate(focusedDate.getDate() + days);
+
+ if (focusedDate.getMonth() == oldMonth) {
+ // Month did not change, only move the selection
+ focusDay(focusedDate);
+ } else {
+ // If the month changed we need to re-render the calendar
+ displayedMonth.setMonth(focusedDate.getMonth());
+ renderCalendar();
+ }
+ }
+
+ /**
+ * Moves the focus backward the given number of days.
+ */
+ private void focusPreviousDay(int days) {
+ focusNextDay(-days);
+ }
+
+ /**
+ * Selects the next month
+ */
+ private void focusNextMonth() {
+
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setMonth(currentMonth + 1);
+ int requestedMonth = (currentMonth + 1) % 12;
+
+ /*
+ * If the selected value was e.g. 31.3 the new value would be 31.4 but
+ * this value is invalid so the new value will be 1.5. This is taken
+ * care of by decreasing the value until we have the correct month.
+ */
+ while (focusedDate.getMonth() != requestedMonth) {
+ focusedDate.setDate(focusedDate.getDate() - 1);
+ }
+ displayedMonth.setMonth(displayedMonth.getMonth() + 1);
+
+ renderCalendar();
+ }
+
+ /**
+ * Selects the previous month
+ */
+ private void focusPreviousMonth() {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setMonth(currentMonth - 1);
+
+ /*
+ * If the selected value was e.g. 31.12 the new value would be 31.11 but
+ * this value is invalid so the new value will be 1.12. This is taken
+ * care of by decreasing the value until we have the correct month.
+ */
+ while (focusedDate.getMonth() == currentMonth) {
+ focusedDate.setDate(focusedDate.getDate() - 1);
+ }
+ displayedMonth.setMonth(displayedMonth.getMonth() - 1);
+
+ renderCalendar();
+ }
+
+ /**
+ * Selects the previous year
+ */
+ private void focusPreviousYear(int years) {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setYear(focusedDate.getYear() - years);
+ displayedMonth.setYear(displayedMonth.getYear() - years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
+ renderCalendar();
+ }
+
+ /**
+ * Selects the next year
+ */
+ private void focusNextYear(int years) {
+ int currentMonth = focusedDate.getMonth();
+ focusedDate.setYear(focusedDate.getYear() + years);
+ displayedMonth.setYear(displayedMonth.getYear() + years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
+ renderCalendar();
+ }
+
+ /**
+ * Handles a user click on the component
+ *
+ * @param sender
+ * The component that was clicked
+ * @param updateVariable
+ * Should the value field be updated
+ *
+ */
+ private void processClickEvent(Widget sender) {
+ if (!isEnabled() || isReadonly()) {
+ return;
+ }
+ if (sender == prevYear) {
+ focusPreviousYear(1);
+ } else if (sender == nextYear) {
+ focusNextYear(1);
+ } else if (sender == prevMonth) {
+ focusPreviousMonth();
+ } else if (sender == nextMonth) {
+ focusNextMonth();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
+ * .event.dom.client.KeyDownEvent)
+ */
+ public void onKeyDown(KeyDownEvent event) {
+ handleKeyPress(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google
+ * .gwt.event.dom.client.KeyPressEvent)
+ */
+ public void onKeyPress(KeyPressEvent event) {
+ handleKeyPress(event);
+ }
+
+ /**
+ * Handles the keypress from both the onKeyPress event and the onKeyDown
+ * event
+ *
+ * @param event
+ * The keydown/keypress event
+ */
+ private void handleKeyPress(DomEvent<?> event) {
+ if (time != null
+ && time.getElement().isOrHasChild(
+ (Node) event.getNativeEvent().getEventTarget().cast())) {
+ int nativeKeyCode = event.getNativeEvent().getKeyCode();
+ if (nativeKeyCode == getSelectKey()) {
+ onSubmit(); // submit happens if enter key hit down on listboxes
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ return;
+ }
+
+ // Check tabs
+ int keycode = event.getNativeEvent().getKeyCode();
+ if (keycode == KeyCodes.KEY_TAB && event.getNativeEvent().getShiftKey()) {
+ if (onTabOut(event)) {
+ return;
+ }
+ }
+
+ // Handle the navigation
+ if (handleNavigation(keycode, event.getNativeEvent().getCtrlKey()
+ || event.getNativeEvent().getMetaKey(), event.getNativeEvent()
+ .getShiftKey())) {
+ event.preventDefault();
+ }
+
+ }
+
+ /**
+ * Notifies submit-listeners of a submit event
+ */
+ private void onSubmit() {
+ if (getSubmitListener() != null) {
+ getSubmitListener().onSubmit();
+ }
+ }
+
+ /**
+ * Notifies submit-listeners of a cancel event
+ */
+ private void onCancel() {
+ if (getSubmitListener() != null) {
+ getSubmitListener().onCancel();
+ }
+ }
+
+ /**
+ * Handles the keyboard navigation when the resolution is set to years.
+ *
+ * @param keycode
+ * The keycode to process
+ * @param ctrl
+ * Is ctrl pressed?
+ * @param shift
+ * is shift pressed
+ * @return Returns true if the keycode was processed, else false
+ */
+ protected boolean handleNavigationYearMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl and Shift selection not supported
+ if (ctrl || shift) {
+ return false;
+ }
+
+ else if (keycode == getPreviousKey()) {
+ focusNextYear(10); // Add 10 years
+ return true;
+ }
+
+ else if (keycode == getForwardKey()) {
+ focusNextYear(1); // Add 1 year
+ return true;
+ }
+
+ else if (keycode == getNextKey()) {
+ focusPreviousYear(10); // Subtract 10 years
+ return true;
+ }
+
+ else if (keycode == getBackwardKey()) {
+ focusPreviousYear(1); // Subtract 1 year
+ return true;
+
+ } else if (keycode == getSelectKey()) {
+ value = (Date) focusedDate.clone();
+ onSubmit();
+ return true;
+
+ } else if (keycode == getResetKey()) {
+ // Restore showing value the selected value
+ focusedDate.setTime(value.getTime());
+ renderCalendar();
+ return true;
+
+ } else if (keycode == getCloseKey()) {
+ // TODO fire listener, on users responsibility??
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Handle the keyboard navigation when the resolution is set to MONTH
+ *
+ * @param keycode
+ * The keycode to handle
+ * @param ctrl
+ * Was the ctrl key pressed?
+ * @param shift
+ * Was the shift key pressed?
+ * @return
+ */
+ protected boolean handleNavigationMonthMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl selection not supported
+ if (ctrl) {
+ return false;
+
+ } else if (keycode == getPreviousKey()) {
+ focusNextYear(1); // Add 1 year
+ return true;
+
+ } else if (keycode == getForwardKey()) {
+ focusNextMonth(); // Add 1 month
+ return true;
+
+ } else if (keycode == getNextKey()) {
+ focusPreviousYear(1); // Subtract 1 year
+ return true;
+
+ } else if (keycode == getBackwardKey()) {
+ focusPreviousMonth(); // Subtract 1 month
+ return true;
+
+ } else if (keycode == getSelectKey()) {
+ value = (Date) focusedDate.clone();
+ onSubmit();
+ return true;
+
+ } else if (keycode == getResetKey()) {
+ // Restore showing value the selected value
+ focusedDate.setTime(value.getTime());
+ renderCalendar();
+ return true;
+
+ } else if (keycode == getCloseKey() || keycode == KeyCodes.KEY_TAB) {
+
+ // TODO fire close event
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handle keyboard navigation what the resolution is set to DAY
+ *
+ * @param keycode
+ * The keycode to handle
+ * @param ctrl
+ * Was the ctrl key pressed?
+ * @param shift
+ * Was the shift key pressed?
+ * @return Return true if the key press was handled by the method, else
+ * return false.
+ */
+ protected boolean handleNavigationDayMode(int keycode, boolean ctrl,
+ boolean shift) {
+
+ // Ctrl key is not in use
+ if (ctrl) {
+ return false;
+ }
+
+ /*
+ * Jumps to the next day.
+ */
+ if (keycode == getForwardKey() && !shift) {
+ focusNextDay(1);
+ return true;
+
+ /*
+ * Jumps to the previous day
+ */
+ } else if (keycode == getBackwardKey() && !shift) {
+ focusPreviousDay(1);
+ return true;
+
+ /*
+ * Jumps one week forward in the calendar
+ */
+ } else if (keycode == getNextKey() && !shift) {
+ focusNextDay(7);
+ return true;
+
+ /*
+ * Jumps one week back in the calendar
+ */
+ } else if (keycode == getPreviousKey() && !shift) {
+ focusPreviousDay(7);
+ return true;
+
+ /*
+ * Selects the value that is chosen
+ */
+ } else if (keycode == getSelectKey() && !shift) {
+ selectFocused();
+ onSubmit(); // submit
+ return true;
+
+ } else if (keycode == getCloseKey()) {
+ onCancel();
+ // TODO close event
+
+ return true;
+
+ /*
+ * Jumps to the next month
+ */
+ } else if (shift && keycode == getForwardKey()) {
+ focusNextMonth();
+ return true;
+
+ /*
+ * Jumps to the previous month
+ */
+ } else if (shift && keycode == getBackwardKey()) {
+ focusPreviousMonth();
+ return true;
+
+ /*
+ * Jumps to the next year
+ */
+ } else if (shift && keycode == getPreviousKey()) {
+ focusNextYear(1);
+ return true;
+
+ /*
+ * Jumps to the previous year
+ */
+ } else if (shift && keycode == getNextKey()) {
+ focusPreviousYear(1);
+ return true;
+
+ /*
+ * Resets the selection
+ */
+ } else if (keycode == getResetKey() && !shift) {
+ // Restore showing value the selected value
+ focusedDate = new Date(value.getYear(), value.getMonth(),
+ value.getDate());
+ displayedMonth = new Date(value.getYear(), value.getMonth(), 1);
+ renderCalendar();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles the keyboard navigation
+ *
+ * @param keycode
+ * The key code that was pressed
+ * @param ctrl
+ * Was the ctrl key pressed
+ * @param shift
+ * Was the shift key pressed
+ * @return Return true if key press was handled by the component, else
+ * return false
+ */
+ protected boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
+ if (!isEnabled() || isReadonly()) {
+ return false;
+ }
+
+ else if (resolution == VDateField.RESOLUTION_YEAR) {
+ return handleNavigationYearMode(keycode, ctrl, shift);
+ }
+
+ else if (resolution == VDateField.RESOLUTION_MONTH) {
+ return handleNavigationMonthMode(keycode, ctrl, shift);
+ }
+
+ else if (resolution == VDateField.RESOLUTION_DAY) {
+ return handleNavigationDayMode(keycode, ctrl, shift);
+ }
+
+ else {
+ return handleNavigationDayMode(keycode, ctrl, shift);
+ }
+
+ }
+
+ /**
+ * Returns the reset key which will reset the calendar to the previous
+ * selection. By default this is backspace but it can be overriden to change
+ * the key to whatever you want.
+ *
+ * @return
+ */
+ protected int getResetKey() {
+ return KeyCodes.KEY_BACKSPACE;
+ }
+
+ /**
+ * Returns the select key which selects the value. By default this is the
+ * enter key but it can be changed to whatever you like by overriding this
+ * method.
+ *
+ * @return
+ */
+ protected int getSelectKey() {
+ return KeyCodes.KEY_ENTER;
+ }
+
+ /**
+ * Returns the key that closes the popup window if this is a VPopopCalendar.
+ * Else this does nothing. By default this is the Escape key but you can
+ * change the key to whatever you want by overriding this method.
+ *
+ * @return
+ */
+ protected int getCloseKey() {
+ return KeyCodes.KEY_ESCAPE;
+ }
+
+ /**
+ * The key that selects the next day in the calendar. By default this is the
+ * right arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getForwardKey() {
+ return KeyCodes.KEY_RIGHT;
+ }
+
+ /**
+ * The key that selects the previous day in the calendar. By default this is
+ * the left arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getBackwardKey() {
+ return KeyCodes.KEY_LEFT;
+ }
+
+ /**
+ * The key that selects the next week in the calendar. By default this is
+ * the down arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getNextKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * The key that selects the previous week in the calendar. By default this
+ * is the up arrow key but by overriding this method it can be changed to
+ * whatever you like.
+ *
+ * @return
+ */
+ protected int getPreviousKey() {
+ return KeyCodes.KEY_UP;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google
+ * .gwt.event.dom.client.MouseOutEvent)
+ */
+ public void onMouseOut(MouseOutEvent event) {
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
+ * .gwt.event.dom.client.MouseDownEvent)
+ */
+ public void onMouseDown(MouseDownEvent event) {
+ // Allow user to click-n-hold for fast-forward or fast-rewind.
+ // Timer is first used for a 500ms delay after mousedown. After that has
+ // elapsed, another timer is triggered to go off every 150ms. Both
+ // timers are cancelled on mouseup or mouseout.
+ if (event.getSource() instanceof VEventButton) {
+ final VEventButton sender = (VEventButton) event.getSource();
+ processClickEvent(sender);
+ mouseTimer = new Timer() {
+ @Override
+ public void run() {
+ mouseTimer = new Timer() {
+ @Override
+ public void run() {
+ processClickEvent(sender);
+ }
+ };
+ mouseTimer.scheduleRepeating(150);
+ }
+ };
+ mouseTimer.schedule(500);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt
+ * .event.dom.client.MouseUpEvent)
+ */
+ public void onMouseUp(MouseUpEvent event) {
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+
+ /**
+ * Sets the data of the Panel.
+ *
+ * @param currentDate
+ * The date to set
+ */
+ public void setDate(Date currentDate) {
+
+ // Check that we are not re-rendering an already active date
+ if (currentDate == value && currentDate != null) {
+ return;
+ }
+
+ Date oldDisplayedMonth = displayedMonth;
+ value = currentDate;
+
+ if (value == null) {
+ focusedDate = displayedMonth = null;
+ } else {
+ focusedDate = new Date(value.getYear(), value.getMonth(),
+ value.getDate());
+ displayedMonth = new Date(value.getYear(), value.getMonth(), 1);
+ }
+
+ // Re-render calendar if month or year of focused date has changed
+ if (oldDisplayedMonth == null || value == null
+ || oldDisplayedMonth.getYear() != value.getYear()
+ || oldDisplayedMonth.getMonth() != value.getMonth()) {
+ renderCalendar();
+ } else {
+ focusDay(focusedDate);
+ selectFocused();
+ }
+
+ if (!hasFocus) {
+ focusDay(null);
+ }
+ }
+
+ /**
+ * TimeSelector is a widget consisting of list boxes that modifie the Date
+ * object that is given for.
+ *
+ */
+ public class VTime extends FlowPanel implements ChangeHandler {
+
+ private ListBox hours;
+
+ private ListBox mins;
+
+ private ListBox sec;
+
+ private ListBox ampm;
+
+ /**
+ * Constructor
+ */
+ public VTime() {
+ super();
+ setStyleName(VDateField.CLASSNAME + "-time");
+ buildTime();
+ }
+
+ private ListBox createListBox() {
+ ListBox lb = new ListBox();
+ lb.setStyleName(VNativeSelect.CLASSNAME);
+ lb.addChangeHandler(this);
+ lb.addBlurHandler(VCalendarPanel.this);
+ lb.addFocusHandler(VCalendarPanel.this);
+ return lb;
+ }
+
+ /**
+ * Constructs the ListBoxes and updates their value
+ *
+ * @param redraw
+ * Should new instances of the listboxes be created
+ */
+ private void buildTime() {
+ clear();
+
+ hours = createListBox();
+ if (getDateTimeService().isTwelveHourClock()) {
+ hours.addItem("12");
+ for (int i = 1; i < 12; i++) {
+ hours.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ } else {
+ for (int i = 0; i < 24; i++) {
+ hours.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ }
+
+ hours.addChangeHandler(this);
+ if (getDateTimeService().isTwelveHourClock()) {
+ ampm = createListBox();
+ final String[] ampmText = getDateTimeService().getAmPmStrings();
+ ampm.addItem(ampmText[0]);
+ ampm.addItem(ampmText[1]);
+ ampm.addChangeHandler(this);
+ }
+
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ mins = createListBox();
+ for (int i = 0; i < 60; i++) {
+ mins.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ mins.addChangeHandler(this);
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ sec = createListBox();
+ for (int i = 0; i < 60; i++) {
+ sec.addItem((i < 10) ? "0" + i : "" + i);
+ }
+ sec.addChangeHandler(this);
+ }
+
+ final String delimiter = getDateTimeService().getClockDelimeter();
+ if (isReadonly()) {
+ int h = 0;
+ if (value != null) {
+ h = value.getHours();
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ h -= h < 12 ? 0 : 12;
+ }
+ add(new VLabel(h < 10 ? "0" + h : "" + h));
+ } else {
+ add(hours);
+ }
+
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ add(new VLabel(delimiter));
+ if (isReadonly()) {
+ final int m = mins.getSelectedIndex();
+ add(new VLabel(m < 10 ? "0" + m : "" + m));
+ } else {
+ add(mins);
+ }
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ add(new VLabel(delimiter));
+ if (isReadonly()) {
+ final int s = sec.getSelectedIndex();
+ add(new VLabel(s < 10 ? "0" + s : "" + s));
+ } else {
+ add(sec);
+ }
+ }
+ if (getResolution() == VDateField.RESOLUTION_HOUR) {
+ add(new VLabel(delimiter + "00")); // o'clock
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ add(new VLabel("&nbsp;"));
+ if (isReadonly()) {
+ int i = 0;
+ if (value != null) {
+ i = (value.getHours() < 12) ? 0 : 1;
+ }
+ add(new VLabel(ampm.getItemText(i)));
+ } else {
+ add(ampm);
+ }
+ }
+
+ if (isReadonly()) {
+ return;
+ }
+
+ // Update times
+ updateTimes();
+
+ ListBox lastDropDown = getLastDropDown();
+ lastDropDown.addKeyDownHandler(new KeyDownHandler() {
+ public void onKeyDown(KeyDownEvent event) {
+ boolean shiftKey = event.getNativeEvent().getShiftKey();
+ if (shiftKey) {
+ return;
+ } else {
+ int nativeKeyCode = event.getNativeKeyCode();
+ if (nativeKeyCode == KeyCodes.KEY_TAB) {
+ onTabOut(event);
+ }
+ }
+ }
+ });
+
+ }
+
+ private ListBox getLastDropDown() {
+ int i = getWidgetCount() - 1;
+ while (i >= 0) {
+ Widget widget = getWidget(i);
+ if (widget instanceof ListBox) {
+ return (ListBox) widget;
+ }
+ i--;
+ }
+ return null;
+ }
+
+ /**
+ * Updates the valus to correspond to the values in value
+ */
+ public void updateTimes() {
+ boolean selected = true;
+ if (value == null) {
+ value = new Date();
+ selected = false;
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ int h = value.getHours();
+ ampm.setSelectedIndex(h < 12 ? 0 : 1);
+ h -= ampm.getSelectedIndex() * 12;
+ hours.setSelectedIndex(h);
+ } else {
+ hours.setSelectedIndex(value.getHours());
+ }
+ if (getResolution() >= VDateField.RESOLUTION_MIN) {
+ mins.setSelectedIndex(value.getMinutes());
+ }
+ if (getResolution() >= VDateField.RESOLUTION_SEC) {
+ sec.setSelectedIndex(value.getSeconds());
+ }
+ if (getDateTimeService().isTwelveHourClock()) {
+ ampm.setSelectedIndex(value.getHours() < 12 ? 0 : 1);
+ }
+
+ hours.setEnabled(isEnabled());
+ if (mins != null) {
+ mins.setEnabled(isEnabled());
+ }
+ if (sec != null) {
+ sec.setEnabled(isEnabled());
+ }
+ if (ampm != null) {
+ ampm.setEnabled(isEnabled());
+ }
+
+ }
+
+ private int getMilliseconds() {
+ return DateTimeService.getMilliseconds(value);
+ }
+
+ private DateTimeService getDateTimeService() {
+ if (dateTimeService == null) {
+ dateTimeService = new DateTimeService();
+ }
+ return dateTimeService;
+ }
+
+ /*
+ * (non-Javadoc) VT
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt
+ * .event.dom.client.ChangeEvent)
+ */
+ public void onChange(ChangeEvent event) {
+ /*
+ * Value from dropdowns gets always set for the value. Like year and
+ * month when resolution is month or year.
+ */
+ if (event.getSource() == hours) {
+ int h = hours.getSelectedIndex();
+ if (getDateTimeService().isTwelveHourClock()) {
+ h = h + ampm.getSelectedIndex() * 12;
+ }
+ value.setHours(h);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(h, value.getMinutes(),
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == mins) {
+ final int m = mins.getSelectedIndex();
+ value.setMinutes(m);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(value.getHours(), m,
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == sec) {
+ final int s = sec.getSelectedIndex();
+ value.setSeconds(s);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(value.getHours(),
+ value.getMinutes(), s,
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getSource() == ampm) {
+ final int h = hours.getSelectedIndex()
+ + (ampm.getSelectedIndex() * 12);
+ value.setHours(h);
+ if (timeChangeListener != null) {
+ timeChangeListener.changed(h, value.getMinutes(),
+ value.getSeconds(),
+ DateTimeService.getMilliseconds(value));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ }
+
+ /**
+ * A widget representing a single day in the calendar panel.
+ */
+ private class Day extends InlineHTML {
+ private static final String BASECLASS = VDateField.CLASSNAME
+ + "-calendarpanel-day";
+ private final Date date;
+
+ Day(Date date) {
+ super("" + date.getDate());
+ setStyleName(BASECLASS);
+ this.date = date;
+ addClickHandler(dayClickHandler);
+ }
+
+ public Date getDate() {
+ return date;
+ }
+ }
+
+ public Date getDate() {
+ return value;
+ }
+
+ /**
+ * If true should be returned if the panel will not be used after this
+ * event.
+ *
+ * @param event
+ * @return
+ */
+ protected boolean onTabOut(DomEvent<?> event) {
+ if (focusOutListener != null) {
+ return focusOutListener.onFocusOut(event);
+ }
+ return false;
+ }
+
+ /**
+ * A focus out listener is triggered when the panel loosed focus. This can
+ * happen either after a user clicks outside the panel or tabs out.
+ *
+ * @param listener
+ * The listener to trigger
+ */
+ public void setFocusOutListener(FocusOutListener listener) {
+ focusOutListener = listener;
+ }
+
+ /**
+ * The submit listener is called when the user selects a value from the
+ * calender either by clicking the day or selects it by keyboard.
+ *
+ * @param submitListener
+ * The listener to trigger
+ */
+ public void setSubmitListener(SubmitListener submitListener) {
+ this.submitListener = submitListener;
+ }
+
+ /**
+ * The given FocusChangeListener is notified when the focused date changes
+ * by user either clicking on a new date or by using the keyboard.
+ *
+ * @param listener
+ * The FocusChangeListener to be notified
+ */
+ public void setFocusChangeListener(FocusChangeListener listener) {
+ focusChangeListener = listener;
+ }
+
+ /**
+ * The time change listener is triggered when the user changes the time.
+ *
+ * @param listener
+ */
+ public void setTimeChangeListener(TimeChangeListener listener) {
+ timeChangeListener = listener;
+ }
+
+ /**
+ * Returns the submit listener that listens to selection made from the panel
+ *
+ * @return The listener or NULL if no listener has been set
+ */
+ public SubmitListener getSubmitListener() {
+ return submitListener;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
+ * .dom.client.BlurEvent)
+ */
+ public void onBlur(final BlurEvent event) {
+ if (event.getSource() instanceof VCalendarPanel) {
+ hasFocus = false;
+ focusDay(null);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event
+ * .dom.client.FocusEvent)
+ */
+ public void onFocus(FocusEvent event) {
+ if (event.getSource() instanceof VCalendarPanel) {
+ hasFocus = true;
+
+ // Focuses the current day if the calendar shows the days
+ if (focusedDay != null) {
+ focusDay(focusedDate);
+ }
+ }
+ }
+
+ private static final String SUBPART_NEXT_MONTH = "nextmon";
+ private static final String SUBPART_PREV_MONTH = "prevmon";
+
+ private static final String SUBPART_NEXT_YEAR = "nexty";
+ private static final String SUBPART_PREV_YEAR = "prevy";
+ private static final String SUBPART_HOUR_SELECT = "h";
+ private static final String SUBPART_MINUTE_SELECT = "m";
+ private static final String SUBPART_SECS_SELECT = "s";
+ private static final String SUBPART_MSECS_SELECT = "ms";
+ private static final String SUBPART_AMPM_SELECT = "ampm";
+ private static final String SUBPART_DAY = "day";
+ private static final String SUBPART_MONTH_YEAR_HEADER = "header";
+
+ public String getSubPartName(Element subElement) {
+ if (contains(nextMonth, subElement)) {
+ return SUBPART_NEXT_MONTH;
+ } else if (contains(prevMonth, subElement)) {
+ return SUBPART_PREV_MONTH;
+ } else if (contains(nextYear, subElement)) {
+ return SUBPART_NEXT_YEAR;
+ } else if (contains(prevYear, subElement)) {
+ return SUBPART_PREV_YEAR;
+ } else if (contains(days, subElement)) {
+ // Day, find out which dayOfMonth and use that as the identifier
+ Day day = Util.findWidget(subElement, Day.class);
+ if (day != null) {
+ Date date = day.getDate();
+ int id = date.getDate();
+ // Zero or negative ids map to days of the preceding month,
+ // past-the-end-of-month ids to days of the following month
+ if (date.getMonth() < displayedMonth.getMonth()) {
+ id -= DateTimeService.getNumberOfDaysInMonth(date);
+ } else if (date.getMonth() > displayedMonth.getMonth()) {
+ id += DateTimeService
+ .getNumberOfDaysInMonth(displayedMonth);
+ }
+ return SUBPART_DAY + id;
+ }
+ } else if (time != null) {
+ if (contains(time.hours, subElement)) {
+ return SUBPART_HOUR_SELECT;
+ } else if (contains(time.mins, subElement)) {
+ return SUBPART_MINUTE_SELECT;
+ } else if (contains(time.sec, subElement)) {
+ return SUBPART_SECS_SELECT;
+ } else if (contains(time.ampm, subElement)) {
+ return SUBPART_AMPM_SELECT;
+
+ }
+ } else if (getCellFormatter().getElement(0, 2).isOrHasChild(subElement)) {
+ return SUBPART_MONTH_YEAR_HEADER;
+ }
+
+ return null;
+ }
+
+ /**
+ * Checks if subElement is inside the widget DOM hierarchy.
+ *
+ * @param w
+ * @param subElement
+ * @return true if {@code w} is a parent of subElement, false otherwise.
+ */
+ private boolean contains(Widget w, Element subElement) {
+ if (w == null || w.getElement() == null) {
+ return false;
+ }
+
+ return w.getElement().isOrHasChild(subElement);
+ }
+
+ public Element getSubPartElement(String subPart) {
+ if (SUBPART_NEXT_MONTH.equals(subPart)) {
+ return nextMonth.getElement();
+ }
+ if (SUBPART_PREV_MONTH.equals(subPart)) {
+ return prevMonth.getElement();
+ }
+ if (SUBPART_NEXT_YEAR.equals(subPart)) {
+ return nextYear.getElement();
+ }
+ if (SUBPART_PREV_YEAR.equals(subPart)) {
+ return prevYear.getElement();
+ }
+ if (SUBPART_HOUR_SELECT.equals(subPart)) {
+ return time.hours.getElement();
+ }
+ if (SUBPART_MINUTE_SELECT.equals(subPart)) {
+ return time.mins.getElement();
+ }
+ if (SUBPART_SECS_SELECT.equals(subPart)) {
+ return time.sec.getElement();
+ }
+ if (SUBPART_AMPM_SELECT.equals(subPart)) {
+ return time.ampm.getElement();
+ }
+ if (subPart.startsWith(SUBPART_DAY)) {
+ // Zero or negative ids map to days in the preceding month,
+ // past-the-end-of-month ids to days in the following month
+ int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY
+ .length()));
+ Date date = new Date(displayedMonth.getYear(),
+ displayedMonth.getMonth(), dayOfMonth);
+ Iterator<Widget> iter = days.iterator();
+ while (iter.hasNext()) {
+ Widget w = iter.next();
+ if (w instanceof Day) {
+ Day day = (Day) w;
+ if (day.getDate().equals(date)) {
+ return day.getElement();
+ }
+ }
+ }
+ }
+
+ if (SUBPART_MONTH_YEAR_HEADER.equals(subPart)) {
+ return (Element) getCellFormatter().getElement(0, 2).getChild(0);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onDetach() {
+ super.onDetach();
+ if (mouseTimer != null) {
+ mouseTimer.cancel();
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
index d92d7e37ed..320520cb39 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java
@@ -14,7 +14,6 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
@@ -101,8 +100,4 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox implements
client.updateVariable(id, EventId.BLUR, "", true);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
index 03233c6e27..9fee6a8ba6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBoxPaintable.java
@@ -1,96 +1,99 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.EventHelper;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VTooltip;
-
-public class VCheckBoxPaintable extends VAbstractPaintableWidget {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Save details
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
-
- getWidgetForPaintable().focusHandlerRegistration = EventHelper
- .updateFocusHandler(this, client,
- getWidgetForPaintable().focusHandlerRegistration);
- getWidgetForPaintable().blurHandlerRegistration = EventHelper
- .updateBlurHandler(this, client,
- getWidgetForPaintable().blurHandlerRegistration);
-
- if (uidl.hasAttribute("error")) {
- if (getWidgetForPaintable().errorIndicatorElement == null) {
- getWidgetForPaintable().errorIndicatorElement = DOM
- .createSpan();
- getWidgetForPaintable().errorIndicatorElement
- .setInnerHTML("&nbsp;");
- DOM.setElementProperty(
- getWidgetForPaintable().errorIndicatorElement,
- "className", "v-errorindicator");
- DOM.appendChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().errorIndicatorElement);
- DOM.sinkEvents(getWidgetForPaintable().errorIndicatorElement,
- VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
- } else {
- DOM.setStyleAttribute(
- getWidgetForPaintable().errorIndicatorElement,
- "display", "");
- }
- } else if (getWidgetForPaintable().errorIndicatorElement != null) {
- DOM.setStyleAttribute(
- getWidgetForPaintable().errorIndicatorElement, "display",
- "none");
- }
-
- if (uidl.hasAttribute("readonly")) {
- getWidgetForPaintable().setEnabled(false);
- }
-
- if (uidl.hasAttribute("icon")) {
- if (getWidgetForPaintable().icon == null) {
- getWidgetForPaintable().icon = new Icon(client);
- DOM.insertChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().icon.getElement(), 1);
- getWidgetForPaintable().icon
- .sinkEvents(VTooltip.TOOLTIP_EVENTS);
- getWidgetForPaintable().icon.sinkEvents(Event.ONCLICK);
- }
- getWidgetForPaintable().icon
- .setUri(uidl.getStringAttribute("icon"));
- } else if (getWidgetForPaintable().icon != null) {
- // detach icon
- DOM.removeChild(getWidgetForPaintable().getElement(),
- getWidgetForPaintable().icon.getElement());
- getWidgetForPaintable().icon = null;
- }
-
- // Set text
- getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
- getWidgetForPaintable()
- .setValue(
- uidl.getBooleanVariable(getWidgetForPaintable().VARIABLE_STATE));
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
- }
-
- @Override
- public VCheckBox getWidgetForPaintable() {
- return (VCheckBox) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VCheckBox.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventHelper;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VTooltip;
+
+public class VCheckBoxPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ getWidgetForPaintable().focusHandlerRegistration = EventHelper
+ .updateFocusHandler(this, client,
+ getWidgetForPaintable().focusHandlerRegistration);
+ getWidgetForPaintable().blurHandlerRegistration = EventHelper
+ .updateBlurHandler(this, client,
+ getWidgetForPaintable().blurHandlerRegistration);
+
+ if (uidl.hasAttribute("error")) {
+ if (getWidgetForPaintable().errorIndicatorElement == null) {
+ getWidgetForPaintable().errorIndicatorElement = DOM
+ .createSpan();
+ getWidgetForPaintable().errorIndicatorElement
+ .setInnerHTML("&nbsp;");
+ DOM.setElementProperty(
+ getWidgetForPaintable().errorIndicatorElement,
+ "className", "v-errorindicator");
+ DOM.appendChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().errorIndicatorElement);
+ DOM.sinkEvents(getWidgetForPaintable().errorIndicatorElement,
+ VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
+ } else {
+ DOM.setStyleAttribute(
+ getWidgetForPaintable().errorIndicatorElement,
+ "display", "");
+ }
+ } else if (getWidgetForPaintable().errorIndicatorElement != null) {
+ DOM.setStyleAttribute(
+ getWidgetForPaintable().errorIndicatorElement, "display",
+ "none");
+ }
+
+ if (uidl.hasAttribute("readonly")) {
+ getWidgetForPaintable().setEnabled(false);
+ }
+
+ if (uidl.hasAttribute("icon")) {
+ if (getWidgetForPaintable().icon == null) {
+ getWidgetForPaintable().icon = new Icon(client);
+ DOM.insertChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().icon.getElement(), 1);
+ getWidgetForPaintable().icon
+ .sinkEvents(VTooltip.TOOLTIP_EVENTS);
+ getWidgetForPaintable().icon.sinkEvents(Event.ONCLICK);
+ }
+ getWidgetForPaintable().icon
+ .setUri(uidl.getStringAttribute("icon"));
+ } else if (getWidgetForPaintable().icon != null) {
+ // detach icon
+ DOM.removeChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().icon.getElement());
+ getWidgetForPaintable().icon = null;
+ }
+
+ // Set text
+ getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
+ getWidgetForPaintable()
+ .setValue(
+ uidl.getBooleanVariable(getWidgetForPaintable().VARIABLE_STATE));
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ }
+
+ @Override
+ public VCheckBox getWidgetForPaintable() {
+ return (VCheckBox) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCheckBox.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
index ffd7fc49b2..839b84061c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
@@ -11,9 +11,6 @@ import java.util.Iterator;
import java.util.Set;
import com.google.gwt.dom.client.Style;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -22,7 +19,6 @@ 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.Container;
-import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.StyleConstants;
import com.vaadin.terminal.gwt.client.UIDL;
@@ -33,33 +29,17 @@ import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ValueMap;
-public class VCssLayout extends SimplePanel implements VPaintableWidget,
- Container {
+public class VCssLayout extends SimplePanel implements Container {
public static final String TAGNAME = "csslayout";
public static final String CLASSNAME = "v-" + TAGNAME;
- private FlowPane panel = new FlowPane();
+ FlowPane panel = new FlowPane();
- private Element margin = DOM.createDiv();
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return panel.getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
+ Element margin = DOM.createDiv();
private boolean hasHeight;
private boolean hasWidth;
- private boolean rendering;
+ boolean rendering;
public VCssLayout() {
super();
@@ -94,32 +74,6 @@ public class VCssLayout extends SimplePanel implements VPaintableWidget,
}
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
-
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
- clickEventHandler.handleEventHandlerRegistration(client);
-
- final VMarginInfo margins = new VMarginInfo(
- uidl.getIntAttribute("margins"));
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP,
- margins.hasTop());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_RIGHT,
- margins.hasRight());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_BOTTOM,
- margins.hasBottom());
- setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_LEFT,
- margins.hasLeft());
-
- setStyleName(margin, CLASSNAME + "-" + "spacing",
- uidl.hasAttribute("spacing"));
- panel.updateFromUIDL(uidl, client);
- rendering = false;
- }
-
public boolean hasChildComponent(Widget component) {
return panel.hasChildComponent(component);
}
@@ -128,10 +82,6 @@ public class VCssLayout extends SimplePanel implements VPaintableWidget,
panel.replaceChildComponent(oldComponent, newComponent);
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- panel.updateCaption(component, uidl);
- }
-
public class FlowPane extends FlowPanel {
private final HashMap<Widget, VCaption> widgetToCaption = new HashMap<Widget, VCaption>();
@@ -275,7 +225,7 @@ public class VCssLayout extends SimplePanel implements VPaintableWidget,
}
}
- private VPaintableWidget getComponent(Element element) {
+ VPaintableWidget getComponent(Element element) {
return Util
.getPaintableForElement(client, VCssLayout.this, element);
}
@@ -344,7 +294,27 @@ public class VCssLayout extends SimplePanel implements VPaintableWidget,
return cssProperty;
}
- public Widget getWidgetForPaintable() {
- return this;
+ /**
+ * Sets CSS classes for margin and spacing based on the given parameters.
+ *
+ * @param margins
+ * A {@link VMarginInfo} object that provides info on
+ * top/left/bottom/right margins
+ * @param spacing
+ * true to enable spacing, false otherwise
+ */
+ protected void setMarginAndSpacingStyles(VMarginInfo margins,
+ boolean spacing) {
+ setStyleName(margin, VCssLayout.CLASSNAME + "-"
+ + StyleConstants.MARGIN_TOP, margins.hasTop());
+ setStyleName(margin, VCssLayout.CLASSNAME + "-"
+ + StyleConstants.MARGIN_RIGHT, margins.hasRight());
+ setStyleName(margin, VCssLayout.CLASSNAME + "-"
+ + StyleConstants.MARGIN_BOTTOM, margins.hasBottom());
+ setStyleName(margin, VCssLayout.CLASSNAME + "-"
+ + StyleConstants.MARGIN_LEFT, margins.hasLeft());
+
+ setStyleName(margin, VCssLayout.CLASSNAME + "-" + "spacing", spacing);
+
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
new file mode 100644
index 0000000000..4d551fa5e8
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayoutPaintable.java
@@ -0,0 +1,64 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCssLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().panel.getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().setMarginAndSpacingStyles(
+ new VMarginInfo(uidl.getIntAttribute("margins")),
+ uidl.hasAttribute("spacing"));
+ getWidgetForPaintable().panel.updateFromUIDL(uidl, client);
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ public VCssLayout getWidgetForPaintable() {
+ return (VCssLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCssLayout.class);
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ getWidgetForPaintable().panel.updateCaption(component, uidl);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
index 39d1ee462c..d8181cf00c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java
@@ -6,81 +6,28 @@ package com.vaadin.terminal.gwt.client.ui;
import java.util.Set;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VCustomComponent extends SimplePanel implements Container {
private static final String CLASSNAME = "v-customcomponent";
private String height;
- private ApplicationConnection client;
- private boolean rendering;
+ ApplicationConnection client;
+ boolean rendering;
private String width;
- private RenderSpace renderSpace = new RenderSpace();
+ RenderSpace renderSpace = new RenderSpace();
public VCustomComponent() {
super();
setStyleName(CLASSNAME);
}
- public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
- rendering = true;
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
- this.client = client;
-
- final UIDL child = uidl.getChildUIDL(0);
- if (child != null) {
- final VPaintableWidget paintable = client.getPaintable(child);
- Widget widget = paintable.getWidgetForPaintable();
- if (widget != getWidget()) {
- if (getWidget() != null) {
- client.unregisterPaintable(VPaintableMap.get(client)
- .getPaintable(getWidget()));
- clear();
- }
- setWidget(widget);
- }
- paintable.updateFromUIDL(child, client);
- }
-
- boolean updateDynamicSize = 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(VCustomComponent.this);
-
- }
- });
- }
-
- renderSpace.setWidth(getElement().getOffsetWidth());
- renderSpace.setHeight(getElement().getOffsetHeight());
-
- /*
- * Needed to update client size if the size of this component has
- * changed and the child uses relative size(s).
- */
- client.runDescendentsLayout(this);
-
- rendering = false;
- }
-
- private boolean updateDynamicSize() {
+ boolean updateDynamicSize() {
boolean updated = false;
if (isDynamicWidth()) {
int childWidth = Util.getRequiredWidth(getWidget());
@@ -121,10 +68,6 @@ public class VCustomComponent extends SimplePanel implements Container {
}
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, custom component dont render composition roots caption
- }
-
public boolean requestLayout(Set<Widget> children) {
// If a child grows in size, it will not necessarily be calculated
// correctly unless we remove previous size definitions
@@ -168,8 +111,4 @@ public class VCustomComponent extends SimplePanel implements Container {
}
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
new file mode 100644
index 0000000000..585466f4f7
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponentPaintable.java
@@ -0,0 +1,82 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCustomComponentPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ getWidgetForPaintable().client = client;
+
+ final UIDL child = uidl.getChildUIDL(0);
+ if (child != null) {
+ final VPaintableWidget paintable = client.getPaintable(child);
+ Widget widget = paintable.getWidgetForPaintable();
+ if (widget != getWidgetForPaintable().getWidget()) {
+ if (getWidgetForPaintable().getWidget() != null) {
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidgetForPaintable().getWidget()));
+ getWidgetForPaintable().clear();
+ }
+ getWidgetForPaintable().setWidget(widget);
+ }
+ paintable.updateFromUIDL(child, client);
+ }
+
+ boolean updateDynamicSize = getWidgetForPaintable().updateDynamicSize();
+ if (updateDynamicSize) {
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ // FIXME deferred relative size update needed to fix some
+ // scrollbar issues in sampler. This must be the wrong way
+ // to do it. Might be that some other component is broken.
+ client.handleComponentRelativeSize(getWidgetForPaintable());
+
+ }
+ });
+ }
+
+ getWidgetForPaintable().renderSpace.setWidth(getWidgetForPaintable()
+ .getElement().getOffsetWidth());
+ getWidgetForPaintable().renderSpace.setHeight(getWidgetForPaintable()
+ .getElement().getOffsetHeight());
+
+ /*
+ * Needed to update client size if the size of this component has
+ * changed and the child uses relative size(s).
+ */
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCustomComponent.class);
+ }
+
+ @Override
+ public VCustomComponent getWidgetForPaintable() {
+ return (VCustomComponent) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, custom component dont render composition roots caption
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
index 40b6acd28a..5782c74c9a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java
@@ -35,8 +35,8 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget;
* @author Vaadin Ltd
*
*/
-public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
- Container, ContainerResizedListener {
+public class VCustomLayout extends ComplexPanel implements Container,
+ ContainerResizedListener {
public static final String CLASSNAME = "v-customlayout";
@@ -44,7 +44,7 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
private final HashMap<String, Element> locationToElement = new HashMap<String, Element>();
/** Location-name to contained widget map */
- private final HashMap<String, Widget> locationToWidget = new HashMap<String, Widget>();
+ final HashMap<String, Widget> locationToWidget = new HashMap<String, Widget>();
/** Widget to captionwrapper map */
private final HashMap<VPaintableWidget, VCaptionWrapper> paintableToCaptionWrapper = new HashMap<VPaintableWidget, VCaptionWrapper>();
@@ -53,12 +53,12 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
String currentTemplateName;
/** Unexecuted scripts loaded from the template */
- private String scripts = "";
+ String scripts = "";
/** Paintable ID of this paintable */
- private String pid;
+ String pid;
- private ApplicationConnection client;
+ ApplicationConnection client;
/** Has the template been loaded from contents passed in UIDL **/
private boolean hasTemplateContents = false;
@@ -132,66 +132,8 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
locationToWidget.put(location, widget);
}
- /** Update the layout from UIDL */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- // ApplicationConnection manages generic component features
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- pid = uidl.getId();
- if (!hasTemplate()) {
- // Update HTML template only once
- initializeHTML(uidl, client);
- }
-
- // Evaluate scripts
- eval(scripts);
- scripts = null;
-
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- Set<Widget> oldWidgets = new HashSet<Widget>();
- oldWidgets.addAll(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 {
- setWidget(childWidget, location);
- childPaintable.updateFromUIDL(childUIDL, client);
- } catch (final IllegalArgumentException e) {
- // If no location is found, this component is not visible
- }
- oldWidgets.remove(childWidget);
- }
- }
- for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
- .hasNext();) {
- Widget oldWidget = iterator.next();
- if (oldWidget.isAttached()) {
- // slot of this widget is emptied, remove it
- remove(oldWidget);
- }
- }
-
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- }
-
/** Initialize HTML-layout. */
- private void initializeHTML(UIDL uidl, ApplicationConnection client) {
+ void initializeHTML(UIDL uidl, ApplicationConnection client) {
final String newTemplateContents = uidl
.getStringAttribute("templateContents");
@@ -264,7 +206,7 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
return false;
}-*/;
- private boolean hasTemplate() {
+ boolean hasTemplate() {
if (currentTemplateName == null && !hasTemplateContents) {
return false;
} else {
@@ -295,7 +237,7 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
}
/** Evaluate given script in browser document */
- private static native void eval(String script)
+ static native void eval(String script)
/*-{
try {
if (script != null)
@@ -574,8 +516,4 @@ public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
return larger;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
new file mode 100644
index 0000000000..9cf877f446
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayoutPaintable.java
@@ -0,0 +1,90 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VCustomLayoutPaintable extends VAbstractPaintableWidgetContainer {
+
+ /** Update the layout from UIDL */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ // ApplicationConnection manages generic component features
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().pid = uidl.getId();
+ if (!getWidgetForPaintable().hasTemplate()) {
+ // Update HTML template only once
+ getWidgetForPaintable().initializeHTML(uidl, client);
+ }
+
+ // Evaluate scripts
+ VCustomLayout.eval(getWidgetForPaintable().scripts);
+ getWidgetForPaintable().scripts = null;
+
+ getWidgetForPaintable().iLayout();
+ // TODO Check if this is needed
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ Set<Widget> oldWidgets = new HashSet<Widget>();
+ oldWidgets.addAll(getWidgetForPaintable().locationToWidget.values());
+
+ // For all contained widgets
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL uidlForChild = (UIDL) i.next();
+ if (uidlForChild.getTag().equals("location")) {
+ final String location = uidlForChild.getStringAttribute("name");
+ UIDL childUIDL = uidlForChild.getChildUIDL(0);
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUIDL);
+ Widget childWidget = childPaintable.getWidgetForPaintable();
+ try {
+ getWidgetForPaintable().setWidget(childWidget, location);
+ childPaintable.updateFromUIDL(childUIDL, client);
+ } catch (final IllegalArgumentException e) {
+ // If no location is found, this component is not visible
+ }
+ oldWidgets.remove(childWidget);
+ }
+ }
+ for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
+ .hasNext();) {
+ Widget oldWidget = iterator.next();
+ if (oldWidget.isAttached()) {
+ // slot of this widget is emptied, remove it
+ getWidgetForPaintable().remove(oldWidget);
+ }
+ }
+
+ getWidgetForPaintable().iLayout();
+ // TODO Check if this is needed
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ }
+
+ @Override
+ public VCustomLayout getWidgetForPaintable() {
+ return (VCustomLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VCustomLayout.class);
+ }
+
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ getWidgetForPaintable().updateCaption(paintable, uidl);
+
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateField.java b/src/com/vaadin/terminal/gwt/client/ui/VDateField.java
index d21a20229e..14c3b99210 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDateField.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateField.java
@@ -8,22 +8,17 @@ import java.util.Date;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VDateField extends FlowPanel implements VPaintableWidget, Field {
+public class VDateField extends FlowPanel implements Field {
public static final String CLASSNAME = "v-datefield";
- private String id;
+ protected String paintableId;
- private ApplicationConnection client;
+ protected ApplicationConnection client;
protected boolean immediate;
@@ -65,7 +60,7 @@ public class VDateField extends FlowPanel implements VPaintableWidget, Field {
protected DateTimeService dts;
- private boolean showISOWeekNumbers = false;
+ protected boolean showISOWeekNumbers = false;
public VDateField() {
setStyleName(CLASSNAME);
@@ -77,80 +72,7 @@ public class VDateField extends FlowPanel implements VPaintableWidget, Field {
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, this);
- }
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Ensure correct implementation and let layout manage caption
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- // Save details
- this.client = client;
- id = uidl.getId();
- immediate = uidl.getBooleanAttribute("immediate");
-
- readonly = uidl.getBooleanAttribute("readonly");
- enabled = !uidl.getBooleanAttribute("disabled");
-
- if (uidl.hasAttribute("locale")) {
- final String locale = uidl.getStringAttribute("locale");
- try {
- dts.setLocale(locale);
- currentLocale = locale;
- } catch (final LocaleNotLoadedException e) {
- currentLocale = dts.getLocale();
- VConsole.error("Tried to use an unloaded locale \"" + locale
- + "\". Using default locale (" + currentLocale + ").");
- VConsole.error(e);
- }
- }
-
- // We show week numbers only if the week starts with Monday, as ISO 8601
- // specifies
- showISOWeekNumbers = uidl.getBooleanAttribute(WEEK_NUMBERS)
- && dts.getFirstDayOfWeek() == 1;
-
- int newResolution;
- if (uidl.hasVariable("sec")) {
- newResolution = RESOLUTION_SEC;
- } else if (uidl.hasVariable("min")) {
- newResolution = RESOLUTION_MIN;
- } else if (uidl.hasVariable("hour")) {
- newResolution = RESOLUTION_HOUR;
- } else if (uidl.hasVariable("day")) {
- newResolution = RESOLUTION_DAY;
- } else if (uidl.hasVariable("month")) {
- newResolution = RESOLUTION_MONTH;
- } else {
- newResolution = RESOLUTION_YEAR;
- }
-
- currentResolution = newResolution;
-
- // Add stylename that indicates current resolution
- addStyleName(CLASSNAME + "-" + resolutionToString(currentResolution));
-
- final int year = uidl.getIntVariable("year");
- final int month = (currentResolution >= RESOLUTION_MONTH) ? uidl
- .getIntVariable("month") : -1;
- final int day = (currentResolution >= RESOLUTION_DAY) ? uidl
- .getIntVariable("day") : -1;
- final int hour = (currentResolution >= RESOLUTION_HOUR) ? uidl
- .getIntVariable("hour") : 0;
- final int min = (currentResolution >= RESOLUTION_MIN) ? uidl
- .getIntVariable("min") : 0;
- final int sec = (currentResolution >= RESOLUTION_SEC) ? uidl
- .getIntVariable("sec") : 0;
-
- // Construct new date for this datefield (only if not null)
- if (year > -1) {
- setCurrentDate(new Date((long) getTime(year, month, day, hour, min,
- sec, 0)));
- } else {
- setCurrentDate(null);
+ client.handleWidgetTooltipEvent(event, this);
}
}
@@ -158,7 +80,7 @@ public class VDateField extends FlowPanel implements VPaintableWidget, Field {
* We need this redundant native function because Java's Date object doesn't
* have a setMilliseconds method.
*/
- private static native double getTime(int y, int m, int d, int h, int mi,
+ protected static native double getTime(int y, int m, int d, int h, int mi,
int s, int ms)
/*-{
try {
@@ -227,7 +149,7 @@ public class VDateField extends FlowPanel implements VPaintableWidget, Field {
}
public String getId() {
- return id;
+ return paintableId;
}
public ApplicationConnection getClient() {
@@ -270,8 +192,4 @@ public class VDateField extends FlowPanel implements VPaintableWidget, Field {
protected void setDate(Date date) {
this.date = date;
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
index 73bfe27700..6bf1d4a3a7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendar.java
@@ -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.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;
-
- 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() {
- Date date2 = calendarPanel.getDate();
- Date currentDate = getCurrentDate();
- if (currentDate == null || date2.getTime() != currentDate.getTime()) {
- setCurrentDate((Date) date2.clone());
- getClient().updateVariable(getId(), "year", date2.getYear() + 1900,
- false);
- if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
- getClient().updateVariable(getId(), "month",
- date2.getMonth() + 1, false);
- if (getCurrentResolution() > RESOLUTION_MONTH) {
- getClient().updateVariable(getId(), "day", date2.getDate(),
- false);
- if (getCurrentResolution() > RESOLUTION_DAY) {
- getClient().updateVariable(getId(), "hour",
- date2.getHours(), false);
- if (getCurrentResolution() > RESOLUTION_HOUR) {
- getClient().updateVariable(getId(), "min",
- date2.getMinutes(), false);
- if (getCurrentResolution() > RESOLUTION_MIN) {
- getClient().updateVariable(getId(), "sec",
- date2.getSeconds(), false);
- if (getCurrentResolution() > RESOLUTION_SEC) {
- getClient().updateVariable(
- getId(),
- "msec",
- DateTimeService
- .getMilliseconds(date2),
- false);
- }
- }
- }
- }
- }
- }
- if (isImmediate()) {
- getClient().sendPendingVariableChanges();
- }
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.event.dom.client.DomEvent;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
+
+/**
+ * A client side implementation for InlineDateField
+ */
+public class VDateFieldCalendar extends VDateField {
+
+ protected final VCalendarPanel calendarPanel;
+
+ public VDateFieldCalendar() {
+ super();
+ calendarPanel = new VCalendarPanel();
+ add(calendarPanel);
+ calendarPanel.setSubmitListener(new SubmitListener() {
+ public void onSubmit() {
+ updateValueFromPanel();
+ }
+
+ public void onCancel() {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ calendarPanel.setFocusOutListener(new FocusOutListener() {
+ public boolean onFocusOut(DomEvent<?> event) {
+ updateValueFromPanel();
+ return false;
+ }
+ });
+ }
+
+ /**
+ * TODO refactor: almost same method as in VPopupCalendar.updateValue
+ */
+ @SuppressWarnings("deprecation")
+ protected void updateValueFromPanel() {
+ Date date2 = calendarPanel.getDate();
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || date2.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) date2.clone());
+ getClient().updateVariable(getId(), "year", date2.getYear() + 1900,
+ false);
+ if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
+ getClient().updateVariable(getId(), "month",
+ date2.getMonth() + 1, false);
+ if (getCurrentResolution() > RESOLUTION_MONTH) {
+ getClient().updateVariable(getId(), "day", date2.getDate(),
+ false);
+ if (getCurrentResolution() > RESOLUTION_DAY) {
+ getClient().updateVariable(getId(), "hour",
+ date2.getHours(), false);
+ if (getCurrentResolution() > RESOLUTION_HOUR) {
+ getClient().updateVariable(getId(), "min",
+ date2.getMinutes(), false);
+ if (getCurrentResolution() > RESOLUTION_MIN) {
+ getClient().updateVariable(getId(), "sec",
+ date2.getSeconds(), false);
+ if (getCurrentResolution() > RESOLUTION_SEC) {
+ getClient().updateVariable(
+ getId(),
+ "msec",
+ DateTimeService
+ .getMilliseconds(date2),
+ false);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (isImmediate()) {
+ getClient().sendPendingVariableChanges();
+ }
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendarPaintable.java
new file mode 100644
index 0000000000..8dced06235
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldCalendarPaintable.java
@@ -0,0 +1,101 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+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.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.TimeChangeListener;
+
+public class VDateFieldCalendarPaintable extends VDateFieldPaintable {
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ super.updateFromUIDL(uidl, client);
+ getWidgetForPaintable().calendarPanel
+ .setShowISOWeekNumbers(getWidgetForPaintable()
+ .isShowISOWeekNumbers());
+ getWidgetForPaintable().calendarPanel
+ .setDateTimeService(getWidgetForPaintable()
+ .getDateTimeService());
+ getWidgetForPaintable().calendarPanel
+ .setResolution(getWidgetForPaintable().getCurrentResolution());
+ Date currentDate = getWidgetForPaintable().getCurrentDate();
+ if (currentDate != null) {
+ getWidgetForPaintable().calendarPanel.setDate(new Date(currentDate
+ .getTime()));
+ } else {
+ getWidgetForPaintable().calendarPanel.setDate(null);
+ }
+
+ if (getWidgetForPaintable().currentResolution > VDateField.RESOLUTION_DAY) {
+ getWidgetForPaintable().calendarPanel
+ .setTimeChangeListener(new TimeChangeListener() {
+ public void changed(int hour, int min, int sec, int msec) {
+ Date d = getWidgetForPaintable().getDate();
+ if (d == null) {
+ // date currently null, use the value from
+ // calendarPanel
+ // (~ client time at the init of the widget)
+ d = (Date) getWidgetForPaintable().calendarPanel
+ .getDate().clone();
+ }
+ d.setHours(hour);
+ d.setMinutes(min);
+ d.setSeconds(sec);
+ DateTimeService.setMilliseconds(d, msec);
+
+ // Always update time changes to the server
+ getWidgetForPaintable().calendarPanel.setDate(d);
+ getWidgetForPaintable().updateValueFromPanel();
+ }
+ });
+ }
+
+ if (getWidgetForPaintable().currentResolution <= VDateField.RESOLUTION_MONTH) {
+ getWidgetForPaintable().calendarPanel
+ .setFocusChangeListener(new FocusChangeListener() {
+ public void focusChanged(Date date) {
+ Date date2 = new Date();
+ if (getWidgetForPaintable().calendarPanel.getDate() != null) {
+ date2.setTime(getWidgetForPaintable().calendarPanel
+ .getDate().getTime());
+ }
+ /*
+ * Update the value of calendarPanel
+ */
+ date2.setYear(date.getYear());
+ date2.setMonth(date.getMonth());
+ getWidgetForPaintable().calendarPanel
+ .setDate(date2);
+ /*
+ * Then update the value from panel to server
+ */
+ getWidgetForPaintable().updateValueFromPanel();
+ }
+ });
+ } else {
+ getWidgetForPaintable().calendarPanel.setFocusChangeListener(null);
+ }
+
+ // Update possible changes
+ getWidgetForPaintable().calendarPanel.renderCalendar();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VDateFieldCalendar.class);
+ }
+
+ @Override
+ public VDateFieldCalendar getWidgetForPaintable() {
+ return (VDateFieldCalendar) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java
new file mode 100644
index 0000000000..a4bbe64a30
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDateFieldPaintable.java
@@ -0,0 +1,109 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+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.LocaleNotLoadedException;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VDateFieldPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Ensure correct implementation and let layout manage caption
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getId();
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+ getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
+
+ if (uidl.hasAttribute("locale")) {
+ final String locale = uidl.getStringAttribute("locale");
+ try {
+ getWidgetForPaintable().dts.setLocale(locale);
+ getWidgetForPaintable().currentLocale = locale;
+ } catch (final LocaleNotLoadedException e) {
+ getWidgetForPaintable().currentLocale = getWidgetForPaintable().dts
+ .getLocale();
+ VConsole.error("Tried to use an unloaded locale \"" + locale
+ + "\". Using default locale ("
+ + getWidgetForPaintable().currentLocale + ").");
+ VConsole.error(e);
+ }
+ }
+
+ // We show week numbers only if the week starts with Monday, as ISO 8601
+ // specifies
+ getWidgetForPaintable().showISOWeekNumbers = uidl
+ .getBooleanAttribute(VDateField.WEEK_NUMBERS)
+ && getWidgetForPaintable().dts.getFirstDayOfWeek() == 1;
+
+ int newResolution;
+ if (uidl.hasVariable("sec")) {
+ newResolution = VDateField.RESOLUTION_SEC;
+ } else if (uidl.hasVariable("min")) {
+ newResolution = VDateField.RESOLUTION_MIN;
+ } else if (uidl.hasVariable("hour")) {
+ newResolution = VDateField.RESOLUTION_HOUR;
+ } else if (uidl.hasVariable("day")) {
+ newResolution = VDateField.RESOLUTION_DAY;
+ } else if (uidl.hasVariable("month")) {
+ newResolution = VDateField.RESOLUTION_MONTH;
+ } else {
+ newResolution = VDateField.RESOLUTION_YEAR;
+ }
+
+ getWidgetForPaintable().currentResolution = newResolution;
+
+ // Add stylename that indicates current resolution
+ getWidgetForPaintable()
+ .addStyleName(
+ VDateField.CLASSNAME
+ + "-"
+ + VDateField
+ .resolutionToString(getWidgetForPaintable().currentResolution));
+
+ final int year = uidl.getIntVariable("year");
+ final int month = (getWidgetForPaintable().currentResolution >= VDateField.RESOLUTION_MONTH) ? uidl
+ .getIntVariable("month") : -1;
+ final int day = (getWidgetForPaintable().currentResolution >= VDateField.RESOLUTION_DAY) ? uidl
+ .getIntVariable("day") : -1;
+ final int hour = (getWidgetForPaintable().currentResolution >= VDateField.RESOLUTION_HOUR) ? uidl
+ .getIntVariable("hour") : 0;
+ final int min = (getWidgetForPaintable().currentResolution >= VDateField.RESOLUTION_MIN) ? uidl
+ .getIntVariable("min") : 0;
+ final int sec = (getWidgetForPaintable().currentResolution >= VDateField.RESOLUTION_SEC) ? uidl
+ .getIntVariable("sec") : 0;
+
+ // Construct new date for this datefield (only if not null)
+ if (year > -1) {
+ getWidgetForPaintable().setCurrentDate(
+ new Date((long) getWidgetForPaintable().getTime(year,
+ month, day, hour, min, sec, 0)));
+ } else {
+ getWidgetForPaintable().setCurrentDate(null);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VDateField.class);
+ }
+
+ @Override
+ public VDateField getWidgetForPaintable() {
+ return (VDateField) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
index 3251a03d6a..0297e8df3f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
@@ -4,10 +4,8 @@
package com.vaadin.terminal.gwt.client.ui;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArrayString;
@@ -28,7 +26,6 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VPaintable;
@@ -97,7 +94,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
}
@@ -111,7 +108,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements
private boolean startDrag(NativeEvent event) {
if (dragStartMode == WRAPPER || dragStartMode == COMPONENT) {
VTransferable transferable = new VTransferable();
- transferable.setDragSource(VDragAndDropWrapper.this);
+ transferable.setDragSource(VPaintableMap.get(client).getPaintable(
+ VDragAndDropWrapper.this));
VPaintableWidget paintable = Util.findPaintable(client,
(Element) event.getEventTarget().cast());
@@ -140,58 +138,15 @@ public class VDragAndDropWrapper extends VCustomComponent implements
protected int dragStartMode;
- private ApplicationConnection client;
- private VAbstractDropHandler dropHandler;
+ ApplicationConnection client;
+ VAbstractDropHandler dropHandler;
private VDragEvent vaadinDragEvent;
- private int filecounter = 0;
- private Map<String, String> fileIdToReceiver;
- private ValueMap html5DataFlavors;
+ int filecounter = 0;
+ Map<String, String> fileIdToReceiver;
+ ValueMap html5DataFlavors;
private Element dragStartElement;
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- super.updateFromUIDL(uidl, client);
- if (!uidl.hasAttribute("cached") && !uidl.hasAttribute("hidden")) {
- UIDL acceptCrit = uidl.getChildByTagName("-ac");
- if (acceptCrit == null) {
- dropHandler = null;
- } else {
- if (dropHandler == null) {
- dropHandler = new CustomDropHandler();
- }
- dropHandler.updateAcceptRules(acceptCrit);
- }
-
- Set<String> variableNames = uidl.getVariableNames();
- for (String fileId : variableNames) {
- if (fileId.startsWith("rec-")) {
- String receiverUrl = uidl.getStringVariable(fileId);
- fileId = fileId.substring(4);
- if (fileIdToReceiver == null) {
- fileIdToReceiver = new HashMap<String, String>();
- }
- if ("".equals(receiverUrl)) {
- Integer id = Integer.parseInt(fileId);
- int indexOf = fileIds.indexOf(id);
- if (indexOf != -1) {
- files.remove(indexOf);
- fileIds.remove(indexOf);
- }
- } else {
- fileIdToReceiver.put(fileId, receiverUrl);
- }
- }
- }
- startNextUpload();
-
- dragStartMode = uidl.getIntAttribute(DRAG_START_MODE);
- initDragStartMode();
- html5DataFlavors = uidl.getMapAttribute(HTML5_DATA_FLAVORS);
- }
- }
-
protected void initDragStartMode() {
Element div = getElement();
if (dragStartMode == HTML5) {
@@ -231,7 +186,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements
};
private Timer dragleavetimer;
- private void startNextUpload() {
+ void startNextUpload() {
Scheduler.get().scheduleDeferred(new Command() {
public void execute() {
@@ -287,7 +242,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
if (VDragAndDropManager.get().getCurrentDropHandler() != getDropHandler()) {
VTransferable transferable = new VTransferable();
- transferable.setDragSource(this);
+ transferable.setDragSource(VPaintableMap.get(client)
+ .getPaintable(this));
vaadinDragEvent = VDragAndDropManager.get().startDrag(
transferable, event, false);
@@ -455,8 +411,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements
* @param fileId
* @param data
*/
- private List<Integer> fileIds = new ArrayList<Integer>();
- private List<VHtml5File> files = new ArrayList<VHtml5File>();
+ List<Integer> fileIds = new ArrayList<Integer>();
+ List<VHtml5File> files = new ArrayList<VHtml5File>();
private void queueFilePost(final int fileId, final VHtml5File file) {
fileIds.add(fileId);
@@ -544,7 +500,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements
@Override
public VPaintableWidget getPaintable() {
- return VDragAndDropWrapper.this;
+ return VPaintableMap.get(client).getPaintable(
+ VDragAndDropWrapper.this);
}
public ApplicationConnection getApplicationConnection() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
new file mode 100644
index 0000000000..2d2f0fcad3
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperPaintable.java
@@ -0,0 +1,74 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VDragAndDropWrapperPaintable extends VCustomComponentPaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ super.updateFromUIDL(uidl, client);
+ if (!uidl.hasAttribute("cached") && !uidl.hasAttribute("hidden")) {
+ UIDL acceptCrit = uidl.getChildByTagName("-ac");
+ if (acceptCrit == null) {
+ getWidgetForPaintable().dropHandler = null;
+ } else {
+ if (getWidgetForPaintable().dropHandler == null) {
+ getWidgetForPaintable().dropHandler = getWidgetForPaintable().new CustomDropHandler();
+ }
+ getWidgetForPaintable().dropHandler
+ .updateAcceptRules(acceptCrit);
+ }
+
+ Set<String> variableNames = uidl.getVariableNames();
+ for (String fileId : variableNames) {
+ if (fileId.startsWith("rec-")) {
+ String receiverUrl = uidl.getStringVariable(fileId);
+ fileId = fileId.substring(4);
+ if (getWidgetForPaintable().fileIdToReceiver == null) {
+ getWidgetForPaintable().fileIdToReceiver = new HashMap<String, String>();
+ }
+ if ("".equals(receiverUrl)) {
+ Integer id = Integer.parseInt(fileId);
+ int indexOf = getWidgetForPaintable().fileIds
+ .indexOf(id);
+ if (indexOf != -1) {
+ getWidgetForPaintable().files.remove(indexOf);
+ getWidgetForPaintable().fileIds.remove(indexOf);
+ }
+ } else {
+ getWidgetForPaintable().fileIdToReceiver.put(fileId,
+ receiverUrl);
+ }
+ }
+ }
+ getWidgetForPaintable().startNextUpload();
+
+ getWidgetForPaintable().dragStartMode = uidl
+ .getIntAttribute(VDragAndDropWrapper.DRAG_START_MODE);
+ getWidgetForPaintable().initDragStartMode();
+ getWidgetForPaintable().html5DataFlavors = uidl
+ .getMapAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VDragAndDropWrapper.class);
+ }
+
+ @Override
+ public VDragAndDropWrapper getWidgetForPaintable() {
+ return (VDragAndDropWrapper) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java
index 54385c665f..549a7b4549 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java
@@ -8,190 +8,31 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.dom.client.ObjectElement;
-import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.event.dom.client.DomEvent.Type;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VTooltip;
-public class VEmbedded extends HTML implements VPaintableWidget {
- public static final String CLICK_EVENT_IDENTIFIER = "click";
+public class VEmbedded extends HTML {
+ public static String CLASSNAME = "v-embedded";
- private static String CLASSNAME = "v-embedded";
+ protected String height;
+ protected String width;
+ protected Element browserElement;
- private String height;
- private String width;
- private Element browserElement;
+ protected String type;
- private String type;
-
- private ApplicationConnection client;
-
- private final ClickEventHandler clickEventHandler = new ClickEventHandler(
- this, CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
-
- };
+ protected ApplicationConnection client;
public VEmbedded() {
setStyleName(CLASSNAME);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- this.client = client;
-
- boolean clearBrowserElement = true;
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- if (uidl.hasAttribute("type")) {
- type = uidl.getStringAttribute("type");
- if (type.equals("image")) {
- addStyleName(CLASSNAME + "-image");
- Element el = null;
- boolean created = false;
- NodeList<Node> nodes = getElement().getChildNodes();
- if (nodes != null && nodes.getLength() == 1) {
- Node n = nodes.getItem(0);
- if (n.getNodeType() == Node.ELEMENT_NODE) {
- Element e = (Element) n;
- if (e.getTagName().equals("IMG")) {
- el = e;
- }
- }
- }
- if (el == null) {
- setHTML("");
- el = DOM.createImg();
- created = true;
- DOM.sinkEvents(el, Event.ONLOAD);
- }
-
- // Set attributes
- Style style = el.getStyle();
- String w = uidl.getStringAttribute("width");
- if (w != null) {
- style.setProperty("width", w);
- } else {
- style.setProperty("width", "");
- }
- String h = uidl.getStringAttribute("height");
- if (h != null) {
- style.setProperty("height", h);
- } else {
- style.setProperty("height", "");
- }
- DOM.setElementProperty(el, "src", getSrc(uidl, client));
-
- if (created) {
- // insert in dom late
- getElement().appendChild(el);
- }
-
- /*
- * Sink tooltip events so tooltip is displayed when hovering the
- * image.
- */
- sinkEvents(VTooltip.TOOLTIP_EVENTS);
-
- } else if (type.equals("browser")) {
- addStyleName(CLASSNAME + "-browser");
- if (browserElement == null) {
- setHTML("<iframe width=\"100%\" height=\"100%\" frameborder=\"0\""
- + " allowTransparency=\"true\" src=\"\""
- + " name=\"" + uidl.getId() + "\"></iframe>");
- browserElement = DOM.getFirstChild(getElement());
- }
- DOM.setElementAttribute(browserElement, "src",
- getSrc(uidl, client));
- clearBrowserElement = false;
- } else {
- VConsole.log("Unknown Embedded type '" + type + "'");
- }
- } else if (uidl.hasAttribute("mimetype")) {
- final String mime = uidl.getStringAttribute("mimetype");
- if (mime.equals("application/x-shockwave-flash")) {
- // Handle embedding of Flash
- addStyleName(CLASSNAME + "-flash");
- setHTML(createFlashEmbed(uidl));
-
- } else if (mime.equals("image/svg+xml")) {
- addStyleName(CLASSNAME + "-svg");
- String data;
- Map<String, String> parameters = getParameters(uidl);
- if (parameters.get("data") == null) {
- data = getSrc(uidl, client);
- } else {
- data = "data:image/svg+xml," + parameters.get("data");
- }
- setHTML("");
- ObjectElement obj = Document.get().createObjectElement();
- obj.setType(mime);
- obj.setData(data);
- if (width != null) {
- obj.getStyle().setProperty("width", "100%");
- }
- if (height != null) {
- obj.getStyle().setProperty("height", "100%");
- }
- if (uidl.hasAttribute("classid")) {
- obj.setAttribute("classid",
- uidl.getStringAttribute("classid"));
- }
- if (uidl.hasAttribute("codebase")) {
- obj.setAttribute("codebase",
- uidl.getStringAttribute("codebase"));
- }
- if (uidl.hasAttribute("codetype")) {
- obj.setAttribute("codetype",
- uidl.getStringAttribute("codetype"));
- }
- if (uidl.hasAttribute("archive")) {
- obj.setAttribute("archive",
- uidl.getStringAttribute("archive"));
- }
- if (uidl.hasAttribute("standby")) {
- obj.setAttribute("standby",
- uidl.getStringAttribute("standby"));
- }
- getElement().appendChild(obj);
-
- } else {
- VConsole.log("Unknown Embedded mimetype '" + mime + "'");
- }
- } else {
- VConsole.log("Unknown Embedded; no type or mimetype attribute");
- }
-
- if (clearBrowserElement) {
- browserElement = null;
- }
- }
-
/**
* Creates the Object and Embed tags for the Flash plugin so it works
* cross-browser
@@ -200,7 +41,7 @@ public class VEmbedded extends HTML implements VPaintableWidget {
* The UIDL
* @return Tags concatenated into a string
*/
- private String createFlashEmbed(UIDL uidl) {
+ protected String createFlashEmbed(UIDL uidl) {
/*
* To ensure cross-browser compatibility we are using the twice-cooked
* method to embed flash i.e. we add a OBJECT tag for IE ActiveX and
@@ -318,7 +159,7 @@ public class VEmbedded extends HTML implements VPaintableWidget {
* @param uidl
* @return
*/
- private static Map<String, String> getParameters(UIDL uidl) {
+ protected static Map<String, String> getParameters(UIDL uidl) {
Map<String, String> parameters = new HashMap<String, String>();
Iterator<Object> childIterator = uidl.getChildIterator();
@@ -347,7 +188,7 @@ public class VEmbedded extends HTML implements VPaintableWidget {
* @param client
* @return
*/
- private String getSrc(UIDL uidl, ApplicationConnection client) {
+ protected String getSrc(UIDL uidl, ApplicationConnection client) {
String url = client.translateVaadinUri(uidl.getStringAttribute("src"));
if (url == null) {
return "";
@@ -412,7 +253,7 @@ public class VEmbedded extends HTML implements VPaintableWidget {
Util.notifyParentOfSizeChange(this, true);
}
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
/**
@@ -432,9 +273,4 @@ public class VEmbedded extends HTML implements VPaintableWidget {
Unit.PX);
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbeddedPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbeddedPaintable.java
new file mode 100644
index 0000000000..bdb34b6d14
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbeddedPaintable.java
@@ -0,0 +1,198 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.dom.client.ObjectElement;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.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.VConsole;
+import com.vaadin.terminal.gwt.client.VTooltip;
+
+public class VEmbeddedPaintable extends VAbstractPaintableWidget {
+
+ public static final String CLICK_EVENT_IDENTIFIER = "click";
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ // Save details
+ getWidgetForPaintable().client = client;
+
+ boolean clearBrowserElement = true;
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ if (uidl.hasAttribute("type")) {
+ getWidgetForPaintable().type = uidl.getStringAttribute("type");
+ if (getWidgetForPaintable().type.equals("image")) {
+ getWidgetForPaintable().addStyleName(
+ VEmbedded.CLASSNAME + "-image");
+ Element el = null;
+ boolean created = false;
+ NodeList<Node> nodes = getWidgetForPaintable().getElement()
+ .getChildNodes();
+ if (nodes != null && nodes.getLength() == 1) {
+ Node n = nodes.getItem(0);
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ Element e = (Element) n;
+ if (e.getTagName().equals("IMG")) {
+ el = e;
+ }
+ }
+ }
+ if (el == null) {
+ getWidgetForPaintable().setHTML("");
+ el = DOM.createImg();
+ created = true;
+ DOM.sinkEvents(el, Event.ONLOAD);
+ }
+
+ // Set attributes
+ Style style = el.getStyle();
+ String w = uidl.getStringAttribute("width");
+ if (w != null) {
+ style.setProperty("width", w);
+ } else {
+ style.setProperty("width", "");
+ }
+ String h = uidl.getStringAttribute("height");
+ if (h != null) {
+ style.setProperty("height", h);
+ } else {
+ style.setProperty("height", "");
+ }
+ DOM.setElementProperty(el, "src", getWidgetForPaintable()
+ .getSrc(uidl, client));
+
+ if (created) {
+ // insert in dom late
+ getWidgetForPaintable().getElement().appendChild(el);
+ }
+
+ /*
+ * Sink tooltip events so tooltip is displayed when hovering the
+ * image.
+ */
+ getWidgetForPaintable().sinkEvents(VTooltip.TOOLTIP_EVENTS);
+
+ } else if (getWidgetForPaintable().type.equals("browser")) {
+ getWidgetForPaintable().addStyleName(
+ VEmbedded.CLASSNAME + "-browser");
+ if (getWidgetForPaintable().browserElement == null) {
+ getWidgetForPaintable().setHTML(
+ "<iframe width=\"100%\" height=\"100%\" frameborder=\"0\""
+ + " allowTransparency=\"true\" src=\"\""
+ + " name=\"" + uidl.getId()
+ + "\"></iframe>");
+ getWidgetForPaintable().browserElement = DOM
+ .getFirstChild(getWidgetForPaintable().getElement());
+ }
+ DOM.setElementAttribute(getWidgetForPaintable().browserElement,
+ "src", getWidgetForPaintable().getSrc(uidl, client));
+ clearBrowserElement = false;
+ } else {
+ VConsole.log("Unknown Embedded type '"
+ + getWidgetForPaintable().type + "'");
+ }
+ } else if (uidl.hasAttribute("mimetype")) {
+ final String mime = uidl.getStringAttribute("mimetype");
+ if (mime.equals("application/x-shockwave-flash")) {
+ // Handle embedding of Flash
+ getWidgetForPaintable().addStyleName(
+ VEmbedded.CLASSNAME + "-flash");
+ getWidgetForPaintable().setHTML(
+ getWidgetForPaintable().createFlashEmbed(uidl));
+
+ } else if (mime.equals("image/svg+xml")) {
+ getWidgetForPaintable().addStyleName(
+ VEmbedded.CLASSNAME + "-svg");
+ String data;
+ Map<String, String> parameters = VEmbedded.getParameters(uidl);
+ if (parameters.get("data") == null) {
+ data = getWidgetForPaintable().getSrc(uidl, client);
+ } else {
+ data = "data:image/svg+xml," + parameters.get("data");
+ }
+ getWidgetForPaintable().setHTML("");
+ ObjectElement obj = Document.get().createObjectElement();
+ obj.setType(mime);
+ obj.setData(data);
+ if (getWidgetForPaintable().width != null) {
+ obj.getStyle().setProperty("width", "100%");
+ }
+ if (getWidgetForPaintable().height != null) {
+ obj.getStyle().setProperty("height", "100%");
+ }
+ if (uidl.hasAttribute("classid")) {
+ obj.setAttribute("classid",
+ uidl.getStringAttribute("classid"));
+ }
+ if (uidl.hasAttribute("codebase")) {
+ obj.setAttribute("codebase",
+ uidl.getStringAttribute("codebase"));
+ }
+ if (uidl.hasAttribute("codetype")) {
+ obj.setAttribute("codetype",
+ uidl.getStringAttribute("codetype"));
+ }
+ if (uidl.hasAttribute("archive")) {
+ obj.setAttribute("archive",
+ uidl.getStringAttribute("archive"));
+ }
+ if (uidl.hasAttribute("standby")) {
+ obj.setAttribute("standby",
+ uidl.getStringAttribute("standby"));
+ }
+ getWidgetForPaintable().getElement().appendChild(obj);
+
+ } else {
+ VConsole.log("Unknown Embedded mimetype '" + mime + "'");
+ }
+ } else {
+ VConsole.log("Unknown Embedded; no type or mimetype attribute");
+ }
+
+ if (clearBrowserElement) {
+ getWidgetForPaintable().browserElement = null;
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VEmbedded.class);
+ }
+
+ @Override
+ public VEmbedded getWidgetForPaintable() {
+ return (VEmbedded) super.getWidgetForPaintable();
+ }
+
+ protected final ClickEventHandler clickEventHandler = new ClickEventHandler(
+ this, CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+
+ };
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
index b6bbe5dd19..b54c3dd943 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
@@ -42,12 +42,10 @@ import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.google.gwt.user.client.ui.TextBox;
-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.Focusable;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
@@ -59,9 +57,8 @@ import com.vaadin.terminal.gwt.client.VTooltip;
* TODO needs major refactoring (to be extensible etc)
*/
@SuppressWarnings("deprecation")
-public class VFilterSelect extends Composite implements VPaintableWidget, Field,
- KeyDownHandler, KeyUpHandler, ClickHandler, FocusHandler, BlurHandler,
- Focusable {
+public class VFilterSelect extends Composite implements Field, KeyDownHandler,
+ KeyUpHandler, ClickHandler, FocusHandler, BlurHandler, Focusable {
/**
* Represents a suggestion in the suggestion popup box
@@ -153,7 +150,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
private static final String Z_INDEX = "30000";
- private final SuggestionMenu menu;
+ protected final SuggestionMenu menu;
private final Element up = DOM.createDiv();
private final Element down = DOM.createDiv();
@@ -776,7 +773,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
return keyboardSelectedItem;
}
- private void setKeyboardSelectedItem(MenuItem firstItem) {
+ protected void setKeyboardSelectedItem(MenuItem firstItem) {
keyboardSelectedItem = firstItem;
}
@@ -803,7 +800,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
/**
* The text box where the filter is written
*/
- private final TextBox tb = new TextBox() {
+ protected final TextBox tb = new TextBox() {
/*
* (non-Javadoc)
*
@@ -815,7 +812,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, VFilterSelect.this);
+ client.handleWidgetTooltipEvent(event, VFilterSelect.this);
}
}
@@ -830,7 +827,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
};
};
- private final SuggestionPopup suggestionPopup = new SuggestionPopup();
+ protected final SuggestionPopup suggestionPopup = new SuggestionPopup();
/**
* Used when measuring the width of the popup
@@ -848,7 +845,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, VFilterSelect.this);
+ client.handleWidgetTooltipEvent(event, VFilterSelect.this);
}
/*
@@ -861,73 +858,73 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
private final Image selectedItemIcon = new Image();
- private ApplicationConnection client;
+ protected ApplicationConnection client;
- private String paintableId;
+ protected String paintableId;
- private int currentPage;
+ protected int currentPage;
/**
* A collection of available suggestions (options) as received from the
* server.
*/
- private final List<FilterSelectSuggestion> currentSuggestions = new ArrayList<FilterSelectSuggestion>();
+ protected final List<FilterSelectSuggestion> currentSuggestions = new ArrayList<FilterSelectSuggestion>();
- private boolean immediate;
+ protected boolean immediate;
- private String selectedOptionKey;
+ protected String selectedOptionKey;
- private boolean waitingForFilteringResponse = false;
- private boolean updateSelectionWhenReponseIsReceived = false;
+ protected boolean waitingForFilteringResponse = false;
+ protected boolean updateSelectionWhenReponseIsReceived = false;
private boolean tabPressedWhenPopupOpen = false;
- private boolean initDone = false;
+ protected boolean initDone = false;
- private String lastFilter = "";
+ protected String lastFilter = "";
- private enum Select {
+ protected enum Select {
NONE, FIRST, LAST
};
- private Select selectPopupItemWhenResponseIsReceived = Select.NONE;
+ protected Select selectPopupItemWhenResponseIsReceived = Select.NONE;
/**
* The current suggestion selected from the dropdown. This is one of the
* values in currentSuggestions except when filtering, in this case
* currentSuggestion might not be in currentSuggestions.
*/
- private FilterSelectSuggestion currentSuggestion;
+ protected FilterSelectSuggestion currentSuggestion;
- private int totalMatches;
- private boolean allowNewItem;
- private boolean nullSelectionAllowed;
- private boolean nullSelectItem;
- private boolean enabled;
- private boolean readonly;
+ protected int totalMatches;
+ protected boolean allowNewItem;
+ protected boolean nullSelectionAllowed;
+ protected boolean nullSelectItem;
+ protected boolean enabled;
+ protected boolean readonly;
- private int filteringmode = FILTERINGMODE_OFF;
+ protected int filteringmode = FILTERINGMODE_OFF;
// shown in unfocused empty field, disappears on focus (e.g "Search here")
private static final String CLASSNAME_PROMPT = "prompt";
- private static final String ATTR_INPUTPROMPT = "prompt";
+ protected static final String ATTR_INPUTPROMPT = "prompt";
public static final String ATTR_NO_TEXT_INPUT = "noInput";
- private String inputPrompt = "";
- private boolean prompting = false;
+ protected String inputPrompt = "";
+ protected boolean prompting = false;
// Set true when popupopened has been clicked. Cleared on each UIDL-update.
// This handles the special case where are not filtering yet and the
// selected value has changed on the server-side. See #2119
- private boolean popupOpenerClicked;
+ protected boolean popupOpenerClicked;
private String width = null;
private int textboxPadding = -1;
private int componentPadding = -1;
- private int suggestionPopupMinWidth = 0;
+ protected int suggestionPopupMinWidth = 0;
private int popupWidth = -1;
/*
* Stores the last new item string to avoid double submissions. Cleared on
* uidl updates
*/
- private String lastNewItemString;
- private boolean focused = false;
+ protected String lastNewItemString;
+ protected boolean focused = false;
private int horizPaddingAndBorder = 2;
/**
@@ -1006,6 +1003,20 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* The filter to apply to the components
*/
public void filterOptions(int page, String filter) {
+ filterOptions(page, filter, true);
+ }
+
+ /**
+ * Filters the options at certain page using the given filter
+ *
+ * @param page
+ * The page to filter
+ * @param filter
+ * The filter to apply to the options
+ * @param immediate
+ * Whether to send the options request immediately
+ */
+ private void filterOptions(int page, String filter, boolean immediate) {
if (filter.equals(lastFilter) && currentPage == page) {
if (!suggestionPopup.isAttached()) {
suggestionPopup.showSuggestions(currentSuggestions,
@@ -1025,209 +1036,16 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
waitingForFilteringResponse = true;
client.updateVariable(paintableId, "filter", filter, false);
- client.updateVariable(paintableId, "page", page, true);
+ client.updateVariable(paintableId, "page", page, immediate);
lastFilter = filter;
currentPage = page;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
- * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- paintableId = uidl.getId();
- this.client = client;
-
- readonly = uidl.hasAttribute("readonly");
- enabled = !uidl.hasAttribute("disabled");
-
- tb.setEnabled(enabled);
- updateReadOnly();
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- // Inverse logic here to make the default case (text input enabled)
- // work without additional UIDL messages
- boolean noTextInput = uidl.hasAttribute(ATTR_NO_TEXT_INPUT)
- && uidl.getBooleanAttribute(ATTR_NO_TEXT_INPUT);
- setTextInputEnabled(!noTextInput);
-
- // not a FocusWidget -> needs own tabindex handling
- if (uidl.hasAttribute("tabindex")) {
- tb.setTabIndex(uidl.getIntAttribute("tabindex"));
- }
-
- if (uidl.hasAttribute("filteringmode")) {
- filteringmode = uidl.getIntAttribute("filteringmode");
- }
-
- immediate = uidl.hasAttribute("immediate");
-
- nullSelectionAllowed = uidl.hasAttribute("nullselect");
-
- nullSelectItem = uidl.hasAttribute("nullselectitem")
- && uidl.getBooleanAttribute("nullselectitem");
-
- currentPage = uidl.getIntVariable("page");
-
- if (uidl.hasAttribute("pagelength")) {
- pageLength = uidl.getIntAttribute("pagelength");
- }
-
- if (uidl.hasAttribute(ATTR_INPUTPROMPT)) {
- // input prompt changed from server
- inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT);
- } else {
- inputPrompt = "";
- }
-
- suggestionPopup.updateStyleNames(uidl);
-
- allowNewItem = uidl.hasAttribute("allownewitem");
- lastNewItemString = null;
-
- currentSuggestions.clear();
- if (!waitingForFilteringResponse) {
- /*
- * Clear the current suggestions as the server response always
- * includes the new ones. Exception is when filtering, then we need
- * to retain the value if the user does not select any of the
- * options matching the filter.
- */
- currentSuggestion = null;
- /*
- * Also ensure no old items in menu. Unless cleared the old values
- * may cause odd effects on blur events. Suggestions in menu might
- * not necessary exist in select at all anymore.
- */
- suggestionPopup.menu.clearItems();
-
- }
-
- final UIDL options = uidl.getChildUIDL(0);
- if (uidl.hasAttribute("totalMatches")) {
- totalMatches = uidl.getIntAttribute("totalMatches");
- } else {
- totalMatches = 0;
- }
-
- // used only to calculate minimum popup width
- String captions = Util.escapeHTML(inputPrompt);
-
- for (final Iterator<?> i = options.getChildIterator(); i.hasNext();) {
- final UIDL optionUidl = (UIDL) i.next();
- final FilterSelectSuggestion suggestion = new FilterSelectSuggestion(
- optionUidl);
- currentSuggestions.add(suggestion);
- if (optionUidl.hasAttribute("selected")) {
- if (!waitingForFilteringResponse || popupOpenerClicked) {
- String newSelectedOptionKey = Integer.toString(suggestion
- .getOptionKey());
- if (!newSelectedOptionKey.equals(selectedOptionKey)
- || suggestion.getReplacementString().equals(
- tb.getText())) {
- // Update text field if we've got a new selection
- // Also update if we've got the same text to retain old
- // text selection behavior
- setPromptingOff(suggestion.getReplacementString());
- selectedOptionKey = newSelectedOptionKey;
- }
- }
- currentSuggestion = suggestion;
- setSelectedItemIcon(suggestion.getIconUri());
- }
-
- // Collect captions so we can calculate minimum width for textarea
- if (captions.length() > 0) {
- captions += "|";
- }
- captions += Util.escapeHTML(suggestion.getReplacementString());
- }
-
- if ((!waitingForFilteringResponse || popupOpenerClicked)
- && uidl.hasVariable("selected")
- && uidl.getStringArrayVariable("selected").length == 0) {
- // select nulled
- if (!waitingForFilteringResponse || !popupOpenerClicked) {
- if (!focused) {
- /*
- * client.updateComponent overwrites all styles so we must
- * ALWAYS set the prompting style at this point, even though
- * we think it has been set already...
- */
- prompting = false;
- setPromptingOn();
- } else {
- // we have focus in field, prompting can't be set on,
- // instead just clear the input
- tb.setValue("");
- }
- }
- selectedOptionKey = null;
- }
-
- if (waitingForFilteringResponse
- && lastFilter.toLowerCase().equals(
- uidl.getStringVariable("filter"))) {
- suggestionPopup.showSuggestions(currentSuggestions, currentPage,
- totalMatches);
- waitingForFilteringResponse = false;
- if (!popupOpenerClicked
- && selectPopupItemWhenResponseIsReceived != Select.NONE) {
- // we're paging w/ arrows
- if (selectPopupItemWhenResponseIsReceived == Select.LAST) {
- suggestionPopup.menu.selectLastItem();
- } else {
- suggestionPopup.menu.selectFirstItem();
- }
-
- // This is used for paging so we update the keyboard selection
- // variable as well.
- MenuItem activeMenuItem = suggestionPopup.menu
- .getSelectedItem();
- suggestionPopup.menu.setKeyboardSelectedItem(activeMenuItem);
-
- // Update text field to contain the correct text
- setTextboxText(activeMenuItem.getText());
- tb.setSelectionRange(lastFilter.length(), activeMenuItem
- .getText().length() - lastFilter.length());
-
- selectPopupItemWhenResponseIsReceived = Select.NONE; // reset
- }
- if (updateSelectionWhenReponseIsReceived) {
- suggestionPopup.menu.doPostFilterSelectedItemAction();
- }
- }
-
- // Calculate minumum textarea width
- suggestionPopupMinWidth = minWidth(captions);
-
- popupOpenerClicked = false;
-
- if (!initDone) {
- updateRootWidth();
- }
-
- // Focus dependent style names are lost during the update, so we add
- // them here back again
- if (focused) {
- addStyleDependentName("focus");
- }
-
- initDone = true;
- }
-
- private void updateReadOnly() {
+ protected void updateReadOnly() {
tb.setReadOnly(readonly || !textInputEnabled);
}
- private void setTextInputEnabled(boolean textInputEnabled) {
+ protected void setTextInputEnabled(boolean textInputEnabled) {
// Always update styles as they might have been overwritten
if (textInputEnabled) {
removeStyleDependentName(STYLE_NO_INPUT);
@@ -1249,7 +1067,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* @param text
* the text to set in the text box
*/
- private void setTextboxText(final String text) {
+ protected void setTextboxText(final String text) {
tb.setText(text);
}
@@ -1273,7 +1091,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* Turns prompting on. When prompting is turned on a command prompt is shown
* in the text box if nothing has been entered.
*/
- private void setPromptingOn() {
+ protected void setPromptingOn() {
if (!prompting) {
prompting = true;
addStyleDependentName(CLASSNAME_PROMPT);
@@ -1288,7 +1106,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* @param text
* The text the text box should contain.
*/
- private void setPromptingOff(String text) {
+ protected void setPromptingOff(String text) {
setTextboxText(text);
if (prompting) {
prompting = false;
@@ -1338,7 +1156,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* @param iconUri
* The URI of the icon
*/
- private void setSelectedItemIcon(String iconUri) {
+ protected void setSelectedItemIcon(String iconUri) {
if (iconUri == null || iconUri == "") {
panel.remove(selectedItemIcon);
updateRootWidth();
@@ -1600,7 +1418,12 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
// ask suggestionPopup if it was just closed, we are using GWT
// Popup's auto close feature
if (!suggestionPopup.isJustClosed()) {
- filterOptions(-1, "");
+ // If a focus event is not going to be sent, send the options
+ // request immediately; otherwise queue in the same burst as the
+ // focus event. Fixes #8321.
+ boolean immediate = focused
+ || !client.hasWidgetEventListeners(this, EventId.FOCUS);
+ filterOptions(-1, "", immediate);
popupOpenerClicked = true;
lastFilter = "";
}
@@ -1613,7 +1436,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
/**
* Calculate minimum width for FilterSelect textarea
*/
- private native int minWidth(String captions)
+ protected native int minWidth(String captions)
/*-{
if(!captions || captions.length <= 0)
return 0;
@@ -1665,7 +1488,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
}
addStyleDependentName("focus");
- if (client.hasEventListeners(this, EventId.FOCUS)) {
+ if (client.hasWidgetEventListeners(this, EventId.FOCUS)) {
client.updateVariable(paintableId, EventId.FOCUS, "", true);
}
}
@@ -1730,7 +1553,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
}
removeStyleDependentName("focus");
- if (client.hasEventListeners(this, EventId.BLUR)) {
+ if (client.hasWidgetEventListeners(this, EventId.BLUR)) {
client.updateVariable(paintableId, EventId.BLUR, "", true);
}
}
@@ -1784,7 +1607,7 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
* Calculates the width of the select if the select has undefined width.
* Should be called when the width changes or when the icon changes.
*/
- private void updateRootWidth() {
+ protected void updateRootWidth() {
if (width == null) {
/*
* When the width is not specified we must specify width for root
@@ -1934,8 +1757,4 @@ public class VFilterSelect extends Composite implements VPaintableWidget, Field,
super.onDetach();
suggestionPopup.hide();
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java
new file mode 100644
index 0000000000..3249ea17d5
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelectPaintable.java
@@ -0,0 +1,244 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelect.FilterSelectSuggestion;
+
+public class VFilterSelectPaintable extends VAbstractPaintableWidget {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
+ * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ @SuppressWarnings("deprecation")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getId();
+
+ getWidgetForPaintable().readonly = uidl.hasAttribute("readonly");
+ getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
+
+ getWidgetForPaintable().tb.setEnabled(getWidgetForPaintable().enabled);
+ getWidgetForPaintable().updateReadOnly();
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ // Inverse logic here to make the default case (text input enabled)
+ // work without additional UIDL messages
+ boolean noTextInput = uidl
+ .hasAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT)
+ && uidl.getBooleanAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT);
+ getWidgetForPaintable().setTextInputEnabled(!noTextInput);
+
+ // not a FocusWidget -> needs own tabindex handling
+ if (uidl.hasAttribute("tabindex")) {
+ getWidgetForPaintable().tb.setTabIndex(uidl
+ .getIntAttribute("tabindex"));
+ }
+
+ if (uidl.hasAttribute("filteringmode")) {
+ getWidgetForPaintable().filteringmode = uidl
+ .getIntAttribute("filteringmode");
+ }
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ getWidgetForPaintable().nullSelectionAllowed = uidl
+ .hasAttribute("nullselect");
+
+ getWidgetForPaintable().nullSelectItem = uidl
+ .hasAttribute("nullselectitem")
+ && uidl.getBooleanAttribute("nullselectitem");
+
+ getWidgetForPaintable().currentPage = uidl.getIntVariable("page");
+
+ if (uidl.hasAttribute("pagelength")) {
+ getWidgetForPaintable().pageLength = uidl
+ .getIntAttribute("pagelength");
+ }
+
+ if (uidl.hasAttribute(VFilterSelect.ATTR_INPUTPROMPT)) {
+ // input prompt changed from server
+ getWidgetForPaintable().inputPrompt = uidl
+ .getStringAttribute(VFilterSelect.ATTR_INPUTPROMPT);
+ } else {
+ getWidgetForPaintable().inputPrompt = "";
+ }
+
+ getWidgetForPaintable().suggestionPopup.updateStyleNames(uidl);
+
+ getWidgetForPaintable().allowNewItem = uidl
+ .hasAttribute("allownewitem");
+ getWidgetForPaintable().lastNewItemString = null;
+
+ getWidgetForPaintable().currentSuggestions.clear();
+ if (!getWidgetForPaintable().waitingForFilteringResponse) {
+ /*
+ * Clear the current suggestions as the server response always
+ * includes the new ones. Exception is when filtering, then we need
+ * to retain the value if the user does not select any of the
+ * options matching the filter.
+ */
+ getWidgetForPaintable().currentSuggestion = null;
+ /*
+ * Also ensure no old items in menu. Unless cleared the old values
+ * may cause odd effects on blur events. Suggestions in menu might
+ * not necessary exist in select at all anymore.
+ */
+ getWidgetForPaintable().suggestionPopup.menu.clearItems();
+
+ }
+
+ final UIDL options = uidl.getChildUIDL(0);
+ if (uidl.hasAttribute("totalMatches")) {
+ getWidgetForPaintable().totalMatches = uidl
+ .getIntAttribute("totalMatches");
+ } else {
+ getWidgetForPaintable().totalMatches = 0;
+ }
+
+ // used only to calculate minimum popup width
+ String captions = Util.escapeHTML(getWidgetForPaintable().inputPrompt);
+
+ for (final Iterator<?> i = options.getChildIterator(); i.hasNext();) {
+ final UIDL optionUidl = (UIDL) i.next();
+ final FilterSelectSuggestion suggestion = getWidgetForPaintable().new FilterSelectSuggestion(
+ optionUidl);
+ getWidgetForPaintable().currentSuggestions.add(suggestion);
+ if (optionUidl.hasAttribute("selected")) {
+ if (!getWidgetForPaintable().waitingForFilteringResponse
+ || getWidgetForPaintable().popupOpenerClicked) {
+ String newSelectedOptionKey = Integer.toString(suggestion
+ .getOptionKey());
+ if (!newSelectedOptionKey
+ .equals(getWidgetForPaintable().selectedOptionKey)
+ || suggestion.getReplacementString().equals(
+ getWidgetForPaintable().tb.getText())) {
+ // Update text field if we've got a new selection
+ // Also update if we've got the same text to retain old
+ // text selection behavior
+ getWidgetForPaintable().setPromptingOff(
+ suggestion.getReplacementString());
+ getWidgetForPaintable().selectedOptionKey = newSelectedOptionKey;
+ }
+ }
+ getWidgetForPaintable().currentSuggestion = suggestion;
+ getWidgetForPaintable().setSelectedItemIcon(
+ suggestion.getIconUri());
+ }
+
+ // Collect captions so we can calculate minimum width for textarea
+ if (captions.length() > 0) {
+ captions += "|";
+ }
+ captions += Util.escapeHTML(suggestion.getReplacementString());
+ }
+
+ if ((!getWidgetForPaintable().waitingForFilteringResponse || getWidgetForPaintable().popupOpenerClicked)
+ && uidl.hasVariable("selected")
+ && uidl.getStringArrayVariable("selected").length == 0) {
+ // select nulled
+ if (!getWidgetForPaintable().waitingForFilteringResponse
+ || !getWidgetForPaintable().popupOpenerClicked) {
+ if (!getWidgetForPaintable().focused) {
+ /*
+ * client.updateComponent overwrites all styles so we must
+ * ALWAYS set the prompting style at this point, even though
+ * we think it has been set already...
+ */
+ getWidgetForPaintable().prompting = false;
+ getWidgetForPaintable().setPromptingOn();
+ } else {
+ // we have focus in field, prompting can't be set on,
+ // instead just clear the input
+ getWidgetForPaintable().tb.setValue("");
+ }
+ }
+ getWidgetForPaintable().selectedOptionKey = null;
+ }
+
+ if (getWidgetForPaintable().waitingForFilteringResponse
+ && getWidgetForPaintable().lastFilter.toLowerCase().equals(
+ uidl.getStringVariable("filter"))) {
+ getWidgetForPaintable().suggestionPopup.showSuggestions(
+ getWidgetForPaintable().currentSuggestions,
+ getWidgetForPaintable().currentPage,
+ getWidgetForPaintable().totalMatches);
+ getWidgetForPaintable().waitingForFilteringResponse = false;
+ if (!getWidgetForPaintable().popupOpenerClicked
+ && getWidgetForPaintable().selectPopupItemWhenResponseIsReceived != VFilterSelect.Select.NONE) {
+ // we're paging w/ arrows
+ if (getWidgetForPaintable().selectPopupItemWhenResponseIsReceived == VFilterSelect.Select.LAST) {
+ getWidgetForPaintable().suggestionPopup.menu
+ .selectLastItem();
+ } else {
+ getWidgetForPaintable().suggestionPopup.menu
+ .selectFirstItem();
+ }
+
+ // This is used for paging so we update the keyboard selection
+ // variable as well.
+ MenuItem activeMenuItem = getWidgetForPaintable().suggestionPopup.menu
+ .getSelectedItem();
+ getWidgetForPaintable().suggestionPopup.menu
+ .setKeyboardSelectedItem(activeMenuItem);
+
+ // Update text field to contain the correct text
+ getWidgetForPaintable()
+ .setTextboxText(activeMenuItem.getText());
+ getWidgetForPaintable().tb.setSelectionRange(
+ getWidgetForPaintable().lastFilter.length(),
+ activeMenuItem.getText().length()
+ - getWidgetForPaintable().lastFilter.length());
+
+ getWidgetForPaintable().selectPopupItemWhenResponseIsReceived = VFilterSelect.Select.NONE; // reset
+ }
+ if (getWidgetForPaintable().updateSelectionWhenReponseIsReceived) {
+ getWidgetForPaintable().suggestionPopup.menu
+ .doPostFilterSelectedItemAction();
+ }
+ }
+
+ // Calculate minumum textarea width
+ getWidgetForPaintable().suggestionPopupMinWidth = getWidgetForPaintable()
+ .minWidth(captions);
+
+ getWidgetForPaintable().popupOpenerClicked = false;
+
+ if (!getWidgetForPaintable().initDone) {
+ getWidgetForPaintable().updateRootWidth();
+ }
+
+ // Focus dependent style names are lost during the update, so we add
+ // them here back again
+ if (getWidgetForPaintable().focused) {
+ getWidgetForPaintable().addStyleDependentName("focus");
+ }
+
+ getWidgetForPaintable().initDone = true;
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VFilterSelect.class);
+ }
+
+ @Override
+ public VFilterSelect getWidgetForPaintable() {
+ return (VFilterSelect) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VForm.java b/src/com/vaadin/terminal/gwt/client/ui/VForm.java
index a329e1eaef..f3276db008 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VForm.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VForm.java
@@ -19,12 +19,9 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VErrorMessage;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VForm extends ComplexPanel implements Container, KeyDownHandler {
@@ -36,33 +33,33 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
public static final String CLASSNAME = "v-form";
- private Container lo;
- private Element legend = DOM.createLegend();
- private Element caption = DOM.createSpan();
+ Widget lo;
+ Element legend = DOM.createLegend();
+ Element caption = DOM.createSpan();
private Element errorIndicatorElement = DOM.createDiv();
- private Element desc = DOM.createDiv();
- private Icon icon;
- private VErrorMessage errorMessage = new VErrorMessage();
+ Element desc = DOM.createDiv();
+ Icon icon;
+ VErrorMessage errorMessage = new VErrorMessage();
- private Element fieldContainer = DOM.createDiv();
+ Element fieldContainer = DOM.createDiv();
- private Element footerContainer = DOM.createDiv();
+ Element footerContainer = DOM.createDiv();
- private Element fieldSet = DOM.createFieldSet();
+ Element fieldSet = DOM.createFieldSet();
- private Container footer;
+ Widget footer;
- private ApplicationConnection client;
+ ApplicationConnection client;
private RenderInformation renderInformation = new RenderInformation();
private int borderPaddingHorizontal = -1;
- private boolean rendering = false;
+ boolean rendering = false;
ShortcutActionHandler shortcutHandler;
- private HandlerRegistration keyDownRegistration;
+ HandlerRegistration keyDownRegistration;
public VForm() {
setElement(DOM.createDiv());
@@ -84,130 +81,6 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
fieldSet.appendChild(footerContainer);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- this.client = client;
- id = uidl.getId();
-
- if (client.updateComponent(this, uidl, false)) {
- rendering = false;
- return;
- }
-
- boolean legendEmpty = true;
- if (uidl.hasAttribute("caption")) {
- caption.setInnerText(uidl.getStringAttribute("caption"));
- legendEmpty = false;
- } else {
- caption.setInnerText("");
- }
- if (uidl.hasAttribute("icon")) {
- if (icon == null) {
- icon = new Icon(client);
- legend.insertFirst(icon.getElement());
- }
- icon.setUri(uidl.getStringAttribute("icon"));
- legendEmpty = false;
- } else {
- if (icon != null) {
- legend.removeChild(icon.getElement());
- }
- }
- if (legendEmpty) {
- addStyleDependentName("nocaption");
- } else {
- removeStyleDependentName("nocaption");
- }
-
- if (uidl.hasAttribute("error")) {
- final UIDL errorUidl = uidl.getErrors();
- errorMessage.updateFromUIDL(errorUidl);
- errorMessage.setVisible(true);
-
- } else {
- errorMessage.setVisible(false);
- }
-
- if (uidl.hasAttribute("description")) {
- desc.setInnerHTML(uidl.getStringAttribute("description"));
- if (desc.getParentElement() == null) {
- fieldSet.insertAfter(desc, legend);
- }
- } else {
- desc.setInnerHTML("");
- if (desc.getParentElement() != null) {
- fieldSet.removeChild(desc);
- }
- }
-
- 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
- Container newFooter = (Container) client.getPaintable(uidl
- .getChildUIDL(1));
- if (footer == null) {
- add(newFooter.getWidgetForPaintable(), footerContainer);
- footer = newFooter;
- } else if (newFooter != footer) {
- remove(footer.getWidgetForPaintable());
- client.unregisterPaintable(footer);
- add(newFooter.getWidgetForPaintable(), footerContainer);
- }
- footer = newFooter;
- footer.updateFromUIDL(uidl.getChildUIDL(1), client);
- // needed for the main layout to know the space it has available
- updateSize();
- } else {
- if (footer != null) {
- remove(footer.getWidgetForPaintable());
- client.unregisterPaintable(footer);
- // needed for the main layout to know the space it has available
- updateSize();
- }
- }
-
- final UIDL layoutUidl = uidl.getChildUIDL(0);
- Container newLo = (Container) client.getPaintable(layoutUidl);
- if (lo == null) {
- lo = newLo;
- add(lo.getWidgetForPaintable(), fieldContainer);
- } else if (lo != newLo) {
- client.unregisterPaintable(lo);
- remove(lo.getWidgetForPaintable());
- lo = newLo;
- add(lo.getWidgetForPaintable(), fieldContainer);
- }
- lo.updateFromUIDL(layoutUidl, client);
-
- // also recalculates size of the footer if undefined size form - see
- // #3710
- updateSize();
- client.runDescendentsLayout(this);
-
- // We may have actions attached
- if (uidl.getChildCount() > 1) {
- UIDL childUidl = uidl.getChildByTagName("actions");
- if (childUidl != null) {
- if (shortcutHandler == null) {
- shortcutHandler = new ShortcutActionHandler(id, client);
- keyDownRegistration = addDomHandler(this,
- KeyDownEvent.getType());
- }
- shortcutHandler.updateActionMap(childUidl);
- }
- } else if (shortcutHandler != null) {
- keyDownRegistration.removeHandler();
- shortcutHandler = null;
- keyDownRegistration = null;
- }
-
- rendering = false;
- }
-
public void updateSize() {
renderInformation.updateSize(getElement());
@@ -241,12 +114,10 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
}
remove(oldComponent);
if (oldComponent == lo) {
- lo = (Container) VPaintableMap.get(client).getPaintable(
- newComponent);
+ lo = newComponent;
add(newComponent, fieldContainer);
} else {
- footer = (Container) VPaintableMap.get(client).getPaintable(
- newComponent);
+ footer = newComponent;
add(newComponent, footerContainer);
}
@@ -272,11 +143,6 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP form don't render caption for neither field layout nor footer
- // layout
- }
-
@Override
public void setHeight(String height) {
if (this.height.equals(height)) {
@@ -329,7 +195,10 @@ public class VForm extends ComplexPanel implements Container, KeyDownHandler {
shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent()));
}
- public Widget getWidgetForPaintable() {
- return this;
+ @Override
+ protected void add(Widget child, Element container) {
+ // Overridden to allow VFormPaintable to call this. Should be removed
+ // once functionality from VFormPaintable is moved to VForm.
+ super.add(child, container);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
index e6305b3c42..6d3072f407 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
@@ -38,13 +38,13 @@ public class VFormLayout extends SimplePanel implements Container {
private final static String CLASSNAME = "v-formlayout";
- private ApplicationConnection client;
- private VFormLayoutTable table;
+ ApplicationConnection client;
+ VFormLayoutTable table;
private String width = "";
private String height = "";
- private boolean rendering = false;
+ boolean rendering = false;
public VFormLayout() {
super();
@@ -279,21 +279,6 @@ public class VFormLayout extends SimplePanel implements Container {
}
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
-
- this.client = client;
-
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
-
- table.updateFromUIDL(uidl, client);
-
- rendering = false;
- }
-
public boolean isDynamicWidth() {
return width.equals("");
}
@@ -306,10 +291,6 @@ public class VFormLayout extends SimplePanel implements Container {
table.replaceChildComponent(oldComponent, newComponent);
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- table.updateCaption(component, uidl);
- }
-
public class Caption extends HTML {
public static final String CLASSNAME = "v-caption";
@@ -545,8 +526,4 @@ public class VFormLayout extends SimplePanel implements Container {
}
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
new file mode 100644
index 0000000000..3be2a028c5
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayoutPaintable.java
@@ -0,0 +1,42 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VFormLayoutPaintable extends VAbstractPaintableWidgetContainer {
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().client = client;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().table.updateFromUIDL(uidl, client);
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ getWidgetForPaintable().table.updateCaption(component, uidl);
+ }
+
+ @Override
+ public VFormLayout getWidgetForPaintable() {
+ return (VFormLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VFormLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
new file mode 100644
index 0000000000..e2533591ea
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFormPaintable.java
@@ -0,0 +1,176 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VFormPaintable extends VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ if (client.updateComponent(this, uidl, false)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ boolean legendEmpty = true;
+ if (uidl.hasAttribute("caption")) {
+ getWidgetForPaintable().caption.setInnerText(uidl
+ .getStringAttribute("caption"));
+ legendEmpty = false;
+ } else {
+ getWidgetForPaintable().caption.setInnerText("");
+ }
+ if (uidl.hasAttribute("icon")) {
+ if (getWidgetForPaintable().icon == null) {
+ getWidgetForPaintable().icon = new Icon(client);
+ getWidgetForPaintable().legend
+ .insertFirst(getWidgetForPaintable().icon.getElement());
+ }
+ getWidgetForPaintable().icon
+ .setUri(uidl.getStringAttribute("icon"));
+ legendEmpty = false;
+ } else {
+ if (getWidgetForPaintable().icon != null) {
+ getWidgetForPaintable().legend
+ .removeChild(getWidgetForPaintable().icon.getElement());
+ }
+ }
+ if (legendEmpty) {
+ getWidgetForPaintable().addStyleDependentName("nocaption");
+ } else {
+ getWidgetForPaintable().removeStyleDependentName("nocaption");
+ }
+
+ if (uidl.hasAttribute("error")) {
+ final UIDL errorUidl = uidl.getErrors();
+ getWidgetForPaintable().errorMessage.updateFromUIDL(errorUidl);
+ getWidgetForPaintable().errorMessage.setVisible(true);
+ } else {
+ getWidgetForPaintable().errorMessage.setVisible(false);
+ }
+
+ if (uidl.hasAttribute("description")) {
+ getWidgetForPaintable().desc.setInnerHTML(uidl
+ .getStringAttribute("description"));
+ if (getWidgetForPaintable().desc.getParentElement() == null) {
+ getWidgetForPaintable().fieldSet.insertAfter(
+ getWidgetForPaintable().desc,
+ getWidgetForPaintable().legend);
+ }
+ } else {
+ getWidgetForPaintable().desc.setInnerHTML("");
+ if (getWidgetForPaintable().desc.getParentElement() != null) {
+ getWidgetForPaintable().fieldSet
+ .removeChild(getWidgetForPaintable().desc);
+ }
+ }
+
+ getWidgetForPaintable().updateSize();
+
+ // first render footer so it will be easier to handle relative height of
+ // main layout
+ if (uidl.getChildCount() > 1
+ && !uidl.getChildUIDL(1).getTag().equals("actions")) {
+ // render footer
+ VPaintableWidget newFooter = client.getPaintable(uidl
+ .getChildUIDL(1));
+ Widget newFooterWidget = newFooter.getWidgetForPaintable();
+ if (getWidgetForPaintable().footer == null) {
+ getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
+ getWidgetForPaintable().footerContainer);
+ getWidgetForPaintable().footer = newFooterWidget;
+ } else if (newFooter != getWidgetForPaintable().footer) {
+ getWidgetForPaintable().remove(getWidgetForPaintable().footer);
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().footer));
+ getWidgetForPaintable().add(newFooter.getWidgetForPaintable(),
+ getWidgetForPaintable().footerContainer);
+ }
+ getWidgetForPaintable().footer = newFooterWidget;
+ newFooter.updateFromUIDL(uidl.getChildUIDL(1), client);
+ // needed for the main layout to know the space it has available
+ getWidgetForPaintable().updateSize();
+ } else {
+ if (getWidgetForPaintable().footer != null) {
+ getWidgetForPaintable().remove(getWidgetForPaintable().footer);
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().footer));
+ // needed for the main layout to know the space it has available
+ getWidgetForPaintable().updateSize();
+ }
+ }
+
+ final UIDL layoutUidl = uidl.getChildUIDL(0);
+ VPaintableWidget newLayout = client.getPaintable(layoutUidl);
+ Widget newLayoutWidget = newLayout.getWidgetForPaintable();
+ if (getWidgetForPaintable().lo == null) {
+ // Layout not rendered before
+ getWidgetForPaintable().lo = newLayoutWidget;
+ getWidgetForPaintable().add(newLayoutWidget,
+ getWidgetForPaintable().fieldContainer);
+ } else if (getWidgetForPaintable().lo != newLayoutWidget) {
+ // Layout has changed
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(getWidgetForPaintable().lo));
+ getWidgetForPaintable().remove(getWidgetForPaintable().lo);
+ getWidgetForPaintable().lo = newLayoutWidget;
+ getWidgetForPaintable().add(newLayoutWidget,
+ getWidgetForPaintable().fieldContainer);
+ }
+ newLayout.updateFromUIDL(layoutUidl, client);
+
+ // also recalculates size of the footer if undefined size form - see
+ // #3710
+ getWidgetForPaintable().updateSize();
+ client.runDescendentsLayout(getWidgetForPaintable());
+
+ // We may have actions attached
+ if (uidl.getChildCount() > 1) {
+ UIDL childUidl = uidl.getChildByTagName("actions");
+ if (childUidl != null) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ getWidgetForPaintable().keyDownRegistration = getWidgetForPaintable()
+ .addDomHandler(getWidgetForPaintable(),
+ KeyDownEvent.getType());
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ } else if (getWidgetForPaintable().shortcutHandler != null) {
+ getWidgetForPaintable().keyDownRegistration.removeHandler();
+ getWidgetForPaintable().shortcutHandler = null;
+ getWidgetForPaintable().keyDownRegistration = null;
+ }
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP form don't render caption for neither field layout nor footer
+ // layout
+ }
+
+ @Override
+ public VForm getWidgetForPaintable() {
+ return (VForm) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VForm.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
index b37032e987..5302fa6f67 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
@@ -14,16 +14,12 @@ import java.util.Set;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
-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.AbsolutePanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.StyleConstants;
import com.vaadin.terminal.gwt.client.UIDL;
@@ -33,59 +29,43 @@ import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout;
import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
-public class VGridLayout extends SimplePanel implements VPaintableWidget,
- Container {
+public class VGridLayout extends SimplePanel implements Container {
public static final String CLASSNAME = "v-gridlayout";
private DivElement margin = Document.get().createDivElement();
- private final AbsolutePanel canvas = new AbsolutePanel();
+ final AbsolutePanel canvas = new AbsolutePanel();
- private ApplicationConnection client;
+ ApplicationConnection client;
protected HashMap<Widget, ChildComponentContainer> widgetToComponentContainer = new HashMap<Widget, ChildComponentContainer>();
- private HashMap<Widget, Cell> widgetToCell = new HashMap<Widget, Cell>();
+ HashMap<Widget, Cell> widgetToCell = new HashMap<Widget, Cell>();
private int spacingPixelsHorizontal;
private int spacingPixelsVertical;
- private int[] columnWidths;
- private int[] rowHeights;
+ int[] columnWidths;
+ int[] rowHeights;
private String height;
private String width;
- private int[] colExpandRatioArray;
+ int[] colExpandRatioArray;
- private int[] rowExpandRatioArray;
+ int[] rowExpandRatioArray;
- private int[] minColumnWidths;
+ int[] minColumnWidths;
private int[] minRowHeights;
- private boolean rendering;
+ boolean rendering;
- private HashMap<Widget, ChildComponentContainer> nonRenderedWidgets;
+ HashMap<Widget, ChildComponentContainer> nonRenderedWidgets;
- private boolean sizeChangedDuringRendering = false;
-
- private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
- this, EventId.LAYOUT_CLICK) {
-
- @Override
- protected VPaintableWidget getChildComponent(Element element) {
- return getComponent(element);
- }
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
+ boolean sizeChangedDuringRendering = false;
public VGridLayout() {
super();
@@ -135,126 +115,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
return spacingPixelsVertical;
}
- @SuppressWarnings("unchecked")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- this.client = client;
-
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
- clickEventHandler.handleEventHandlerRegistration(client);
-
- canvas.setWidth("0px");
-
- handleMargins(uidl);
- detectSpacing(uidl);
-
- int cols = uidl.getIntAttribute("w");
- int rows = uidl.getIntAttribute("h");
-
- columnWidths = new int[cols];
- rowHeights = new int[rows];
-
- if (cells == null) {
- cells = new Cell[cols][rows];
- } else if (cells.length != cols || cells[0].length != rows) {
- Cell[][] newCells = new Cell[cols][rows];
- for (int i = 0; i < cells.length; i++) {
- for (int j = 0; j < cells[i].length; j++) {
- if (i < cols && j < rows) {
- newCells[i][j] = cells[i][j];
- }
- }
- }
- cells = newCells;
- }
-
- nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) widgetToComponentContainer
- .clone();
-
- final int[] alignments = uidl.getIntArrayAttribute("alignments");
- int alignmentIndex = 0;
-
- LinkedList<Cell> pendingCells = new LinkedList<Cell>();
-
- LinkedList<Cell> relativeHeighted = new LinkedList<Cell>();
-
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
- final UIDL r = (UIDL) i.next();
- if ("gr".equals(r.getTag())) {
- for (final Iterator<?> j = r.getChildIterator(); j.hasNext();) {
- final UIDL c = (UIDL) j.next();
- if ("gc".equals(c.getTag())) {
- Cell cell = getCell(c);
- if (cell.hasContent()) {
- boolean rendered = cell.renderIfNoRelativeWidth();
- cell.alignment = alignments[alignmentIndex++];
- if (!rendered) {
- pendingCells.add(cell);
- }
-
- if (cell.colspan > 1) {
- storeColSpannedCell(cell);
- } else if (rendered) {
- // strore non-colspanned widths to columnWidth
- // array
- if (columnWidths[cell.col] < cell.getWidth()) {
- columnWidths[cell.col] = cell.getWidth();
- }
- }
- if (cell.hasRelativeHeight()) {
- relativeHeighted.add(cell);
- }
- }
- }
- }
- }
- }
-
- colExpandRatioArray = uidl.getIntArrayAttribute("colExpand");
- rowExpandRatioArray = uidl.getIntArrayAttribute("rowExpand");
- distributeColSpanWidths();
-
- minColumnWidths = cloneArray(columnWidths);
- expandColumns();
-
- renderRemainingComponentsWithNoRelativeHeight(pendingCells);
-
- detectRowHeights();
-
- expandRows();
-
- 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();
- }
-
- layoutCells();
-
- // clean non rendered components
- for (Widget w : nonRenderedWidgets.keySet()) {
- ChildComponentContainer childComponentContainer = widgetToComponentContainer
- .get(w);
- widgetToCell.remove(w);
- widgetToComponentContainer.remove(w);
- childComponentContainer.removeFromParent();
- VPaintableMap paintableMap = VPaintableMap.get(client);
- paintableMap.unregisterPaintable(paintableMap.getPaintable(w));
- }
- nonRenderedWidgets = null;
-
- rendering = false;
- sizeChangedDuringRendering = false;
-
- }
-
- private static int[] cloneArray(int[] toBeCloned) {
+ static int[] cloneArray(int[] toBeCloned) {
int[] clone = new int[toBeCloned.length];
for (int i = 0; i < clone.length; i++) {
clone[i] = toBeCloned[i] * 1;
@@ -262,7 +123,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
return clone;
}
- private void expandRows() {
+ void expandRows() {
if (!"".equals(height)) {
int usedSpace = minRowHeights[0];
for (int i = 1; i < minRowHeights.length; i++) {
@@ -401,7 +262,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
}
}
- private void expandColumns() {
+ void expandColumns() {
if (!"".equals(width)) {
int usedSpace = minColumnWidths[0];
for (int i = 1; i < minColumnWidths.length; i++) {
@@ -428,7 +289,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
}
}
- private void layoutCells() {
+ void layoutCells() {
int x = 0;
int y = 0;
for (int i = 0; i < cells.length; i++) {
@@ -470,13 +331,13 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
return "".equals(width);
}
- private void renderRemainingComponents(LinkedList<Cell> pendingCells) {
+ void renderRemainingComponents(LinkedList<Cell> pendingCells) {
for (Cell cell : pendingCells) {
cell.render();
}
}
- private void detectRowHeights() {
+ void detectRowHeights() {
// collect min rowheight from non-rowspanned cells
for (int i = 0; i < cells.length; i++) {
@@ -531,7 +392,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
l.cells.add(cell);
}
- private void renderRemainingComponentsWithNoRelativeHeight(
+ void renderRemainingComponentsWithNoRelativeHeight(
LinkedList<Cell> pendingCells) {
for (Iterator<Cell> iterator = pendingCells.iterator(); iterator
@@ -549,7 +410,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
* Iterates colspanned cells, ensures cols have enough space to accommodate
* them
*/
- private void distributeColSpanWidths() {
+ void distributeColSpanWidths() {
for (SpanList list : colSpans) {
for (Cell cell : list.cells) {
// cells with relative content may return non 0 here if on
@@ -643,7 +504,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
}
}
- private void storeColSpannedCell(Cell cell) {
+ void storeColSpannedCell(Cell cell) {
SpanList l = null;
for (SpanList list : colSpans) {
if (list.span < cell.colspan) {
@@ -666,7 +527,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
l.cells.add(cell);
}
- private void detectSpacing(UIDL uidl) {
+ void detectSpacing(UIDL uidl) {
DivElement spacingmeter = Document.get().createDivElement();
spacingmeter.setClassName(CLASSNAME + "-" + "spacing-"
+ (uidl.getBooleanAttribute("spacing") ? "on" : "off"));
@@ -678,7 +539,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
canvas.getElement().removeChild(spacingmeter);
}
- private void handleMargins(UIDL uidl) {
+ void handleMargins(UIDL uidl) {
final VMarginInfo margins = new VMarginInfo(
uidl.getIntAttribute("margins"));
@@ -719,23 +580,6 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
widgetToCell.put(newComponent, widgetToCell.get(oldComponent));
}
- public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
- Widget widget = paintable.getWidgetForPaintable();
- ChildComponentContainer cc = widgetToComponentContainer.get(widget);
- if (cc != null) {
- cc.updateCaption(uidl, client);
- }
- if (!rendering) {
- // ensure rel size details are updated
- widgetToCell.get(widget).updateRelSizeStatus(uidl);
- /*
- * This was a component-only update and the possible size change
- * must be propagated to the layout
- */
- client.captionSizeUpdated(widget);
- }
- }
-
public boolean requestLayout(final Set<Widget> changedChildren) {
boolean needsLayout = false;
boolean reDistributeColSpanWidths = false;
@@ -895,12 +739,12 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
return cell.getAllocatedSpace();
}
- private Cell[][] cells;
+ Cell[][] cells;
/**
* Private helper class.
*/
- private class Cell {
+ class Cell {
private boolean relHeight = false;
private boolean relWidth = false;
private boolean widthCanAffectHeight = false;
@@ -1109,7 +953,7 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
}
}
- private Cell getCell(UIDL c) {
+ Cell getCell(UIDL c) {
int row = c.getIntAttribute("y");
int col = c.getIntAttribute("x");
Cell cell = cells[col][row];
@@ -1132,12 +976,8 @@ public class VGridLayout extends SimplePanel implements VPaintableWidget,
* @return The Paintable which the element is a part of. Null if the element
* belongs to the layout and not to a child.
*/
- private VPaintableWidget getComponent(Element element) {
+ VPaintableWidget getComponent(Element element) {
return Util.getPaintableForElement(client, this, element);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
new file mode 100644
index 0000000000..8f84f27297
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayoutPaintable.java
@@ -0,0 +1,196 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VGridLayout.Cell;
+import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
+
+public class VGridLayoutPaintable extends VAbstractPaintableWidgetContainer {
+ private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
+ this, EventId.LAYOUT_CLICK) {
+
+ @Override
+ protected VPaintableWidget getChildComponent(Element element) {
+ return getWidgetForPaintable().getComponent(element);
+ }
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ getWidgetForPaintable().client = client;
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().canvas.setWidth("0px");
+
+ getWidgetForPaintable().handleMargins(uidl);
+ getWidgetForPaintable().detectSpacing(uidl);
+
+ int cols = uidl.getIntAttribute("w");
+ int rows = uidl.getIntAttribute("h");
+
+ getWidgetForPaintable().columnWidths = new int[cols];
+ getWidgetForPaintable().rowHeights = new int[rows];
+
+ if (getWidgetForPaintable().cells == null) {
+ getWidgetForPaintable().cells = new Cell[cols][rows];
+ } else if (getWidgetForPaintable().cells.length != cols
+ || getWidgetForPaintable().cells[0].length != rows) {
+ Cell[][] newCells = new Cell[cols][rows];
+ for (int i = 0; i < getWidgetForPaintable().cells.length; i++) {
+ for (int j = 0; j < getWidgetForPaintable().cells[i].length; j++) {
+ if (i < cols && j < rows) {
+ newCells[i][j] = getWidgetForPaintable().cells[i][j];
+ }
+ }
+ }
+ getWidgetForPaintable().cells = newCells;
+ }
+
+ getWidgetForPaintable().nonRenderedWidgets = (HashMap<Widget, ChildComponentContainer>) getWidgetForPaintable().widgetToComponentContainer
+ .clone();
+
+ final int[] alignments = uidl.getIntArrayAttribute("alignments");
+ int alignmentIndex = 0;
+
+ LinkedList<Cell> pendingCells = new LinkedList<Cell>();
+
+ LinkedList<Cell> relativeHeighted = new LinkedList<Cell>();
+
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL r = (UIDL) i.next();
+ if ("gr".equals(r.getTag())) {
+ for (final Iterator<?> j = r.getChildIterator(); j.hasNext();) {
+ final UIDL c = (UIDL) j.next();
+ if ("gc".equals(c.getTag())) {
+ Cell cell = getWidgetForPaintable().getCell(c);
+ if (cell.hasContent()) {
+ boolean rendered = cell.renderIfNoRelativeWidth();
+ cell.alignment = alignments[alignmentIndex++];
+ if (!rendered) {
+ pendingCells.add(cell);
+ }
+
+ if (cell.colspan > 1) {
+ getWidgetForPaintable().storeColSpannedCell(
+ cell);
+ } else if (rendered) {
+ // strore non-colspanned widths to columnWidth
+ // array
+ if (getWidgetForPaintable().columnWidths[cell.col] < cell
+ .getWidth()) {
+ getWidgetForPaintable().columnWidths[cell.col] = cell
+ .getWidth();
+ }
+ }
+ if (cell.hasRelativeHeight()) {
+ relativeHeighted.add(cell);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ getWidgetForPaintable().colExpandRatioArray = uidl
+ .getIntArrayAttribute("colExpand");
+ getWidgetForPaintable().rowExpandRatioArray = uidl
+ .getIntArrayAttribute("rowExpand");
+ getWidgetForPaintable().distributeColSpanWidths();
+
+ getWidgetForPaintable().minColumnWidths = VGridLayout
+ .cloneArray(getWidgetForPaintable().columnWidths);
+ getWidgetForPaintable().expandColumns();
+
+ getWidgetForPaintable().renderRemainingComponentsWithNoRelativeHeight(
+ pendingCells);
+
+ getWidgetForPaintable().detectRowHeights();
+
+ getWidgetForPaintable().expandRows();
+
+ getWidgetForPaintable().renderRemainingComponents(pendingCells);
+
+ for (Cell cell : relativeHeighted) {
+ // rendering done above so cell.cc should not be null
+ Widget widget2 = cell.cc.getWidget();
+ client.handleComponentRelativeSize(widget2);
+ cell.cc.updateWidgetSize();
+ }
+
+ getWidgetForPaintable().layoutCells();
+
+ // clean non rendered components
+ for (Widget w : getWidgetForPaintable().nonRenderedWidgets.keySet()) {
+ ChildComponentContainer childComponentContainer = getWidgetForPaintable().widgetToComponentContainer
+ .get(w);
+ getWidgetForPaintable().widgetToCell.remove(w);
+ getWidgetForPaintable().widgetToComponentContainer.remove(w);
+ childComponentContainer.removeFromParent();
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ paintableMap.unregisterPaintable(paintableMap.getPaintable(w));
+ }
+ getWidgetForPaintable().nonRenderedWidgets = null;
+
+ getWidgetForPaintable().rendering = false;
+ getWidgetForPaintable().sizeChangedDuringRendering = false;
+
+ }
+
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ ChildComponentContainer cc = getWidgetForPaintable().widgetToComponentContainer
+ .get(widget);
+ if (cc != null) {
+ cc.updateCaption(uidl, getConnection());
+ }
+ if (!getWidgetForPaintable().rendering) {
+ // ensure rel size details are updated
+ getWidgetForPaintable().widgetToCell.get(widget)
+ .updateRelSizeStatus(uidl);
+ /*
+ * This was a component-only update and the possible size change
+ * must be propagated to the layout
+ */
+ getConnection().captionSizeUpdated(widget);
+ }
+ }
+
+ @Override
+ public VGridLayout getWidgetForPaintable() {
+ return (VGridLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VGridLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
new file mode 100644
index 0000000000..acc49ece18
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalLayoutPaintable.java
@@ -0,0 +1,20 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VHorizontalLayoutPaintable extends VOrderedLayoutPaintable {
+
+ @Override
+ public VHorizontalLayout getWidgetForPaintable() {
+ return (VHorizontalLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected VHorizontalLayout createWidget() {
+ return GWT.create(VHorizontalLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
new file mode 100644
index 0000000000..44141107aa
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VHorizontalSplitPanelPaintable.java
@@ -0,0 +1,16 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VHorizontalSplitPanelPaintable extends
+ VAbstractSplitPanelPaintable {
+
+ @Override
+ protected VAbstractSplitPanel createWidget() {
+ return GWT.create(VSplitPanelHorizontal.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java b/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
index 018df57327..aac8ca5ee7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VLazyExecutor.java
@@ -1,52 +1,52 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.user.client.Timer;
-
-/**
- * Executes the given command {@code delayMs} milliseconds after a call to
- * {@link #trigger()}. Calling {@link #trigger()} again before the command has
- * been executed causes the execution to be rescheduled to {@code delayMs} after
- * the second call.
- *
- */
-public class VLazyExecutor {
-
- private Timer timer;
- private int delayMs;
- private ScheduledCommand cmd;
-
- /**
- * @param delayMs
- * Delay in milliseconds to wait before executing the command
- * @param cmd
- * The command to execute
- */
- public VLazyExecutor(int delayMs, ScheduledCommand cmd) {
- this.delayMs = delayMs;
- this.cmd = cmd;
- }
-
- /**
- * Triggers execution of the command. Each call reschedules any existing
- * execution to {@link #delayMs} milliseconds from that point in time.
- */
- public void trigger() {
- if (timer == null) {
- timer = new Timer() {
- @Override
- public void run() {
- timer = null;
- cmd.execute();
- }
- };
- }
- // Schedule automatically cancels any old schedule
- timer.schedule(delayMs);
-
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.user.client.Timer;
+
+/**
+ * Executes the given command {@code delayMs} milliseconds after a call to
+ * {@link #trigger()}. Calling {@link #trigger()} again before the command has
+ * been executed causes the execution to be rescheduled to {@code delayMs} after
+ * the second call.
+ *
+ */
+public class VLazyExecutor {
+
+ private Timer timer;
+ private int delayMs;
+ private ScheduledCommand cmd;
+
+ /**
+ * @param delayMs
+ * Delay in milliseconds to wait before executing the command
+ * @param cmd
+ * The command to execute
+ */
+ public VLazyExecutor(int delayMs, ScheduledCommand cmd) {
+ this.delayMs = delayMs;
+ this.cmd = cmd;
+ }
+
+ /**
+ * Triggers execution of the command. Each call reschedules any existing
+ * execution to {@link #delayMs} milliseconds from that point in time.
+ */
+ public void trigger() {
+ if (timer == null) {
+ timer = new Timer() {
+ @Override
+ public void run() {
+ timer = null;
+ cmd.execute();
+ }
+ };
+ }
+ // Schedule automatically cancels any old schedule
+ timer.schedule(delayMs);
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLink.java b/src/com/vaadin/terminal/gwt/client/ui/VLink.java
index 0ade84aaf5..df651c0a4d 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VLink.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VLink.java
@@ -11,44 +11,41 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VLink extends HTML implements VPaintableWidget, ClickHandler {
+public class VLink extends HTML implements ClickHandler {
public static final String CLASSNAME = "v-link";
- private static final int BORDER_STYLE_DEFAULT = 0;
- private static final int BORDER_STYLE_MINIMAL = 1;
- private static final int BORDER_STYLE_NONE = 2;
+ protected static final int BORDER_STYLE_DEFAULT = 0;
+ protected static final int BORDER_STYLE_MINIMAL = 1;
+ protected static final int BORDER_STYLE_NONE = 2;
- private String src;
+ protected String src;
- private String target;
+ protected String target;
- private int borderStyle = BORDER_STYLE_DEFAULT;
+ protected int borderStyle = BORDER_STYLE_DEFAULT;
- private boolean enabled;
+ protected boolean enabled;
- private boolean readonly;
+ protected boolean readonly;
- private int targetWidth;
+ protected int targetWidth;
- private int targetHeight;
+ protected int targetHeight;
- private Element errorIndicatorElement;
+ protected Element errorIndicatorElement;
- private final Element anchor = DOM.createAnchor();
+ protected final Element anchor = DOM.createAnchor();
- private final Element captionElement = DOM.createSpan();
+ protected final Element captionElement = DOM.createSpan();
- private Icon icon;
+ protected Icon icon;
- private ApplicationConnection client;
+ protected ApplicationConnection client;
public VLink() {
super();
@@ -59,68 +56,6 @@ public class VLink extends HTML implements VPaintableWidget, ClickHandler {
setStyleName(CLASSNAME);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- // Ensure correct implementation,
- // but don't let container manage caption etc.
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
-
- this.client = client;
-
- enabled = uidl.hasAttribute("disabled") ? false : true;
- readonly = uidl.hasAttribute("readonly") ? true : false;
-
- if (uidl.hasAttribute("name")) {
- target = uidl.getStringAttribute("name");
- anchor.setAttribute("target", target);
- }
- if (uidl.hasAttribute("src")) {
- src = client.translateVaadinUri(uidl.getStringAttribute("src"));
- anchor.setAttribute("href", src);
- }
-
- if (uidl.hasAttribute("border")) {
- if ("none".equals(uidl.getStringAttribute("border"))) {
- borderStyle = BORDER_STYLE_NONE;
- } else {
- borderStyle = BORDER_STYLE_MINIMAL;
- }
- } else {
- borderStyle = BORDER_STYLE_DEFAULT;
- }
-
- targetHeight = uidl.hasAttribute("targetHeight") ? uidl
- .getIntAttribute("targetHeight") : -1;
- targetWidth = uidl.hasAttribute("targetWidth") ? uidl
- .getIntAttribute("targetWidth") : -1;
-
- // Set link caption
- captionElement.setInnerText(uidl.getStringAttribute("caption"));
-
- // handle error
- if (uidl.hasAttribute("error")) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- DOM.setElementProperty(errorIndicatorElement, "className",
- "v-errorindicator");
- }
- DOM.insertChild(getElement(), errorIndicatorElement, 0);
- } else if (errorIndicatorElement != null) {
- DOM.setStyleAttribute(errorIndicatorElement, "display", "none");
- }
-
- if (uidl.hasAttribute("icon")) {
- if (icon == null) {
- icon = new Icon(client);
- anchor.insertBefore(icon.getElement(), captionElement);
- }
- icon.setUri(uidl.getStringAttribute("icon"));
- }
-
- }
-
public void onClick(ClickEvent event) {
if (enabled && !readonly) {
if (target == null) {
@@ -168,7 +103,7 @@ public class VLink extends HTML implements VPaintableWidget, ClickHandler {
Util.notifyParentOfSizeChange(this, true);
}
if (client != null) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
if (target == captionElement || target == anchor
|| (icon != null && target == icon.getElement())) {
@@ -180,8 +115,4 @@ public class VLink extends HTML implements VPaintableWidget, ClickHandler {
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLinkPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VLinkPaintable.java
new file mode 100644
index 0000000000..3fbd796c4b
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VLinkPaintable.java
@@ -0,0 +1,100 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VLinkPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ // Ensure correct implementation,
+ // but don't let container manage caption etc.
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ getWidgetForPaintable().client = client;
+
+ getWidgetForPaintable().enabled = uidl.hasAttribute("disabled") ? false
+ : true;
+ getWidgetForPaintable().readonly = uidl.hasAttribute("readonly") ? true
+ : false;
+
+ if (uidl.hasAttribute("name")) {
+ getWidgetForPaintable().target = uidl.getStringAttribute("name");
+ getWidgetForPaintable().anchor.setAttribute("target",
+ getWidgetForPaintable().target);
+ }
+ if (uidl.hasAttribute("src")) {
+ getWidgetForPaintable().src = client.translateVaadinUri(uidl
+ .getStringAttribute("src"));
+ getWidgetForPaintable().anchor.setAttribute("href",
+ getWidgetForPaintable().src);
+ }
+
+ if (uidl.hasAttribute("border")) {
+ if ("none".equals(uidl.getStringAttribute("border"))) {
+ getWidgetForPaintable().borderStyle = VLink.BORDER_STYLE_NONE;
+ } else {
+ getWidgetForPaintable().borderStyle = VLink.BORDER_STYLE_MINIMAL;
+ }
+ } else {
+ getWidgetForPaintable().borderStyle = VLink.BORDER_STYLE_DEFAULT;
+ }
+
+ getWidgetForPaintable().targetHeight = uidl
+ .hasAttribute("targetHeight") ? uidl
+ .getIntAttribute("targetHeight") : -1;
+ getWidgetForPaintable().targetWidth = uidl.hasAttribute("targetWidth") ? uidl
+ .getIntAttribute("targetWidth") : -1;
+
+ // Set link caption
+ getWidgetForPaintable().captionElement.setInnerText(uidl
+ .getStringAttribute("caption"));
+
+ // handle error
+ if (uidl.hasAttribute("error")) {
+ if (getWidgetForPaintable().errorIndicatorElement == null) {
+ getWidgetForPaintable().errorIndicatorElement = DOM.createDiv();
+ DOM.setElementProperty(
+ getWidgetForPaintable().errorIndicatorElement,
+ "className", "v-errorindicator");
+ }
+ DOM.insertChild(getWidgetForPaintable().getElement(),
+ getWidgetForPaintable().errorIndicatorElement, 0);
+ } else if (getWidgetForPaintable().errorIndicatorElement != null) {
+ DOM.setStyleAttribute(
+ getWidgetForPaintable().errorIndicatorElement, "display",
+ "none");
+ }
+
+ if (uidl.hasAttribute("icon")) {
+ if (getWidgetForPaintable().icon == null) {
+ getWidgetForPaintable().icon = new Icon(client);
+ getWidgetForPaintable().anchor.insertBefore(
+ getWidgetForPaintable().icon.getElement(),
+ getWidgetForPaintable().captionElement);
+ }
+ getWidgetForPaintable().icon
+ .setUri(uidl.getStringAttribute("icon"));
+ }
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VLink.class);
+ }
+
+ @Override
+ public VLink getWidgetForPaintable() {
+ return (VLink) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
index 25bd6f35b2..1ea2f4f705 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java
@@ -12,7 +12,6 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VTooltip;
@@ -81,11 +80,11 @@ public class VListSelect extends VOptionGroupBase {
} else {
lastSelectedIndex = si;
if (isMultiselect()) {
- client.updateVariable(id, "selected", getSelectedItems(),
- isImmediate());
+ client.updateVariable(paintableId, "selected",
+ getSelectedItems(), isImmediate());
} else {
- client.updateVariable(id, "selected", new String[] { ""
- + getSelectedItem() }, isImmediate());
+ client.updateVariable(paintableId, "selected",
+ new String[] { "" + getSelectedItem() }, isImmediate());
}
}
}
@@ -110,11 +109,6 @@ public class VListSelect extends VOptionGroupBase {
public void focus() {
select.setFocus(true);
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
/**
@@ -123,7 +117,7 @@ public class VListSelect extends VOptionGroupBase {
*/
class TooltipListBox extends ListBox {
private ApplicationConnection client;
- private VPaintableWidget pntbl;
+ private Widget widget;
TooltipListBox(boolean isMultiselect) {
super(isMultiselect);
@@ -134,15 +128,15 @@ class TooltipListBox extends ListBox {
this.client = client;
}
- public void setSelect(VPaintableWidget s) {
- pntbl = s;
+ public void setSelect(Widget widget) {
+ this.widget = widget;
}
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, pntbl);
+ client.handleWidgetTooltipEvent(event, widget);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VListSelectPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VListSelectPaintable.java
new file mode 100644
index 0000000000..b77bfa33e3
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VListSelectPaintable.java
@@ -0,0 +1,21 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+
+public class VListSelectPaintable extends VOptionGroupBasePaintable {
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VListSelect.class);
+ }
+
+ @Override
+ public VListSelect getWidgetForPaintable() {
+ return (VListSelect) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
index fc709d56b3..1f6bbe6a0a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMediaBasePaintable.java
@@ -1,109 +1,112 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public abstract class VMediaBasePaintable extends VAbstractPaintableWidget {
-
- public static final String TAG_SOURCE = "src";
-
- public static final String ATTR_PAUSE = "pause";
- public static final String ATTR_PLAY = "play";
- public static final String ATTR_MUTED = "muted";
- public static final String ATTR_CONTROLS = "ctrl";
- public static final String ATTR_AUTOPLAY = "auto";
- public static final String ATTR_RESOURCE = "res";
- public static final String ATTR_RESOURCE_TYPE = "type";
- public static final String ATTR_HTML = "html";
- public static final String ATTR_ALT_TEXT = "alt";
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().setControls(shouldShowControls(uidl));
- getWidgetForPaintable().setAutoplay(shouldAutoplay(uidl));
- getWidgetForPaintable().setMuted(isMediaMuted(uidl));
-
- // Add all sources
- for (int ix = 0; ix < uidl.getChildCount(); ix++) {
- UIDL child = uidl.getChildUIDL(ix);
- if (TAG_SOURCE.equals(child.getTag())) {
- getWidgetForPaintable().addSource(getSourceUrl(child),
- getSourceType(child));
- }
- }
- setAltText(uidl);
-
- evalPauseCommand(uidl);
- evalPlayCommand(uidl);
- }
-
- protected boolean shouldShowControls(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_CONTROLS);
- }
-
- private boolean shouldAutoplay(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_AUTOPLAY);
- }
-
- private boolean isMediaMuted(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_MUTED);
- }
-
- private boolean allowHtmlContent(UIDL uidl) {
- return uidl.getBooleanAttribute(ATTR_HTML);
- }
-
- private void evalPlayCommand(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_PLAY)) {
- getWidgetForPaintable().play();
- }
- }
-
- private void evalPauseCommand(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_PAUSE)) {
- getWidgetForPaintable().pause();
- }
- }
-
- @Override
- public VMediaBase getWidgetForPaintable() {
- return (VMediaBase) super.getWidgetForPaintable();
- }
-
- /**
- * @param uidl
- * @return the URL of a resource to be used as a source for the media
- */
- private String getSourceUrl(UIDL uidl) {
- String url = getConnection().translateVaadinUri(
- uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE));
- if (url == null) {
- return "";
- }
- return url;
- }
-
- /**
- * @param uidl
- * @return the mime type of the media
- */
- private String getSourceType(UIDL uidl) {
- return uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE_TYPE);
- }
-
- private void setAltText(UIDL uidl) {
- String alt = uidl.getStringAttribute(VMediaBasePaintable.ATTR_ALT_TEXT);
-
- if (alt == null || "".equals(alt)) {
- alt = getWidgetForPaintable().getDefaultAltHtml();
- } else if (!allowHtmlContent(uidl)) {
- alt = Util.escapeHTML(alt);
- }
- getWidgetForPaintable().setAltText(alt);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public abstract class VMediaBasePaintable extends VAbstractPaintableWidget {
+
+ public static final String TAG_SOURCE = "src";
+
+ public static final String ATTR_PAUSE = "pause";
+ public static final String ATTR_PLAY = "play";
+ public static final String ATTR_MUTED = "muted";
+ public static final String ATTR_CONTROLS = "ctrl";
+ public static final String ATTR_AUTOPLAY = "auto";
+ public static final String ATTR_RESOURCE = "res";
+ public static final String ATTR_RESOURCE_TYPE = "type";
+ public static final String ATTR_HTML = "html";
+ public static final String ATTR_ALT_TEXT = "alt";
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().setControls(shouldShowControls(uidl));
+ getWidgetForPaintable().setAutoplay(shouldAutoplay(uidl));
+ getWidgetForPaintable().setMuted(isMediaMuted(uidl));
+
+ // Add all sources
+ for (int ix = 0; ix < uidl.getChildCount(); ix++) {
+ UIDL child = uidl.getChildUIDL(ix);
+ if (TAG_SOURCE.equals(child.getTag())) {
+ getWidgetForPaintable().addSource(getSourceUrl(child),
+ getSourceType(child));
+ }
+ }
+ setAltText(uidl);
+
+ evalPauseCommand(uidl);
+ evalPlayCommand(uidl);
+ }
+
+ protected boolean shouldShowControls(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_CONTROLS);
+ }
+
+ private boolean shouldAutoplay(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_AUTOPLAY);
+ }
+
+ private boolean isMediaMuted(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_MUTED);
+ }
+
+ private boolean allowHtmlContent(UIDL uidl) {
+ return uidl.getBooleanAttribute(ATTR_HTML);
+ }
+
+ private void evalPlayCommand(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_PLAY)) {
+ getWidgetForPaintable().play();
+ }
+ }
+
+ private void evalPauseCommand(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_PAUSE)) {
+ getWidgetForPaintable().pause();
+ }
+ }
+
+ @Override
+ public VMediaBase getWidgetForPaintable() {
+ return (VMediaBase) super.getWidgetForPaintable();
+ }
+
+ /**
+ * @param uidl
+ * @return the URL of a resource to be used as a source for the media
+ */
+ private String getSourceUrl(UIDL uidl) {
+ String url = getConnection().translateVaadinUri(
+ uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE));
+ if (url == null) {
+ return "";
+ }
+ return url;
+ }
+
+ /**
+ * @param uidl
+ * @return the mime type of the media
+ */
+ private String getSourceType(UIDL uidl) {
+ return uidl.getStringAttribute(VMediaBasePaintable.ATTR_RESOURCE_TYPE);
+ }
+
+ private void setAltText(UIDL uidl) {
+ String alt = uidl.getStringAttribute(VMediaBasePaintable.ATTR_ALT_TEXT);
+
+ if (alt == null || "".equals(alt)) {
+ alt = getWidgetForPaintable().getDefaultAltHtml();
+ } else if (!allowHtmlContent(uidl)) {
+ alt = Util.escapeHTML(alt);
+ }
+ getWidgetForPaintable().setAltText(alt);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
index fabc77bced..ef2a49b9d0 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
@@ -1,161 +1,161 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Iterator;
-import java.util.Stack;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
-
-public class VMenuBarPaintable extends VAbstractPaintableWidget {
- /**
- * This method must be implemented to update the client-side component from
- * UIDL data received from server.
- *
- * This method is called when the page is loaded for the first time, and
- * every time UI changes in the component are received from the server.
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // This call should be made first. Ensure correct implementation,
- // and let the containing layout manage caption, etc.
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().htmlContentAllowed = uidl
- .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
-
- getWidgetForPaintable().openRootOnHover = uidl
- .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
-
- getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
-
- // For future connections
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().uidlId = uidl.getId();
-
- // Empty the menu every time it receives new information
- if (!getWidgetForPaintable().getItems().isEmpty()) {
- getWidgetForPaintable().clearItems();
- }
-
- UIDL options = uidl.getChildUIDL(0);
-
- if (uidl.hasAttribute("width")) {
- UIDL moreItemUIDL = options.getChildUIDL(0);
- StringBuffer itemHTML = new StringBuffer();
-
- if (moreItemUIDL.hasAttribute("icon")) {
- itemHTML.append("<img src=\""
- + Util.escapeAttribute(client
- .translateVaadinUri(moreItemUIDL
- .getStringAttribute("icon")))
- + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
- }
-
- String moreItemText = moreItemUIDL.getStringAttribute("text");
- if ("".equals(moreItemText)) {
- moreItemText = "&#x25BA;";
- }
- itemHTML.append(moreItemText);
-
- getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
- getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
- getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);
-
- getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
- getWidgetForPaintable());
- getWidgetForPaintable().moreItem
- .setSubMenu(getWidgetForPaintable().collapsedRootItems);
- getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
- + "-more-menuitem");
- }
-
- UIDL uidlItems = uidl.getChildUIDL(1);
- Iterator<Object> itr = uidlItems.getChildIterator();
- Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
- Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
- VMenuBar currentMenu = getWidgetForPaintable();
-
- while (itr.hasNext()) {
- UIDL item = (UIDL) itr.next();
- CustomMenuItem currentItem = null;
-
- final int itemId = item.getIntAttribute("id");
-
- boolean itemHasCommand = item.hasAttribute("command");
- boolean itemIsCheckable = item
- .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
-
- String itemHTML = getWidgetForPaintable().buildItemHTML(item);
-
- Command cmd = null;
- if (!item.hasAttribute("separator")) {
- if (itemHasCommand || itemIsCheckable) {
- // Construct a command that fires onMenuClick(int) with the
- // item's id-number
- cmd = new Command() {
- public void execute() {
- getWidgetForPaintable().hostReference
- .onMenuClick(itemId);
- }
- };
- }
- }
-
- currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
- currentItem.updateFromUIDL(item, client);
-
- if (item.getChildCount() > 0) {
- menuStack.push(currentMenu);
- iteratorStack.push(itr);
- itr = item.getChildIterator();
- currentMenu = new VMenuBar(true, currentMenu);
- if (uidl.hasAttribute("style")) {
- for (String style : uidl.getStringAttribute("style").split(
- " ")) {
- currentMenu.addStyleDependentName(style);
- }
- }
- currentItem.setSubMenu(currentMenu);
- }
-
- while (!itr.hasNext() && !iteratorStack.empty()) {
- boolean hasCheckableItem = false;
- for (CustomMenuItem menuItem : currentMenu.getItems()) {
- hasCheckableItem = hasCheckableItem
- || menuItem.isCheckable();
- }
- if (hasCheckableItem) {
- currentMenu.addStyleDependentName("check-column");
- } else {
- currentMenu.removeStyleDependentName("check-column");
- }
-
- itr = iteratorStack.pop();
- currentMenu = menuStack.pop();
- }
- }// while
-
- getWidgetForPaintable().iLayout(false);
-
- }// updateFromUIDL
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VMenuBar.class);
- }
-
- @Override
- public VMenuBar getWidgetForPaintable() {
- return (VMenuBar) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
+
+public class VMenuBarPaintable extends VAbstractPaintableWidget {
+ /**
+ * This method must be implemented to update the client-side component from
+ * UIDL data received from server.
+ *
+ * This method is called when the page is loaded for the first time, and
+ * every time UI changes in the component are received from the server.
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and let the containing layout manage caption, etc.
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().htmlContentAllowed = uidl
+ .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
+
+ getWidgetForPaintable().openRootOnHover = uidl
+ .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
+
+ getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
+
+ // For future connections
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().uidlId = uidl.getId();
+
+ // Empty the menu every time it receives new information
+ if (!getWidgetForPaintable().getItems().isEmpty()) {
+ getWidgetForPaintable().clearItems();
+ }
+
+ UIDL options = uidl.getChildUIDL(0);
+
+ if (uidl.hasAttribute("width")) {
+ UIDL moreItemUIDL = options.getChildUIDL(0);
+ StringBuffer itemHTML = new StringBuffer();
+
+ if (moreItemUIDL.hasAttribute("icon")) {
+ itemHTML.append("<img src=\""
+ + Util.escapeAttribute(client
+ .translateVaadinUri(moreItemUIDL
+ .getStringAttribute("icon")))
+ + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
+ }
+
+ String moreItemText = moreItemUIDL.getStringAttribute("text");
+ if ("".equals(moreItemText)) {
+ moreItemText = "&#x25BA;";
+ }
+ itemHTML.append(moreItemText);
+
+ getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
+ getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
+ getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);
+
+ getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
+ getWidgetForPaintable());
+ getWidgetForPaintable().moreItem
+ .setSubMenu(getWidgetForPaintable().collapsedRootItems);
+ getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
+ + "-more-menuitem");
+ }
+
+ UIDL uidlItems = uidl.getChildUIDL(1);
+ Iterator<Object> itr = uidlItems.getChildIterator();
+ Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
+ Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
+ VMenuBar currentMenu = getWidgetForPaintable();
+
+ while (itr.hasNext()) {
+ UIDL item = (UIDL) itr.next();
+ CustomMenuItem currentItem = null;
+
+ final int itemId = item.getIntAttribute("id");
+
+ boolean itemHasCommand = item.hasAttribute("command");
+ boolean itemIsCheckable = item
+ .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
+
+ String itemHTML = getWidgetForPaintable().buildItemHTML(item);
+
+ Command cmd = null;
+ if (!item.hasAttribute("separator")) {
+ if (itemHasCommand || itemIsCheckable) {
+ // Construct a command that fires onMenuClick(int) with the
+ // item's id-number
+ cmd = new Command() {
+ public void execute() {
+ getWidgetForPaintable().hostReference
+ .onMenuClick(itemId);
+ }
+ };
+ }
+ }
+
+ currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
+ currentItem.updateFromUIDL(item, client);
+
+ if (item.getChildCount() > 0) {
+ menuStack.push(currentMenu);
+ iteratorStack.push(itr);
+ itr = item.getChildIterator();
+ currentMenu = new VMenuBar(true, currentMenu);
+ if (uidl.hasAttribute("style")) {
+ for (String style : uidl.getStringAttribute("style").split(
+ " ")) {
+ currentMenu.addStyleDependentName(style);
+ }
+ }
+ currentItem.setSubMenu(currentMenu);
+ }
+
+ while (!itr.hasNext() && !iteratorStack.empty()) {
+ boolean hasCheckableItem = false;
+ for (CustomMenuItem menuItem : currentMenu.getItems()) {
+ hasCheckableItem = hasCheckableItem
+ || menuItem.isCheckable();
+ }
+ if (hasCheckableItem) {
+ currentMenu.addStyleDependentName("check-column");
+ } else {
+ currentMenu.removeStyleDependentName("check-column");
+ }
+
+ itr = iteratorStack.pop();
+ currentMenu = menuStack.pop();
+ }
+ }// while
+
+ getWidgetForPaintable().iLayout(false);
+
+ }// updateFromUIDL
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VMenuBar.class);
+ }
+
+ @Override
+ public VMenuBar getWidgetForPaintable() {
+ return (VMenuBar) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java
index 9991769e46..94e5cdf40c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java
@@ -15,7 +15,6 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
-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;
@@ -145,8 +144,4 @@ public class VNativeButton extends Button implements ClickHandler,
setStyleName(ApplicationConnection.DISABLED_CLASSNAME, !enabled);
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java
index 5e0dceea75..ebf9cad264 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java
@@ -1,3 +1,6 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
package com.vaadin.terminal.gwt.client.ui;
import com.google.gwt.core.client.GWT;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
index 038b598555..ec2f6e42a1 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java
@@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.UIDL;
public class VNativeSelect extends VOptionGroupBase implements Field {
@@ -74,10 +73,10 @@ public class VNativeSelect extends VOptionGroupBase implements Field {
public void onChange(ChangeEvent event) {
if (select.isMultipleSelect()) {
- client.updateVariable(id, "selected", getSelectedItems(),
+ client.updateVariable(paintableId, "selected", getSelectedItems(),
isImmediate());
} else {
- client.updateVariable(id, "selected", new String[] { ""
+ client.updateVariable(paintableId, "selected", new String[] { ""
+ getSelectedItem() }, isImmediate());
}
if (firstValueIsTemporaryNullItem) {
@@ -107,8 +106,4 @@ public class VNativeSelect extends VOptionGroupBase implements Field {
public void focus() {
select.setFocus(true);
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelectPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelectPaintable.java
new file mode 100644
index 0000000000..37defb605f
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelectPaintable.java
@@ -0,0 +1,21 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+
+public class VNativeSelectPaintable extends VOptionGroupBasePaintable {
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VNativeSelect.class);
+ }
+
+ @Override
+ public VNativeSelect getWidgetForPaintable() {
+ return (VNativeSelect) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
index 128e3bd597..27407c55aa 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java
@@ -1,417 +1,417 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class VNotification extends VOverlay {
-
- public static final int CENTERED = 1;
- public static final int CENTERED_TOP = 2;
- public static final int CENTERED_BOTTOM = 3;
- public static final int TOP_LEFT = 4;
- public static final int TOP_RIGHT = 5;
- public static final int BOTTOM_LEFT = 6;
- public static final int BOTTOM_RIGHT = 7;
-
- public static final int DELAY_FOREVER = -1;
- public static final int DELAY_NONE = 0;
-
- private static final String STYLENAME = "v-Notification";
- private static final int mouseMoveThreshold = 7;
- private static final int Z_INDEX_BASE = 20000;
- public static final String STYLE_SYSTEM = "system";
- private static final int FADE_ANIMATION_INTERVAL = 50; // == 20 fps
-
- private int startOpacity = 90;
- private int fadeMsec = 400;
- private int delayMsec = 1000;
-
- private Timer fader;
- private Timer delay;
-
- private int x = -1;
- private int y = -1;
-
- private String temporaryStyle;
-
- private ArrayList<EventListener> listeners;
- private static final int TOUCH_DEVICE_IDLE_DELAY = 1000;
-
- /**
- * Default constructor. You should use GWT.create instead.
- */
- public VNotification() {
- setStyleName(STYLENAME);
- sinkEvents(Event.ONCLICK);
- DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE);
- }
-
- /**
- * @deprecated Use static {@link #createNotification(int)} instead to enable
- * GWT deferred binding.
- *
- * @param delayMsec
- */
- @Deprecated
- public VNotification(int delayMsec) {
- this();
- this.delayMsec = delayMsec;
- if (BrowserInfo.get().isTouchDevice()) {
- new Timer() {
- @Override
- public void run() {
- if (isAttached()) {
- fade();
- }
- }
- }.schedule(delayMsec + TOUCH_DEVICE_IDLE_DELAY);
- }
- }
-
- /**
- * @deprecated Use static {@link #createNotification(int, int, int)} instead
- * to enable GWT deferred binding.
- *
- * @param delayMsec
- * @param fadeMsec
- * @param startOpacity
- */
- @Deprecated
- public VNotification(int delayMsec, int fadeMsec, int startOpacity) {
- this(delayMsec);
- this.fadeMsec = fadeMsec;
- this.startOpacity = startOpacity;
- }
-
- public void startDelay() {
- DOM.removeEventPreview(this);
- if (delayMsec > 0) {
- if (delay == null) {
- delay = new Timer() {
- @Override
- public void run() {
- fade();
- }
- };
- delay.schedule(delayMsec);
- }
- } else if (delayMsec == 0) {
- fade();
- }
- }
-
- @Override
- public void show() {
- show(CENTERED);
- }
-
- public void show(String style) {
- show(CENTERED, style);
- }
-
- public void show(int position) {
- show(position, null);
- }
-
- public void show(Widget widget, int position, String style) {
- setWidget(widget);
- show(position, style);
- }
-
- public void show(String html, int position, String style) {
- setWidget(new HTML(html));
- show(position, style);
- }
-
- public void show(int position, String style) {
- setOpacity(getElement(), startOpacity);
- if (style != null) {
- temporaryStyle = style;
- addStyleName(style);
- addStyleDependentName(style);
- }
- super.show();
- setPosition(position);
- }
-
- @Override
- public void hide() {
- DOM.removeEventPreview(this);
- cancelDelay();
- cancelFade();
- if (temporaryStyle != null) {
- removeStyleName(temporaryStyle);
- removeStyleDependentName(temporaryStyle);
- temporaryStyle = null;
- }
- super.hide();
- fireEvent(new HideEvent(this));
- }
-
- public void fade() {
- DOM.removeEventPreview(this);
- cancelDelay();
- if (fader == null) {
- fader = new Timer() {
- private final long start = new Date().getTime();
-
- @Override
- public void run() {
- /*
- * To make animation smooth, don't count that event happens
- * on time. Reduce opacity according to the actual time
- * spent instead of fixed decrement.
- */
- long now = new Date().getTime();
- long timeEplaced = now - start;
- float remainingFraction = 1 - timeEplaced
- / (float) fadeMsec;
- int opacity = (int) (startOpacity * remainingFraction);
- if (opacity <= 0) {
- cancel();
- hide();
- if (BrowserInfo.get().isOpera()) {
- // tray notification on opera needs to explicitly
- // define
- // size, reset it
- DOM.setStyleAttribute(getElement(), "width", "");
- DOM.setStyleAttribute(getElement(), "height", "");
- }
- } else {
- setOpacity(getElement(), opacity);
- }
- }
- };
- fader.scheduleRepeating(FADE_ANIMATION_INTERVAL);
- }
- }
-
- public void setPosition(int position) {
- final Element el = getElement();
- DOM.setStyleAttribute(el, "top", "");
- DOM.setStyleAttribute(el, "left", "");
- DOM.setStyleAttribute(el, "bottom", "");
- DOM.setStyleAttribute(el, "right", "");
- switch (position) {
- case TOP_LEFT:
- DOM.setStyleAttribute(el, "top", "0px");
- DOM.setStyleAttribute(el, "left", "0px");
- break;
- case TOP_RIGHT:
- DOM.setStyleAttribute(el, "top", "0px");
- DOM.setStyleAttribute(el, "right", "0px");
- break;
- case BOTTOM_RIGHT:
- DOM.setStyleAttribute(el, "position", "absolute");
- if (BrowserInfo.get().isOpera()) {
- // tray notification on opera needs explicitly defined size
- DOM.setStyleAttribute(el, "width", getOffsetWidth() + "px");
- DOM.setStyleAttribute(el, "height", getOffsetHeight() + "px");
- }
- DOM.setStyleAttribute(el, "bottom", "0px");
- DOM.setStyleAttribute(el, "right", "0px");
- break;
- case BOTTOM_LEFT:
- DOM.setStyleAttribute(el, "bottom", "0px");
- DOM.setStyleAttribute(el, "left", "0px");
- break;
- case CENTERED_TOP:
- center();
- DOM.setStyleAttribute(el, "top", "0px");
- break;
- case CENTERED_BOTTOM:
- center();
- DOM.setStyleAttribute(el, "top", "");
- DOM.setStyleAttribute(el, "bottom", "0px");
- break;
- default:
- case CENTERED:
- center();
- break;
- }
- }
-
- private void cancelFade() {
- if (fader != null) {
- fader.cancel();
- fader = null;
- }
- }
-
- private void cancelDelay() {
- if (delay != null) {
- delay.cancel();
- delay = null;
- }
- }
-
- private void setOpacity(Element el, int opacity) {
- DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0));
- if (BrowserInfo.get().isIE()) {
- DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity
- + ")");
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- DOM.removeEventPreview(this);
- if (fader == null) {
- fade();
- }
- }
-
- @Override
- public boolean onEventPreview(Event event) {
- int type = DOM.eventGetType(event);
- // "modal"
- if (delayMsec == -1 || temporaryStyle == STYLE_SYSTEM) {
- if (type == Event.ONCLICK) {
- if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) {
- fade();
- return false;
- }
- } else if (type == Event.ONKEYDOWN
- && event.getKeyCode() == KeyCodes.KEY_ESCAPE) {
- fade();
- return false;
- }
- if (temporaryStyle == STYLE_SYSTEM) {
- return true;
- } else {
- return false;
- }
- }
- // default
- switch (type) {
- case Event.ONMOUSEMOVE:
-
- if (x < 0) {
- x = DOM.eventGetClientX(event);
- y = DOM.eventGetClientY(event);
- } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold
- || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) {
- startDelay();
- }
- break;
- case Event.ONMOUSEDOWN:
- case Event.ONMOUSEWHEEL:
- case Event.ONSCROLL:
- startDelay();
- break;
- case Event.ONKEYDOWN:
- if (event.getRepeat()) {
- return true;
- }
- startDelay();
- break;
- default:
- break;
- }
- return true;
- }
-
- public void addEventListener(EventListener listener) {
- if (listeners == null) {
- listeners = new ArrayList<EventListener>();
- }
- listeners.add(listener);
- }
-
- public void removeEventListener(EventListener listener) {
- if (listeners == null) {
- return;
- }
- listeners.remove(listener);
- }
-
- private void fireEvent(HideEvent event) {
- if (listeners != null) {
- for (Iterator<EventListener> it = listeners.iterator(); it
- .hasNext();) {
- EventListener l = it.next();
- l.notificationHidden(event);
- }
- }
- }
-
- public static void showNotification(ApplicationConnection client,
- final UIDL notification) {
- boolean onlyPlainText = notification
- .hasAttribute(VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED);
- String html = "";
- if (notification.hasAttribute("icon")) {
- final String parsedUri = client.translateVaadinUri(notification
- .getStringAttribute("icon"));
- html += "<img src=\"" + Util.escapeAttribute(parsedUri) + "\" />";
- }
- if (notification.hasAttribute("caption")) {
- String caption = notification.getStringAttribute("caption");
- if (onlyPlainText) {
- caption = Util.escapeHTML(caption);
- caption = caption.replaceAll("\\n", "<br />");
- }
- html += "<h1>" + caption + "</h1>";
- }
- if (notification.hasAttribute("message")) {
- String message = notification.getStringAttribute("message");
- if (onlyPlainText) {
- message = Util.escapeHTML(message);
- message = message.replaceAll("\\n", "<br />");
- }
- html += "<p>" + message + "</p>";
- }
-
- final String style = notification.hasAttribute("style") ? notification
- .getStringAttribute("style") : null;
- final int position = notification.getIntAttribute("position");
- final int delay = notification.getIntAttribute("delay");
- createNotification(delay).show(html, position, style);
- }
-
- public static VNotification createNotification(int delayMsec) {
- final VNotification notification = GWT.create(VNotification.class);
- notification.delayMsec = delayMsec;
- if (BrowserInfo.get().isTouchDevice()) {
- new Timer() {
- @Override
- public void run() {
- if (notification.isAttached()) {
- notification.fade();
- }
- }
- }.schedule(notification.delayMsec + TOUCH_DEVICE_IDLE_DELAY);
- }
- return notification;
- }
-
- public class HideEvent extends EventObject {
-
- public HideEvent(Object source) {
- super(source);
- }
- }
-
- public interface EventListener extends java.util.EventListener {
- public void notificationHidden(HideEvent event);
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public class VNotification extends VOverlay {
+
+ public static final int CENTERED = 1;
+ public static final int CENTERED_TOP = 2;
+ public static final int CENTERED_BOTTOM = 3;
+ public static final int TOP_LEFT = 4;
+ public static final int TOP_RIGHT = 5;
+ public static final int BOTTOM_LEFT = 6;
+ public static final int BOTTOM_RIGHT = 7;
+
+ public static final int DELAY_FOREVER = -1;
+ public static final int DELAY_NONE = 0;
+
+ private static final String STYLENAME = "v-Notification";
+ private static final int mouseMoveThreshold = 7;
+ private static final int Z_INDEX_BASE = 20000;
+ public static final String STYLE_SYSTEM = "system";
+ private static final int FADE_ANIMATION_INTERVAL = 50; // == 20 fps
+
+ private int startOpacity = 90;
+ private int fadeMsec = 400;
+ private int delayMsec = 1000;
+
+ private Timer fader;
+ private Timer delay;
+
+ private int x = -1;
+ private int y = -1;
+
+ private String temporaryStyle;
+
+ private ArrayList<EventListener> listeners;
+ private static final int TOUCH_DEVICE_IDLE_DELAY = 1000;
+
+ /**
+ * Default constructor. You should use GWT.create instead.
+ */
+ public VNotification() {
+ setStyleName(STYLENAME);
+ sinkEvents(Event.ONCLICK);
+ DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE);
+ }
+
+ /**
+ * @deprecated Use static {@link #createNotification(int)} instead to enable
+ * GWT deferred binding.
+ *
+ * @param delayMsec
+ */
+ @Deprecated
+ public VNotification(int delayMsec) {
+ this();
+ this.delayMsec = delayMsec;
+ if (BrowserInfo.get().isTouchDevice()) {
+ new Timer() {
+ @Override
+ public void run() {
+ if (isAttached()) {
+ fade();
+ }
+ }
+ }.schedule(delayMsec + TOUCH_DEVICE_IDLE_DELAY);
+ }
+ }
+
+ /**
+ * @deprecated Use static {@link #createNotification(int, int, int)} instead
+ * to enable GWT deferred binding.
+ *
+ * @param delayMsec
+ * @param fadeMsec
+ * @param startOpacity
+ */
+ @Deprecated
+ public VNotification(int delayMsec, int fadeMsec, int startOpacity) {
+ this(delayMsec);
+ this.fadeMsec = fadeMsec;
+ this.startOpacity = startOpacity;
+ }
+
+ public void startDelay() {
+ DOM.removeEventPreview(this);
+ if (delayMsec > 0) {
+ if (delay == null) {
+ delay = new Timer() {
+ @Override
+ public void run() {
+ fade();
+ }
+ };
+ delay.schedule(delayMsec);
+ }
+ } else if (delayMsec == 0) {
+ fade();
+ }
+ }
+
+ @Override
+ public void show() {
+ show(CENTERED);
+ }
+
+ public void show(String style) {
+ show(CENTERED, style);
+ }
+
+ public void show(int position) {
+ show(position, null);
+ }
+
+ public void show(Widget widget, int position, String style) {
+ setWidget(widget);
+ show(position, style);
+ }
+
+ public void show(String html, int position, String style) {
+ setWidget(new HTML(html));
+ show(position, style);
+ }
+
+ public void show(int position, String style) {
+ setOpacity(getElement(), startOpacity);
+ if (style != null) {
+ temporaryStyle = style;
+ addStyleName(style);
+ addStyleDependentName(style);
+ }
+ super.show();
+ setPosition(position);
+ }
+
+ @Override
+ public void hide() {
+ DOM.removeEventPreview(this);
+ cancelDelay();
+ cancelFade();
+ if (temporaryStyle != null) {
+ removeStyleName(temporaryStyle);
+ removeStyleDependentName(temporaryStyle);
+ temporaryStyle = null;
+ }
+ super.hide();
+ fireEvent(new HideEvent(this));
+ }
+
+ public void fade() {
+ DOM.removeEventPreview(this);
+ cancelDelay();
+ if (fader == null) {
+ fader = new Timer() {
+ private final long start = new Date().getTime();
+
+ @Override
+ public void run() {
+ /*
+ * To make animation smooth, don't count that event happens
+ * on time. Reduce opacity according to the actual time
+ * spent instead of fixed decrement.
+ */
+ long now = new Date().getTime();
+ long timeEplaced = now - start;
+ float remainingFraction = 1 - timeEplaced
+ / (float) fadeMsec;
+ int opacity = (int) (startOpacity * remainingFraction);
+ if (opacity <= 0) {
+ cancel();
+ hide();
+ if (BrowserInfo.get().isOpera()) {
+ // tray notification on opera needs to explicitly
+ // define
+ // size, reset it
+ DOM.setStyleAttribute(getElement(), "width", "");
+ DOM.setStyleAttribute(getElement(), "height", "");
+ }
+ } else {
+ setOpacity(getElement(), opacity);
+ }
+ }
+ };
+ fader.scheduleRepeating(FADE_ANIMATION_INTERVAL);
+ }
+ }
+
+ public void setPosition(int position) {
+ final Element el = getElement();
+ DOM.setStyleAttribute(el, "top", "");
+ DOM.setStyleAttribute(el, "left", "");
+ DOM.setStyleAttribute(el, "bottom", "");
+ DOM.setStyleAttribute(el, "right", "");
+ switch (position) {
+ case TOP_LEFT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case TOP_RIGHT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_RIGHT:
+ DOM.setStyleAttribute(el, "position", "absolute");
+ if (BrowserInfo.get().isOpera()) {
+ // tray notification on opera needs explicitly defined size
+ DOM.setStyleAttribute(el, "width", getOffsetWidth() + "px");
+ DOM.setStyleAttribute(el, "height", getOffsetHeight() + "px");
+ }
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_LEFT:
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case CENTERED_TOP:
+ center();
+ DOM.setStyleAttribute(el, "top", "0px");
+ break;
+ case CENTERED_BOTTOM:
+ center();
+ DOM.setStyleAttribute(el, "top", "");
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ break;
+ default:
+ case CENTERED:
+ center();
+ break;
+ }
+ }
+
+ private void cancelFade() {
+ if (fader != null) {
+ fader.cancel();
+ fader = null;
+ }
+ }
+
+ private void cancelDelay() {
+ if (delay != null) {
+ delay.cancel();
+ delay = null;
+ }
+ }
+
+ private void setOpacity(Element el, int opacity) {
+ DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0));
+ if (BrowserInfo.get().isIE()) {
+ DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity
+ + ")");
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ DOM.removeEventPreview(this);
+ if (fader == null) {
+ fade();
+ }
+ }
+
+ @Override
+ public boolean onEventPreview(Event event) {
+ int type = DOM.eventGetType(event);
+ // "modal"
+ if (delayMsec == -1 || temporaryStyle == STYLE_SYSTEM) {
+ if (type == Event.ONCLICK) {
+ if (DOM.isOrHasChild(getElement(), DOM.eventGetTarget(event))) {
+ fade();
+ return false;
+ }
+ } else if (type == Event.ONKEYDOWN
+ && event.getKeyCode() == KeyCodes.KEY_ESCAPE) {
+ fade();
+ return false;
+ }
+ if (temporaryStyle == STYLE_SYSTEM) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ // default
+ switch (type) {
+ case Event.ONMOUSEMOVE:
+
+ if (x < 0) {
+ x = DOM.eventGetClientX(event);
+ y = DOM.eventGetClientY(event);
+ } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold
+ || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) {
+ startDelay();
+ }
+ break;
+ case Event.ONMOUSEDOWN:
+ case Event.ONMOUSEWHEEL:
+ case Event.ONSCROLL:
+ startDelay();
+ break;
+ case Event.ONKEYDOWN:
+ if (event.getRepeat()) {
+ return true;
+ }
+ startDelay();
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ public void addEventListener(EventListener listener) {
+ if (listeners == null) {
+ listeners = new ArrayList<EventListener>();
+ }
+ listeners.add(listener);
+ }
+
+ public void removeEventListener(EventListener listener) {
+ if (listeners == null) {
+ return;
+ }
+ listeners.remove(listener);
+ }
+
+ private void fireEvent(HideEvent event) {
+ if (listeners != null) {
+ for (Iterator<EventListener> it = listeners.iterator(); it
+ .hasNext();) {
+ EventListener l = it.next();
+ l.notificationHidden(event);
+ }
+ }
+ }
+
+ public static void showNotification(ApplicationConnection client,
+ final UIDL notification) {
+ boolean onlyPlainText = notification
+ .hasAttribute(VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED);
+ String html = "";
+ if (notification.hasAttribute("icon")) {
+ final String parsedUri = client.translateVaadinUri(notification
+ .getStringAttribute("icon"));
+ html += "<img src=\"" + Util.escapeAttribute(parsedUri) + "\" />";
+ }
+ if (notification.hasAttribute("caption")) {
+ String caption = notification.getStringAttribute("caption");
+ if (onlyPlainText) {
+ caption = Util.escapeHTML(caption);
+ caption = caption.replaceAll("\\n", "<br />");
+ }
+ html += "<h1>" + caption + "</h1>";
+ }
+ if (notification.hasAttribute("message")) {
+ String message = notification.getStringAttribute("message");
+ if (onlyPlainText) {
+ message = Util.escapeHTML(message);
+ message = message.replaceAll("\\n", "<br />");
+ }
+ html += "<p>" + message + "</p>";
+ }
+
+ final String style = notification.hasAttribute("style") ? notification
+ .getStringAttribute("style") : null;
+ final int position = notification.getIntAttribute("position");
+ final int delay = notification.getIntAttribute("delay");
+ createNotification(delay).show(html, position, style);
+ }
+
+ public static VNotification createNotification(int delayMsec) {
+ final VNotification notification = GWT.create(VNotification.class);
+ notification.delayMsec = delayMsec;
+ if (BrowserInfo.get().isTouchDevice()) {
+ new Timer() {
+ @Override
+ public void run() {
+ if (notification.isAttached()) {
+ notification.fade();
+ }
+ }
+ }.schedule(notification.delayMsec + TOUCH_DEVICE_IDLE_DELAY);
+ }
+ return notification;
+ }
+
+ public class HideEvent extends EventObject {
+
+ public HideEvent(Object source) {
+ super(source);
+ }
+ }
+
+ public interface EventListener extends java.util.EventListener {
+ public void notificationHidden(HideEvent event);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
index 0175134355..bf89a01a03 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java
@@ -4,7 +4,6 @@
package com.vaadin.terminal.gwt.client.ui;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -38,14 +37,14 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
public static final String CLASSNAME = "v-select-optiongroup";
- private final Panel panel;
+ protected final Panel panel;
private final Map<CheckBox, String> optionsToKeys;
- private boolean sendFocusEvents = false;
- private boolean sendBlurEvents = false;
- private List<HandlerRegistration> focusHandlers = null;
- private List<HandlerRegistration> blurHandlers = null;
+ protected boolean sendFocusEvents = false;
+ protected boolean sendBlurEvents = false;
+ protected List<HandlerRegistration> focusHandlers = null;
+ protected List<HandlerRegistration> blurHandlers = null;
private final LoadHandler iconLoadHandler = new LoadHandler() {
public void onLoad(LoadEvent event) {
@@ -62,7 +61,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
*/
private boolean blurOccured = false;
- private boolean htmlContentAllowed = false;
+ protected boolean htmlContentAllowed = false;
public VOptionGroup() {
super(CLASSNAME);
@@ -70,43 +69,6 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
optionsToKeys = new HashMap<CheckBox, String>();
}
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- htmlContentAllowed = uidl.hasAttribute(HTML_CONTENT_ALLOWED);
-
- super.updateFromUIDL(uidl, client);
-
- sendFocusEvents = client.hasEventListeners(this, EventId.FOCUS);
- sendBlurEvents = client.hasEventListeners(this, EventId.BLUR);
-
- if (focusHandlers != null) {
- for (HandlerRegistration reg : focusHandlers) {
- reg.removeHandler();
- }
- focusHandlers.clear();
- focusHandlers = null;
-
- for (HandlerRegistration reg : blurHandlers) {
- reg.removeHandler();
- }
- blurHandlers.clear();
- blurHandlers = null;
- }
-
- if (sendFocusEvents || sendBlurEvents) {
- focusHandlers = new ArrayList<HandlerRegistration>();
- blurHandlers = new ArrayList<HandlerRegistration>();
-
- // add focus and blur handlers to checkboxes / radio buttons
- for (Widget wid : panel) {
- if (wid instanceof CheckBox) {
- focusHandlers.add(((CheckBox) wid).addFocusHandler(this));
- blurHandlers.add(((CheckBox) wid).addBlurHandler(this));
- }
- }
- }
- }
-
/*
* Return true if no elements were changed, false otherwise.
*/
@@ -133,7 +95,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
op = new VCheckBox();
op.setHTML(itemHtml);
} else {
- op = new RadioButton(id, itemHtml, true);
+ op = new RadioButton(paintableId, itemHtml, true);
op.setStyleName("v-radiobutton");
}
@@ -174,7 +136,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
} else {
selectedKeys.remove(key);
}
- client.updateVariable(id, "selected", getSelectedItems(),
+ client.updateVariable(paintableId, "selected", getSelectedItems(),
isImmediate());
}
}
@@ -200,7 +162,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
// panel was blurred => fire the event to the server side if
// requested by server side
if (sendFocusEvents) {
- client.updateVariable(id, EventId.FOCUS, "", true);
+ client.updateVariable(paintableId, EventId.FOCUS, "", true);
}
} else {
// blur occured before this focus event
@@ -219,16 +181,12 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
// check whether blurOccured still is true and then send the
// event out to the server
if (blurOccured) {
- client.updateVariable(id, EventId.BLUR, "", true);
+ client.updateVariable(paintableId, EventId.BLUR, "",
+ true);
blurOccured = false;
}
}
});
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
index c4d92783c8..bcd5cc891f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java
@@ -19,35 +19,34 @@ import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
-abstract class VOptionGroupBase extends Composite implements VPaintableWidget,
- Field, ClickHandler, ChangeHandler, KeyPressHandler, Focusable {
+abstract class VOptionGroupBase extends Composite implements Field,
+ ClickHandler, ChangeHandler, KeyPressHandler, Focusable {
public static final String CLASSNAME_OPTION = "v-select-option";
protected ApplicationConnection client;
- protected String id;
+ protected String paintableId;
protected Set<String> selectedKeys;
- private boolean immediate;
+ protected boolean immediate;
- private boolean multiselect;
+ protected boolean multiselect;
- private boolean disabled;
+ protected boolean disabled;
- private boolean readonly;
+ protected boolean readonly;
- private int cols = 0;
+ protected int cols = 0;
- private int rows = 0;
+ protected int rows = 0;
- private boolean nullSelectionAllowed = true;
+ protected boolean nullSelectionAllowed = true;
- private boolean nullSelectionItemAvailable = false;
+ protected boolean nullSelectionItemAvailable = false;
/**
* Widget holding the different options (e.g. ListBox or Panel for radio
@@ -58,11 +57,11 @@ abstract class VOptionGroupBase extends Composite implements VPaintableWidget,
/**
* Panel containing the component
*/
- private final Panel container;
+ protected final Panel container;
- private VTextField newItemField;
+ protected VTextField newItemField;
- private VNativeButton newItemButton;
+ protected VNativeButton newItemButton;
public VOptionGroupBase(String classname) {
container = new FlowPanel();
@@ -122,84 +121,23 @@ abstract class VOptionGroupBase extends Composite implements VPaintableWidget,
return rows;
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- id = uidl.getId();
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- selectedKeys = uidl.getStringArrayVariableAsSet("selected");
-
- readonly = uidl.getBooleanAttribute("readonly");
- disabled = uidl.getBooleanAttribute("disabled");
- multiselect = "multi".equals(uidl.getStringAttribute("selectmode"));
- immediate = uidl.getBooleanAttribute("immediate");
- nullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
- nullSelectionItemAvailable = uidl.getBooleanAttribute("nullselectitem");
-
- if (uidl.hasAttribute("cols")) {
- cols = uidl.getIntAttribute("cols");
- }
- if (uidl.hasAttribute("rows")) {
- rows = uidl.getIntAttribute("rows");
- }
-
- final UIDL ops = uidl.getChildUIDL(0);
-
- if (getColumns() > 0) {
- container.setWidth(getColumns() + "em");
- if (container != optionsContainer) {
- optionsContainer.setWidth("100%");
- }
- }
-
- buildOptions(ops);
-
- if (uidl.getBooleanAttribute("allownewitem")) {
- if (newItemField == null) {
- newItemButton = new VNativeButton();
- newItemButton.setText("+");
- newItemButton.addClickHandler(this);
- newItemField = new VTextField();
- newItemField.addKeyPressHandler(this);
- }
- newItemField.setEnabled(!disabled && !readonly);
- newItemButton.setEnabled(!disabled && !readonly);
-
- if (newItemField == null || newItemField.getParent() != container) {
- container.add(newItemField);
- container.add(newItemButton);
- final int w = container.getOffsetWidth()
- - newItemButton.getOffsetWidth();
- newItemField.setWidth(Math.max(w, 0) + "px");
- }
- } else if (newItemField != null) {
- container.remove(newItemField);
- container.remove(newItemButton);
- }
-
- setTabIndex(uidl.hasAttribute("tabindex") ? uidl
- .getIntAttribute("tabindex") : 0);
-
- }
-
abstract protected void setTabIndex(int tabIndex);
public void onClick(ClickEvent event) {
if (event.getSource() == newItemButton
&& !newItemField.getText().equals("")) {
- client.updateVariable(id, "newitem", newItemField.getText(), true);
+ client.updateVariable(paintableId, "newitem",
+ newItemField.getText(), true);
newItemField.setText("");
}
}
public void onChange(ChangeEvent event) {
if (multiselect) {
- client.updateVariable(id, "selected", getSelectedItems(), immediate);
+ client.updateVariable(paintableId, "selected", getSelectedItems(),
+ immediate);
} else {
- client.updateVariable(id, "selected", new String[] { ""
+ client.updateVariable(paintableId, "selected", new String[] { ""
+ getSelectedItem() }, immediate);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBasePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBasePaintable.java
new file mode 100644
index 0000000000..76486ff8a3
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBasePaintable.java
@@ -0,0 +1,103 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public abstract class VOptionGroupBasePaintable extends
+ VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getId();
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().selectedKeys = uidl
+ .getStringArrayVariableAsSet("selected");
+
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+ getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
+ getWidgetForPaintable().multiselect = "multi".equals(uidl
+ .getStringAttribute("selectmode"));
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ getWidgetForPaintable().nullSelectionAllowed = uidl
+ .getBooleanAttribute("nullselect");
+ getWidgetForPaintable().nullSelectionItemAvailable = uidl
+ .getBooleanAttribute("nullselectitem");
+
+ if (uidl.hasAttribute("cols")) {
+ getWidgetForPaintable().cols = uidl.getIntAttribute("cols");
+ }
+ if (uidl.hasAttribute("rows")) {
+ getWidgetForPaintable().rows = uidl.getIntAttribute("rows");
+ }
+
+ final UIDL ops = uidl.getChildUIDL(0);
+
+ if (getWidgetForPaintable().getColumns() > 0) {
+ getWidgetForPaintable().container.setWidth(getWidgetForPaintable()
+ .getColumns() + "em");
+ if (getWidgetForPaintable().container != getWidgetForPaintable().optionsContainer) {
+ getWidgetForPaintable().optionsContainer.setWidth("100%");
+ }
+ }
+
+ getWidgetForPaintable().buildOptions(ops);
+
+ if (uidl.getBooleanAttribute("allownewitem")) {
+ if (getWidgetForPaintable().newItemField == null) {
+ getWidgetForPaintable().newItemButton = new VNativeButton();
+ getWidgetForPaintable().newItemButton.setText("+");
+ getWidgetForPaintable().newItemButton
+ .addClickHandler(getWidgetForPaintable());
+ getWidgetForPaintable().newItemField = new VTextField();
+ getWidgetForPaintable().newItemField
+ .addKeyPressHandler(getWidgetForPaintable());
+ }
+ getWidgetForPaintable().newItemField
+ .setEnabled(!getWidgetForPaintable().disabled
+ && !getWidgetForPaintable().readonly);
+ getWidgetForPaintable().newItemButton
+ .setEnabled(!getWidgetForPaintable().disabled
+ && !getWidgetForPaintable().readonly);
+
+ if (getWidgetForPaintable().newItemField == null
+ || getWidgetForPaintable().newItemField.getParent() != getWidgetForPaintable().container) {
+ getWidgetForPaintable().container
+ .add(getWidgetForPaintable().newItemField);
+ getWidgetForPaintable().container
+ .add(getWidgetForPaintable().newItemButton);
+ final int w = getWidgetForPaintable().container
+ .getOffsetWidth()
+ - getWidgetForPaintable().newItemButton
+ .getOffsetWidth();
+ getWidgetForPaintable().newItemField.setWidth(Math.max(w, 0)
+ + "px");
+ }
+ } else if (getWidgetForPaintable().newItemField != null) {
+ getWidgetForPaintable().container
+ .remove(getWidgetForPaintable().newItemField);
+ getWidgetForPaintable().container
+ .remove(getWidgetForPaintable().newItemButton);
+ }
+
+ getWidgetForPaintable().setTabIndex(
+ uidl.hasAttribute("tabindex") ? uidl
+ .getIntAttribute("tabindex") : 0);
+
+ }
+
+ @Override
+ public VOptionGroupBase getWidgetForPaintable() {
+ return (VOptionGroupBase) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupPaintable.java
new file mode 100644
index 0000000000..f4ffc4f0da
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupPaintable.java
@@ -0,0 +1,71 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.CheckBox;
+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;
+
+public class VOptionGroupPaintable extends VOptionGroupBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().htmlContentAllowed = uidl
+ .hasAttribute(VOptionGroup.HTML_CONTENT_ALLOWED);
+
+ super.updateFromUIDL(uidl, client);
+
+ getWidgetForPaintable().sendFocusEvents = client.hasEventListeners(
+ this, EventId.FOCUS);
+ getWidgetForPaintable().sendBlurEvents = client.hasEventListeners(this,
+ EventId.BLUR);
+
+ if (getWidgetForPaintable().focusHandlers != null) {
+ for (HandlerRegistration reg : getWidgetForPaintable().focusHandlers) {
+ reg.removeHandler();
+ }
+ getWidgetForPaintable().focusHandlers.clear();
+ getWidgetForPaintable().focusHandlers = null;
+
+ for (HandlerRegistration reg : getWidgetForPaintable().blurHandlers) {
+ reg.removeHandler();
+ }
+ getWidgetForPaintable().blurHandlers.clear();
+ getWidgetForPaintable().blurHandlers = null;
+ }
+
+ if (getWidgetForPaintable().sendFocusEvents
+ || getWidgetForPaintable().sendBlurEvents) {
+ getWidgetForPaintable().focusHandlers = new ArrayList<HandlerRegistration>();
+ getWidgetForPaintable().blurHandlers = new ArrayList<HandlerRegistration>();
+
+ // add focus and blur handlers to checkboxes / radio buttons
+ for (Widget wid : getWidgetForPaintable().panel) {
+ if (wid instanceof CheckBox) {
+ getWidgetForPaintable().focusHandlers.add(((CheckBox) wid)
+ .addFocusHandler(getWidgetForPaintable()));
+ getWidgetForPaintable().blurHandlers.add(((CheckBox) wid)
+ .addBlurHandler(getWidgetForPaintable()));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VOptionGroup.class);
+ }
+
+ @Override
+ public VOptionGroup getWidgetForPaintable() {
+ return (VOptionGroup) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
index 9eec275b59..82b362a385 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java
@@ -8,11 +8,8 @@ import java.util.Set;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
-import com.google.gwt.event.dom.client.DomEvent.Type;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.dom.client.TouchStartHandler;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -33,28 +30,27 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan
public class VPanel extends SimplePanel implements Container,
ShortcutActionHandlerOwner, Focusable {
- public static final String CLICK_EVENT_IDENTIFIER = "click";
public static final String CLASSNAME = "v-panel";
ApplicationConnection client;
String id;
- private final Element captionNode = DOM.createDiv();
+ final Element captionNode = DOM.createDiv();
private final Element captionText = DOM.createSpan();
private Icon icon;
- private final Element bottomDecoration = DOM.createDiv();
+ final Element bottomDecoration = DOM.createDiv();
- private final Element contentNode = DOM.createDiv();
+ final Element contentNode = DOM.createDiv();
private Element errorIndicatorElement;
private String height;
- private VPaintableWidget layout;
+ VPaintableWidget layout;
ShortcutActionHandler shortcutHandler;
@@ -62,9 +58,9 @@ public class VPanel extends SimplePanel implements Container,
private Element geckoCaptionMeter;
- private int scrollTop;
+ int scrollTop;
- private int scrollLeft;
+ int scrollLeft;
private RenderInformation renderInformation = new RenderInformation();
@@ -76,21 +72,12 @@ public class VPanel extends SimplePanel implements Container,
private int captionMarginLeft = -1;
- private boolean rendering;
+ boolean rendering;
private int contentMarginLeft = -1;
private String previousStyleName;
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
private TouchScrollDelegate touchScrollDelegate;
public VPanel() {
@@ -157,129 +144,10 @@ public class VPanel extends SimplePanel implements Container,
return contentNode;
}
- private void setCaption(String text) {
+ void setCaption(String text) {
DOM.setInnerHTML(captionText, text);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- if (!uidl.hasAttribute("cached")) {
-
- // Handle caption displaying and style names, prior generics.
- // Affects size
- // calculations
-
- // Restore default stylenames
- contentNode.setClassName(CLASSNAME + "-content");
- bottomDecoration.setClassName(CLASSNAME + "-deco");
- captionNode.setClassName(CLASSNAME + "-caption");
- boolean hasCaption = false;
- if (uidl.hasAttribute("caption")
- && !uidl.getStringAttribute("caption").equals("")) {
- setCaption(uidl.getStringAttribute("caption"));
- hasCaption = true;
- } else {
- setCaption("");
- captionNode.setClassName(CLASSNAME + "-nocaption");
- }
-
- // Add proper stylenames for all elements. This way we can prevent
- // unwanted CSS selector inheritance.
- if (uidl.hasAttribute("style")) {
- final String[] styles = uidl.getStringAttribute("style").split(
- " ");
- final String captionBaseClass = CLASSNAME
- + (hasCaption ? "-caption" : "-nocaption");
- final String contentBaseClass = CLASSNAME + "-content";
- final String decoBaseClass = CLASSNAME + "-deco";
- String captionClass = captionBaseClass;
- String contentClass = contentBaseClass;
- String decoClass = decoBaseClass;
- for (int i = 0; i < styles.length; i++) {
- captionClass += " " + captionBaseClass + "-" + styles[i];
- contentClass += " " + contentBaseClass + "-" + styles[i];
- decoClass += " " + decoBaseClass + "-" + styles[i];
- }
- captionNode.setClassName(captionClass);
- contentNode.setClassName(contentClass);
- bottomDecoration.setClassName(decoClass);
-
- }
- }
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, false)) {
- rendering = false;
- return;
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- this.client = client;
- id = uidl.getId();
-
- setIconUri(uidl, client);
-
- handleError(uidl);
-
- // Render content
- final UIDL layoutUidl = uidl.getChildUIDL(0);
- final VPaintableWidget newLayout = client.getPaintable(layoutUidl);
- if (newLayout != layout) {
- if (layout != null) {
- client.unregisterPaintable(layout);
- }
- setWidget(newLayout.getWidgetForPaintable());
- layout = newLayout;
- }
- layout.updateFromUIDL(layoutUidl, client);
-
- // We may have actions attached to this panel
- if (uidl.getChildCount() > 1) {
- final int cnt = uidl.getChildCount();
- for (int i = 1; i < cnt; i++) {
- UIDL childUidl = uidl.getChildUIDL(i);
- if (childUidl.getTag().equals("actions")) {
- if (shortcutHandler == null) {
- shortcutHandler = new ShortcutActionHandler(id, client);
- }
- shortcutHandler.updateActionMap(childUidl);
- }
- }
- }
-
- if (uidl.hasVariable("scrollTop")
- && uidl.getIntVariable("scrollTop") != scrollTop) {
- scrollTop = uidl.getIntVariable("scrollTop");
- contentNode.setScrollTop(scrollTop);
- // re-read the actual scrollTop in case invalid value was set
- // (scrollTop != 0 when no scrollbar exists, other values would be
- // caught by scroll listener), see #3784
- scrollTop = contentNode.getScrollTop();
- }
-
- if (uidl.hasVariable("scrollLeft")
- && uidl.getIntVariable("scrollLeft") != scrollLeft) {
- scrollLeft = uidl.getIntVariable("scrollLeft");
- contentNode.setScrollLeft(scrollLeft);
- // re-read the actual scrollTop in case invalid value was set
- // (scrollTop != 0 when no scrollbar exists, other values would be
- // caught by scroll listener), see #3784
- scrollLeft = contentNode.getScrollLeft();
- }
-
- // Must be run after scrollTop is set as Webkit overflow fix re-sets the
- // scrollTop
- runHacks(false);
-
- // And apply tab index
- if (uidl.hasVariable("tabindex")) {
- contentNode.setTabIndex(uidl.getIntVariable("tabindex"));
- }
-
- rendering = false;
-
- }
-
@Override
public void setStyleName(String style) {
if (!style.equals(previousStyleName)) {
@@ -289,7 +157,7 @@ public class VPanel extends SimplePanel implements Container,
}
}
- private void handleError(UIDL uidl) {
+ void handleError(UIDL uidl) {
if (uidl.hasAttribute("error")) {
if (errorIndicatorElement == null) {
errorIndicatorElement = DOM.createSpan();
@@ -305,7 +173,7 @@ public class VPanel extends SimplePanel implements Container,
}
}
- private void setIconUri(UIDL uidl, ApplicationConnection client) {
+ void setIconUri(UIDL uidl, ApplicationConnection client) {
final String iconUri = uidl.hasAttribute("icon") ? uidl
.getStringAttribute("icon") : null;
if (iconUri == null) {
@@ -394,7 +262,7 @@ public class VPanel extends SimplePanel implements Container,
}
} else if (captionNode.isOrHasChild(target)) {
if (client != null) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
}
}
@@ -554,10 +422,6 @@ public class VPanel extends SimplePanel implements Container,
return !renderInformation.updateSize(getElement());
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP: layouts caption, errors etc not rendered in Panel
- }
-
@Override
protected void onAttach() {
super.onAttach();
@@ -568,8 +432,4 @@ public class VPanel extends SimplePanel implements Container,
return shortcutHandler;
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
new file mode 100644
index 0000000000..df4554ea5e
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPanelPaintable.java
@@ -0,0 +1,178 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VPanelPaintable extends VAbstractPaintableWidgetContainer {
+
+ public static final String CLICK_EVENT_IDENTIFIER = "click";
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ if (!uidl.hasAttribute("cached")) {
+
+ // Handle caption displaying and style names, prior generics.
+ // Affects size
+ // calculations
+
+ // Restore default stylenames
+ getWidgetForPaintable().contentNode.setClassName(VPanel.CLASSNAME
+ + "-content");
+ getWidgetForPaintable().bottomDecoration
+ .setClassName(VPanel.CLASSNAME + "-deco");
+ getWidgetForPaintable().captionNode.setClassName(VPanel.CLASSNAME
+ + "-caption");
+ boolean hasCaption = false;
+ if (uidl.hasAttribute("caption")
+ && !uidl.getStringAttribute("caption").equals("")) {
+ getWidgetForPaintable().setCaption(
+ uidl.getStringAttribute("caption"));
+ hasCaption = true;
+ } else {
+ getWidgetForPaintable().setCaption("");
+ getWidgetForPaintable().captionNode
+ .setClassName(VPanel.CLASSNAME + "-nocaption");
+ }
+
+ // Add proper stylenames for all elements. This way we can prevent
+ // unwanted CSS selector inheritance.
+ if (uidl.hasAttribute("style")) {
+ final String[] styles = uidl.getStringAttribute("style").split(
+ " ");
+ final String captionBaseClass = VPanel.CLASSNAME
+ + (hasCaption ? "-caption" : "-nocaption");
+ final String contentBaseClass = VPanel.CLASSNAME + "-content";
+ final String decoBaseClass = VPanel.CLASSNAME + "-deco";
+ String captionClass = captionBaseClass;
+ String contentClass = contentBaseClass;
+ String decoClass = decoBaseClass;
+ for (int i = 0; i < styles.length; i++) {
+ captionClass += " " + captionBaseClass + "-" + styles[i];
+ contentClass += " " + contentBaseClass + "-" + styles[i];
+ decoClass += " " + decoBaseClass + "-" + styles[i];
+ }
+ getWidgetForPaintable().captionNode.setClassName(captionClass);
+ getWidgetForPaintable().contentNode.setClassName(contentClass);
+ getWidgetForPaintable().bottomDecoration
+ .setClassName(decoClass);
+
+ }
+ }
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ getWidgetForPaintable().setIconUri(uidl, client);
+
+ getWidgetForPaintable().handleError(uidl);
+
+ // Render content
+ final UIDL layoutUidl = uidl.getChildUIDL(0);
+ final VPaintableWidget newLayout = client.getPaintable(layoutUidl);
+ if (newLayout != getWidgetForPaintable().layout) {
+ if (getWidgetForPaintable().layout != null) {
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ }
+ getWidgetForPaintable()
+ .setWidget(newLayout.getWidgetForPaintable());
+ getWidgetForPaintable().layout = newLayout;
+ }
+ getWidgetForPaintable().layout.updateFromUIDL(layoutUidl, client);
+
+ // We may have actions attached to this panel
+ if (uidl.getChildCount() > 1) {
+ final int cnt = uidl.getChildCount();
+ for (int i = 1; i < cnt; i++) {
+ UIDL childUidl = uidl.getChildUIDL(i);
+ if (childUidl.getTag().equals("actions")) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ }
+ }
+
+ if (uidl.hasVariable("scrollTop")
+ && uidl.getIntVariable("scrollTop") != getWidgetForPaintable().scrollTop) {
+ getWidgetForPaintable().scrollTop = uidl
+ .getIntVariable("scrollTop");
+ getWidgetForPaintable().contentNode
+ .setScrollTop(getWidgetForPaintable().scrollTop);
+ // re-read the actual scrollTop in case invalid value was set
+ // (scrollTop != 0 when no scrollbar exists, other values would be
+ // caught by scroll listener), see #3784
+ getWidgetForPaintable().scrollTop = getWidgetForPaintable().contentNode
+ .getScrollTop();
+ }
+
+ if (uidl.hasVariable("scrollLeft")
+ && uidl.getIntVariable("scrollLeft") != getWidgetForPaintable().scrollLeft) {
+ getWidgetForPaintable().scrollLeft = uidl
+ .getIntVariable("scrollLeft");
+ getWidgetForPaintable().contentNode
+ .setScrollLeft(getWidgetForPaintable().scrollLeft);
+ // re-read the actual scrollTop in case invalid value was set
+ // (scrollTop != 0 when no scrollbar exists, other values would be
+ // caught by scroll listener), see #3784
+ getWidgetForPaintable().scrollLeft = getWidgetForPaintable().contentNode
+ .getScrollLeft();
+ }
+
+ // Must be run after scrollTop is set as Webkit overflow fix re-sets the
+ // scrollTop
+ getWidgetForPaintable().runHacks(false);
+
+ // And apply tab index
+ if (uidl.hasVariable("tabindex")) {
+ getWidgetForPaintable().contentNode.setTabIndex(uidl
+ .getIntVariable("tabindex"));
+ }
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP: layouts caption, errors etc not rendered in Panel
+ }
+
+ @Override
+ public VPanel getWidgetForPaintable() {
+ return (VPanel) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPanel.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java b/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
index 945f0d85e6..5182457067 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPasswordField.java
@@ -1,21 +1,21 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.DOM;
-
-/**
- * This class represents a password field.
- *
- * @author Vaadin Ltd.
- *
- */
-public class VPasswordField extends VTextField {
-
- public VPasswordField() {
- super(DOM.createInputPassword());
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.DOM;
+
+/**
+ * This class represents a password field.
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class VPasswordField extends VTextField {
+
+ public VPasswordField() {
+ super(DOM.createInputPassword());
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPasswordFieldPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPasswordFieldPaintable.java
new file mode 100644
index 0000000000..98be1250a3
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPasswordFieldPaintable.java
@@ -0,0 +1,28 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VPasswordFieldPaintable extends VTextFieldPaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ super.updateFromUIDL(uidl, client);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPasswordField.class);
+ }
+
+ @Override
+ public VPasswordField getWidgetForPaintable() {
+ return (VPasswordField) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
index 44fb9ac69c..1c0b937e05 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
@@ -1,474 +1,378 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VConsole;
-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;
-
-/**
- * Represents a date selection component with a text field and a popup date
- * selector.
- *
- * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
- * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
- * and then pass set it by calling the
- * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
- *
- */
-public class VPopupCalendar extends VTextualDate implements VPaintableWidget,
- Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
-
- private static final String POPUP_PRIMARY_STYLE_NAME = VDateField.CLASSNAME
- + "-popup";
-
- private final Button calendarToggle;
-
- private VCalendarPanel calendar;
-
- private final VOverlay popup;
- private boolean open = false;
- private boolean parsable = true;
-
- public VPopupCalendar() {
- super();
-
- calendarToggle = new Button();
- calendarToggle.setStyleName(CLASSNAME + "-button");
- calendarToggle.setText("");
- calendarToggle.addClickHandler(this);
- // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
- calendarToggle.getElement().setTabIndex(-2);
- add(calendarToggle);
-
- calendar = GWT.create(VCalendarPanel.class);
- calendar.setFocusOutListener(new FocusOutListener() {
- public boolean onFocusOut(DomEvent<?> event) {
- event.preventDefault();
- closeCalendarPanel();
- return true;
- }
- });
-
- calendar.setSubmitListener(new SubmitListener() {
- public void onSubmit() {
- // Update internal value and send valuechange event if immediate
- updateValue(calendar.getDate());
-
- // Update text field (a must when not immediate).
- buildDate(true);
-
- closeCalendarPanel();
- }
-
- public void onCancel() {
- closeCalendarPanel();
- }
- });
-
- popup = new VOverlay(true, true, true);
- popup.setStyleName(POPUP_PRIMARY_STYLE_NAME);
- popup.setWidget(calendar);
- popup.addCloseHandler(this);
-
- DOM.setElementProperty(calendar.getElement(), "id",
- "PID_VAADIN_POPUPCAL");
-
- sinkEvents(Event.ONKEYDOWN);
-
- }
-
- @SuppressWarnings("deprecation")
- private void updateValue(Date newDate) {
- Date currentDate = getCurrentDate();
- if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
- setCurrentDate((Date) newDate.clone());
- getClient().updateVariable(getId(), "year",
- newDate.getYear() + 1900, false);
- if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
- getClient().updateVariable(getId(), "month",
- newDate.getMonth() + 1, false);
- if (getCurrentResolution() > RESOLUTION_MONTH) {
- getClient().updateVariable(getId(), "day",
- newDate.getDate(), false);
- if (getCurrentResolution() > RESOLUTION_DAY) {
- getClient().updateVariable(getId(), "hour",
- newDate.getHours(), false);
- if (getCurrentResolution() > RESOLUTION_HOUR) {
- getClient().updateVariable(getId(), "min",
- newDate.getMinutes(), false);
- if (getCurrentResolution() > RESOLUTION_MIN) {
- getClient().updateVariable(getId(), "sec",
- newDate.getSeconds(), false);
- }
- }
- }
- }
- }
- if (isImmediate()) {
- getClient().sendPendingVariableChanges();
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin
- * .terminal.gwt.client.UIDL,
- * com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- @Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- boolean lastReadOnlyState = readonly;
- boolean lastEnabledState = isEnabled();
-
- parsable = uidl.getBooleanAttribute("parsable");
-
- super.updateFromUIDL(uidl, client);
-
- String popupStyleNames = ApplicationConnection.getStyleName(
- POPUP_PRIMARY_STYLE_NAME, uidl, false);
- popupStyleNames += " " + VDateField.CLASSNAME + "-"
- + resolutionToString(currentResolution);
- popup.setStyleName(popupStyleNames);
-
- calendar.setDateTimeService(getDateTimeService());
- calendar.setShowISOWeekNumbers(isShowISOWeekNumbers());
- if (calendar.getResolution() != currentResolution) {
- calendar.setResolution(currentResolution);
- if (calendar.getDate() != null) {
- calendar.setDate((Date) getCurrentDate().clone());
- // force re-render when changing resolution only
- calendar.renderCalendar();
- }
- }
- calendarToggle.setEnabled(enabled);
-
- if (currentResolution <= RESOLUTION_MONTH) {
- calendar.setFocusChangeListener(new FocusChangeListener() {
- public void focusChanged(Date date) {
- updateValue(date);
- buildDate();
- Date date2 = calendar.getDate();
- date2.setYear(date.getYear());
- date2.setMonth(date.getMonth());
- }
- });
- } else {
- calendar.setFocusChangeListener(null);
- }
-
- if (currentResolution > RESOLUTION_DAY) {
- calendar.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) calendar.getDate().clone();
- }
- d.setHours(hour);
- d.setMinutes(min);
- d.setSeconds(sec);
- DateTimeService.setMilliseconds(d, msec);
-
- // Always update time changes to the server
- updateValue(d);
-
- // Update text field
- buildDate();
- }
- });
- }
-
- if (readonly) {
- calendarToggle.addStyleName(CLASSNAME + "-button-readonly");
- } else {
- calendarToggle.removeStyleName(CLASSNAME + "-button-readonly");
- }
-
- if (lastReadOnlyState != readonly || lastEnabledState != isEnabled()) {
- // Enabled or readonly state changed. Differences in theming might
- // affect the width (for instance if the popup button is hidden) so
- // we have to recalculate the width (IF the width of the field is
- // fixed)
- updateWidth();
- }
-
- calendarToggle.setEnabled(true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
- */
- @Override
- public void setStyleName(String style) {
- // make sure the style is there before size calculation
- super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
- }
-
- /**
- * Opens the calendar panel popup
- */
- public void openCalendarPanel() {
-
- if (!open && !readonly) {
- open = true;
-
- if (getCurrentDate() != null) {
- calendar.setDate((Date) getCurrentDate().clone());
- } else {
- calendar.setDate(new Date());
- }
-
- // clear previous values
- popup.setWidth("");
- popup.setHeight("");
- popup.setPopupPositionAndShow(new PositionCallback() {
- public void setPosition(int offsetWidth, int offsetHeight) {
- final int w = offsetWidth;
- final int h = offsetHeight;
- final int browserWindowWidth = Window.getClientWidth()
- + Window.getScrollLeft();
- final int browserWindowHeight = Window.getClientHeight()
- + Window.getScrollTop();
- int t = calendarToggle.getAbsoluteTop();
- int l = calendarToggle.getAbsoluteLeft();
-
- // Add a little extra space to the right to avoid
- // problems with IE7 scrollbars and to make it look
- // nicer.
- int extraSpace = 30;
-
- boolean overflowRight = false;
- if (l + +w + extraSpace > browserWindowWidth) {
- overflowRight = true;
- // Part of the popup is outside the browser window
- // (to the right)
- l = browserWindowWidth - w - extraSpace;
- }
-
- if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
- // Part of the popup is outside the browser window
- // (below)
- t = browserWindowHeight - h
- - calendarToggle.getOffsetHeight() - 30;
- if (!overflowRight) {
- // Show to the right of the popup button unless we
- // are in the lower right corner of the screen
- l += calendarToggle.getOffsetWidth();
- }
- }
-
- // fix size
- popup.setWidth(w + "px");
- popup.setHeight(h + "px");
-
- popup.setPopupPosition(l,
- t + calendarToggle.getOffsetHeight() + 2);
-
- /*
- * We have to wait a while before focusing since the popup
- * needs to be opened before we can focus
- */
- Timer focusTimer = new Timer() {
- @Override
- public void run() {
- setFocus(true);
- }
- };
-
- focusTimer.schedule(100);
- }
- });
- } else {
- VConsole.error("Cannot reopen popup, it is already open!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
- * .dom.client.ClickEvent)
- */
- public void onClick(ClickEvent event) {
- if (event.getSource() == calendarToggle && isEnabled()) {
- openCalendarPanel();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
- * .event.logical.shared.CloseEvent)
- */
- public void onClose(CloseEvent<PopupPanel> event) {
- if (event.getSource() == popup) {
- buildDate();
- if (!BrowserInfo.get().isTouchDevice()) {
- /*
- * Move focus to textbox, unless on touch device (avoids opening
- * virtual keyboard).
- */
- focus();
- }
-
- // TODO resolve what the "Sigh." is all about and document it here
- // Sigh.
- Timer t = new Timer() {
- @Override
- public void run() {
- open = false;
- }
- };
- t.schedule(100);
- }
- }
-
- /**
- * Sets focus to Calendar panel.
- *
- * @param focus
- */
- public void setFocus(boolean focus) {
- calendar.setFocus(focus);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
- */
- @Override
- protected int getFieldExtraWidth() {
- if (fieldExtraWidth < 0) {
- fieldExtraWidth = super.getFieldExtraWidth();
- fieldExtraWidth += calendarToggle.getOffsetWidth();
- }
- return fieldExtraWidth;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
- */
- @Override
- protected void buildDate() {
- // Save previous value
- String previousValue = getText();
- super.buildDate();
-
- // Restore previous value if the input could not be parsed
- if (!parsable) {
- setText(previousValue);
- }
- }
-
- /**
- * Update the text field contents from the date. See {@link #buildDate()}.
- *
- * @param forceValid
- * true to force the text field to be updated, false to only
- * update if the parsable flag is true.
- */
- protected void buildDate(boolean forceValid) {
- if (forceValid) {
- parsable = true;
- }
- buildDate();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
- * .gwt.user.client.Event)
- */
- @Override
- public void onBrowserEvent(com.google.gwt.user.client.Event event) {
- super.onBrowserEvent(event);
- if (DOM.eventGetType(event) == Event.ONKEYDOWN
- && event.getKeyCode() == getOpenCalenderPanelKey()) {
- openCalendarPanel();
- event.preventDefault();
- }
- }
-
- /**
- * Get the key code that opens the calendar panel. By default it is the down
- * key but you can override this to be whatever you like
- *
- * @return
- */
- protected int getOpenCalenderPanelKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * Closes the open popup panel
- */
- public void closeCalendarPanel() {
- if (open) {
- popup.hide(true);
- }
- }
-
- private final String CALENDAR_TOGGLE_ID = "popupButton";
-
- @Override
- public Element getSubPartElement(String subPart) {
- if (subPart.equals(CALENDAR_TOGGLE_ID)) {
- return calendarToggle.getElement();
- }
-
- return super.getSubPartElement(subPart);
- }
-
- @Override
- public String getSubPartName(Element subElement) {
- if (calendarToggle.getElement().isOrHasChild(subElement)) {
- return CALENDAR_TOGGLE_ID;
- }
-
- return super.getSubPartName(subElement);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
+
+/**
+ * Represents a date selection component with a text field and a popup date
+ * selector.
+ *
+ * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
+ * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
+ * and then pass set it by calling the
+ * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
+ *
+ */
+public class VPopupCalendar extends VTextualDate implements Field,
+ ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
+
+ protected static final String POPUP_PRIMARY_STYLE_NAME = VDateField.CLASSNAME
+ + "-popup";
+
+ protected final Button calendarToggle;
+
+ protected VCalendarPanel calendar;
+
+ protected final VOverlay popup;
+ private boolean open = false;
+ protected boolean parsable = true;
+
+ public VPopupCalendar() {
+ super();
+
+ calendarToggle = new Button();
+ calendarToggle.setStyleName(CLASSNAME + "-button");
+ calendarToggle.setText("");
+ calendarToggle.addClickHandler(this);
+ // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
+ calendarToggle.getElement().setTabIndex(-2);
+ add(calendarToggle);
+
+ calendar = GWT.create(VCalendarPanel.class);
+ calendar.setFocusOutListener(new FocusOutListener() {
+ public boolean onFocusOut(DomEvent<?> event) {
+ event.preventDefault();
+ closeCalendarPanel();
+ return true;
+ }
+ });
+
+ calendar.setSubmitListener(new SubmitListener() {
+ public void onSubmit() {
+ // Update internal value and send valuechange event if immediate
+ updateValue(calendar.getDate());
+
+ // Update text field (a must when not immediate).
+ buildDate(true);
+
+ closeCalendarPanel();
+ }
+
+ public void onCancel() {
+ closeCalendarPanel();
+ }
+ });
+
+ popup = new VOverlay(true, true, true);
+ popup.setStyleName(POPUP_PRIMARY_STYLE_NAME);
+ popup.setWidget(calendar);
+ popup.addCloseHandler(this);
+
+ DOM.setElementProperty(calendar.getElement(), "id",
+ "PID_VAADIN_POPUPCAL");
+
+ sinkEvents(Event.ONKEYDOWN);
+
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void updateValue(Date newDate) {
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) newDate.clone());
+ getClient().updateVariable(getId(), "year",
+ newDate.getYear() + 1900, false);
+ if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
+ getClient().updateVariable(getId(), "month",
+ newDate.getMonth() + 1, false);
+ if (getCurrentResolution() > RESOLUTION_MONTH) {
+ getClient().updateVariable(getId(), "day",
+ newDate.getDate(), false);
+ if (getCurrentResolution() > RESOLUTION_DAY) {
+ getClient().updateVariable(getId(), "hour",
+ newDate.getHours(), false);
+ if (getCurrentResolution() > RESOLUTION_HOUR) {
+ getClient().updateVariable(getId(), "min",
+ newDate.getMinutes(), false);
+ if (getCurrentResolution() > RESOLUTION_MIN) {
+ getClient().updateVariable(getId(), "sec",
+ newDate.getSeconds(), false);
+ }
+ }
+ }
+ }
+ }
+ if (isImmediate()) {
+ getClient().sendPendingVariableChanges();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
+ */
+ @Override
+ public void setStyleName(String style) {
+ // make sure the style is there before size calculation
+ super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
+ }
+
+ /**
+ * Opens the calendar panel popup
+ */
+ public void openCalendarPanel() {
+
+ if (!open && !readonly) {
+ open = true;
+
+ if (getCurrentDate() != null) {
+ calendar.setDate((Date) getCurrentDate().clone());
+ } else {
+ calendar.setDate(new Date());
+ }
+
+ // clear previous values
+ popup.setWidth("");
+ popup.setHeight("");
+ popup.setPopupPositionAndShow(new PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ final int w = offsetWidth;
+ final int h = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int browserWindowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
+ int t = calendarToggle.getAbsoluteTop();
+ int l = calendarToggle.getAbsoluteLeft();
+
+ // Add a little extra space to the right to avoid
+ // problems with IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflowRight = false;
+ if (l + +w + extraSpace > browserWindowWidth) {
+ overflowRight = true;
+ // Part of the popup is outside the browser window
+ // (to the right)
+ l = browserWindowWidth - w - extraSpace;
+ }
+
+ if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
+ // Part of the popup is outside the browser window
+ // (below)
+ t = browserWindowHeight - h
+ - calendarToggle.getOffsetHeight() - 30;
+ if (!overflowRight) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ l += calendarToggle.getOffsetWidth();
+ }
+ }
+
+ // fix size
+ popup.setWidth(w + "px");
+ popup.setHeight(h + "px");
+
+ popup.setPopupPosition(l,
+ t + calendarToggle.getOffsetHeight() + 2);
+
+ /*
+ * We have to wait a while before focusing since the popup
+ * needs to be opened before we can focus
+ */
+ Timer focusTimer = new Timer() {
+ @Override
+ public void run() {
+ setFocus(true);
+ }
+ };
+
+ focusTimer.schedule(100);
+ }
+ });
+ } else {
+ VConsole.error("Cannot reopen popup, it is already open!");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
+ * .dom.client.ClickEvent)
+ */
+ public void onClick(ClickEvent event) {
+ if (event.getSource() == calendarToggle && isEnabled()) {
+ openCalendarPanel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
+ * .event.logical.shared.CloseEvent)
+ */
+ public void onClose(CloseEvent<PopupPanel> event) {
+ if (event.getSource() == popup) {
+ buildDate();
+ if (!BrowserInfo.get().isTouchDevice()) {
+ /*
+ * Move focus to textbox, unless on touch device (avoids opening
+ * virtual keyboard).
+ */
+ focus();
+ }
+
+ // TODO resolve what the "Sigh." is all about and document it here
+ // Sigh.
+ Timer t = new Timer() {
+ @Override
+ public void run() {
+ open = false;
+ }
+ };
+ t.schedule(100);
+ }
+ }
+
+ /**
+ * Sets focus to Calendar panel.
+ *
+ * @param focus
+ */
+ public void setFocus(boolean focus) {
+ calendar.setFocus(focus);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
+ */
+ @Override
+ protected int getFieldExtraWidth() {
+ if (fieldExtraWidth < 0) {
+ fieldExtraWidth = super.getFieldExtraWidth();
+ fieldExtraWidth += calendarToggle.getOffsetWidth();
+ }
+ return fieldExtraWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
+ */
+ @Override
+ protected void buildDate() {
+ // Save previous value
+ String previousValue = getText();
+ super.buildDate();
+
+ // Restore previous value if the input could not be parsed
+ if (!parsable) {
+ setText(previousValue);
+ }
+ }
+
+ /**
+ * Update the text field contents from the date. See {@link #buildDate()}.
+ *
+ * @param forceValid
+ * true to force the text field to be updated, false to only
+ * update if the parsable flag is true.
+ */
+ protected void buildDate(boolean forceValid) {
+ if (forceValid) {
+ parsable = true;
+ }
+ buildDate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
+ * .gwt.user.client.Event)
+ */
+ @Override
+ public void onBrowserEvent(com.google.gwt.user.client.Event event) {
+ super.onBrowserEvent(event);
+ if (DOM.eventGetType(event) == Event.ONKEYDOWN
+ && event.getKeyCode() == getOpenCalenderPanelKey()) {
+ openCalendarPanel();
+ event.preventDefault();
+ }
+ }
+
+ /**
+ * Get the key code that opens the calendar panel. By default it is the down
+ * key but you can override this to be whatever you like
+ *
+ * @return
+ */
+ protected int getOpenCalenderPanelKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Closes the open popup panel
+ */
+ public void closeCalendarPanel() {
+ if (open) {
+ popup.hide(true);
+ }
+ }
+
+ private final String CALENDAR_TOGGLE_ID = "popupButton";
+
+ @Override
+ public Element getSubPartElement(String subPart) {
+ if (subPart.equals(CALENDAR_TOGGLE_ID)) {
+ return calendarToggle.getElement();
+ }
+
+ return super.getSubPartElement(subPart);
+ }
+
+ @Override
+ public String getSubPartName(Element subElement) {
+ if (calendarToggle.getElement().isOrHasChild(subElement)) {
+ return CALENDAR_TOGGLE_ID;
+ }
+
+ return super.getSubPartName(subElement);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java
new file mode 100644
index 0000000000..96e966a993
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendarPaintable.java
@@ -0,0 +1,138 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+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.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.TimeChangeListener;
+
+public class VPopupCalendarPaintable extends VTextualDatePaintable {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin
+ * .terminal.gwt.client.UIDL,
+ * com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ @Override
+ @SuppressWarnings("deprecation")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ boolean lastReadOnlyState = getWidgetForPaintable().readonly;
+ boolean lastEnabledState = getWidgetForPaintable().isEnabled();
+
+ getWidgetForPaintable().parsable = uidl.getBooleanAttribute("parsable");
+
+ super.updateFromUIDL(uidl, client);
+
+ String popupStyleNames = ApplicationConnection.getStyleName(
+ VPopupCalendar.POPUP_PRIMARY_STYLE_NAME, uidl, false);
+ popupStyleNames += " "
+ + VDateField.CLASSNAME
+ + "-"
+ + VPopupCalendar
+ .resolutionToString(getWidgetForPaintable().currentResolution);
+ getWidgetForPaintable().popup.setStyleName(popupStyleNames);
+
+ getWidgetForPaintable().calendar
+ .setDateTimeService(getWidgetForPaintable()
+ .getDateTimeService());
+ getWidgetForPaintable().calendar
+ .setShowISOWeekNumbers(getWidgetForPaintable()
+ .isShowISOWeekNumbers());
+ if (getWidgetForPaintable().calendar.getResolution() != getWidgetForPaintable().currentResolution) {
+ getWidgetForPaintable().calendar
+ .setResolution(getWidgetForPaintable().currentResolution);
+ if (getWidgetForPaintable().calendar.getDate() != null) {
+ getWidgetForPaintable().calendar
+ .setDate((Date) getWidgetForPaintable()
+ .getCurrentDate().clone());
+ // force re-render when changing resolution only
+ getWidgetForPaintable().calendar.renderCalendar();
+ }
+ }
+ getWidgetForPaintable().calendarToggle
+ .setEnabled(getWidgetForPaintable().enabled);
+
+ if (getWidgetForPaintable().currentResolution <= VPopupCalendar.RESOLUTION_MONTH) {
+ getWidgetForPaintable().calendar
+ .setFocusChangeListener(new FocusChangeListener() {
+ public void focusChanged(Date date) {
+ getWidgetForPaintable().updateValue(date);
+ getWidgetForPaintable().buildDate();
+ Date date2 = getWidgetForPaintable().calendar
+ .getDate();
+ date2.setYear(date.getYear());
+ date2.setMonth(date.getMonth());
+ }
+ });
+ } else {
+ getWidgetForPaintable().calendar.setFocusChangeListener(null);
+ }
+
+ if (getWidgetForPaintable().currentResolution > VPopupCalendar.RESOLUTION_DAY) {
+ getWidgetForPaintable().calendar
+ .setTimeChangeListener(new TimeChangeListener() {
+ public void changed(int hour, int min, int sec, int msec) {
+ Date d = getWidgetForPaintable().getDate();
+ if (d == null) {
+ // date currently null, use the value from
+ // calendarPanel
+ // (~ client time at the init of the widget)
+ d = (Date) getWidgetForPaintable().calendar
+ .getDate().clone();
+ }
+ d.setHours(hour);
+ d.setMinutes(min);
+ d.setSeconds(sec);
+ DateTimeService.setMilliseconds(d, msec);
+
+ // Always update time changes to the server
+ getWidgetForPaintable().updateValue(d);
+
+ // Update text field
+ getWidgetForPaintable().buildDate();
+ }
+ });
+ }
+
+ if (getWidgetForPaintable().readonly) {
+ getWidgetForPaintable().calendarToggle
+ .addStyleName(VPopupCalendar.CLASSNAME + "-button-readonly");
+ } else {
+ getWidgetForPaintable().calendarToggle
+ .removeStyleName(VPopupCalendar.CLASSNAME
+ + "-button-readonly");
+ }
+
+ if (lastReadOnlyState != getWidgetForPaintable().readonly
+ || lastEnabledState != getWidgetForPaintable().isEnabled()) {
+ // Enabled or readonly state changed. Differences in theming might
+ // affect the width (for instance if the popup button is hidden) so
+ // we have to recalculate the width (IF the width of the field is
+ // fixed)
+ getWidgetForPaintable().updateWidth();
+ }
+
+ getWidgetForPaintable().calendarToggle.setEnabled(true);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPopupCalendar.class);
+ }
+
+ @Override
+ public VPopupCalendar getWidgetForPaintable() {
+ return (VPopupCalendar) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
index e667489dda..b3acc9a9a7 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java
@@ -29,7 +29,6 @@ import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VCaptionWrapper;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
@@ -40,13 +39,13 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
public static final String CLASSNAME = "v-popupview";
/** For server-client communication */
- private String uidlId;
- private ApplicationConnection client;
+ String uidlId;
+ ApplicationConnection client;
/** This variable helps to communicate popup visibility to the server */
- private boolean hostPopupVisible;
+ boolean hostPopupVisible;
- private final CustomPopup popup;
+ final CustomPopup popup;
private final Label loading = new Label();
/**
@@ -82,61 +81,6 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
}
/**
- *
- *
- * @see com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
- * com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // This call should be made first. Ensure correct implementation,
- // and don't let the containing layout manage caption.
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
- // These are for future server connections
- this.client = client;
- uidlId = uidl.getId();
-
- hostPopupVisible = uidl.getBooleanVariable("popupVisibility");
-
- setHTML(uidl.getStringAttribute("html"));
-
- if (uidl.hasAttribute("hideOnMouseOut")) {
- popup.setHideOnMouseOut(uidl.getBooleanAttribute("hideOnMouseOut"));
- }
-
- // Render the popup if visible and show it.
- if (hostPopupVisible) {
- UIDL popupUIDL = uidl.getChildUIDL(0);
-
- // showPopupOnTop(popup, hostReference);
- preparePopup(popup);
- popup.updateFromUIDL(popupUIDL, client);
- if (uidl.hasAttribute("style")) {
- final String[] styles = uidl.getStringAttribute("style").split(
- " ");
- final StringBuffer styleBuf = new StringBuffer();
- final String primaryName = popup.getStylePrimaryName();
- styleBuf.append(primaryName);
- for (int i = 0; i < styles.length; i++) {
- styleBuf.append(" ");
- styleBuf.append(primaryName);
- styleBuf.append("-");
- styleBuf.append(styles[i]);
- }
- popup.setStyleName(styleBuf.toString());
- } else {
- popup.setStyleName(popup.getStylePrimaryName());
- }
- showPopup(popup);
-
- // The popup shouldn't be visible, try to hide it.
- } else {
- popup.hide();
- }
- }// updateFromUIDL
-
- /**
* Update popup visibility to server
*
* @param visibility
@@ -149,7 +93,7 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
}
}
- private void preparePopup(final CustomPopup popup) {
+ void preparePopup(final CustomPopup popup) {
popup.setVisible(false);
popup.show();
}
@@ -231,8 +175,8 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
protected class CustomPopup extends VOverlay {
private VPaintableWidget popupComponentPaintable = null;
- private Widget popupComponentWidget = null;
- private VCaptionWrapper captionWrapper = null;
+ Widget popupComponentWidget = null;
+ VCaptionWrapper captionWrapper = null;
private boolean hasHadMouseOver = false;
private boolean hideOnMouseOut = true;
@@ -446,27 +390,11 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
return true;
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- if (VCaption.isNeeded(uidl)) {
- if (popup.captionWrapper != null) {
- popup.captionWrapper.updateCaption(uidl);
- } else {
- popup.captionWrapper = new VCaptionWrapper(component, client);
- popup.setWidget(popup.captionWrapper);
- popup.captionWrapper.updateCaption(uidl);
- }
- } else {
- if (popup.captionWrapper != null) {
- popup.setWidget(popup.popupComponentWidget);
- }
- }
- }
-
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
}
@@ -496,8 +424,4 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> {
};
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}// class VPopupView
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java
new file mode 100644
index 0000000000..cd8965ffc6
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupViewPaintable.java
@@ -0,0 +1,107 @@
+/*
+ @VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VCaption;
+import com.vaadin.terminal.gwt.client.VCaptionWrapper;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VPopupViewPaintable extends VAbstractPaintableWidgetContainer {
+
+ /**
+ *
+ *
+ * @see com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
+ * com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and don't let the containing layout manage caption.
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+ // These are for future server connections
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().uidlId = uidl.getId();
+
+ getWidgetForPaintable().hostPopupVisible = uidl
+ .getBooleanVariable("popupVisibility");
+
+ getWidgetForPaintable().setHTML(uidl.getStringAttribute("html"));
+
+ if (uidl.hasAttribute("hideOnMouseOut")) {
+ getWidgetForPaintable().popup.setHideOnMouseOut(uidl
+ .getBooleanAttribute("hideOnMouseOut"));
+ }
+
+ // Render the popup if visible and show it.
+ if (getWidgetForPaintable().hostPopupVisible) {
+ UIDL popupUIDL = uidl.getChildUIDL(0);
+
+ // showPopupOnTop(popup, hostReference);
+ getWidgetForPaintable().preparePopup(getWidgetForPaintable().popup);
+ getWidgetForPaintable().popup.updateFromUIDL(popupUIDL, client);
+ if (uidl.hasAttribute("style")) {
+ final String[] styles = uidl.getStringAttribute("style").split(
+ " ");
+ final StringBuffer styleBuf = new StringBuffer();
+ final String primaryName = getWidgetForPaintable().popup
+ .getStylePrimaryName();
+ styleBuf.append(primaryName);
+ for (int i = 0; i < styles.length; i++) {
+ styleBuf.append(" ");
+ styleBuf.append(primaryName);
+ styleBuf.append("-");
+ styleBuf.append(styles[i]);
+ }
+ getWidgetForPaintable().popup.setStyleName(styleBuf.toString());
+ } else {
+ getWidgetForPaintable().popup
+ .setStyleName(getWidgetForPaintable().popup
+ .getStylePrimaryName());
+ }
+ getWidgetForPaintable().showPopup(getWidgetForPaintable().popup);
+
+ // The popup shouldn't be visible, try to hide it.
+ } else {
+ getWidgetForPaintable().popup.hide();
+ }
+ }// updateFromUIDL
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ if (VCaption.isNeeded(uidl)) {
+ if (getWidgetForPaintable().popup.captionWrapper != null) {
+ getWidgetForPaintable().popup.captionWrapper
+ .updateCaption(uidl);
+ } else {
+ getWidgetForPaintable().popup.captionWrapper = new VCaptionWrapper(
+ component, getConnection());
+ getWidgetForPaintable().popup
+ .setWidget(getWidgetForPaintable().popup.captionWrapper);
+ getWidgetForPaintable().popup.captionWrapper
+ .updateCaption(uidl);
+ }
+ } else {
+ if (getWidgetForPaintable().popup.captionWrapper != null) {
+ getWidgetForPaintable().popup
+ .setWidget(getWidgetForPaintable().popup.popupComponentWidget);
+ }
+ }
+ }
+
+ @Override
+ public VPopupView getWidgetForPaintable() {
+ return (VPopupView) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VPopupView.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java
index f7cc4240b7..cff6bf89bd 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java
@@ -9,20 +9,18 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-public class VProgressIndicator extends Widget implements VPaintableWidget {
+public class VProgressIndicator extends Widget {
- private static final String CLASSNAME = "v-progressindicator";
+ public static final String CLASSNAME = "v-progressindicator";
Element wrapper = DOM.createDiv();
Element indicator = DOM.createDiv();
- private ApplicationConnection client;
- private final Poller poller;
- private boolean indeterminate = false;
+ protected ApplicationConnection client;
+ protected final Poller poller;
+ protected boolean indeterminate = false;
private boolean pollerSuspendedDueDetach;
- private int interval;
+ protected int interval;
public VProgressIndicator() {
setElement(DOM.createDiv());
@@ -34,38 +32,6 @@ public class VProgressIndicator extends Widget implements VPaintableWidget {
poller = new Poller();
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- if (!uidl.getBooleanAttribute("cached")) {
- poller.cancel();
- }
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- indeterminate = uidl.getBooleanAttribute("indeterminate");
-
- if (indeterminate) {
- String basename = CLASSNAME + "-indeterminate";
- VProgressIndicator.setStyleName(getElement(), basename, true);
- VProgressIndicator.setStyleName(getElement(), basename
- + "-disabled", uidl.getBooleanAttribute("disabled"));
- } else {
- try {
- final float f = Float.parseFloat(uidl
- .getStringAttribute("state"));
- final int size = Math.round(100 * f);
- DOM.setStyleAttribute(indicator, "width", size + "%");
- } catch (final Exception e) {
- }
- }
-
- if (!uidl.getBooleanAttribute("disabled")) {
- interval = uidl.getIntAttribute("pollinginterval");
- poller.scheduleRepeating(interval);
- }
- }
-
@Override
protected void onAttach() {
super.onAttach();
@@ -102,9 +68,4 @@ public class VProgressIndicator extends Widget implements VPaintableWidget {
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicatorPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicatorPaintable.java
new file mode 100644
index 0000000000..39ffe1ad96
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicatorPaintable.java
@@ -0,0 +1,65 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VProgressIndicatorPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ // Ensure correct implementation,
+ // but don't let container manage caption etc.
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ // Save details
+ getWidgetForPaintable().client = client;
+
+ getWidgetForPaintable().indeterminate = uidl
+ .getBooleanAttribute("indeterminate");
+
+ if (getWidgetForPaintable().indeterminate) {
+ String basename = VProgressIndicator.CLASSNAME + "-indeterminate";
+ getWidgetForPaintable().addStyleName(basename);
+ if (uidl.getBooleanAttribute("disabled")) {
+ getWidgetForPaintable().addStyleName(basename + "-disabled");
+ } else {
+ getWidgetForPaintable().removeStyleName(basename + "-disabled");
+ }
+ } else {
+ try {
+ final float f = Float.parseFloat(uidl
+ .getStringAttribute("state"));
+ final int size = Math.round(100 * f);
+ DOM.setStyleAttribute(getWidgetForPaintable().indicator,
+ "width", size + "%");
+ } catch (final Exception e) {
+ }
+ }
+
+ if (!uidl.getBooleanAttribute("disabled")) {
+ getWidgetForPaintable().interval = uidl
+ .getIntAttribute("pollinginterval");
+ getWidgetForPaintable().poller
+ .scheduleRepeating(getWidgetForPaintable().interval);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VProgressIndicator.class);
+ }
+
+ @Override
+ public VProgressIndicator getWidgetForPaintable() {
+ return (VProgressIndicator) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index de68ae96a4..b84fc1312f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -106,7 +106,7 @@ import com.vaadin.terminal.gwt.client.ui.label.VLabel;
*/
public class VScrollTable extends FlowPanel implements HasWidgets,
ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable,
- ActionOwner {
+ ActionOwner, Container {
public enum SelectMode {
NONE(0), SINGLE(1), MULTI(2);
@@ -2150,7 +2150,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.TOUCHEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU | Event.TOUCHEVENTS);
setElement(td);
@@ -2267,8 +2268,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
scrollBodyPanel.setFocus(true);
}
handleCaptionEvent(event);
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasWidgetEventListeners(
+ VScrollTable.this, HEADER_CLICK_EVENT_ID)) {
+ // Prevent showing the browser's context menu only when
+ // there is a header click listener.
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
}
@@ -2325,7 +2336,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
case Event.ONMOUSEDOWN:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHSTART) {
/*
* prevent using this event in e.g. scrolling
@@ -2344,7 +2356,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
case Event.ONMOUSEUP:
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
dragging = false;
DOM.releaseCapture(getElement());
if (moved) {
@@ -2371,7 +2384,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (!moved) {
// mouse event was a click to header -> sort column
- if (sortable) {
+ if (sortable && Util.isTouchEventOrLeftMouseButton(event)) {
if (sortColumn.equals(cid)) {
// just toggle order
client.updateVariable(paintableId, "sortascending",
@@ -2404,9 +2417,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
break;
}
break;
+ case Event.ONDBLCLICK:
+ fireHeaderClickedEvent(event);
+ break;
case Event.ONTOUCHMOVE:
case Event.ONMOUSEMOVE:
- if (dragging) {
+ if (dragging && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHMOVE) {
/*
* prevent using this event in e.g. scrolling
@@ -2452,6 +2468,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private void onResizeEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = true;
DOM.setCapture(getElement());
dragStartX = DOM.eventGetClientX(event);
@@ -2460,6 +2479,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.eventPreventDefault(event);
break;
case Event.ONMOUSEUP:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = false;
DOM.releaseCapture(getElement());
tHead.disableAutoColumnWidthCalculation(this);
@@ -2474,6 +2496,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
fireColumnResizeEvent(cid, originalWidth, getColWidth(cid));
break;
case Event.ONMOUSEMOVE:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
if (isResizing) {
final int deltaX = DOM.eventGetClientX(event) - dragStartX;
if (deltaX == 0) {
@@ -3133,7 +3158,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU);
setElement(td);
}
@@ -3318,8 +3344,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
scrollBodyPanel.setFocus(true);
}
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasWidgetEventListeners(VScrollTable.this,
+ FOOTER_CLICK_EVENT_ID)) {
+ // Show browser context menu if a footer click listener is
+ // not present
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
@@ -3330,7 +3366,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* The event to handle
*/
protected void handleCaptionEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
+ if (event.getTypeInt() == Event.ONMOUSEUP
+ || event.getTypeInt() == Event.ONDBLCLICK) {
fireFooterClickedEvent(event);
}
}
@@ -4310,8 +4347,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- public class VScrollTableRow extends Panel implements ActionOwner,
- Container {
+ public class VScrollTableRow extends Panel implements ActionOwner {
private static final int TOUCHSCROLL_TIMEOUT = 70;
private static final int DRAGMODE_MULTIROW = 2;
@@ -4540,6 +4576,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.get(client).getPaintable(uidl.getId());
paintable.updateFromUIDL(uidl, client);
}
+ pendingComponentPaints.clear();
}
}
@@ -5267,29 +5304,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return paintableId;
}
- public RenderSpace getAllocatedSpace(Widget child) {
- int w = 0;
- int i = getColIndexOf(child);
- HeaderCell headerCell = tHead.getHeaderCell(i);
- if (headerCell != null) {
- if (initializedAndAttached) {
- w = headerCell.getWidth();
- } else {
- // header offset width is not absolutely correct value,
- // but a best guess (expecting similar content in all
- // columns ->
- // if one component is relative width so are others)
- w = headerCell.getOffsetWidth() - getCellExtraWidth();
- }
- }
- return new RenderSpace(w, 0) {
- @Override
- public int getHeight() {
- return (int) getRowHeight();
- }
- };
- }
-
private int getColIndexOf(Widget child) {
com.google.gwt.dom.client.Element widgetCell = child
.getElement().getParentElement().getParentElement();
@@ -5319,16 +5333,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
- public boolean requestLayout(Set<Widget> children) {
- // row size should never change and system wouldn't event
- // survive as this is a kind of fake paitable
- return true;
- }
-
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, not rendered
- }
-
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
// Should never be called,
// Component container interface faked here to get layouts
@@ -6694,4 +6698,45 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return this;
}
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ VScrollTableRow row = (VScrollTableRow) oldComponent.getParent();
+ row.replaceChildComponent(oldComponent, newComponent);
+
+ }
+
+ public boolean hasChildComponent(Widget child) {
+ VScrollTableRow row = (VScrollTableRow) child.getParent();
+ return row.hasChildComponent(child);
+ }
+
+ public boolean requestLayout(Set<Widget> children) {
+ // row size should never change
+ return true;
+ }
+
+ public RenderSpace getAllocatedSpace(Widget child) {
+ // Called by widgets attached to a row
+ VScrollTableRow row = (VScrollTableRow) child.getParent();
+ int w = 0;
+ int i = row.getColIndexOf(child);
+ HeaderCell headerCell = tHead.getHeaderCell(i);
+ if (headerCell != null) {
+ if (initializedAndAttached) {
+ w = headerCell.getWidth();
+ } else {
+ // header offset width is not absolutely correct value,
+ // but a best guess (expecting similar content in all
+ // columns ->
+ // if one component is relative width so are others)
+ w = headerCell.getOffsetWidth()
+ - scrollBody.getCellExtraWidth();
+ }
+ }
+ return new RenderSpace(w, 0) {
+ @Override
+ public int getHeight() {
+ return (int) scrollBody.getRowHeight();
+ }
+ };
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
index fa7cc3d4ec..058b8f15b3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
@@ -1,254 +1,260 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.dom.client.Style.Position;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class VScrollTablePaintable extends VAbstractPaintableWidget {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
- * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- getWidgetForPaintable().rendering = true;
-
- if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {
- getWidgetForPaintable().serverCacheFirst = uidl
- .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);
- getWidgetForPaintable().serverCacheLast = uidl
- .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);
- } else {
- getWidgetForPaintable().serverCacheFirst = -1;
- getWidgetForPaintable().serverCacheLast = -1;
- }
- /*
- * We need to do this before updateComponent since updateComponent calls
- * this.setHeight() which will calculate a new body height depending on
- * the space available.
- */
- if (uidl.hasAttribute("colfooters")) {
- getWidgetForPaintable().showColFooters = uidl
- .getBooleanAttribute("colfooters");
- }
-
- getWidgetForPaintable().tFoot
- .setVisible(getWidgetForPaintable().showColFooters);
-
- if (client.updateComponent(this, uidl, true)) {
- getWidgetForPaintable().rendering = false;
- return;
- }
-
- getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
-
- if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {
- /*
- * The disabled shim will not cover the table body if it is relative
- * in IE8. See #7324
- */
- getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.STATIC);
- } else if (BrowserInfo.get().isIE8()) {
- getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.RELATIVE);
- }
-
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
-
- int previousTotalRows = getWidgetForPaintable().totalRows;
- getWidgetForPaintable().updateTotalRows(uidl);
- boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);
-
- getWidgetForPaintable().updateDragMode(uidl);
-
- getWidgetForPaintable().updateSelectionProperties(uidl);
-
- if (uidl.hasAttribute("alb")) {
- getWidgetForPaintable().bodyActionKeys = uidl
- .getStringArrayAttribute("alb");
- } else {
- // Need to clear the actions if the action handlers have been
- // removed
- getWidgetForPaintable().bodyActionKeys = null;
- }
-
- getWidgetForPaintable().setCacheRateFromUIDL(uidl);
-
- getWidgetForPaintable().recalcWidths = uidl
- .hasAttribute("recalcWidths");
- if (getWidgetForPaintable().recalcWidths) {
- getWidgetForPaintable().tHead.clear();
- getWidgetForPaintable().tFoot.clear();
- }
-
- getWidgetForPaintable().updatePageLength(uidl);
-
- getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);
-
- getWidgetForPaintable().showRowHeaders = uidl
- .getBooleanAttribute("rowheaders");
- getWidgetForPaintable().showColHeaders = uidl
- .getBooleanAttribute("colheaders");
-
- getWidgetForPaintable().updateSortingProperties(uidl);
-
- boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()
- .selectSelectedRows(uidl);
-
- getWidgetForPaintable().updateActionMap(uidl);
-
- getWidgetForPaintable().updateColumnProperties(uidl);
-
- UIDL ac = uidl.getChildByTagName("-ac");
- if (ac == null) {
- if (getWidgetForPaintable().dropHandler != null) {
- // remove dropHandler if not present anymore
- getWidgetForPaintable().dropHandler = null;
- }
- } else {
- if (getWidgetForPaintable().dropHandler == null) {
- getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();
- }
- getWidgetForPaintable().dropHandler.updateAcceptRules(ac);
- }
-
- UIDL partialRowAdditions = uidl.getChildByTagName("prows");
- UIDL partialRowUpdates = uidl.getChildByTagName("urows");
- if (partialRowUpdates != null || partialRowAdditions != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- getWidgetForPaintable().rowRequestHandler.cancel();
-
- getWidgetForPaintable().updateRowsInBody(partialRowUpdates);
- getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);
- } else {
- UIDL rowData = uidl.getChildByTagName("rows");
- if (rowData != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- getWidgetForPaintable().rowRequestHandler.cancel();
-
- if (!getWidgetForPaintable().recalcWidths
- && getWidgetForPaintable().initializedAndAttached) {
- getWidgetForPaintable().updateBody(rowData,
- uidl.getIntAttribute("firstrow"),
- uidl.getIntAttribute("rows"));
- if (getWidgetForPaintable().headerChangedDuringUpdate) {
- getWidgetForPaintable().triggerLazyColumnAdjustment(
- true);
- } else if (!getWidgetForPaintable()
- .isScrollPositionVisible()
- || totalRowsChanged
- || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody
- .getOffsetHeight()) {
- // webkits may still bug with their disturbing scrollbar
- // bug, see #3457
- // Run overflow fix for the scrollable area
- // #6698 - If there's a scroll going on, don't abort it
- // by changing overflows as the length of the contents
- // *shouldn't* have changed (unless the number of rows
- // or the height of the widget has also changed)
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel
- .getElement());
- }
- });
- }
- } else {
- getWidgetForPaintable().initializeRows(uidl, rowData);
- }
- }
- }
-
- if (!getWidgetForPaintable().isSelectable()) {
- getWidgetForPaintable().scrollBody
- .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");
- } else {
- getWidgetForPaintable().scrollBody
- .removeStyleName(VScrollTable.CLASSNAME
- + "-body-noselection");
- }
-
- getWidgetForPaintable().hideScrollPositionAnnotation();
- getWidgetForPaintable().purgeUnregistryBag();
-
- // selection is no in sync with server, avoid excessive server visits by
- // clearing to flag used during the normal operation
- if (!keyboardSelectionOverRowFetchInProgress) {
- getWidgetForPaintable().selectionChanged = false;
- }
-
- /*
- * This is called when the Home or page up button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (getWidgetForPaintable().selectFirstItemInNextRender
- || getWidgetForPaintable().focusFirstItemInNextRender) {
- getWidgetForPaintable().selectFirstRenderedRowInViewPort(
- getWidgetForPaintable().focusFirstItemInNextRender);
- getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;
- }
-
- /*
- * This is called when the page down or end button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (getWidgetForPaintable().selectLastItemInNextRender
- || getWidgetForPaintable().focusLastItemInNextRender) {
- getWidgetForPaintable().selectLastRenderedRowInViewPort(
- getWidgetForPaintable().focusLastItemInNextRender);
- getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;
- }
- getWidgetForPaintable().multiselectPending = false;
-
- if (getWidgetForPaintable().focusedRow != null) {
- if (!getWidgetForPaintable().focusedRow.isAttached()
- && !getWidgetForPaintable().rowRequestHandler.isRunning()) {
- // focused row has been orphaned, can't focus
- getWidgetForPaintable().focusRowFromBody();
- }
- }
-
- getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl
- .getIntAttribute("tabindex") : 0;
- getWidgetForPaintable().setProperTabIndex();
-
- getWidgetForPaintable().resizeSortedColumnForSortIndicator();
-
- // Remember this to detect situations where overflow hack might be
- // needed during scrolling
- getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody
- .getOffsetHeight();
-
- getWidgetForPaintable().rendering = false;
- getWidgetForPaintable().headerChangedDuringUpdate = false;
-
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VScrollTable.class);
- }
-
- @Override
- public VScrollTable getWidgetForPaintable() {
- return (VScrollTable) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VScrollTablePaintable extends VAbstractPaintableWidgetContainer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
+ * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {
+ getWidgetForPaintable().serverCacheFirst = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);
+ getWidgetForPaintable().serverCacheLast = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);
+ } else {
+ getWidgetForPaintable().serverCacheFirst = -1;
+ getWidgetForPaintable().serverCacheLast = -1;
+ }
+ /*
+ * We need to do this before updateComponent since updateComponent calls
+ * this.setHeight() which will calculate a new body height depending on
+ * the space available.
+ */
+ if (uidl.hasAttribute("colfooters")) {
+ getWidgetForPaintable().showColFooters = uidl
+ .getBooleanAttribute("colfooters");
+ }
+
+ getWidgetForPaintable().tFoot
+ .setVisible(getWidgetForPaintable().showColFooters);
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
+
+ if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {
+ /*
+ * The disabled shim will not cover the table body if it is relative
+ * in IE8. See #7324
+ */
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.STATIC);
+ } else if (BrowserInfo.get().isIE8()) {
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.RELATIVE);
+ }
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+
+ int previousTotalRows = getWidgetForPaintable().totalRows;
+ getWidgetForPaintable().updateTotalRows(uidl);
+ boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);
+
+ getWidgetForPaintable().updateDragMode(uidl);
+
+ getWidgetForPaintable().updateSelectionProperties(uidl);
+
+ if (uidl.hasAttribute("alb")) {
+ getWidgetForPaintable().bodyActionKeys = uidl
+ .getStringArrayAttribute("alb");
+ } else {
+ // Need to clear the actions if the action handlers have been
+ // removed
+ getWidgetForPaintable().bodyActionKeys = null;
+ }
+
+ getWidgetForPaintable().setCacheRateFromUIDL(uidl);
+
+ getWidgetForPaintable().recalcWidths = uidl
+ .hasAttribute("recalcWidths");
+ if (getWidgetForPaintable().recalcWidths) {
+ getWidgetForPaintable().tHead.clear();
+ getWidgetForPaintable().tFoot.clear();
+ }
+
+ getWidgetForPaintable().updatePageLength(uidl);
+
+ getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);
+
+ getWidgetForPaintable().showRowHeaders = uidl
+ .getBooleanAttribute("rowheaders");
+ getWidgetForPaintable().showColHeaders = uidl
+ .getBooleanAttribute("colheaders");
+
+ getWidgetForPaintable().updateSortingProperties(uidl);
+
+ boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()
+ .selectSelectedRows(uidl);
+
+ getWidgetForPaintable().updateActionMap(uidl);
+
+ getWidgetForPaintable().updateColumnProperties(uidl);
+
+ UIDL ac = uidl.getChildByTagName("-ac");
+ if (ac == null) {
+ if (getWidgetForPaintable().dropHandler != null) {
+ // remove dropHandler if not present anymore
+ getWidgetForPaintable().dropHandler = null;
+ }
+ } else {
+ if (getWidgetForPaintable().dropHandler == null) {
+ getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();
+ }
+ getWidgetForPaintable().dropHandler.updateAcceptRules(ac);
+ }
+
+ UIDL partialRowAdditions = uidl.getChildByTagName("prows");
+ UIDL partialRowUpdates = uidl.getChildByTagName("urows");
+ if (partialRowUpdates != null || partialRowAdditions != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ getWidgetForPaintable().updateRowsInBody(partialRowUpdates);
+ getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);
+ } else {
+ UIDL rowData = uidl.getChildByTagName("rows");
+ if (rowData != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ if (!getWidgetForPaintable().recalcWidths
+ && getWidgetForPaintable().initializedAndAttached) {
+ getWidgetForPaintable().updateBody(rowData,
+ uidl.getIntAttribute("firstrow"),
+ uidl.getIntAttribute("rows"));
+ if (getWidgetForPaintable().headerChangedDuringUpdate) {
+ getWidgetForPaintable().triggerLazyColumnAdjustment(
+ true);
+ } else if (!getWidgetForPaintable()
+ .isScrollPositionVisible()
+ || totalRowsChanged
+ || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody
+ .getOffsetHeight()) {
+ // webkits may still bug with their disturbing scrollbar
+ // bug, see #3457
+ // Run overflow fix for the scrollable area
+ // #6698 - If there's a scroll going on, don't abort it
+ // by changing overflows as the length of the contents
+ // *shouldn't* have changed (unless the number of rows
+ // or the height of the widget has also changed)
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel
+ .getElement());
+ }
+ });
+ }
+ } else {
+ getWidgetForPaintable().initializeRows(uidl, rowData);
+ }
+ }
+ }
+
+ if (!getWidgetForPaintable().isSelectable()) {
+ getWidgetForPaintable().scrollBody
+ .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");
+ } else {
+ getWidgetForPaintable().scrollBody
+ .removeStyleName(VScrollTable.CLASSNAME
+ + "-body-noselection");
+ }
+
+ getWidgetForPaintable().hideScrollPositionAnnotation();
+ getWidgetForPaintable().purgeUnregistryBag();
+
+ // selection is no in sync with server, avoid excessive server visits by
+ // clearing to flag used during the normal operation
+ if (!keyboardSelectionOverRowFetchInProgress) {
+ getWidgetForPaintable().selectionChanged = false;
+ }
+
+ /*
+ * This is called when the Home or page up button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectFirstItemInNextRender
+ || getWidgetForPaintable().focusFirstItemInNextRender) {
+ getWidgetForPaintable().selectFirstRenderedRowInViewPort(
+ getWidgetForPaintable().focusFirstItemInNextRender);
+ getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;
+ }
+
+ /*
+ * This is called when the page down or end button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectLastItemInNextRender
+ || getWidgetForPaintable().focusLastItemInNextRender) {
+ getWidgetForPaintable().selectLastRenderedRowInViewPort(
+ getWidgetForPaintable().focusLastItemInNextRender);
+ getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;
+ }
+ getWidgetForPaintable().multiselectPending = false;
+
+ if (getWidgetForPaintable().focusedRow != null) {
+ if (!getWidgetForPaintable().focusedRow.isAttached()
+ && !getWidgetForPaintable().rowRequestHandler.isRunning()) {
+ // focused row has been orphaned, can't focus
+ getWidgetForPaintable().focusRowFromBody();
+ }
+ }
+
+ getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl
+ .getIntAttribute("tabindex") : 0;
+ getWidgetForPaintable().setProperTabIndex();
+
+ getWidgetForPaintable().resizeSortedColumnForSortIndicator();
+
+ // Remember this to detect situations where overflow hack might be
+ // needed during scrolling
+ getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody
+ .getOffsetHeight();
+
+ getWidgetForPaintable().rendering = false;
+ getWidgetForPaintable().headerChangedDuringUpdate = false;
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VScrollTable.class);
+ }
+
+ @Override
+ public VScrollTable getWidgetForPaintable() {
+ return (VScrollTable) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, not rendered
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
index 9fbbeb7181..d213a3826f 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java
@@ -1,517 +1,513 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-//
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-
-public class VSlider extends SimpleFocusablePanel implements Field,
- ContainerResizedListener {
-
- public static final String CLASSNAME = "v-slider";
-
- /**
- * Minimum size (width or height, depending on orientation) of the slider
- * base.
- */
- private static final int MIN_SIZE = 50;
-
- ApplicationConnection client;
-
- String id;
-
- boolean immediate;
- boolean disabled;
- boolean readonly;
-
- private int acceleration = 1;
- double min;
- double max;
- int resolution;
- Double value;
- boolean vertical;
-
- private final HTML feedback = new HTML("", false);
- private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
- @Override
- public void show() {
- super.show();
- updateFeedbackPosition();
- }
- };
-
- /* DOM element for slider's base */
- private final Element base;
- private final int BASE_BORDER_WIDTH = 1;
-
- /* DOM element for slider's handle */
- private final Element handle;
-
- /* DOM element for decrement arrow */
- private final Element smaller;
-
- /* DOM element for increment arrow */
- private final Element bigger;
-
- /* Temporary dragging/animation variables */
- private boolean dragging = false;
-
- private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
- new ScheduledCommand() {
-
- public void execute() {
- updateValueToServer();
- acceleration = 1;
- }
- });
-
- public VSlider() {
- super();
-
- base = DOM.createDiv();
- handle = DOM.createDiv();
- smaller = DOM.createDiv();
- bigger = DOM.createDiv();
-
- setStyleName(CLASSNAME);
- DOM.setElementProperty(base, "className", CLASSNAME + "-base");
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
- DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
- DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
-
- DOM.appendChild(getElement(), bigger);
- DOM.appendChild(getElement(), smaller);
- DOM.appendChild(getElement(), base);
- DOM.appendChild(base, handle);
-
- // Hide initially
- DOM.setStyleAttribute(smaller, "display", "none");
- DOM.setStyleAttribute(bigger, "display", "none");
- DOM.setStyleAttribute(handle, "visibility", "hidden");
-
- sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
- | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
-
- feedbackPopup.addStyleName(CLASSNAME + "-feedback");
- feedbackPopup.setWidget(feedback);
- }
-
- void setFeedbackValue(double value) {
- String currentValue = "" + value;
- if (resolution == 0) {
- currentValue = "" + new Double(value).intValue();
- }
- feedback.setText(currentValue);
- }
-
- private void updateFeedbackPosition() {
- if (vertical) {
- feedbackPopup.setPopupPosition(
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
- DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
- - feedbackPopup.getOffsetHeight() / 2);
- } else {
- feedbackPopup.setPopupPosition(
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
- - feedbackPopup.getOffsetWidth() / 2,
- DOM.getAbsoluteTop(handle)
- - feedbackPopup.getOffsetHeight());
- }
- }
-
- void buildBase() {
- final String styleAttribute = vertical ? "height" : "width";
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
-
- final Element p = DOM.getParent(getElement());
- if (DOM.getElementPropertyInt(p, domProperty) > 50) {
- if (vertical) {
- setHeight();
- } else {
- DOM.setStyleAttribute(base, styleAttribute, "");
- }
- } else {
- // Set minimum size and adjust after all components have
- // (supposedly) been drawn completely.
- DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- final Element p = DOM.getParent(getElement());
- if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
- if (vertical) {
- setHeight();
- } else {
- DOM.setStyleAttribute(base, styleAttribute, "");
- }
- // Ensure correct position
- setValue(value, false);
- }
- }
- });
- }
-
- // TODO attach listeners for focusing and arrow keys
- }
-
- void buildHandle() {
- final String handleAttribute = vertical ? "marginTop" : "marginLeft";
-
- DOM.setStyleAttribute(handle, handleAttribute, "0");
-
- // Restore visibility
- DOM.setStyleAttribute(handle, "visibility", "visible");
-
- }
-
- void setValue(Double value, boolean updateToServer) {
- if (value == null) {
- return;
- }
-
- if (value < min) {
- value = min;
- } else if (value > max) {
- value = max;
- }
-
- // Update handle position
- final String styleAttribute = vertical ? "marginTop" : "marginLeft";
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
- final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
- domProperty));
- final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
- domProperty)) - (2 * BASE_BORDER_WIDTH);
-
- final int range = baseSize - handleSize;
- double v = value.doubleValue();
-
- // Round value to resolution
- if (resolution > 0) {
- v = Math.round(v * Math.pow(10, resolution));
- v = v / Math.pow(10, resolution);
- } else {
- v = Math.round(v);
- }
- final double valueRange = max - min;
- double p = 0;
- if (valueRange > 0) {
- p = range * ((v - min) / valueRange);
- }
- if (p < 0) {
- p = 0;
- }
- if (vertical) {
- p = range - p;
- }
- final double pos = p;
-
- DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
-
- // Update value
- this.value = new Double(v);
- setFeedbackValue(v);
-
- if (updateToServer) {
- updateValueToServer();
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- if (disabled || readonly) {
- return;
- }
- final Element targ = DOM.eventGetTarget(event);
-
- if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
- processMouseWheelEvent(event);
- } else if (dragging || targ == handle) {
- processHandleEvent(event);
- } else if (targ == smaller) {
- decreaseValue(true);
- } else if (targ == bigger) {
- increaseValue(true);
- } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
- processBaseEvent(event);
- } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
- || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
-
- if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
- event.getShiftKey())) {
-
- feedbackPopup.show();
-
- delayedValueUpdater.trigger();
-
- DOM.eventPreventDefault(event);
- DOM.eventCancelBubble(event, true);
- }
- } else if (targ.equals(getElement())
- && DOM.eventGetType(event) == Event.ONFOCUS) {
- feedbackPopup.show();
- } else if (targ.equals(getElement())
- && DOM.eventGetType(event) == Event.ONBLUR) {
- feedbackPopup.hide();
- } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
- feedbackPopup.show();
- }
- if (Util.isTouchEvent(event)) {
- event.preventDefault(); // avoid simulated events
- event.stopPropagation();
- }
- }
-
- private void processMouseWheelEvent(final Event event) {
- final int dir = DOM.eventGetMouseWheelVelocityY(event);
-
- if (dir < 0) {
- increaseValue(false);
- } else {
- decreaseValue(false);
- }
-
- delayedValueUpdater.trigger();
-
- DOM.eventPreventDefault(event);
- DOM.eventCancelBubble(event, true);
- }
-
- private void processHandleEvent(Event event) {
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEDOWN:
- case Event.ONTOUCHSTART:
- if (!disabled && !readonly) {
- focus();
- feedbackPopup.show();
- dragging = true;
- DOM.setElementProperty(handle, "className", CLASSNAME
- + "-handle " + CLASSNAME + "-handle-active");
- DOM.setCapture(getElement());
- DOM.eventPreventDefault(event); // prevent selecting text
- DOM.eventCancelBubble(event, true);
- event.stopPropagation();
- VConsole.log("Slider move start");
- }
- break;
- case Event.ONMOUSEMOVE:
- case Event.ONTOUCHMOVE:
- if (dragging) {
- VConsole.log("Slider move");
- setValueByEvent(event, false);
- updateFeedbackPosition();
- event.stopPropagation();
- }
- break;
- case Event.ONTOUCHEND:
- feedbackPopup.hide();
- case Event.ONMOUSEUP:
- // feedbackPopup.hide();
- VConsole.log("Slider move end");
- dragging = false;
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
- DOM.releaseCapture(getElement());
- setValueByEvent(event, true);
- event.stopPropagation();
- break;
- default:
- break;
- }
- }
-
- private void processBaseEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
- if (!disabled && !readonly && !dragging) {
- setValueByEvent(event, true);
- DOM.eventCancelBubble(event, true);
- }
- }
- }
-
- private void decreaseValue(boolean updateToServer) {
- setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
- updateToServer);
- }
-
- private void increaseValue(boolean updateToServer) {
- setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
- updateToServer);
- }
-
- private void setValueByEvent(Event event, boolean updateToServer) {
- double v = min; // Fallback to min
-
- final int coord = getEventPosition(event);
-
- final int handleSize, baseSize, baseOffset;
- if (vertical) {
- handleSize = handle.getOffsetHeight();
- baseSize = base.getOffsetHeight();
- baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
- - handleSize / 2;
- } else {
- handleSize = handle.getOffsetWidth();
- baseSize = base.getOffsetWidth();
- baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
- + handleSize / 2;
- }
-
- if (vertical) {
- v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
- * (max - min) + min;
- } else {
- v = ((coord - baseOffset) / (double) (baseSize - handleSize))
- * (max - min) + min;
- }
-
- if (v < min) {
- v = min;
- } else if (v > max) {
- v = max;
- }
-
- setValue(v, updateToServer);
- }
-
- /**
- * TODO consider extracting touches support to an impl class specific for
- * webkit (only browser that really supports touches).
- *
- * @param event
- * @return
- */
- protected int getEventPosition(Event event) {
- if (vertical) {
- return Util.getTouchOrMouseClientY(event);
- } else {
- return Util.getTouchOrMouseClientX(event);
- }
- }
-
- public void iLayout() {
- if (vertical) {
- setHeight();
- }
- // Update handle position
- setValue(value, false);
- }
-
- private void setHeight() {
- // Calculate decoration size
- DOM.setStyleAttribute(base, "height", "0");
- DOM.setStyleAttribute(base, "overflow", "hidden");
- int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
- if (h < MIN_SIZE) {
- h = MIN_SIZE;
- }
- DOM.setStyleAttribute(base, "height", h + "px");
- DOM.setStyleAttribute(base, "overflow", "");
- }
-
- private void updateValueToServer() {
- client.updateVariable(id, "value", value.doubleValue(), immediate);
- }
-
- /**
- * Handles the keyboard events handled by the Slider
- *
- * @param event
- * The keyboard event received
- * @return true iff the navigation event was handled
- */
- public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
-
- // No support for ctrl moving
- if (ctrl) {
- return false;
- }
-
- if ((keycode == getNavigationUpKey() && vertical)
- || (keycode == getNavigationRightKey() && !vertical)) {
- if (shift) {
- for (int a = 0; a < acceleration; a++) {
- increaseValue(false);
- }
- acceleration++;
- } else {
- increaseValue(false);
- }
- return true;
- } else if (keycode == getNavigationDownKey() && vertical
- || (keycode == getNavigationLeftKey() && !vertical)) {
- if (shift) {
- for (int a = 0; a < acceleration; a++) {
- decreaseValue(false);
- }
- acceleration++;
- } else {
- decreaseValue(false);
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Get the key that increases the vertical slider. By default it is the up
- * arrow key but by overriding this you can change the key to whatever you
- * want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationUpKey() {
- return KeyCodes.KEY_UP;
- }
-
- /**
- * Get the key that decreases the vertical slider. By default it is the down
- * arrow key but by overriding this you can change the key to whatever you
- * want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationDownKey() {
- return KeyCodes.KEY_DOWN;
- }
-
- /**
- * Get the key that decreases the horizontal slider. By default it is the
- * left arrow key but by overriding this you can change the key to whatever
- * you want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationLeftKey() {
- return KeyCodes.KEY_LEFT;
- }
-
- /**
- * Get the key that increases the horizontal slider. By default it is the
- * right arrow key but by overriding this you can change the key to whatever
- * you want.
- *
- * @return The keycode of the key
- */
- protected int getNavigationRightKey() {
- return KeyCodes.KEY_RIGHT;
- }
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+//
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VSlider extends SimpleFocusablePanel implements Field,
+ ContainerResizedListener {
+
+ public static final String CLASSNAME = "v-slider";
+
+ /**
+ * Minimum size (width or height, depending on orientation) of the slider
+ * base.
+ */
+ private static final int MIN_SIZE = 50;
+
+ ApplicationConnection client;
+
+ String id;
+
+ boolean immediate;
+ boolean disabled;
+ boolean readonly;
+
+ private int acceleration = 1;
+ double min;
+ double max;
+ int resolution;
+ Double value;
+ boolean vertical;
+
+ private final HTML feedback = new HTML("", false);
+ private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
+ @Override
+ public void show() {
+ super.show();
+ updateFeedbackPosition();
+ }
+ };
+
+ /* DOM element for slider's base */
+ private final Element base;
+ private final int BASE_BORDER_WIDTH = 1;
+
+ /* DOM element for slider's handle */
+ private final Element handle;
+
+ /* DOM element for decrement arrow */
+ private final Element smaller;
+
+ /* DOM element for increment arrow */
+ private final Element bigger;
+
+ /* Temporary dragging/animation variables */
+ private boolean dragging = false;
+
+ private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
+ new ScheduledCommand() {
+
+ public void execute() {
+ updateValueToServer();
+ acceleration = 1;
+ }
+ });
+
+ public VSlider() {
+ super();
+
+ base = DOM.createDiv();
+ handle = DOM.createDiv();
+ smaller = DOM.createDiv();
+ bigger = DOM.createDiv();
+
+ setStyleName(CLASSNAME);
+ DOM.setElementProperty(base, "className", CLASSNAME + "-base");
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
+ DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
+
+ DOM.appendChild(getElement(), bigger);
+ DOM.appendChild(getElement(), smaller);
+ DOM.appendChild(getElement(), base);
+ DOM.appendChild(base, handle);
+
+ // Hide initially
+ DOM.setStyleAttribute(smaller, "display", "none");
+ DOM.setStyleAttribute(bigger, "display", "none");
+ DOM.setStyleAttribute(handle, "visibility", "hidden");
+
+ sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
+ | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
+
+ feedbackPopup.addStyleName(CLASSNAME + "-feedback");
+ feedbackPopup.setWidget(feedback);
+ }
+
+ void setFeedbackValue(double value) {
+ String currentValue = "" + value;
+ if (resolution == 0) {
+ currentValue = "" + new Double(value).intValue();
+ }
+ feedback.setText(currentValue);
+ }
+
+ private void updateFeedbackPosition() {
+ if (vertical) {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
+ DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
+ - feedbackPopup.getOffsetHeight() / 2);
+ } else {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
+ - feedbackPopup.getOffsetWidth() / 2,
+ DOM.getAbsoluteTop(handle)
+ - feedbackPopup.getOffsetHeight());
+ }
+ }
+
+ void buildBase() {
+ final String styleAttribute = vertical ? "height" : "width";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > 50) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ } else {
+ // Set minimum size and adjust after all components have
+ // (supposedly) been drawn completely.
+ DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ // Ensure correct position
+ setValue(value, false);
+ }
+ }
+ });
+ }
+
+ // TODO attach listeners for focusing and arrow keys
+ }
+
+ void buildHandle() {
+ final String handleAttribute = vertical ? "marginTop" : "marginLeft";
+
+ DOM.setStyleAttribute(handle, handleAttribute, "0");
+
+ // Restore visibility
+ DOM.setStyleAttribute(handle, "visibility", "visible");
+
+ }
+
+ void setValue(Double value, boolean updateToServer) {
+ if (value == null) {
+ return;
+ }
+
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+
+ // Update handle position
+ final String styleAttribute = vertical ? "marginTop" : "marginLeft";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+ final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
+ domProperty));
+ final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
+ domProperty)) - (2 * BASE_BORDER_WIDTH);
+
+ final int range = baseSize - handleSize;
+ double v = value.doubleValue();
+
+ // Round value to resolution
+ if (resolution > 0) {
+ v = Math.round(v * Math.pow(10, resolution));
+ v = v / Math.pow(10, resolution);
+ } else {
+ v = Math.round(v);
+ }
+ final double valueRange = max - min;
+ double p = 0;
+ if (valueRange > 0) {
+ p = range * ((v - min) / valueRange);
+ }
+ if (p < 0) {
+ p = 0;
+ }
+ if (vertical) {
+ p = range - p;
+ }
+ final double pos = p;
+
+ DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
+
+ // Update value
+ this.value = new Double(v);
+ setFeedbackValue(v);
+
+ if (updateToServer) {
+ updateValueToServer();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ if (disabled || readonly) {
+ return;
+ }
+ final Element targ = DOM.eventGetTarget(event);
+
+ if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
+ processMouseWheelEvent(event);
+ } else if (dragging || targ == handle) {
+ processHandleEvent(event);
+ } else if (targ == smaller) {
+ decreaseValue(true);
+ } else if (targ == bigger) {
+ increaseValue(true);
+ } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
+ processBaseEvent(event);
+ } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
+ || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
+
+ if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
+ event.getShiftKey())) {
+
+ feedbackPopup.show();
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONFOCUS) {
+ feedbackPopup.show();
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONBLUR) {
+ feedbackPopup.hide();
+ } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ feedbackPopup.show();
+ }
+ if (Util.isTouchEvent(event)) {
+ event.preventDefault(); // avoid simulated events
+ event.stopPropagation();
+ }
+ }
+
+ private void processMouseWheelEvent(final Event event) {
+ final int dir = DOM.eventGetMouseWheelVelocityY(event);
+
+ if (dir < 0) {
+ increaseValue(false);
+ } else {
+ decreaseValue(false);
+ }
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+
+ private void processHandleEvent(Event event) {
+ switch (DOM.eventGetType(event)) {
+ case Event.ONMOUSEDOWN:
+ case Event.ONTOUCHSTART:
+ if (!disabled && !readonly) {
+ focus();
+ feedbackPopup.show();
+ dragging = true;
+ DOM.setElementProperty(handle, "className", CLASSNAME
+ + "-handle " + CLASSNAME + "-handle-active");
+ DOM.setCapture(getElement());
+ DOM.eventPreventDefault(event); // prevent selecting text
+ DOM.eventCancelBubble(event, true);
+ event.stopPropagation();
+ VConsole.log("Slider move start");
+ }
+ break;
+ case Event.ONMOUSEMOVE:
+ case Event.ONTOUCHMOVE:
+ if (dragging) {
+ VConsole.log("Slider move");
+ setValueByEvent(event, false);
+ updateFeedbackPosition();
+ event.stopPropagation();
+ }
+ break;
+ case Event.ONTOUCHEND:
+ feedbackPopup.hide();
+ case Event.ONMOUSEUP:
+ // feedbackPopup.hide();
+ VConsole.log("Slider move end");
+ dragging = false;
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.releaseCapture(getElement());
+ setValueByEvent(event, true);
+ event.stopPropagation();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void processBaseEvent(Event event) {
+ if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ if (!disabled && !readonly && !dragging) {
+ setValueByEvent(event, true);
+ DOM.eventCancelBubble(event, true);
+ }
+ }
+ }
+
+ private void decreaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void increaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void setValueByEvent(Event event, boolean updateToServer) {
+ double v = min; // Fallback to min
+
+ final int coord = getEventPosition(event);
+
+ final int handleSize, baseSize, baseOffset;
+ if (vertical) {
+ handleSize = handle.getOffsetHeight();
+ baseSize = base.getOffsetHeight();
+ baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
+ - handleSize / 2;
+ } else {
+ handleSize = handle.getOffsetWidth();
+ baseSize = base.getOffsetWidth();
+ baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
+ + handleSize / 2;
+ }
+
+ if (vertical) {
+ v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ } else {
+ v = ((coord - baseOffset) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ }
+
+ if (v < min) {
+ v = min;
+ } else if (v > max) {
+ v = max;
+ }
+
+ setValue(v, updateToServer);
+ }
+
+ /**
+ * TODO consider extracting touches support to an impl class specific for
+ * webkit (only browser that really supports touches).
+ *
+ * @param event
+ * @return
+ */
+ protected int getEventPosition(Event event) {
+ if (vertical) {
+ return Util.getTouchOrMouseClientY(event);
+ } else {
+ return Util.getTouchOrMouseClientX(event);
+ }
+ }
+
+ public void iLayout() {
+ if (vertical) {
+ setHeight();
+ }
+ // Update handle position
+ setValue(value, false);
+ }
+
+ private void setHeight() {
+ // Calculate decoration size
+ DOM.setStyleAttribute(base, "height", "0");
+ DOM.setStyleAttribute(base, "overflow", "hidden");
+ int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
+ if (h < MIN_SIZE) {
+ h = MIN_SIZE;
+ }
+ DOM.setStyleAttribute(base, "height", h + "px");
+ DOM.setStyleAttribute(base, "overflow", "");
+ }
+
+ private void updateValueToServer() {
+ client.updateVariable(id, "value", value.doubleValue(), immediate);
+ }
+
+ /**
+ * Handles the keyboard events handled by the Slider
+ *
+ * @param event
+ * The keyboard event received
+ * @return true iff the navigation event was handled
+ */
+ public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
+
+ // No support for ctrl moving
+ if (ctrl) {
+ return false;
+ }
+
+ if ((keycode == getNavigationUpKey() && vertical)
+ || (keycode == getNavigationRightKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ increaseValue(false);
+ }
+ acceleration++;
+ } else {
+ increaseValue(false);
+ }
+ return true;
+ } else if (keycode == getNavigationDownKey() && vertical
+ || (keycode == getNavigationLeftKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ decreaseValue(false);
+ }
+ acceleration++;
+ } else {
+ decreaseValue(false);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the key that increases the vertical slider. By default it is the up
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationUpKey() {
+ return KeyCodes.KEY_UP;
+ }
+
+ /**
+ * Get the key that decreases the vertical slider. By default it is the down
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationDownKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Get the key that decreases the horizontal slider. By default it is the
+ * left arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationLeftKey() {
+ return KeyCodes.KEY_LEFT;
+ }
+
+ /**
+ * Get the key that increases the horizontal slider. By default it is the
+ * right arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationRightKey() {
+ return KeyCodes.KEY_RIGHT;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
index f5b8c8a45e..6c0dc74412 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSliderPaintable.java
@@ -1,78 +1,81 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VSliderPaintable extends VAbstractPaintableWidget {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- getWidgetForPaintable().client = client;
- getWidgetForPaintable().id = uidl.getId();
-
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- getWidgetForPaintable().immediate = uidl
- .getBooleanAttribute("immediate");
- getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
- getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
-
- getWidgetForPaintable().vertical = uidl.hasAttribute("vertical");
-
- String style = "";
- if (uidl.hasAttribute("style")) {
- style = uidl.getStringAttribute("style");
- }
-
- if (getWidgetForPaintable().vertical) {
- getWidgetForPaintable().addStyleName(
- VSlider.CLASSNAME + "-vertical");
- } else {
- getWidgetForPaintable().removeStyleName(
- VSlider.CLASSNAME + "-vertical");
- }
-
- getWidgetForPaintable().min = uidl.getDoubleAttribute("min");
- getWidgetForPaintable().max = uidl.getDoubleAttribute("max");
- getWidgetForPaintable().resolution = uidl.getIntAttribute("resolution");
- getWidgetForPaintable().value = new Double(
- uidl.getDoubleVariable("value"));
-
- getWidgetForPaintable().setFeedbackValue(getWidgetForPaintable().value);
-
- getWidgetForPaintable().buildBase();
-
- if (!getWidgetForPaintable().vertical) {
- // Draw handle with a delay to allow base to gain maximum width
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- getWidgetForPaintable().buildHandle();
- getWidgetForPaintable().setValue(
- getWidgetForPaintable().value, false);
- }
- });
- } else {
- getWidgetForPaintable().buildHandle();
- getWidgetForPaintable().setValue(getWidgetForPaintable().value,
- false);
- }
- }
-
- @Override
- public VSlider getWidgetForPaintable() {
- return (VSlider) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VSlider.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VSliderPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+
+ getWidgetForPaintable().vertical = uidl.hasAttribute("vertical");
+
+ String style = "";
+ if (uidl.hasAttribute("style")) {
+ style = uidl.getStringAttribute("style");
+ }
+
+ if (getWidgetForPaintable().vertical) {
+ getWidgetForPaintable().addStyleName(
+ VSlider.CLASSNAME + "-vertical");
+ } else {
+ getWidgetForPaintable().removeStyleName(
+ VSlider.CLASSNAME + "-vertical");
+ }
+
+ getWidgetForPaintable().min = uidl.getDoubleAttribute("min");
+ getWidgetForPaintable().max = uidl.getDoubleAttribute("max");
+ getWidgetForPaintable().resolution = uidl.getIntAttribute("resolution");
+ getWidgetForPaintable().value = new Double(
+ uidl.getDoubleVariable("value"));
+
+ getWidgetForPaintable().setFeedbackValue(getWidgetForPaintable().value);
+
+ getWidgetForPaintable().buildBase();
+
+ if (!getWidgetForPaintable().vertical) {
+ // Draw handle with a delay to allow base to gain maximum width
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ getWidgetForPaintable().buildHandle();
+ getWidgetForPaintable().setValue(
+ getWidgetForPaintable().value, false);
+ }
+ });
+ } else {
+ getWidgetForPaintable().buildHandle();
+ getWidgetForPaintable().setValue(getWidgetForPaintable().value,
+ false);
+ }
+ }
+
+ @Override
+ public VSlider getWidgetForPaintable() {
+ return (VSlider) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VSlider.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java
index ff1e2e6b78..3902f064a5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelHorizontal.java
@@ -4,9 +4,9 @@
package com.vaadin.terminal.gwt.client.ui;
-public class VSplitPanelHorizontal extends VSplitPanel {
+public class VSplitPanelHorizontal extends VAbstractSplitPanel {
public VSplitPanelHorizontal() {
- super(VSplitPanel.ORIENTATION_HORIZONTAL);
+ super(VAbstractSplitPanel.ORIENTATION_HORIZONTAL);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java
index dcf7622e50..e61f8cf5e5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanelVertical.java
@@ -4,9 +4,9 @@
package com.vaadin.terminal.gwt.client.ui;
-public class VSplitPanelVertical extends VSplitPanel {
+public class VSplitPanelVertical extends VAbstractSplitPanel {
public VSplitPanelVertical() {
- super(VSplitPanel.ORIENTATION_VERTICAL);
+ super(VAbstractSplitPanel.ORIENTATION_VERTICAL);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java b/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java
deleted file mode 100644
index cf35dc8e88..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Set;
-
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.SimplePanel;
-import com.google.gwt.user.client.ui.VerticalPanel;
-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;
-
-/**
- * TODO make this work (just an early prototype). We may want to have paging
- * style table which will be much lighter than VScrollTable is.
- */
-public class VTablePaging extends Composite implements Table, VPaintableWidget,
- ClickHandler {
-
- private final Grid tBody = new Grid();
- private final Button nextPage = new Button("&gt;");
- private final Button prevPage = new Button("&lt;");
- private final Button firstPage = new Button("&lt;&lt;");
- private final Button lastPage = new Button("&gt;&gt;");
-
- private int pageLength = 15;
-
- private boolean rowHeaders = false;
-
- private ApplicationConnection client;
- private String id;
-
- private boolean immediate = false;
-
- private int selectMode = Table.SELECT_MODE_NONE;
-
- private final ArrayList<String> selectedRowKeys = new ArrayList<String>();
-
- private int totalRows;
-
- private final HashMap<?, ?> visibleColumns = new HashMap<Object, Object>();
-
- private int rows;
-
- private int firstRow;
- private boolean sortAscending = true;
- private final HorizontalPanel pager;
-
- public HashMap<String, TableRow> rowKeysToTableRows = new HashMap<String, TableRow>();
-
- public VTablePaging() {
-
- tBody.setStyleName("itable-tbody");
-
- final VerticalPanel panel = new VerticalPanel();
-
- pager = new HorizontalPanel();
- pager.add(firstPage);
- firstPage.addClickHandler(this);
- pager.add(prevPage);
- prevPage.addClickHandler(this);
- pager.add(nextPage);
- nextPage.addClickHandler(this);
- pager.add(lastPage);
- lastPage.addClickHandler(this);
-
- panel.add(pager);
- panel.add(tBody);
-
- initWidget(panel);
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- this.client = client;
- id = uidl.getStringAttribute("id");
- immediate = uidl.getBooleanAttribute("immediate");
- totalRows = uidl.getIntAttribute("totalrows");
- pageLength = uidl.getIntAttribute("pagelength");
- firstRow = uidl.getIntAttribute("firstrow");
- rows = uidl.getIntAttribute("rows");
-
- if (uidl.hasAttribute("selectmode")) {
- if (uidl.getStringAttribute("selectmode").equals("multi")) {
- selectMode = Table.SELECT_MODE_MULTI;
- } else {
- selectMode = Table.SELECT_MODE_SINGLE;
- }
-
- if (uidl.hasAttribute("selected")) {
- final Set<String> selectedKeys = uidl
- .getStringArrayVariableAsSet("selected");
- selectedRowKeys.clear();
- for (final Iterator<String> it = selectedKeys.iterator(); it
- .hasNext();) {
- selectedRowKeys.add(it.next());
- }
- }
- }
-
- if (uidl.hasVariable("sortascending")) {
- sortAscending = uidl.getBooleanVariable("sortascending");
- }
-
- if (uidl.hasAttribute("rowheaders")) {
- rowHeaders = true;
- }
-
- UIDL rowData = null;
- UIDL visibleColumns = null;
- for (final Iterator<?> it = uidl.getChildIterator(); it.hasNext();) {
- final UIDL c = (UIDL) it.next();
- if (c.getTag().equals("rows")) {
- rowData = c;
- } else if (c.getTag().equals("actions")) {
- updateActionMap(c);
- } else if (c.getTag().equals("visiblecolumns")) {
- visibleColumns = c;
- }
- }
- tBody.resize(rows + 1, uidl.getIntAttribute("cols")
- + (rowHeaders ? 1 : 0));
- updateHeader(visibleColumns);
- updateBody(rowData);
-
- updatePager();
- }
-
- private void updateHeader(UIDL c) {
- final Iterator<?> it = c.getChildIterator();
- visibleColumns.clear();
- int colIndex = (rowHeaders ? 1 : 0);
- while (it.hasNext()) {
- final UIDL col = (UIDL) it.next();
- final String cid = col.getStringAttribute("cid");
- if (!col.hasAttribute("collapsed")) {
- tBody.setWidget(0, colIndex,
- new HeaderCell(cid, col.getStringAttribute("caption")));
-
- }
- colIndex++;
- }
- }
-
- private void updateActionMap(UIDL c) {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * Updates row data from uidl. UpdateFromUIDL delegates updating tBody to
- * this method.
- *
- * Updates may be to different part of tBody, depending on update type. It
- * can be initial row data, scroll up, scroll down...
- *
- * @param uidl
- * which contains row data
- */
- private void updateBody(UIDL uidl) {
- final Iterator<?> it = uidl.getChildIterator();
-
- int curRowIndex = 1;
- while (it.hasNext()) {
- final UIDL rowUidl = (UIDL) it.next();
- final TableRow row = new TableRow(curRowIndex,
- String.valueOf(rowUidl.getIntAttribute("key")),
- rowUidl.hasAttribute("selected"));
- int colIndex = 0;
- if (rowHeaders) {
- tBody.setWidget(curRowIndex, colIndex, new BodyCell(row,
- rowUidl.getStringAttribute("caption")));
- colIndex++;
- }
- final Iterator<?> cells = rowUidl.getChildIterator();
- while (cells.hasNext()) {
- final Object cell = cells.next();
- if (cell instanceof String) {
- tBody.setWidget(curRowIndex, colIndex, new BodyCell(row,
- (String) cell));
- } else {
- final VPaintableWidget cellContent = client
- .getPaintable((UIDL) cell);
- final BodyCell bodyCell = new BodyCell(row);
- bodyCell.setWidget(cellContent.getWidgetForPaintable());
- tBody.setWidget(curRowIndex, colIndex, bodyCell);
- }
- colIndex++;
- }
- curRowIndex++;
- }
- }
-
- private void updatePager() {
- if (pageLength == 0) {
- pager.setVisible(false);
- return;
- }
- if (isFirstPage()) {
- firstPage.setEnabled(false);
- prevPage.setEnabled(false);
- } else {
- firstPage.setEnabled(true);
- prevPage.setEnabled(true);
- }
- if (hasNextPage()) {
- nextPage.setEnabled(true);
- lastPage.setEnabled(true);
- } else {
- nextPage.setEnabled(false);
- lastPage.setEnabled(false);
-
- }
- }
-
- private boolean hasNextPage() {
- if (firstRow + rows + 1 > totalRows) {
- return false;
- }
- return true;
- }
-
- private boolean isFirstPage() {
- if (firstRow == 0) {
- return true;
- }
- return false;
- }
-
- public void onClick(ClickEvent event) {
- Object sender = event.getSource();
- if (sender instanceof Button) {
- if (sender == firstPage) {
- client.updateVariable(id, "firstvisible", 0, true);
- } else if (sender == nextPage) {
- client.updateVariable(id, "firstvisible",
- firstRow + pageLength, true);
- } else if (sender == prevPage) {
- int newFirst = firstRow - pageLength;
- if (newFirst < 0) {
- newFirst = 0;
- }
- client.updateVariable(id, "firstvisible", newFirst, true);
- } else if (sender == lastPage) {
- client.updateVariable(id, "firstvisible", totalRows
- - pageLength, true);
- }
- }
- if (sender instanceof HeaderCell) {
- final HeaderCell hCell = (HeaderCell) sender;
- client.updateVariable(id, "sortcolumn", hCell.getCid(), false);
- client.updateVariable(id, "sortascending", (sortAscending ? false
- : true), true);
- }
- }
-
- private class HeaderCell extends HTML {
-
- private String cid;
-
- public String getCid() {
- return cid;
- }
-
- public void setCid(String pid) {
- cid = pid;
- }
-
- HeaderCell(String pid, String caption) {
- super();
- cid = pid;
- addClickHandler(VTablePaging.this);
- setText(caption);
- // TODO remove debug color
- DOM.setStyleAttribute(getElement(), "color", "brown");
- DOM.setStyleAttribute(getElement(), "font-weight", "bold");
- }
- }
-
- /**
- * Abstraction of table cell content. In needs to know on which row it is in
- * case of context click.
- *
- * @author mattitahvonen
- */
- public class BodyCell extends SimplePanel {
- private final TableRow row;
-
- public BodyCell(TableRow row) {
- super();
- sinkEvents(Event.BUTTON_LEFT | Event.BUTTON_RIGHT);
- this.row = row;
- }
-
- public BodyCell(TableRow row2, String textContent) {
- super();
- sinkEvents(Event.BUTTON_LEFT | Event.BUTTON_RIGHT);
- row = row2;
- setWidget(new Label(textContent));
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- System.out.println("CEll event: " + event.toString());
- switch (DOM.eventGetType(event)) {
- case Event.BUTTON_RIGHT:
- row.showContextMenu(event);
- Window.alert("context menu un-implemented");
- DOM.eventCancelBubble(event, true);
- break;
- case Event.BUTTON_LEFT:
- if (selectMode > Table.SELECT_MODE_NONE) {
- row.toggleSelected();
- }
- break;
- default:
- break;
- }
- super.onBrowserEvent(event);
- }
- }
-
- private class TableRow {
-
- private final String key;
- private final int rowIndex;
- private boolean selected = false;
-
- public TableRow(int rowIndex, String rowKey, boolean selected) {
- rowKeysToTableRows.put(rowKey, this);
- this.rowIndex = rowIndex;
- key = rowKey;
- setSelected(selected);
- }
-
- /**
- * This method is used to set row status. Does not change value on
- * server.
- *
- * @param selected
- */
- public void setSelected(boolean sel) {
- selected = sel;
- if (selected) {
- selectedRowKeys.add(key);
- DOM.setStyleAttribute(
- tBody.getRowFormatter().getElement(rowIndex),
- "background", "yellow");
-
- } else {
- selectedRowKeys.remove(key);
- DOM.setStyleAttribute(
- tBody.getRowFormatter().getElement(rowIndex),
- "background", "transparent");
- }
- }
-
- public void setContextMenuOptions(HashMap<?, ?> options) {
-
- }
-
- /**
- * Toggles rows select state. Also updates state to server according to
- * tables immediate flag.
- *
- */
- public void toggleSelected() {
- if (selected) {
- setSelected(false);
- } else {
- if (selectMode == Table.SELECT_MODE_SINGLE) {
- deselectAll();
- }
- setSelected(true);
- }
- client.updateVariable(
- id,
- "selected",
- selectedRowKeys.toArray(new String[selectedRowKeys.size()]),
- immediate);
- }
-
- /**
- * Shows context menu for this row.
- *
- * @param event
- * Event which triggered context menu. Correct place for
- * context menu can be determined with it.
- */
- public void showContextMenu(Event event) {
- System.out.println("TODO: Show context menu");
- }
- }
-
- public void deselectAll() {
- final Object[] keys = selectedRowKeys.toArray();
- for (int i = 0; i < keys.length; i++) {
- final TableRow tableRow = rowKeysToTableRows.get(keys[i]);
- if (tableRow != null) {
- tableRow.setSelected(false);
- }
- }
- // still ensure all selects are removed from
- selectedRowKeys.clear();
- }
-
- public void add(Widget w) {
- // TODO Auto-generated method stub
-
- }
-
- public void clear() {
- // TODO Auto-generated method stub
-
- }
-
- public Iterator<Widget> iterator() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public boolean remove(Widget w) {
- // TODO Auto-generated method stub
- return false;
- }
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
index 74ff328710..809c1a0380 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
@@ -54,7 +54,7 @@ public class VTabsheet extends VTabsheetBase {
/**
* Representation of a single "tab" shown in the TabBar
- *
+ *
*/
private static class Tab extends SimplePanel {
private static final String TD_CLASSNAME = CLASSNAME + "-tabitemcell";
@@ -206,9 +206,10 @@ public class VTabsheet extends VTabsheetBase {
if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
tooltipInfo.setErrorUidl(uidl.getErrors());
}
- client.registerTooltip(getTabsheet(), getElement(), tooltipInfo);
+ client.registerWidgetTooltip(getTabsheet(), getElement(),
+ tooltipInfo);
} else {
- client.registerTooltip(getTabsheet(), getElement(), null);
+ client.registerWidgetTooltip(getTabsheet(), getElement(), null);
}
boolean ret = super.updateCaption(uidl);
@@ -236,7 +237,7 @@ public class VTabsheet extends VTabsheetBase {
if (event.getTypeInt() == Event.ONLOAD) {
getTabsheet().tabSizeMightHaveChanged(getTab());
}
- client.handleTooltipEvent(event, getTabsheet(), getElement());
+ client.handleWidgetTooltipEvent(event, getTabsheet(), getElement());
}
public Tab getTab() {
@@ -469,7 +470,7 @@ public class VTabsheet extends VTabsheetBase {
// Can't use "style" as it's already in use
public static final String TAB_STYLE_NAME = "tabstyle";
- private final Element tabs; // tabbar and 'scroller' container
+ final Element tabs; // tabbar and 'scroller' container
private final Element scroller; // tab-scroller element
private final Element scrollerNext; // tab-scroller next button element
private final Element scrollerPrev; // tab-scroller prev button element
@@ -480,15 +481,15 @@ public class VTabsheet extends VTabsheetBase {
private int scrollerIndex = 0;
private final TabBar tb = new TabBar(this);
- private final VTabsheetPanel tp = new VTabsheetPanel();
+ final VTabsheetPanel tp = new VTabsheetPanel();
private final Element contentNode, deco;
private String height;
private String width;
- private boolean waitingForResponse;
+ boolean waitingForResponse;
- private final RenderInformation renderInformation = new RenderInformation();
+ final RenderInformation renderInformation = new RenderInformation();
/**
* Previous visible widget is set invisible with CSS (not display: none, but
@@ -497,7 +498,7 @@ public class VTabsheet extends VTabsheetBase {
*/
private Widget previousVisibleWidget;
- private boolean rendering = false;
+ boolean rendering = false;
private String currentStyle;
@@ -545,11 +546,11 @@ public class VTabsheet extends VTabsheetBase {
client.updateVariable(id, "close", tabKeys.get(tabIndex), true);
}
- private boolean isDynamicWidth() {
+ boolean isDynamicWidth() {
return width == null || width.equals("");
}
- private boolean isDynamicHeight() {
+ boolean isDynamicHeight() {
return height == null || height.equals("");
}
@@ -633,60 +634,7 @@ public class VTabsheet extends VTabsheetBase {
return scrollerIndex > index;
}
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
-
- if (!uidl.getBooleanAttribute("cached")) {
- // Handle stylename changes before generics (might affect size
- // calculations)
- handleStyleNames(uidl);
- }
-
- super.updateFromUIDL(uidl, client);
- if (cachedUpdate) {
- rendering = false;
- return;
- }
-
- // tabs; push or not
- if (!isDynamicWidth()) {
- // FIXME: This makes tab sheet tabs go to 1px width on every update
- // and then back to original width
- // update width later, in updateTabScroller();
- DOM.setStyleAttribute(tabs, "width", "1px");
- DOM.setStyleAttribute(tabs, "overflow", "hidden");
- } else {
- showAllTabs();
- DOM.setStyleAttribute(tabs, "width", "");
- DOM.setStyleAttribute(tabs, "overflow", "visible");
- updateDynamicWidth();
- }
-
- if (!isDynamicHeight()) {
- // Must update height after the styles have been set
- updateContentNodeHeight();
- updateOpenTabSize();
- }
-
- iLayout();
-
- // Re run relative size update to ensure optimal scrollbars
- // TODO isolate to situation that visible tab has undefined height
- try {
- client.handleComponentRelativeSize(tp.getWidget(tp
- .getVisibleWidget()));
- } catch (Exception e) {
- // Ignore, most likely empty tabsheet
- }
-
- renderInformation.updateSize(getElement());
-
- waitingForResponse = false;
- rendering = false;
- }
-
- private void handleStyleNames(UIDL uidl) {
+ void handleStyleNames(UIDL uidl) {
// Add proper stylenames for all elements (easier to prevent unwanted
// style inheritance)
if (uidl.hasAttribute("style")) {
@@ -728,7 +676,7 @@ public class VTabsheet extends VTabsheetBase {
}
}
- private void updateDynamicWidth() {
+ void updateDynamicWidth() {
// Find width consumed by tabs
TableCellElement spacerCell = ((TableElement) tb.getElement().cast())
.getRows().getItem(0).getCells().getItem(tb.getTabCount());
@@ -923,7 +871,7 @@ public class VTabsheet extends VTabsheetBase {
}
}
- private void updateContentNodeHeight() {
+ void updateContentNodeHeight() {
if (height != null && !"".equals(height)) {
int contentHeight = getOffsetHeight();
contentHeight -= DOM.getElementPropertyInt(deco, "offsetHeight");
@@ -990,7 +938,7 @@ public class VTabsheet extends VTabsheetBase {
* position: absolute (to work around a firefox flickering bug) we must keep
* this up-to-date by hand.
*/
- private void updateOpenTabSize() {
+ void updateOpenTabSize() {
/*
* The overflow=auto element must have a height specified, otherwise it
* will be just as high as the contents and no scrollbars will appear
@@ -1066,7 +1014,7 @@ public class VTabsheet extends VTabsheetBase {
}
- private void showAllTabs() {
+ void showAllTabs() {
scrollerIndex = tb.getFirstVisibleTab();
for (int i = 0; i < tb.getTabCount(); i++) {
Tab t = tb.getTab(i);
@@ -1114,10 +1062,6 @@ public class VTabsheet extends VTabsheetBase {
tp.replaceComponent(oldComponent, newComponent);
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- /* Tabsheet does not render its children's captions */
- }
-
public boolean requestLayout(Set<Widget> children) {
if (!isDynamicHeight() && !isDynamicWidth()) {
/*
@@ -1193,8 +1137,4 @@ public class VTabsheet extends VTabsheetBase {
tp.remove(index);
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java
index 9dd74474f3..271aed1859 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java
@@ -14,7 +14,6 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
abstract class VTabsheetBase extends ComplexPanel implements Container {
@@ -34,81 +33,6 @@ abstract class VTabsheetBase extends ComplexPanel implements Container {
setStyleName(classname);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
-
- // Ensure correct implementation
- cachedUpdate = client.updateComponent(this, uidl, true);
- if (cachedUpdate) {
- return;
- }
-
- // Update member references
- id = uidl.getId();
- disabled = uidl.hasAttribute("disabled");
-
- // Render content
- final UIDL tabs = uidl.getChildUIDL(0);
-
- // Paintables in the TabSheet before update
- ArrayList<Widget> oldWidgets = new ArrayList<Widget>();
- for (Iterator<Widget> iterator = getWidgetIterator(); iterator
- .hasNext();) {
- oldWidgets.add(iterator.next());
- }
-
- // Clear previous values
- tabKeys.clear();
- disabledTabKeys.clear();
-
- int index = 0;
- for (final Iterator<Object> it = tabs.getChildIterator(); it.hasNext();) {
- final UIDL tab = (UIDL) it.next();
- final String key = tab.getStringAttribute("key");
- final boolean selected = tab.getBooleanAttribute("selected");
- final boolean hidden = tab.getBooleanAttribute("hidden");
-
- if (tab.getBooleanAttribute("disabled")) {
- disabledTabKeys.add(key);
- }
-
- tabKeys.add(key);
-
- if (selected) {
- activeTabIndex = index;
- }
- renderTab(tab, index, selected, hidden);
- index++;
- }
-
- int tabCount = getTabCount();
- while (tabCount-- > index) {
- removeTab(index);
- }
-
- for (int i = 0; i < getTabCount(); i++) {
- VPaintableWidget p = getTab(i);
- // During the initial rendering the paintable might be null (this is
- // weird...)
- if (p != null) {
- oldWidgets.remove(p.getWidgetForPaintable());
- }
- }
-
- // Perform unregister for any paintables removed during update
- for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
- .hasNext();) {
- Widget oldWidget = iterator.next();
- VPaintableWidget oldPaintable = VPaintableMap.get(client)
- .getPaintable(oldWidget);
- if (oldWidget.isAttached()) {
- oldWidget.removeFromParent();
- }
- VPaintableMap.get(client).unregisterPaintable(oldPaintable);
- }
-
- }
-
/**
* @return a list of currently shown Paintables
*
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java
new file mode 100644
index 0000000000..79f6012ed1
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBasePaintable.java
@@ -0,0 +1,99 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public abstract class VTabsheetBasePaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+
+ // Ensure correct implementation
+ getWidgetForPaintable().cachedUpdate = client.updateComponent(this,
+ uidl, true);
+ if (getWidgetForPaintable().cachedUpdate) {
+ return;
+ }
+
+ // Update member references
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().disabled = uidl.hasAttribute("disabled");
+
+ // Render content
+ final UIDL tabs = uidl.getChildUIDL(0);
+
+ // Paintables in the TabSheet before update
+ ArrayList<Widget> oldWidgets = new ArrayList<Widget>();
+ for (Iterator<Widget> iterator = getWidgetForPaintable()
+ .getWidgetIterator(); iterator.hasNext();) {
+ oldWidgets.add(iterator.next());
+ }
+
+ // Clear previous values
+ getWidgetForPaintable().tabKeys.clear();
+ getWidgetForPaintable().disabledTabKeys.clear();
+
+ int index = 0;
+ for (final Iterator<Object> it = tabs.getChildIterator(); it.hasNext();) {
+ final UIDL tab = (UIDL) it.next();
+ final String key = tab.getStringAttribute("key");
+ final boolean selected = tab.getBooleanAttribute("selected");
+ final boolean hidden = tab.getBooleanAttribute("hidden");
+
+ if (tab.getBooleanAttribute("disabled")) {
+ getWidgetForPaintable().disabledTabKeys.add(key);
+ }
+
+ getWidgetForPaintable().tabKeys.add(key);
+
+ if (selected) {
+ getWidgetForPaintable().activeTabIndex = index;
+ }
+ getWidgetForPaintable().renderTab(tab, index, selected, hidden);
+ index++;
+ }
+
+ int tabCount = getWidgetForPaintable().getTabCount();
+ while (tabCount-- > index) {
+ getWidgetForPaintable().removeTab(index);
+ }
+
+ for (int i = 0; i < getWidgetForPaintable().getTabCount(); i++) {
+ VPaintableWidget p = getWidgetForPaintable().getTab(i);
+ // During the initial rendering the paintable might be null (this is
+ // weird...)
+ if (p != null) {
+ oldWidgets.remove(p.getWidgetForPaintable());
+ }
+ }
+
+ // Perform unregister for any paintables removed during update
+ for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
+ .hasNext();) {
+ Widget oldWidget = iterator.next();
+ VPaintableWidget oldPaintable = VPaintableMap.get(client)
+ .getPaintable(oldWidget);
+ if (oldWidget.isAttached()) {
+ oldWidget.removeFromParent();
+ }
+ VPaintableMap.get(client).unregisterPaintable(oldPaintable);
+ }
+
+ }
+
+ @Override
+ public VTabsheetBase getWidgetForPaintable() {
+ return (VTabsheetBase) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java
new file mode 100644
index 0000000000..0d32484e10
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPaintable.java
@@ -0,0 +1,85 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VTabsheetPaintable extends VTabsheetBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (!uidl.getBooleanAttribute("cached")) {
+ // Handle stylename changes before generics (might affect size
+ // calculations)
+ getWidgetForPaintable().handleStyleNames(uidl);
+ }
+
+ super.updateFromUIDL(uidl, client);
+ if (getWidgetForPaintable().cachedUpdate) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ // tabs; push or not
+ if (!getWidgetForPaintable().isDynamicWidth()) {
+ // FIXME: This makes tab sheet tabs go to 1px width on every update
+ // and then back to original width
+ // update width later, in updateTabScroller();
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "1px");
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
+ "hidden");
+ } else {
+ getWidgetForPaintable().showAllTabs();
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "width", "");
+ DOM.setStyleAttribute(getWidgetForPaintable().tabs, "overflow",
+ "visible");
+ getWidgetForPaintable().updateDynamicWidth();
+ }
+
+ if (!getWidgetForPaintable().isDynamicHeight()) {
+ // Must update height after the styles have been set
+ getWidgetForPaintable().updateContentNodeHeight();
+ getWidgetForPaintable().updateOpenTabSize();
+ }
+
+ getWidgetForPaintable().iLayout();
+
+ // Re run relative size update to ensure optimal scrollbars
+ // TODO isolate to situation that visible tab has undefined height
+ try {
+ client.handleComponentRelativeSize(getWidgetForPaintable().tp
+ .getWidget(getWidgetForPaintable().tp.getVisibleWidget()));
+ } catch (Exception e) {
+ // Ignore, most likely empty tabsheet
+ }
+
+ getWidgetForPaintable().renderInformation
+ .updateSize(getWidgetForPaintable().getElement());
+
+ getWidgetForPaintable().waitingForResponse = false;
+ getWidgetForPaintable().rendering = false;
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTabsheet.class);
+ }
+
+ @Override
+ public VTabsheet getWidgetForPaintable() {
+ return (VTabsheet) super.getWidgetForPaintable();
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ /* Tabsheet does not render its children's captions */
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
index c33daed440..126b0ebea1 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
@@ -1,214 +1,214 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.event.dom.client.TouchStartEvent;
-import com.google.gwt.event.dom.client.TouchStartHandler;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.ComplexPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.Util;
-
-/**
- * A panel that displays all of its child widgets in a 'deck', where only one
- * can be visible at a time. It is used by
- * {@link com.vaadin.terminal.gwt.client.ui.VTabsheet}.
- *
- * This class has the same basic functionality as the GWT DeckPanel
- * {@link com.google.gwt.user.client.ui.DeckPanel}, with the exception that it
- * doesn't manipulate the child widgets' width and height attributes.
- */
-public class VTabsheetPanel extends ComplexPanel {
-
- private Widget visibleWidget;
- private TouchScrollDelegate touchScrollDelegate;
-
- /**
- * Creates an empty tabsheet panel.
- */
- public VTabsheetPanel() {
- setElement(DOM.createDiv());
- sinkEvents(Event.TOUCHEVENTS);
- addDomHandler(new TouchStartHandler() {
- public void onTouchStart(TouchStartEvent event) {
- /*
- * All container elements needs to be scrollable by one finger.
- * Update the scrollable element list of touch delegate on each
- * touch start.
- */
- NodeList<Node> childNodes = getElement().getChildNodes();
- Element[] elements = new Element[childNodes.getLength()];
- for (int i = 0; i < elements.length; i++) {
- elements[i] = (Element) childNodes.getItem(i);
- }
- getTouchScrollDelegate().setElements(elements);
- getTouchScrollDelegate().onTouchStart(event);
- }
- }, TouchStartEvent.getType());
- }
-
- protected TouchScrollDelegate getTouchScrollDelegate() {
- if (touchScrollDelegate == null) {
- touchScrollDelegate = new TouchScrollDelegate();
- }
- return touchScrollDelegate;
-
- }
-
- /**
- * Adds the specified widget to the deck.
- *
- * @param w
- * the widget to be added
- */
- @Override
- public void add(Widget w) {
- Element el = createContainerElement();
- DOM.appendChild(getElement(), el);
- super.add(w, el);
- }
-
- private Element createContainerElement() {
- Element el = DOM.createDiv();
- DOM.setStyleAttribute(el, "position", "absolute");
- DOM.setStyleAttribute(el, "overflow", "auto");
- hide(el);
- return el;
- }
-
- /**
- * Gets the index of the currently-visible widget.
- *
- * @return the visible widget's index
- */
- public int getVisibleWidget() {
- return getWidgetIndex(visibleWidget);
- }
-
- /**
- * Inserts a widget before the specified index.
- *
- * @param w
- * the widget to be inserted
- * @param beforeIndex
- * the index before which it will be inserted
- * @throws IndexOutOfBoundsException
- * if <code>beforeIndex</code> is out of range
- */
- public void insert(Widget w, int beforeIndex) {
- Element el = createContainerElement();
- DOM.insertChild(getElement(), el, beforeIndex);
- super.insert(w, el, beforeIndex, false);
- }
-
- @Override
- public boolean remove(Widget w) {
- Element child = w.getElement();
- Element parent = null;
- if (child != null) {
- parent = DOM.getParent(child);
- }
- final boolean removed = super.remove(w);
- if (removed) {
- if (visibleWidget == w) {
- visibleWidget = null;
- }
- if (parent != null) {
- DOM.removeChild(getElement(), parent);
- }
- }
- return removed;
- }
-
- /**
- * Shows the widget at the specified index. This causes the currently-
- * visible widget to be hidden.
- *
- * @param index
- * the index of the widget to be shown
- */
- public void showWidget(int index) {
- checkIndexBoundsForAccess(index);
- Widget newVisible = getWidget(index);
- if (visibleWidget != newVisible) {
- if (visibleWidget != null) {
- hide(DOM.getParent(visibleWidget.getElement()));
- }
- visibleWidget = newVisible;
- unHide(DOM.getParent(visibleWidget.getElement()));
- }
- }
-
- private void hide(Element e) {
- DOM.setStyleAttribute(e, "visibility", "hidden");
- DOM.setStyleAttribute(e, "top", "-100000px");
- DOM.setStyleAttribute(e, "left", "-100000px");
- }
-
- private void unHide(Element e) {
- DOM.setStyleAttribute(e, "top", "0px");
- DOM.setStyleAttribute(e, "left", "0px");
- DOM.setStyleAttribute(e, "visibility", "");
- }
-
- public void fixVisibleTabSize(int width, int height, int minWidth) {
- if (visibleWidget == null) {
- return;
- }
-
- boolean dynamicHeight = false;
-
- if (height < 0) {
- height = visibleWidget.getOffsetHeight();
- dynamicHeight = true;
- }
- if (width < 0) {
- width = visibleWidget.getOffsetWidth();
- }
- if (width < minWidth) {
- width = minWidth;
- }
-
- Element wrapperDiv = (Element) visibleWidget.getElement()
- .getParentElement();
-
- // width first
- getElement().getStyle().setPropertyPx("width", width);
- wrapperDiv.getStyle().setPropertyPx("width", width);
-
- if (dynamicHeight) {
- // height of widget might have changed due wrapping
- height = visibleWidget.getOffsetHeight();
- }
- // v-tabsheet-tabsheetpanel height
- getElement().getStyle().setPropertyPx("height", height);
-
- // widget wrapper height
- wrapperDiv.getStyle().setPropertyPx("height", height);
- runWebkitOverflowAutoFix();
- }
-
- public void runWebkitOverflowAutoFix() {
- if (visibleWidget != null) {
- Util.runWebkitOverflowAutoFix(DOM.getParent(visibleWidget
- .getElement()));
- }
-
- }
-
- public void replaceComponent(Widget oldComponent, Widget newComponent) {
- boolean isVisible = (visibleWidget == oldComponent);
- int widgetIndex = getWidgetIndex(oldComponent);
- remove(oldComponent);
- insert(newComponent, widgetIndex);
- if (isVisible) {
- showWidget(widgetIndex);
- }
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.event.dom.client.TouchStartEvent;
+import com.google.gwt.event.dom.client.TouchStartHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.Util;
+
+/**
+ * A panel that displays all of its child widgets in a 'deck', where only one
+ * can be visible at a time. It is used by
+ * {@link com.vaadin.terminal.gwt.client.ui.VTabsheet}.
+ *
+ * This class has the same basic functionality as the GWT DeckPanel
+ * {@link com.google.gwt.user.client.ui.DeckPanel}, with the exception that it
+ * doesn't manipulate the child widgets' width and height attributes.
+ */
+public class VTabsheetPanel extends ComplexPanel {
+
+ private Widget visibleWidget;
+ private TouchScrollDelegate touchScrollDelegate;
+
+ /**
+ * Creates an empty tabsheet panel.
+ */
+ public VTabsheetPanel() {
+ setElement(DOM.createDiv());
+ sinkEvents(Event.TOUCHEVENTS);
+ addDomHandler(new TouchStartHandler() {
+ public void onTouchStart(TouchStartEvent event) {
+ /*
+ * All container elements needs to be scrollable by one finger.
+ * Update the scrollable element list of touch delegate on each
+ * touch start.
+ */
+ NodeList<Node> childNodes = getElement().getChildNodes();
+ Element[] elements = new Element[childNodes.getLength()];
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = (Element) childNodes.getItem(i);
+ }
+ getTouchScrollDelegate().setElements(elements);
+ getTouchScrollDelegate().onTouchStart(event);
+ }
+ }, TouchStartEvent.getType());
+ }
+
+ protected TouchScrollDelegate getTouchScrollDelegate() {
+ if (touchScrollDelegate == null) {
+ touchScrollDelegate = new TouchScrollDelegate();
+ }
+ return touchScrollDelegate;
+
+ }
+
+ /**
+ * Adds the specified widget to the deck.
+ *
+ * @param w
+ * the widget to be added
+ */
+ @Override
+ public void add(Widget w) {
+ Element el = createContainerElement();
+ DOM.appendChild(getElement(), el);
+ super.add(w, el);
+ }
+
+ private Element createContainerElement() {
+ Element el = DOM.createDiv();
+ DOM.setStyleAttribute(el, "position", "absolute");
+ DOM.setStyleAttribute(el, "overflow", "auto");
+ hide(el);
+ return el;
+ }
+
+ /**
+ * Gets the index of the currently-visible widget.
+ *
+ * @return the visible widget's index
+ */
+ public int getVisibleWidget() {
+ return getWidgetIndex(visibleWidget);
+ }
+
+ /**
+ * Inserts a widget before the specified index.
+ *
+ * @param w
+ * the widget to be inserted
+ * @param beforeIndex
+ * the index before which it will be inserted
+ * @throws IndexOutOfBoundsException
+ * if <code>beforeIndex</code> is out of range
+ */
+ public void insert(Widget w, int beforeIndex) {
+ Element el = createContainerElement();
+ DOM.insertChild(getElement(), el, beforeIndex);
+ super.insert(w, el, beforeIndex, false);
+ }
+
+ @Override
+ public boolean remove(Widget w) {
+ Element child = w.getElement();
+ Element parent = null;
+ if (child != null) {
+ parent = DOM.getParent(child);
+ }
+ final boolean removed = super.remove(w);
+ if (removed) {
+ if (visibleWidget == w) {
+ visibleWidget = null;
+ }
+ if (parent != null) {
+ DOM.removeChild(getElement(), parent);
+ }
+ }
+ return removed;
+ }
+
+ /**
+ * Shows the widget at the specified index. This causes the currently-
+ * visible widget to be hidden.
+ *
+ * @param index
+ * the index of the widget to be shown
+ */
+ public void showWidget(int index) {
+ checkIndexBoundsForAccess(index);
+ Widget newVisible = getWidget(index);
+ if (visibleWidget != newVisible) {
+ if (visibleWidget != null) {
+ hide(DOM.getParent(visibleWidget.getElement()));
+ }
+ visibleWidget = newVisible;
+ unHide(DOM.getParent(visibleWidget.getElement()));
+ }
+ }
+
+ private void hide(Element e) {
+ DOM.setStyleAttribute(e, "visibility", "hidden");
+ DOM.setStyleAttribute(e, "top", "-100000px");
+ DOM.setStyleAttribute(e, "left", "-100000px");
+ }
+
+ private void unHide(Element e) {
+ DOM.setStyleAttribute(e, "top", "0px");
+ DOM.setStyleAttribute(e, "left", "0px");
+ DOM.setStyleAttribute(e, "visibility", "");
+ }
+
+ public void fixVisibleTabSize(int width, int height, int minWidth) {
+ if (visibleWidget == null) {
+ return;
+ }
+
+ boolean dynamicHeight = false;
+
+ if (height < 0) {
+ height = visibleWidget.getOffsetHeight();
+ dynamicHeight = true;
+ }
+ if (width < 0) {
+ width = visibleWidget.getOffsetWidth();
+ }
+ if (width < minWidth) {
+ width = minWidth;
+ }
+
+ Element wrapperDiv = (Element) visibleWidget.getElement()
+ .getParentElement();
+
+ // width first
+ getElement().getStyle().setPropertyPx("width", width);
+ wrapperDiv.getStyle().setPropertyPx("width", width);
+
+ if (dynamicHeight) {
+ // height of widget might have changed due wrapping
+ height = visibleWidget.getOffsetHeight();
+ }
+ // v-tabsheet-tabsheetpanel height
+ getElement().getStyle().setPropertyPx("height", height);
+
+ // widget wrapper height
+ wrapperDiv.getStyle().setPropertyPx("height", height);
+ runWebkitOverflowAutoFix();
+ }
+
+ public void runWebkitOverflowAutoFix() {
+ if (visibleWidget != null) {
+ Util.runWebkitOverflowAutoFix(DOM.getParent(visibleWidget
+ .getElement()));
+ }
+
+ }
+
+ public void replaceComponent(Widget oldComponent, Widget newComponent) {
+ boolean isVisible = (visibleWidget == oldComponent);
+ int widgetIndex = getWidgetIndex(oldComponent);
+ remove(oldComponent);
+ insert(newComponent, widgetIndex);
+ if (isVisible) {
+ showWidget(widgetIndex);
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java b/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
index cd09e24d67..2c8ed24693 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
@@ -1,79 +1,63 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-/**
- * This class represents a multiline textfield (textarea).
- *
- * TODO consider replacing this with a RichTextArea based implementation. IE
- * does not support CSS height for textareas in Strict mode :-(
- *
- * @author Vaadin Ltd.
- *
- */
-public class VTextArea extends VTextField {
- public static final String CLASSNAME = "v-textarea";
-
- public VTextArea() {
- super(DOM.createTextArea());
- setStyleName(CLASSNAME);
- }
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Call parent renderer explicitly
- super.updateFromUIDL(uidl, client);
-
- if (uidl.hasAttribute("rows")) {
- setRows(uidl.getIntAttribute("rows"));
- }
-
- if (getMaxLength() >= 0) {
- sinkEvents(Event.ONKEYUP);
- }
- }
-
- public void setRows(int rows) {
- setRows(getElement(), rows);
- }
-
- private native void setRows(Element e, int r)
- /*-{
- try {
- if(e.tagName.toLowerCase() == "textarea")
- e.rows = r;
- } catch (e) {}
- }-*/;
-
- @Override
- public void onBrowserEvent(Event event) {
- if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- if (getText().length() > getMaxLength()) {
- setText(getText().substring(0, getMaxLength()));
- }
- }
- });
- }
- super.onBrowserEvent(event);
- }
-
- @Override
- public int getCursorPos() {
- // This is needed so that TextBoxImplIE6 is used to return the correct
- // position for old Internet Explorer versions where it has to be
- // detected in a different way.
- return getImpl().getTextAreaCursorPos(getElement());
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+
+/**
+ * This class represents a multiline textfield (textarea).
+ *
+ * TODO consider replacing this with a RichTextArea based implementation. IE
+ * does not support CSS height for textareas in Strict mode :-(
+ *
+ * @author Vaadin Ltd.
+ *
+ */
+public class VTextArea extends VTextField {
+ public static final String CLASSNAME = "v-textarea";
+
+ public VTextArea() {
+ super(DOM.createTextArea());
+ setStyleName(CLASSNAME);
+ }
+
+ public void setRows(int rows) {
+ setRows(getElement(), rows);
+ }
+
+ private native void setRows(Element e, int r)
+ /*-{
+ try {
+ if(e.tagName.toLowerCase() == "textarea")
+ e.rows = r;
+ } catch (e) {}
+ }-*/;
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ if (getText().length() > getMaxLength()) {
+ setText(getText().substring(0, getMaxLength()));
+ }
+ }
+ });
+ }
+ super.onBrowserEvent(event);
+ }
+
+ @Override
+ public int getCursorPos() {
+ // This is needed so that TextBoxImplIE6 is used to return the correct
+ // position for old Internet Explorer versions where it has to be
+ // detected in a different way.
+ return getImpl().getTextAreaCursorPos(getElement());
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextAreaPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTextAreaPaintable.java
new file mode 100644
index 0000000000..3c21a4ab2f
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextAreaPaintable.java
@@ -0,0 +1,38 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VTextAreaPaintable extends VTextFieldPaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Call parent renderer explicitly
+ super.updateFromUIDL(uidl, client);
+
+ if (uidl.hasAttribute("rows")) {
+ getWidgetForPaintable().setRows(uidl.getIntAttribute("rows"));
+ }
+
+ if (getWidgetForPaintable().getMaxLength() >= 0) {
+ getWidgetForPaintable().sinkEvents(Event.ONKEYUP);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTextArea.class);
+ }
+
+ @Override
+ public VTextArea getWidgetForPaintable() {
+ return (VTextArea) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
index 80dad78e58..80b27e6c8c 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java
@@ -4,7 +4,6 @@
package com.vaadin.terminal.gwt.client.ui;
-import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
@@ -15,21 +14,16 @@ 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.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.TextBoxBase;
-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.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
/**
* This class represents a basic text input field with one row.
@@ -37,9 +31,8 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutAct
* @author Vaadin Ltd.
*
*/
-public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
- ChangeHandler, FocusHandler, BlurHandler, BeforeShortcutActionListener,
- KeyDownHandler {
+public class VTextField extends TextBoxBase implements Field, ChangeHandler,
+ FocusHandler, BlurHandler, KeyDownHandler {
public static final String VAR_CUR_TEXT = "curText";
@@ -53,11 +46,11 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
*/
public static final String CLASSNAME_FOCUS = "focus";
- protected String id;
+ protected String paintableId;
protected ApplicationConnection client;
- private String valueBeforeEdit = null;
+ protected String valueBeforeEdit = null;
/**
* Set to false if a text change event has been sent since the last value
@@ -66,20 +59,20 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
*/
private boolean valueBeforeEditIsSynced = true;
- private boolean immediate = false;
+ protected boolean immediate = false;
private int extraHorizontalPixels = -1;
private int extraVerticalPixels = -1;
private int maxLength = -1;
private static final String CLASSNAME_PROMPT = "prompt";
- private static final String ATTR_INPUTPROMPT = "prompt";
+ protected static final String ATTR_INPUTPROMPT = "prompt";
public static final String ATTR_TEXTCHANGE_TIMEOUT = "iet";
public static final String VAR_CURSOR = "c";
public static final String ATTR_TEXTCHANGE_EVENTMODE = "iem";
- private static final String TEXTCHANGE_MODE_EAGER = "EAGER";
+ protected static final String TEXTCHANGE_MODE_EAGER = "EAGER";
private static final String TEXTCHANGE_MODE_TIMEOUT = "TIMEOUT";
- private String inputPrompt = null;
+ protected String inputPrompt = null;
private boolean prompting = false;
private int lastCursorPos = -1;
private boolean wordwrap = true;
@@ -112,14 +105,14 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
* Eager polling for a change is bit dum and heavy operation, so I guess we
* should first try to survive without.
*/
- private static final int TEXTCHANGE_EVENTS = Event.ONPASTE
+ protected static final int TEXTCHANGE_EVENTS = Event.ONPASTE
| Event.KEYEVENTS | Event.ONMOUSEUP;
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
if (listenTextChangeEvents
@@ -158,7 +151,7 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
client.sendPendingVariableChanges();
} else {
// Default case - just send an immediate text change message
- client.updateVariable(id, VAR_CUR_TEXT, text, true);
+ client.updateVariable(paintableId, VAR_CUR_TEXT, text, true);
// Shouldn't investigate valueBeforeEdit to avoid duplicate text
// change events as the states are not in sync any more
@@ -180,9 +173,9 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
}
};
private boolean scheduled = false;
- private boolean listenTextChangeEvents;
- private String textChangeEventMode;
- private int textChangeEventTimeout;
+ protected boolean listenTextChangeEvents;
+ protected String textChangeEventMode;
+ protected int textChangeEventTimeout;
private void deferTextChangeEvent() {
if (textChangeEventMode.equals(TEXTCHANGE_MODE_TIMEOUT) && scheduled) {
@@ -215,88 +208,7 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
super.setReadOnly(readOnly);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- id = uidl.getId();
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- if (uidl.getBooleanAttribute("readonly")) {
- setReadOnly(true);
- } else {
- setReadOnly(false);
- }
-
- inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT);
-
- setMaxLength(uidl.hasAttribute("maxLength") ? uidl
- .getIntAttribute("maxLength") : -1);
-
- immediate = uidl.getBooleanAttribute("immediate");
-
- listenTextChangeEvents = client.hasEventListeners(this, "ie");
- if (listenTextChangeEvents) {
- textChangeEventMode = uidl
- .getStringAttribute(ATTR_TEXTCHANGE_EVENTMODE);
- if (textChangeEventMode.equals(TEXTCHANGE_MODE_EAGER)) {
- textChangeEventTimeout = 1;
- } else {
- textChangeEventTimeout = uidl
- .getIntAttribute(ATTR_TEXTCHANGE_TIMEOUT);
- if (textChangeEventTimeout < 1) {
- // Sanitize and allow lazy/timeout with timeout set to 0 to
- // work as eager
- textChangeEventTimeout = 1;
- }
- }
- sinkEvents(TEXTCHANGE_EVENTS);
- attachCutEventListener(getElement());
- }
-
- if (uidl.hasAttribute("cols")) {
- setColumns(new Integer(uidl.getStringAttribute("cols")).intValue());
- }
-
- final String text = uidl.getStringVariable("text");
-
- /*
- * We skip the text content update if field has been repainted, but text
- * has not been changed. Additional sanity check verifies there is no
- * change in the que (in which case we count more on the server side
- * value).
- */
- if (!(uidl.getBooleanAttribute(ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS)
- && valueBeforeEdit != null && text.equals(valueBeforeEdit))) {
- updateFieldContent(text);
- }
-
- if (uidl.hasAttribute("selpos")) {
- final int pos = uidl.getIntAttribute("selpos");
- final int length = uidl.getIntAttribute("sellen");
- /*
- * Gecko defers setting the text so we need to defer the selection.
- */
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- setSelectionRange(pos, length);
- }
- });
- }
-
- // Here for backward compatibility; to be moved to TextArea.
- // Optimization: server does not send attribute for the default 'true'
- // state.
- if (uidl.hasAttribute("wordwrap")
- && uidl.getBooleanAttribute("wordwrap") == false) {
- setWordwrap(false);
- } else {
- setWordwrap(true);
- }
- }
-
- private void updateFieldContent(final String text) {
+ protected void updateFieldContent(final String text) {
setPrompting(inputPrompt != null && focusedTextField != this
&& (text.equals("")));
@@ -350,7 +262,7 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
}
}
- private void setMaxLength(int newMaxLength) {
+ protected void setMaxLength(int newMaxLength) {
if (newMaxLength >= 0) {
maxLength = newMaxLength;
if (getElement().getTagName().toLowerCase().equals("textarea")) {
@@ -386,20 +298,20 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
* true if the field was blurred
*/
public void valueChange(boolean blurred) {
- if (client != null && id != null) {
+ if (client != null && paintableId != null) {
boolean sendBlurEvent = false;
boolean sendValueChange = false;
- if (blurred && client.hasEventListeners(this, EventId.BLUR)) {
+ if (blurred && client.hasWidgetEventListeners(this, EventId.BLUR)) {
sendBlurEvent = true;
- client.updateVariable(id, EventId.BLUR, "", false);
+ client.updateVariable(paintableId, EventId.BLUR, "", false);
}
String newText = getText();
if (!prompting && newText != null
&& !newText.equals(valueBeforeEdit)) {
sendValueChange = immediate;
- client.updateVariable(id, "text", getText(), false);
+ client.updateVariable(paintableId, "text", getText(), false);
valueBeforeEdit = newText;
valueBeforeEditIsSynced = true;
}
@@ -432,7 +344,7 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
if (Util.isAttachedAndDisplayed(this)) {
int cursorPos = getCursorPos();
if (lastCursorPos != cursorPos) {
- client.updateVariable(id, VAR_CURSOR, cursorPos, false);
+ client.updateVariable(paintableId, VAR_CURSOR, cursorPos, false);
lastCursorPos = cursorPos;
return true;
}
@@ -456,8 +368,8 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
setPrompting(false);
}
focusedTextField = this;
- if (client.hasEventListeners(this, EventId.FOCUS)) {
- client.updateVariable(id, EventId.FOCUS, "", true);
+ if (client.hasWidgetEventListeners(this, EventId.FOCUS)) {
+ client.updateVariable(paintableId, EventId.FOCUS, "", true);
}
}
@@ -568,10 +480,6 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
}
}
- public void onBeforeShortcutAction(Event e) {
- valueChange(false);
- }
-
// Here for backward compatibility; to be moved to TextArea
public void setWordwrap(boolean enabled) {
if (enabled == wordwrap) {
@@ -601,8 +509,4 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
valueChange(false);
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextFieldPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTextFieldPaintable.java
new file mode 100644
index 0000000000..e3eecd5a09
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextFieldPaintable.java
@@ -0,0 +1,124 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+
+public class VTextFieldPaintable extends VAbstractPaintableWidget implements
+ BeforeShortcutActionListener {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Save details
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getId();
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ if (uidl.getBooleanAttribute("readonly")) {
+ getWidgetForPaintable().setReadOnly(true);
+ } else {
+ getWidgetForPaintable().setReadOnly(false);
+ }
+
+ getWidgetForPaintable().inputPrompt = uidl
+ .getStringAttribute(VTextField.ATTR_INPUTPROMPT);
+
+ getWidgetForPaintable().setMaxLength(
+ uidl.hasAttribute("maxLength") ? uidl
+ .getIntAttribute("maxLength") : -1);
+
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+
+ getWidgetForPaintable().listenTextChangeEvents = client
+ .hasEventListeners(this, "ie");
+ if (getWidgetForPaintable().listenTextChangeEvents) {
+ getWidgetForPaintable().textChangeEventMode = uidl
+ .getStringAttribute(VTextField.ATTR_TEXTCHANGE_EVENTMODE);
+ if (getWidgetForPaintable().textChangeEventMode
+ .equals(VTextField.TEXTCHANGE_MODE_EAGER)) {
+ getWidgetForPaintable().textChangeEventTimeout = 1;
+ } else {
+ getWidgetForPaintable().textChangeEventTimeout = uidl
+ .getIntAttribute(VTextField.ATTR_TEXTCHANGE_TIMEOUT);
+ if (getWidgetForPaintable().textChangeEventTimeout < 1) {
+ // Sanitize and allow lazy/timeout with timeout set to 0 to
+ // work as eager
+ getWidgetForPaintable().textChangeEventTimeout = 1;
+ }
+ }
+ getWidgetForPaintable().sinkEvents(VTextField.TEXTCHANGE_EVENTS);
+ getWidgetForPaintable().attachCutEventListener(
+ getWidgetForPaintable().getElement());
+ }
+
+ if (uidl.hasAttribute("cols")) {
+ getWidgetForPaintable().setColumns(
+ new Integer(uidl.getStringAttribute("cols")).intValue());
+ }
+
+ final String text = uidl.getStringVariable("text");
+
+ /*
+ * We skip the text content update if field has been repainted, but text
+ * has not been changed. Additional sanity check verifies there is no
+ * change in the que (in which case we count more on the server side
+ * value).
+ */
+ if (!(uidl
+ .getBooleanAttribute(VTextField.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS)
+ && getWidgetForPaintable().valueBeforeEdit != null && text
+ .equals(getWidgetForPaintable().valueBeforeEdit))) {
+ getWidgetForPaintable().updateFieldContent(text);
+ }
+
+ if (uidl.hasAttribute("selpos")) {
+ final int pos = uidl.getIntAttribute("selpos");
+ final int length = uidl.getIntAttribute("sellen");
+ /*
+ * Gecko defers setting the text so we need to defer the selection.
+ */
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ getWidgetForPaintable().setSelectionRange(pos, length);
+ }
+ });
+ }
+
+ // Here for backward compatibility; to be moved to TextArea.
+ // Optimization: server does not send attribute for the default 'true'
+ // state.
+ if (uidl.hasAttribute("wordwrap")
+ && uidl.getBooleanAttribute("wordwrap") == false) {
+ getWidgetForPaintable().setWordwrap(false);
+ } else {
+ getWidgetForPaintable().setWordwrap(true);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTextField.class);
+ }
+
+ @Override
+ public VTextField getWidgetForPaintable() {
+ return (VTextField) super.getWidgetForPaintable();
+ }
+
+ public void onBeforeShortcutAction(Event e) {
+ getWidgetForPaintable().valueChange(false);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
index a522c79736..bb808321b9 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
@@ -14,25 +14,22 @@ import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.TextBox;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.Focusable;
import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
import com.vaadin.terminal.gwt.client.LocaleService;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-public class VTextualDate extends VDateField implements VPaintableWidget,
- Field, ChangeHandler, ContainerResizedListener, Focusable, SubPartAware {
+public class VTextualDate extends VDateField implements Field, ChangeHandler,
+ ContainerResizedListener, Focusable, SubPartAware {
private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
+ "-parseerror";
- private final TextBox text;
+ protected final TextBox text;
- private String formatStr;
+ protected String formatStr;
private String width;
@@ -40,11 +37,11 @@ public class VTextualDate extends VDateField implements VPaintableWidget,
protected int fieldExtraWidth = -1;
- private boolean lenient;
+ protected boolean lenient;
private static final String CLASSNAME_PROMPT = "prompt";
- private static final String ATTR_INPUTPROMPT = "prompt";
- private String inputPrompt = "";
+ protected static final String ATTR_INPUTPROMPT = "prompt";
+ protected String inputPrompt = "";
private boolean prompting = false;
public VTextualDate() {
@@ -65,8 +62,8 @@ public class VTextualDate extends VDateField implements VPaintableWidget,
setPrompting(false);
}
if (getClient() != null
- && getClient().hasEventListeners(VTextualDate.this,
- EventId.FOCUS)) {
+ && getClient().hasWidgetEventListeners(
+ VTextualDate.this, EventId.FOCUS)) {
getClient()
.updateVariable(getId(), EventId.FOCUS, "", true);
}
@@ -83,8 +80,8 @@ public class VTextualDate extends VDateField implements VPaintableWidget,
text.setText(readonly ? "" : inputPrompt);
}
if (getClient() != null
- && getClient().hasEventListeners(VTextualDate.this,
- EventId.BLUR)) {
+ && getClient().hasWidgetEventListeners(
+ VTextualDate.this, EventId.BLUR)) {
getClient().updateVariable(getId(), EventId.BLUR, "", true);
}
}
@@ -92,37 +89,6 @@ public class VTextualDate extends VDateField implements VPaintableWidget,
add(text);
}
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- int origRes = currentResolution;
- String oldLocale = currentLocale;
- super.updateFromUIDL(uidl, client);
- if (origRes != currentResolution || oldLocale != currentLocale) {
- // force recreating format string
- formatStr = null;
- }
- if (uidl.hasAttribute("format")) {
- formatStr = uidl.getStringAttribute("format");
- }
-
- inputPrompt = uidl.getStringAttribute(ATTR_INPUTPROMPT);
-
- lenient = !uidl.getBooleanAttribute("strict");
-
- buildDate();
- // not a FocusWidget -> needs own tabindex handling
- if (uidl.hasAttribute("tabindex")) {
- text.setTabIndex(uidl.getIntAttribute("tabindex"));
- }
-
- if (readonly) {
- text.addStyleDependentName("readonly");
- } else {
- text.removeStyleDependentName("readonly");
- }
-
- }
-
protected String getFormatString() {
if (formatStr == null) {
if (currentResolution == RESOLUTION_YEAR) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDatePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDatePaintable.java
new file mode 100644
index 0000000000..6a9da31269
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDatePaintable.java
@@ -0,0 +1,58 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VTextualDatePaintable extends VDateFieldPaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ int origRes = getWidgetForPaintable().currentResolution;
+ String oldLocale = getWidgetForPaintable().currentLocale;
+ super.updateFromUIDL(uidl, client);
+ if (origRes != getWidgetForPaintable().currentResolution
+ || oldLocale != getWidgetForPaintable().currentLocale) {
+ // force recreating format string
+ getWidgetForPaintable().formatStr = null;
+ }
+ if (uidl.hasAttribute("format")) {
+ getWidgetForPaintable().formatStr = uidl
+ .getStringAttribute("format");
+ }
+
+ getWidgetForPaintable().inputPrompt = uidl
+ .getStringAttribute(VTextualDate.ATTR_INPUTPROMPT);
+
+ getWidgetForPaintable().lenient = !uidl.getBooleanAttribute("strict");
+
+ getWidgetForPaintable().buildDate();
+ // not a FocusWidget -> needs own tabindex handling
+ if (uidl.hasAttribute("tabindex")) {
+ getWidgetForPaintable().text.setTabIndex(uidl
+ .getIntAttribute("tabindex"));
+ }
+
+ if (getWidgetForPaintable().readonly) {
+ getWidgetForPaintable().text.addStyleDependentName("readonly");
+ } else {
+ getWidgetForPaintable().text.removeStyleDependentName("readonly");
+ }
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTextualDate.class);
+ }
+
+ @Override
+ public VTextualDate getWidgetForPaintable() {
+ return (VTextualDate) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
index de7f6c652a..be337ae0cb 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
@@ -40,10 +40,10 @@ 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.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler;
@@ -58,9 +58,9 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
/**
*
*/
-public class VTree extends FocusElementPanel implements VPaintableWidget,
- VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler,
- KeyDownHandler, SubPartAware, ActionOwner {
+public class VTree extends FocusElementPanel implements VHasDropHandler,
+ FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
+ SubPartAware, ActionOwner {
public static final String CLASSNAME = "v-tree";
@@ -71,17 +71,17 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
private static final int CHARCODE_SPACE = 32;
- private final FlowPanel body = new FlowPanel();
+ final FlowPanel body = new FlowPanel();
- private Set<String> selectedIds = new HashSet<String>();
- private ApplicationConnection client;
- private String paintableId;
- private boolean selectable;
- private boolean isMultiselect;
+ Set<String> selectedIds = new HashSet<String>();
+ ApplicationConnection client;
+ String paintableId;
+ boolean selectable;
+ boolean isMultiselect;
private String currentMouseOverKey;
- private TreeNode lastSelection;
- private TreeNode focusedNode;
- private int multiSelectMode = MULTISELECT_MODE_DEFAULT;
+ TreeNode lastSelection;
+ TreeNode focusedNode;
+ int multiSelectMode = MULTISELECT_MODE_DEFAULT;
private final HashMap<String, TreeNode> keyToNode = new HashMap<String, TreeNode>();
@@ -91,23 +91,23 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
*/
private final HashMap<String, String> actionMap = new HashMap<String, String>();
- private boolean immediate;
+ boolean immediate;
- private boolean isNullSelectionAllowed = true;
+ boolean isNullSelectionAllowed = true;
- private boolean disabled = false;
+ boolean disabled = false;
- private boolean readonly;
+ boolean readonly;
- private boolean rendering;
+ boolean rendering;
private VAbstractDropHandler dropHandler;
- private int dragMode;
+ int dragMode;
private boolean selectionHasChanged = false;
- private String[] bodyActionKeys;
+ String[] bodyActionKeys;
public VLazyExecutor iconLoaded = new VLazyExecutor(50,
new ScheduledCommand() {
@@ -206,24 +206,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
}
}
- private void updateActionMap(UIDL c) {
- final Iterator<?> it = c.getChildIterator();
- while (it.hasNext()) {
- final UIDL action = (UIDL) it.next();
- final String key = action.getStringAttribute("key");
- final String caption = action.getStringAttribute("caption");
- actionMap.put(key + "_c", caption);
- if (action.hasAttribute("icon")) {
- // TODO need some uri handling ??
- actionMap.put(key + "_i", client.translateVaadinUri(action
- .getStringAttribute("icon")));
- } else {
- actionMap.remove(key + "_i");
- }
- }
-
- }
-
public String getActionCaption(String actionKey) {
return actionMap.get(actionKey + "_c");
}
@@ -232,94 +214,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
return actionMap.get(actionKey + "_i");
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Ensure correct implementation and let container manage caption
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- rendering = true;
-
- this.client = client;
-
- if (uidl.hasAttribute("partialUpdate")) {
- handleUpdate(uidl);
- rendering = false;
- return;
- }
-
- paintableId = uidl.getId();
-
- immediate = uidl.hasAttribute("immediate");
-
- disabled = uidl.getBooleanAttribute("disabled");
- readonly = uidl.getBooleanAttribute("readonly");
-
- dragMode = uidl.hasAttribute("dragMode") ? uidl
- .getIntAttribute("dragMode") : 0;
-
- isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
-
- if (uidl.hasAttribute("alb")) {
- bodyActionKeys = uidl.getStringArrayAttribute("alb");
- }
-
- body.clear();
- // clear out any references to nodes that no longer are attached
- keyToNode.clear();
- TreeNode childTree = null;
- UIDL childUidl = null;
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
- childUidl = (UIDL) i.next();
- if ("actions".equals(childUidl.getTag())) {
- updateActionMap(childUidl);
- continue;
- } else if ("-ac".equals(childUidl.getTag())) {
- updateDropHandler(childUidl);
- continue;
- }
- childTree = new TreeNode();
- childTree.updateFromUIDL(childUidl, client);
- body.add(childTree);
- childTree.addStyleDependentName("root");
- childTree.childNodeContainer.addStyleDependentName("root");
- }
- if (childTree != null && childUidl != null) {
- boolean leaf = !childUidl.getTag().equals("node");
- childTree.addStyleDependentName(leaf ? "leaf-last" : "last");
- childTree.childNodeContainer.addStyleDependentName("last");
- }
- final String selectMode = uidl.getStringAttribute("selectmode");
- selectable = !"none".equals(selectMode);
- isMultiselect = "multi".equals(selectMode);
-
- if (isMultiselect) {
- multiSelectMode = uidl.getIntAttribute("multiselectmode");
- }
-
- selectedIds = uidl.getStringArrayVariableAsSet("selected");
-
- // Update lastSelection and focusedNode to point to *actual* nodes again
- // after the old ones have been cleared from the body. This fixes focus
- // and keyboard navigation issues as described in #7057 and other
- // tickets.
- if (lastSelection != null) {
- lastSelection = keyToNode.get(lastSelection.key);
- }
- if (focusedNode != null) {
- setFocusedNode(keyToNode.get(focusedNode.key));
- }
-
- if (lastSelection == null && focusedNode == null
- && !selectedIds.isEmpty()) {
- setFocusedNode(keyToNode.get(selectedIds.iterator().next()));
- focusedNode.setFocused(false);
- }
-
- rendering = false;
-
- }
-
/**
* Returns the first root node of the tree or null if there are no root
* nodes.
@@ -366,7 +260,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
drag.getDropDetails().put("itemIdOver", currentMouseOverKey);
if (currentMouseOverKey != null) {
- TreeNode treeNode = keyToNode.get(currentMouseOverKey);
+ TreeNode treeNode = getNodeByKey(currentMouseOverKey);
VerticalDropLocation detail = treeNode.getDropDetail(drag
.getCurrentGwtEvent());
Boolean overTreeNode = null;
@@ -388,7 +282,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
return treeNode == null ? null : treeNode.key;
}
- private void updateDropHandler(UIDL childUidl) {
+ void updateDropHandler(UIDL childUidl) {
if (dropHandler == null) {
dropHandler = new VAbstractDropHandler() {
@@ -430,7 +324,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
.getDropDetails().get("detail");
if (curDetail == detail
&& newKey.equals(currentMouseOverKey)) {
- keyToNode.get(newKey).emphasis(detail);
+ getNodeByKey(newKey).emphasis(detail);
}
/*
* Else drag is already on a different
@@ -452,7 +346,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
private void cleanUp() {
if (currentMouseOverKey != null) {
- keyToNode.get(currentMouseOverKey).emphasis(null);
+ getNodeByKey(currentMouseOverKey).emphasis(null);
currentMouseOverKey = null;
}
}
@@ -465,7 +359,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
@Override
public VPaintableWidget getPaintable() {
- return VTree.this;
+ return VPaintableMap.get(client).getPaintable(VTree.this);
}
public ApplicationConnection getApplicationConnection() {
@@ -477,24 +371,12 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
dropHandler.updateAcceptRules(childUidl);
}
- private void handleUpdate(UIDL uidl) {
- final TreeNode rootNode = keyToNode.get(uidl
- .getStringAttribute("rootKey"));
- if (rootNode != null) {
- if (!rootNode.getState()) {
- // expanding node happened server side
- rootNode.setState(true, false);
- }
- rootNode.renderChildNodes(uidl.getChildIterator());
- }
- }
-
public void setSelected(TreeNode treeNode, boolean selected) {
if (selected) {
if (!isMultiselect) {
while (selectedIds.size() > 0) {
final String id = selectedIds.iterator().next();
- final TreeNode oldSelection = keyToNode.get(id);
+ final TreeNode oldSelection = getNodeByKey(id);
if (oldSelection != null) {
// can be null if the node is not visible (parent
// collapsed)
@@ -563,15 +445,15 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
public String key;
- private String[] actionKeys = null;
+ String[] actionKeys = null;
- private boolean childrenLoaded;
+ boolean childrenLoaded;
- private Element nodeCaptionDiv;
+ Element nodeCaptionDiv;
protected Element nodeCaptionSpan;
- private FlowPanel childNodeContainer;
+ FlowPanel childNodeContainer;
private boolean open;
@@ -760,14 +642,14 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
}
if (target == nodeCaptionSpan) {
- client.handleTooltipEvent(event, VTree.this, key);
+ client.handleWidgetTooltipEvent(event, VTree.this, key);
}
final boolean inCaption = target == nodeCaptionSpan
|| (icon != null && target == icon.getElement());
if (inCaption
- && client
- .hasEventListeners(VTree.this, ITEM_CLICK_EVENT_ID)
+ && client.hasWidgetEventListeners(VTree.this,
+ ITEM_CLICK_EVENT_ID)
&& (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
fireClick(event);
@@ -828,7 +710,8 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
if (mouseDownEvent != null) {
// start actual drag on slight move when mouse is down
VTransferable t = new VTransferable();
- t.setDragSource(VTree.this);
+ t.setDragSource(VPaintableMap.get(client).getPaintable(
+ VTree.this));
t.setData("itemId", key);
VDragEvent drag = VDragAndDropManager.get().startDrag(
t, mouseDownEvent, true);
@@ -944,71 +827,6 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
setWidget(childNodeContainer);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- setText(uidl.getStringAttribute("caption"));
- key = uidl.getStringAttribute("key");
-
- keyToNode.put(key, this);
-
- if (uidl.hasAttribute("al")) {
- actionKeys = uidl.getStringArrayAttribute("al");
- }
-
- if (uidl.getTag().equals("node")) {
- if (uidl.getChildCount() == 0) {
- childNodeContainer.setVisible(false);
- } else {
- renderChildNodes(uidl.getChildIterator());
- childrenLoaded = true;
- }
- } else {
- addStyleName(CLASSNAME + "-leaf");
- }
- if (uidl.hasAttribute("style")) {
- addStyleName(CLASSNAME + "-" + uidl.getStringAttribute("style"));
- Widget.setStyleName(nodeCaptionDiv, CLASSNAME + "-caption-"
- + uidl.getStringAttribute("style"), true);
- childNodeContainer.addStyleName(CLASSNAME + "-children-"
- + uidl.getStringAttribute("style"));
- }
-
- String description = uidl.getStringAttribute("descr");
- if (description != null && client != null) {
- // Set tooltip
- TooltipInfo info = new TooltipInfo(description);
- client.registerTooltip(VTree.this, key, info);
- } else {
- // Remove possible previous tooltip
- client.registerTooltip(VTree.this, key, null);
- }
-
- if (uidl.getBooleanAttribute("expanded") && !getState()) {
- setState(true, false);
- }
-
- if (uidl.getBooleanAttribute("selected")) {
- setSelected(true);
- // ensure that identifier is in selectedIds array (this may be a
- // partial update)
- selectedIds.add(key);
- }
-
- if (uidl.hasAttribute("icon")) {
- if (icon == null) {
- icon = new Icon(client);
- DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
- icon.getElement(), nodeCaptionSpan);
- }
- icon.setUri(uidl.getStringAttribute("icon"));
- } else {
- if (icon != null) {
- DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv),
- icon.getElement());
- icon = null;
- }
- }
- }
-
public boolean isLeaf() {
String[] styleNames = getStyleName().split(" ");
for (String styleName : styleNames) {
@@ -1019,7 +837,7 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
return false;
}
- private void setState(boolean state, boolean notifyServer) {
+ void setState(boolean state, boolean notifyServer) {
if (open == state) {
return;
}
@@ -1050,38 +868,14 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
}
}
- private boolean getState() {
+ boolean getState() {
return open;
}
- private void setText(String text) {
+ void setText(String text) {
DOM.setInnerText(nodeCaptionSpan, text);
}
- private void renderChildNodes(Iterator<?> i) {
- childNodeContainer.clear();
- childNodeContainer.setVisible(true);
- while (i.hasNext()) {
- final UIDL childUidl = (UIDL) i.next();
- // actions are in bit weird place, don't mix them with children,
- // but current node's actions
- if ("actions".equals(childUidl.getTag())) {
- updateActionMap(childUidl);
- continue;
- }
- final TreeNode childTree = new TreeNode();
- childTree.updateFromUIDL(childUidl, client);
- childNodeContainer.add(childTree);
- if (!i.hasNext()) {
- childTree
- .addStyleDependentName(childTree.isLeaf() ? "leaf-last"
- : "last");
- childTree.childNodeContainer.addStyleDependentName("last");
- }
- }
- childrenLoaded = true;
- }
-
public boolean isChildrenLoaded() {
return childrenLoaded;
}
@@ -1231,6 +1025,34 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
Util.scrollIntoViewVertically(nodeCaptionDiv);
}
+ public void setIcon(String iconUrl) {
+ if (iconUrl != null) {
+ // Add icon if not present
+ if (icon == null) {
+ icon = new Icon(client);
+ DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv),
+ icon.getElement(), nodeCaptionSpan);
+ }
+ icon.setUri(iconUrl);
+ } else {
+ // Remove icon if present
+ if (icon != null) {
+ DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv),
+ icon.getElement());
+ icon = null;
+ }
+ }
+ }
+
+ public void setNodeStyleName(String styleName) {
+ addStyleName(TreeNode.CLASSNAME + "-" + styleName);
+ setStyleName(nodeCaptionDiv, TreeNode.CLASSNAME + "-caption-"
+ + styleName, true);
+ childNodeContainer.addStyleName(TreeNode.CLASSNAME + "-children-"
+ + styleName);
+
+ }
+
}
public VDropHandler getDropHandler() {
@@ -2243,7 +2065,22 @@ public class VTree extends FocusElementPanel implements VPaintableWidget,
}
}
- public Widget getWidgetForPaintable() {
- return this;
+ public void registerAction(String key, String caption, String iconUrl) {
+ actionMap.put(key + "_c", caption);
+ if (iconUrl != null) {
+ actionMap.put(key + "_i", iconUrl);
+ } else {
+ actionMap.remove(key + "_i");
+ }
+
}
+
+ public void registerNode(TreeNode treeNode) {
+ keyToNode.put(treeNode.key, treeNode);
+ }
+
+ public void clearNodeToKeyMap() {
+ keyToNode.clear();
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
new file mode 100644
index 0000000000..69aecebb06
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreePaintable.java
@@ -0,0 +1,231 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.TooltipInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VTree.TreeNode;
+
+public class VTreePaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Ensure correct implementation and let container manage caption
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().rendering = true;
+
+ getWidgetForPaintable().client = client;
+
+ if (uidl.hasAttribute("partialUpdate")) {
+ handleUpdate(uidl);
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().paintableId = uidl.getId();
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ getWidgetForPaintable().disabled = uidl.getBooleanAttribute("disabled");
+ getWidgetForPaintable().readonly = uidl.getBooleanAttribute("readonly");
+
+ getWidgetForPaintable().dragMode = uidl.hasAttribute("dragMode") ? uidl
+ .getIntAttribute("dragMode") : 0;
+
+ getWidgetForPaintable().isNullSelectionAllowed = uidl
+ .getBooleanAttribute("nullselect");
+
+ if (uidl.hasAttribute("alb")) {
+ getWidgetForPaintable().bodyActionKeys = uidl
+ .getStringArrayAttribute("alb");
+ }
+
+ getWidgetForPaintable().body.clear();
+ // clear out any references to nodes that no longer are attached
+ getWidgetForPaintable().clearNodeToKeyMap();
+ TreeNode childTree = null;
+ UIDL childUidl = null;
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ childUidl = (UIDL) i.next();
+ if ("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
+ continue;
+ } else if ("-ac".equals(childUidl.getTag())) {
+ getWidgetForPaintable().updateDropHandler(childUidl);
+ continue;
+ }
+ childTree = getWidgetForPaintable().new TreeNode();
+ updateNodeFromUIDL(childTree, childUidl);
+ getWidgetForPaintable().body.add(childTree);
+ childTree.addStyleDependentName("root");
+ childTree.childNodeContainer.addStyleDependentName("root");
+ }
+ if (childTree != null && childUidl != null) {
+ boolean leaf = !childUidl.getTag().equals("node");
+ childTree.addStyleDependentName(leaf ? "leaf-last" : "last");
+ childTree.childNodeContainer.addStyleDependentName("last");
+ }
+ final String selectMode = uidl.getStringAttribute("selectmode");
+ getWidgetForPaintable().selectable = !"none".equals(selectMode);
+ getWidgetForPaintable().isMultiselect = "multi".equals(selectMode);
+
+ if (getWidgetForPaintable().isMultiselect) {
+ getWidgetForPaintable().multiSelectMode = uidl
+ .getIntAttribute("multiselectmode");
+ }
+
+ getWidgetForPaintable().selectedIds = uidl
+ .getStringArrayVariableAsSet("selected");
+
+ // Update lastSelection and focusedNode to point to *actual* nodes again
+ // after the old ones have been cleared from the body. This fixes focus
+ // and keyboard navigation issues as described in #7057 and other
+ // tickets.
+ if (getWidgetForPaintable().lastSelection != null) {
+ getWidgetForPaintable().lastSelection = getWidgetForPaintable()
+ .getNodeByKey(getWidgetForPaintable().lastSelection.key);
+ }
+ if (getWidgetForPaintable().focusedNode != null) {
+ getWidgetForPaintable().setFocusedNode(
+ getWidgetForPaintable().getNodeByKey(
+ getWidgetForPaintable().focusedNode.key));
+ }
+
+ if (getWidgetForPaintable().lastSelection == null
+ && getWidgetForPaintable().focusedNode == null
+ && !getWidgetForPaintable().selectedIds.isEmpty()) {
+ getWidgetForPaintable().setFocusedNode(
+ getWidgetForPaintable().getNodeByKey(
+ getWidgetForPaintable().selectedIds.iterator()
+ .next()));
+ getWidgetForPaintable().focusedNode.setFocused(false);
+ }
+
+ getWidgetForPaintable().rendering = false;
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTree.class);
+ }
+
+ @Override
+ public VTree getWidgetForPaintable() {
+ return (VTree) super.getWidgetForPaintable();
+ }
+
+ private void handleUpdate(UIDL uidl) {
+ final TreeNode rootNode = getWidgetForPaintable().getNodeByKey(
+ uidl.getStringAttribute("rootKey"));
+ if (rootNode != null) {
+ if (!rootNode.getState()) {
+ // expanding node happened server side
+ rootNode.setState(true, false);
+ }
+ renderChildNodes(rootNode, (Iterator) uidl.getChildIterator());
+ }
+ }
+
+ /**
+ * Registers action for the root and also for individual nodes
+ *
+ * @param uidl
+ */
+ private void updateActionMap(UIDL uidl) {
+ final Iterator<?> it = uidl.getChildIterator();
+ while (it.hasNext()) {
+ final UIDL action = (UIDL) it.next();
+ final String key = action.getStringAttribute("key");
+ final String caption = action.getStringAttribute("caption");
+ String iconUrl = null;
+ if (action.hasAttribute("icon")) {
+ iconUrl = getConnection().translateVaadinUri(
+ action.getStringAttribute("icon"));
+ }
+ getWidgetForPaintable().registerAction(key, caption, iconUrl);
+ }
+
+ }
+
+ public void updateNodeFromUIDL(TreeNode treeNode, UIDL uidl) {
+ String nodeKey = uidl.getStringAttribute("key");
+ treeNode.setText(uidl.getStringAttribute("caption"));
+ treeNode.key = nodeKey;
+
+ getWidgetForPaintable().registerNode(treeNode);
+
+ if (uidl.hasAttribute("al")) {
+ treeNode.actionKeys = uidl.getStringArrayAttribute("al");
+ }
+
+ if (uidl.getTag().equals("node")) {
+ if (uidl.getChildCount() == 0) {
+ treeNode.childNodeContainer.setVisible(false);
+ } else {
+ renderChildNodes(treeNode, (Iterator) uidl.getChildIterator());
+ treeNode.childrenLoaded = true;
+ }
+ } else {
+ treeNode.addStyleName(TreeNode.CLASSNAME + "-leaf");
+ }
+ if (uidl.hasAttribute("style")) {
+ treeNode.setNodeStyleName(uidl.getStringAttribute("style"));
+ }
+
+ String description = uidl.getStringAttribute("descr");
+ if (description != null && getConnection() != null) {
+ // Set tooltip
+ TooltipInfo info = new TooltipInfo(description);
+ getConnection().registerTooltip(this, nodeKey, info);
+ } else {
+ // Remove possible previous tooltip
+ getConnection().registerTooltip(this, nodeKey, null);
+ }
+
+ if (uidl.getBooleanAttribute("expanded") && !treeNode.getState()) {
+ treeNode.setState(true, false);
+ }
+
+ if (uidl.getBooleanAttribute("selected")) {
+ treeNode.setSelected(true);
+ // ensure that identifier is in selectedIds array (this may be a
+ // partial update)
+ getWidgetForPaintable().selectedIds.add(nodeKey);
+ }
+
+ treeNode.setIcon(uidl.getStringAttribute("icon"));
+ }
+
+ void renderChildNodes(TreeNode containerNode, Iterator<UIDL> i) {
+ containerNode.childNodeContainer.clear();
+ containerNode.childNodeContainer.setVisible(true);
+ while (i.hasNext()) {
+ final UIDL childUidl = i.next();
+ // actions are in bit weird place, don't mix them with children,
+ // but current node's actions
+ if ("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
+ continue;
+ }
+ final TreeNode childTree = getWidgetForPaintable().new TreeNode();
+ updateNodeFromUIDL(childTree, childUidl);
+ containerNode.childNodeContainer.add(childTree);
+ if (!i.hasNext()) {
+ childTree
+ .addStyleDependentName(childTree.isLeaf() ? "leaf-last"
+ : "last");
+ childTree.childNodeContainer.addStyleDependentName("last");
+ }
+ }
+ containerNode.childrenLoaded = true;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
index 0eddca0ed3..f0c284c2d0 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
@@ -223,29 +223,6 @@ public class VTreeTable extends VScrollTable {
}
}
- @Override
- public RenderSpace getAllocatedSpace(Widget child) {
- if (widgetInHierarchyColumn == child) {
- final int hierarchyAndIconWidth = getHierarchyAndIconWidth();
- final RenderSpace allocatedSpace = super
- .getAllocatedSpace(child);
- return new RenderSpace() {
- @Override
- public int getWidth() {
- return allocatedSpace.getWidth()
- - hierarchyAndIconWidth;
- }
-
- @Override
- public int getHeight() {
- return allocatedSpace.getHeight();
- }
-
- };
- }
- return super.getAllocatedSpace(child);
- }
-
private int getHierarchyAndIconWidth() {
int consumedSpace = treeSpacer.getOffsetWidth();
if (treeSpacer.getParentElement().getChildCount() > 2) {
@@ -824,4 +801,27 @@ public class VTreeTable extends VScrollTable {
int newTotalRows = uidl.getIntAttribute("totalrows");
setTotalRows(newTotalRows);
}
+
+ @Override
+ public RenderSpace getAllocatedSpace(Widget child) {
+ VTreeTableRow row = (VTreeTableRow) child.getParent();
+ if (row.widgetInHierarchyColumn == child) {
+ final int hierarchyAndIconWidth = row.getHierarchyAndIconWidth();
+ final RenderSpace allocatedSpace = super.getAllocatedSpace(child);
+ return new RenderSpace() {
+ @Override
+ public int getWidth() {
+ return allocatedSpace.getWidth() - hierarchyAndIconWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return allocatedSpace.getHeight();
+ }
+
+ };
+ }
+ return super.getAllocatedSpace(child);
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
index 9b6f03f612..8c159f43de 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
@@ -1,101 +1,101 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
-import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;
-
-public class VTreeTablePaintable extends VScrollTablePaintable {
- public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- FocusableScrollPanel widget = null;
- int scrollPosition = 0;
- if (getWidgetForPaintable().collapseRequest) {
- widget = (FocusableScrollPanel) getWidgetForPaintable()
- .getWidget(1);
- scrollPosition = widget.getScrollPosition();
- }
- getWidgetForPaintable().animationsEnabled = uidl
- .getBooleanAttribute("animate");
- getWidgetForPaintable().colIndexOfHierarchy = uidl
- .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
- .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
- int oldTotalRows = getWidgetForPaintable().getTotalRows();
- super.updateFromUIDL(uidl, client);
- if (getWidgetForPaintable().collapseRequest) {
- if (getWidgetForPaintable().collapsedRowKey != null
- && getWidgetForPaintable().scrollBody != null) {
- VScrollTableRow row = getWidgetForPaintable()
- .getRenderedRowByKey(
- getWidgetForPaintable().collapsedRowKey);
- if (row != null) {
- getWidgetForPaintable().setRowFocus(row);
- getWidgetForPaintable().focus();
- }
- }
-
- int scrollPosition2 = widget.getScrollPosition();
- if (scrollPosition != scrollPosition2) {
- widget.setScrollPosition(scrollPosition);
- }
-
- // check which rows are needed from the server and initiate a
- // deferred fetch
- getWidgetForPaintable().onScroll(null);
- }
- // Recalculate table size if collapse request, or if page length is zero
- // (not sent by server) and row count changes (#7908).
- if (getWidgetForPaintable().collapseRequest
- || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()
- .getTotalRows() != oldTotalRows)) {
- /*
- * Ensure that possibly removed/added scrollbars are considered.
- * Triggers row calculations, removes cached rows etc. Basically
- * cleans up state. Be careful if touching this, you will break
- * pageLength=0 if you remove this.
- */
- getWidgetForPaintable().triggerLazyColumnAdjustment(true);
-
- getWidgetForPaintable().collapseRequest = false;
- }
- if (uidl.hasAttribute("focusedRow")) {
- String key = uidl.getStringAttribute("focusedRow");
- getWidgetForPaintable().setRowFocus(
- getWidgetForPaintable().getRenderedRowByKey(key));
- getWidgetForPaintable().focusParentResponsePending = false;
- } else if (uidl.hasAttribute("clearFocusPending")) {
- // Special case to detect a response to a focusParent request that
- // does not return any focusedRow because the selected node has no
- // parent
- getWidgetForPaintable().focusParentResponsePending = false;
- }
-
- while (!getWidgetForPaintable().collapseRequest
- && !getWidgetForPaintable().focusParentResponsePending
- && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {
- // Keep replaying any queued events as long as we don't have any
- // potential content changes pending
- PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents
- .removeFirst();
- getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,
- event.shift);
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VTreeTable.class);
- }
-
- @Override
- public VTreeTable getWidgetForPaintable() {
- return (VTreeTable) super.getWidgetForPaintable();
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
+import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;
+
+public class VTreeTablePaintable extends VScrollTablePaintable {
+ public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ FocusableScrollPanel widget = null;
+ int scrollPosition = 0;
+ if (getWidgetForPaintable().collapseRequest) {
+ widget = (FocusableScrollPanel) getWidgetForPaintable()
+ .getWidget(1);
+ scrollPosition = widget.getScrollPosition();
+ }
+ getWidgetForPaintable().animationsEnabled = uidl
+ .getBooleanAttribute("animate");
+ getWidgetForPaintable().colIndexOfHierarchy = uidl
+ .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
+ .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
+ int oldTotalRows = getWidgetForPaintable().getTotalRows();
+ super.updateFromUIDL(uidl, client);
+ if (getWidgetForPaintable().collapseRequest) {
+ if (getWidgetForPaintable().collapsedRowKey != null
+ && getWidgetForPaintable().scrollBody != null) {
+ VScrollTableRow row = getWidgetForPaintable()
+ .getRenderedRowByKey(
+ getWidgetForPaintable().collapsedRowKey);
+ if (row != null) {
+ getWidgetForPaintable().setRowFocus(row);
+ getWidgetForPaintable().focus();
+ }
+ }
+
+ int scrollPosition2 = widget.getScrollPosition();
+ if (scrollPosition != scrollPosition2) {
+ widget.setScrollPosition(scrollPosition);
+ }
+
+ // check which rows are needed from the server and initiate a
+ // deferred fetch
+ getWidgetForPaintable().onScroll(null);
+ }
+ // Recalculate table size if collapse request, or if page length is zero
+ // (not sent by server) and row count changes (#7908).
+ if (getWidgetForPaintable().collapseRequest
+ || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()
+ .getTotalRows() != oldTotalRows)) {
+ /*
+ * Ensure that possibly removed/added scrollbars are considered.
+ * Triggers row calculations, removes cached rows etc. Basically
+ * cleans up state. Be careful if touching this, you will break
+ * pageLength=0 if you remove this.
+ */
+ getWidgetForPaintable().triggerLazyColumnAdjustment(true);
+
+ getWidgetForPaintable().collapseRequest = false;
+ }
+ if (uidl.hasAttribute("focusedRow")) {
+ String key = uidl.getStringAttribute("focusedRow");
+ getWidgetForPaintable().setRowFocus(
+ getWidgetForPaintable().getRenderedRowByKey(key));
+ getWidgetForPaintable().focusParentResponsePending = false;
+ } else if (uidl.hasAttribute("clearFocusPending")) {
+ // Special case to detect a response to a focusParent request that
+ // does not return any focusedRow because the selected node has no
+ // parent
+ getWidgetForPaintable().focusParentResponsePending = false;
+ }
+
+ while (!getWidgetForPaintable().collapseRequest
+ && !getWidgetForPaintable().focusParentResponsePending
+ && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {
+ // Keep replaying any queued events as long as we don't have any
+ // potential content changes pending
+ PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents
+ .removeFirst();
+ getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,
+ event.shift);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTreeTable.class);
+ }
+
+ @Override
+ public VTreeTable getWidgetForPaintable() {
+ return (VTreeTable) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
index 3a5d5f3b41..a7fe89017b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java
@@ -26,8 +26,6 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
@@ -157,18 +155,7 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
return selectionsCaption;
}
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Captions are updated before super call to ensure the widths are set
- // correctly
- if (!uidl.getBooleanAttribute("cached")) {
- updateCaptions(uidl);
- }
-
- super.updateFromUIDL(uidl, client);
- }
-
- private void updateCaptions(UIDL uidl) {
+ protected void updateCaptions(UIDL uidl) {
String leftCaption = (uidl.hasAttribute(ATTRIBUTE_LEFT_CAPTION) ? uidl
.getStringAttribute(ATTRIBUTE_LEFT_CAPTION) : null);
String rightCaption = (uidl.hasAttribute(ATTRIBUTE_RIGHT_CAPTION) ? uidl
@@ -297,7 +284,7 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
Set<String> movedItems = moveSelectedItems(options, selections);
selectedKeys.addAll(movedItems);
- client.updateVariable(id, "selected",
+ client.updateVariable(paintableId, "selected",
selectedKeys.toArray(new String[selectedKeys.size()]),
isImmediate());
}
@@ -306,7 +293,7 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
Set<String> movedItems = moveSelectedItems(selections, options);
selectedKeys.removeAll(movedItems);
- client.updateVariable(id, "selected",
+ client.updateVariable(paintableId, "selected",
selectedKeys.toArray(new String[selectedKeys.size()]),
isImmediate());
}
@@ -628,8 +615,4 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
return null;
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelectPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelectPaintable.java
new file mode 100644
index 0000000000..ce176113da
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelectPaintable.java
@@ -0,0 +1,34 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VTwinColSelectPaintable extends VOptionGroupBasePaintable {
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Captions are updated before super call to ensure the widths are set
+ // correctly
+ if (!uidl.getBooleanAttribute("cached")) {
+ getWidgetForPaintable().updateCaptions(uidl);
+ }
+
+ super.updateFromUIDL(uidl, client);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTwinColSelect.class);
+ }
+
+ @Override
+ public VTwinColSelect getWidgetForPaintable() {
+ return (VTwinColSelect) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
index 5b3790f521..ad702430f6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java
@@ -6,19 +6,14 @@ package com.vaadin.terminal.gwt.client.ui;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.SimpleTree;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VUIDLBrowser;
-public class VUnknownComponent extends Composite implements VPaintableWidget {
+public class VUnknownComponent extends Composite {
com.google.gwt.user.client.ui.Label caption = new com.google.gwt.user.client.ui.Label();;
SimpleTree uidlTree;
- private VerticalPanel panel;
- private String serverClassName = "unkwnown";
+ protected VerticalPanel panel;
+ protected String serverClassName = "unkwnown";
public VUnknownComponent() {
panel = new VerticalPanel();
@@ -32,33 +27,7 @@ public class VUnknownComponent extends Composite implements VPaintableWidget {
this.serverClassName = serverClassName;
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
- setCaption("Widgetset does not contain implementation for "
- + serverClassName
- + ". Check its @ClientWidget mapping, widgetsets "
- + "GWT module description file and re-compile your"
- + " widgetset. In case you have downloaded a vaadin"
- + " add-on package, you might want to refer to "
- + "<a href='http://vaadin.com/using-addons'>add-on "
- + "instructions</a>. Unrendered UIDL:");
- if (uidlTree != null) {
- uidlTree.removeFromParent();
- }
-
- uidlTree = new VUIDLBrowser(uidl, client.getConfiguration());
- uidlTree.open(true);
- uidlTree.setText("Unrendered UIDL");
- panel.add(uidlTree);
- }
-
public void setCaption(String c) {
caption.getElement().setInnerHTML(c);
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponentPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponentPaintable.java
new file mode 100644
index 0000000000..252d7528ca
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponentPaintable.java
@@ -0,0 +1,52 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VUIDLBrowser;
+
+public class VUnknownComponentPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+ getWidgetForPaintable().setCaption(
+ "Widgetset does not contain implementation for "
+ + getWidgetForPaintable().serverClassName
+ + ". Check its @ClientWidget mapping, widgetsets "
+ + "GWT module description file and re-compile your"
+ + " widgetset. In case you have downloaded a vaadin"
+ + " add-on package, you might want to refer to "
+ + "<a href='http://vaadin.com/using-addons'>add-on "
+ + "instructions</a>. Unrendered UIDL:");
+ if (getWidgetForPaintable().uidlTree != null) {
+ getWidgetForPaintable().uidlTree.removeFromParent();
+ }
+
+ getWidgetForPaintable().uidlTree = new VUIDLBrowser(uidl,
+ client.getConfiguration());
+ getWidgetForPaintable().uidlTree.open(true);
+ getWidgetForPaintable().uidlTree.setText("Unrendered UIDL");
+ getWidgetForPaintable().panel.add(getWidgetForPaintable().uidlTree);
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VUnknownComponent.class);
+ }
+
+ @Override
+ public VUnknownComponent getWidgetForPaintable() {
+ return (VUnknownComponent) super.getWidgetForPaintable();
+ }
+
+ public void setServerSideClassName(String serverClassName) {
+ getWidgetForPaintable().setServerSideClassName(serverClassName);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
index 66894417f3..bc94ae317a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
@@ -21,12 +21,9 @@ import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
/**
@@ -35,7 +32,7 @@ import com.vaadin.terminal.gwt.client.VTooltip;
* events even though the upload component is already detached.
*
*/
-public class VUpload extends SimplePanel implements VPaintableWidget {
+public class VUpload extends SimplePanel {
private final class MyFileUpload extends FileUpload {
@Override
@@ -73,19 +70,19 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
ApplicationConnection client;
- private String paintableId;
+ protected String paintableId;
/**
* Button that initiates uploading
*/
- private final VButton submitButton;
+ protected final VButton submitButton;
/**
* When expecting big files, programmer may initiate some UI changes when
* uploading the file starts. Bit after submitting file we'll visit the
* server to check possible changes.
*/
- private Timer t;
+ protected Timer t;
/**
* some browsers tries to send form twice if submit is called in button
@@ -100,11 +97,11 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
private Hidden maxfilesize = new Hidden();
- private FormElement element;
+ protected FormElement element;
private com.google.gwt.dom.client.Element synthesizedFrame;
- private int nextUploadId;
+ protected int nextUploadId;
public VUpload() {
super(com.google.gwt.dom.client.Document.get().createFormElement());
@@ -137,7 +134,7 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
@Override
public void onBrowserEvent(Event event) {
if ((event.getTypeInt() & VTooltip.TOOLTIP_EVENTS) > 0) {
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
super.onBrowserEvent(event);
}
@@ -147,43 +144,7 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
form.enctype = encoding;
}-*/;
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- if (uidl.hasAttribute("notStarted")) {
- t.schedule(400);
- return;
- }
- if (uidl.hasAttribute("forceSubmit")) {
- submit();
- return;
- }
- setImmediate(uidl.getBooleanAttribute("immediate"));
- this.client = client;
- paintableId = uidl.getId();
- nextUploadId = uidl.getIntAttribute("nextid");
- final String action = client.translateVaadinUri(uidl
- .getStringVariable("action"));
- element.setAction(action);
- if (uidl.hasAttribute("buttoncaption")) {
- submitButton.setText(uidl.getStringAttribute("buttoncaption"));
- submitButton.setVisible(true);
- } else {
- submitButton.setVisible(false);
- }
- fu.setName(paintableId + "_file");
-
- if (uidl.hasAttribute("disabled") || uidl.hasAttribute("readonly")) {
- disableUpload();
- } else if (!uidl.getBooleanAttribute("state")) {
- // Enable the button only if an upload is not in progress
- enableUpload();
- ensureTargetFrame();
- }
- }
-
- private void setImmediate(boolean booleanAttribute) {
+ protected void setImmediate(boolean booleanAttribute) {
if (immediate != booleanAttribute) {
immediate = booleanAttribute;
if (immediate) {
@@ -277,7 +238,7 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
});
}
- private void submit() {
+ protected void submit() {
if (fu.getFilename().length() == 0 || submitted || !enabled) {
VConsole.log("Submit cancelled (disabled, no file or already submitted)");
return;
@@ -315,15 +276,12 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
}
}
- private void ensureTargetFrame() {
+ protected void ensureTargetFrame() {
if (synthesizedFrame == null) {
// Attach a hidden IFrame to the form. This is the target iframe to
- // which
- // the form will be submitted. We have to create the iframe using
- // innerHTML,
- // because setting an iframe's 'name' property dynamically doesn't
- // work on
- // most browsers.
+ // which the form will be submitted. We have to create the iframe
+ // using innerHTML, because setting an iframe's 'name' property
+ // dynamically doesn't work on most browsers.
DivElement dummy = Document.get().createDivElement();
dummy.setInnerHTML("<iframe src=\"javascript:''\" name='"
+ getFrameName()
@@ -354,9 +312,4 @@ public class VUpload extends SimplePanel implements VPaintableWidget {
synthesizedFrame = null;
}
}
-
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUploadPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VUploadPaintable.java
new file mode 100644
index 0000000000..7fd59fc176
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUploadPaintable.java
@@ -0,0 +1,62 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VUploadPaintable extends VAbstractPaintableWidget {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+ if (uidl.hasAttribute("notStarted")) {
+ getWidgetForPaintable().t.schedule(400);
+ return;
+ }
+ if (uidl.hasAttribute("forceSubmit")) {
+ getWidgetForPaintable().submit();
+ return;
+ }
+ getWidgetForPaintable().setImmediate(
+ uidl.getBooleanAttribute("immediate"));
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getId();
+ getWidgetForPaintable().nextUploadId = uidl.getIntAttribute("nextid");
+ final String action = client.translateVaadinUri(uidl
+ .getStringVariable("action"));
+ getWidgetForPaintable().element.setAction(action);
+ if (uidl.hasAttribute("buttoncaption")) {
+ getWidgetForPaintable().submitButton.setText(uidl
+ .getStringAttribute("buttoncaption"));
+ getWidgetForPaintable().submitButton.setVisible(true);
+ } else {
+ getWidgetForPaintable().submitButton.setVisible(false);
+ }
+ getWidgetForPaintable().fu.setName(getWidgetForPaintable().paintableId
+ + "_file");
+
+ if (uidl.hasAttribute("disabled") || uidl.hasAttribute("readonly")) {
+ getWidgetForPaintable().disableUpload();
+ } else if (!uidl.getBooleanAttribute("state")) {
+ // Enable the button only if an upload is not in progress
+ getWidgetForPaintable().enableUpload();
+ getWidgetForPaintable().ensureTargetFrame();
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VUpload.class);
+ }
+
+ @Override
+ public VUpload getWidgetForPaintable() {
+ return (VUpload) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java
new file mode 100644
index 0000000000..71c6d91c69
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalLayoutPaintable.java
@@ -0,0 +1,20 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VVerticalLayoutPaintable extends VOrderedLayoutPaintable {
+
+ @Override
+ public VVerticalLayout getWidgetForPaintable() {
+ return (VVerticalLayout) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected VVerticalLayout createWidget() {
+ return GWT.create(VVerticalLayout.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
new file mode 100644
index 0000000000..a2dc1fbbb2
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVerticalSplitPanelPaintable.java
@@ -0,0 +1,15 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+
+public class VVerticalSplitPanelPaintable extends VAbstractSplitPanelPaintable {
+
+ @Override
+ protected VAbstractSplitPanel createWidget() {
+ return GWT.create(VSplitPanelVertical.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
index a9a46671be..53b79344cf 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VVideoPaintable.java
@@ -1,38 +1,41 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VVideoPaintable extends VMediaBasePaintable {
- public static final String ATTR_POSTER = "poster";
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
- super.updateFromUIDL(uidl, client);
- setPosterFromUIDL(uidl);
- }
-
- private void setPosterFromUIDL(UIDL uidl) {
- if (uidl.hasAttribute(ATTR_POSTER)) {
- getWidgetForPaintable().setPoster(
- getConnection().translateVaadinUri(
- uidl.getStringAttribute(ATTR_POSTER)));
- }
- }
-
- @Override
- public VVideo getWidgetForPaintable() {
- return (VVideo) super.getWidgetForPaintable();
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VVideo.class);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VVideoPaintable extends VMediaBasePaintable {
+ public static final String ATTR_POSTER = "poster";
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+ super.updateFromUIDL(uidl, client);
+ setPosterFromUIDL(uidl);
+ }
+
+ private void setPosterFromUIDL(UIDL uidl) {
+ if (uidl.hasAttribute(ATTR_POSTER)) {
+ getWidgetForPaintable().setPoster(
+ getConnection().translateVaadinUri(
+ uidl.getStringAttribute(ATTR_POSTER)));
+ }
+ }
+
+ @Override
+ public VVideo getWidgetForPaintable() {
+ return (VVideo) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VVideo.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java
index e3aba21096..ea5610cdaa 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VView.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java
@@ -5,8 +5,6 @@
package com.vaadin.terminal.gwt.client.ui;
import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -17,12 +15,10 @@ import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
-import com.google.gwt.event.dom.client.DomEvent.Type;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
@@ -30,7 +26,6 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
@@ -56,15 +51,15 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
public static final String NOTIFICATION_HTML_CONTENT_NOT_ALLOWED = "useplain";
- private String theme;
+ String theme;
- private VPaintableWidget layout;
+ VPaintableWidget layout;
- private final LinkedHashSet<VWindow> subWindows = new LinkedHashSet<VWindow>();
+ final LinkedHashSet<VWindow> subWindows = new LinkedHashSet<VWindow>();
- private String id;
+ String id;
- private ShortcutActionHandler actionHandler;
+ ShortcutActionHandler actionHandler;
/** stored width for IE resize optimization */
private int width;
@@ -72,7 +67,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
/** stored height for IE resize optimization */
private int height;
- private ApplicationConnection connection;
+ ApplicationConnection connection;
/** Identifies the click event */
public static final String CLICK_EVENT_ID = "click";
@@ -85,17 +80,17 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
*/
private Timer resizeTimer;
- private int scrollTop;
+ int scrollTop;
- private int scrollLeft;
+ int scrollLeft;
- private boolean rendering;
+ boolean rendering;
- private boolean scrollable;
+ boolean scrollable;
- private boolean immediate;
+ boolean immediate;
- private boolean resizeLazy = false;
+ boolean resizeLazy = false;
/**
* Attribute name for the lazy resize setting .
@@ -106,7 +101,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
* Reference to the parent frame/iframe. Null if there is no parent (i)frame
* or if the application and parent frame are in different domains.
*/
- private Element parentFrame;
+ Element parentFrame;
private HandlerRegistration historyHandlerRegistration;
@@ -114,7 +109,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
* The current URI fragment, used to avoid sending updates if nothing has
* changed.
*/
- private String currentFragment;
+ String currentFragment;
/**
* Listener for URI fragment changes. Notifies the server of the new value
@@ -133,16 +128,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
}
};
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- VPanel.CLICK_EVENT_IDENTIFIER) {
-
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
-
private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200,
new ScheduledCommand() {
public void execute() {
@@ -212,7 +197,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
/**
* Used to reload host page on theme changes.
*/
- private static native void reloadHostPage()
+ static native void reloadHostPage()
/*-{
$wnd.location.reload();
}-*/;
@@ -223,7 +208,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
* @param script
* Script to be executed.
*/
- private static native void eval(String script)
+ static native void eval(String script)
/*-{
try {
if (script == null) return;
@@ -244,229 +229,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
.contains(ApplicationConnection.GENERATED_BODY_CLASSNAME);
}
- public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
- rendering = true;
-
- id = uidl.getId();
- boolean firstPaint = connection == null;
- connection = client;
-
- immediate = uidl.hasAttribute("immediate");
- resizeLazy = uidl.hasAttribute(RESIZE_LAZY);
- String newTheme = uidl.getStringAttribute("theme");
- if (theme != null && !newTheme.equals(theme)) {
- // Complete page refresh is needed due css can affect layout
- // calculations etc
- reloadHostPage();
- } else {
- theme = newTheme;
- }
- if (uidl.hasAttribute("style")) {
- setStyleName(getStylePrimaryName() + " "
- + uidl.getStringAttribute("style"));
- }
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- if (!isEmbedded() && uidl.hasAttribute("caption")) {
- // only change window title if we're in charge of the whole page
- com.google.gwt.user.client.Window.setTitle(uidl
- .getStringAttribute("caption"));
- }
-
- // Process children
- int childIndex = 0;
-
- // Open URL:s
- boolean isClosed = false; // was this window closed?
- while (childIndex < uidl.getChildCount()
- && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
- final UIDL open = uidl.getChildUIDL(childIndex);
- final String url = client.translateVaadinUri(open
- .getStringAttribute("src"));
- final String target = open.getStringAttribute("name");
- if (target == null) {
- // source will be opened to this browser window, but we may have
- // to finish rendering this window in case this is a download
- // (and window stays open).
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- goTo(url);
- }
- });
- } else if ("_self".equals(target)) {
- // This window is closing (for sure). Only other opens are
- // relevant in this change. See #3558, #2144
- isClosed = true;
- goTo(url);
- } else {
- String options;
- if (open.hasAttribute("border")) {
- if (open.getStringAttribute("border").equals("minimal")) {
- options = "menubar=yes,location=no,status=no";
- } else {
- options = "menubar=no,location=no,status=no";
- }
-
- } else {
- options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
- }
-
- if (open.hasAttribute("width")) {
- int w = open.getIntAttribute("width");
- options += ",width=" + w;
- }
- if (open.hasAttribute("height")) {
- int h = open.getIntAttribute("height");
- options += ",height=" + h;
- }
-
- Window.open(url, target, options);
- }
- childIndex++;
- }
- if (isClosed) {
- // don't render the content, something else will be opened to this
- // browser view
- rendering = false;
- return;
- }
-
- // Draw this application level window
- UIDL childUidl = uidl.getChildUIDL(childIndex);
- final VPaintableWidget lo = client.getPaintable(childUidl);
-
- if (layout != null) {
- if (layout != lo) {
- // remove old
- client.unregisterPaintable(layout);
- // add new
- setWidget(lo.getWidgetForPaintable());
- layout = lo;
- }
- } else {
- setWidget(lo.getWidgetForPaintable());
- layout = lo;
- }
-
- layout.updateFromUIDL(childUidl, client);
- if (!childUidl.getBooleanAttribute("cached")) {
- updateParentFrameSize();
- }
-
- // Save currently open subwindows to track which will need to be closed
- final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(
- subWindows);
-
- // Handle other UIDL children
- while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {
- String tag = childUidl.getTag().intern();
- if (tag == "actions") {
- if (actionHandler == null) {
- actionHandler = new ShortcutActionHandler(id, client);
- }
- actionHandler.updateActionMap(childUidl);
- } else if (tag == "execJS") {
- String script = childUidl.getStringAttribute("script");
- eval(script);
- } else if (tag == "notifications") {
- for (final Iterator<?> it = childUidl.getChildIterator(); it
- .hasNext();) {
- final UIDL notification = (UIDL) it.next();
- VNotification.showNotification(client, notification);
- }
- } else {
- // subwindows
- final VPaintableWidget w = client.getPaintable(childUidl);
- if (subWindows.contains(w)) {
- removedSubWindows.remove(w);
- } else {
- subWindows.add((VWindow) w);
- }
- w.updateFromUIDL(childUidl, client);
- }
- }
-
- // Close old windows which where not in UIDL anymore
- for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem
- .hasNext();) {
- final VWindow w = rem.next();
- client.unregisterPaintable(w);
- subWindows.remove(w);
- w.hide();
- }
-
- if (uidl.hasAttribute("focused")) {
- // set focused component when render phase is finished
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- VPaintableWidget paintable = (VPaintableWidget) uidl
- .getPaintableAttribute("focused", connection);
-
- final Widget toBeFocused = paintable
- .getWidgetForPaintable();
- /*
- * Two types of Widgets can be focused, either implementing
- * GWT HasFocus of a thinner Vaadin specific Focusable
- * interface.
- */
- if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
- final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
- toBeFocusedWidget.setFocus(true);
- } else if (toBeFocused instanceof Focusable) {
- ((Focusable) toBeFocused).focus();
- } else {
- VConsole.log("Could not focus component");
- }
- }
- });
- }
-
- // Add window listeners on first paint, to prevent premature
- // variablechanges
- if (firstPaint) {
- Window.addWindowClosingHandler(this);
- Window.addResizeHandler(this);
- }
-
- onResize();
-
- // finally set scroll position from UIDL
- if (uidl.hasVariable("scrollTop")) {
- scrollable = true;
- scrollTop = uidl.getIntVariable("scrollTop");
- DOM.setElementPropertyInt(getElement(), "scrollTop", scrollTop);
- scrollLeft = uidl.getIntVariable("scrollLeft");
- DOM.setElementPropertyInt(getElement(), "scrollLeft", scrollLeft);
- } else {
- scrollable = false;
- }
-
- // Safari workaround must be run after scrollTop is updated as it sets
- // scrollTop using a deferred command.
- if (BrowserInfo.get().isSafari()) {
- Util.runWebkitOverflowAutoFix(getElement());
- }
-
- scrollIntoView(uidl);
-
- if (uidl.hasAttribute(FRAGMENT_VARIABLE)) {
- currentFragment = uidl.getStringAttribute(FRAGMENT_VARIABLE);
- if (!currentFragment.equals(History.getToken())) {
- History.newItem(currentFragment, true);
- }
- } else {
- // Initial request for which the server doesn't yet have a fragment
- // (and haven't shown any interest in getting one)
- currentFragment = History.getToken();
-
- // Include current fragment in the next request
- client.updateVariable(id, FRAGMENT_VARIABLE, currentFragment, false);
- }
-
- rendering = false;
- }
-
/**
* Tries to scroll paintable referenced from given UIDL snippet to be
* visible.
@@ -530,7 +292,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
/**
* Called when a resize event is received.
*/
- private void onResize() {
+ void onResize() {
/*
* IE (pre IE9 at least) will give us some false resize events due to
* problems with scrollbars. Firefox 3 might also produce some extra
@@ -742,7 +504,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
}
- private void updateParentFrameSize() {
+ void updateParentFrameSize() {
if (parentFrame == null) {
return;
}
@@ -754,7 +516,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
parentFrame.getStyle().setPropertyPx("height", childHeight);
}
- private static native Element getParentFrame()
+ static native Element getParentFrame()
/*-{
try {
var frameElement = $wnd.frameElement;
@@ -769,10 +531,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
return null;
}-*/;
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP Subwindows never draw caption for their first child (layout)
- }
-
/**
* Return an iterator for current subwindows. This method is meant for
* testing purposes only.
@@ -787,42 +545,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
return windows;
}
- public void init(String rootPanelId,
- ApplicationConnection applicationConnection) {
- DOM.sinkEvents(getElement(), Event.ONKEYDOWN | Event.ONSCROLL);
-
- // iview is focused when created so element needs tabIndex
- // 1 due 0 is at the end of natural tabbing order
- DOM.setElementProperty(getElement(), "tabIndex", "1");
-
- RootPanel root = RootPanel.get(rootPanelId);
-
- // Remove the v-app-loading or any splash screen added inside the div by
- // the user
- root.getElement().setInnerHTML("");
- // For backwards compatibility with static index pages only.
- // No longer added by AbstractApplicationServlet/Portlet
- root.removeStyleName("v-app-loading");
-
- String themeUri = applicationConnection.getConfiguration()
- .getThemeUri();
- String themeName = themeUri.substring(themeUri.lastIndexOf('/'));
- themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");
- root.addStyleName("v-theme-" + themeName);
-
- root.add(this);
-
- if (applicationConnection.getConfiguration().isStandalone()) {
- // set focus to iview element by default to listen possible keyboard
- // shortcuts. For embedded applications this is unacceptable as we
- // don't want to steal focus from the main page nor we don't want
- // side-effects from focusing (scrollIntoView).
- getElement().focus();
- }
-
- parentFrame = getParentFrame();
- }
-
public ShortcutActionHandler getShortcutActionHandler() {
return actionHandler;
}
@@ -831,8 +553,4 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
getElement().focus();
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
new file mode 100644
index 0000000000..94e7bfd9af
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java
@@ -0,0 +1,338 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.Focusable;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VViewPaintable extends VAbstractPaintableWidgetContainer {
+
+ private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
+
+ public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+ // As VView is not created in the same way as all other paintables we
+ // have to set the id here
+ setId(uidl.getId());
+ getWidgetForPaintable().id = uidl.getId();
+ boolean firstPaint = getWidgetForPaintable().connection == null;
+ getWidgetForPaintable().connection = client;
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+ getWidgetForPaintable().resizeLazy = uidl
+ .hasAttribute(VView.RESIZE_LAZY);
+ String newTheme = uidl.getStringAttribute("theme");
+ if (getWidgetForPaintable().theme != null
+ && !newTheme.equals(getWidgetForPaintable().theme)) {
+ // Complete page refresh is needed due css can affect layout
+ // calculations etc
+ getWidgetForPaintable().reloadHostPage();
+ } else {
+ getWidgetForPaintable().theme = newTheme;
+ }
+ if (uidl.hasAttribute("style")) {
+ getWidgetForPaintable().setStyleName(
+ getWidgetForPaintable().getStylePrimaryName() + " "
+ + uidl.getStringAttribute("style"));
+ }
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ if (!getWidgetForPaintable().isEmbedded()
+ && uidl.hasAttribute("caption")) {
+ // only change window title if we're in charge of the whole page
+ com.google.gwt.user.client.Window.setTitle(uidl
+ .getStringAttribute("caption"));
+ }
+
+ // Process children
+ int childIndex = 0;
+
+ // Open URL:s
+ boolean isClosed = false; // was this window closed?
+ while (childIndex < uidl.getChildCount()
+ && "open".equals(uidl.getChildUIDL(childIndex).getTag())) {
+ final UIDL open = uidl.getChildUIDL(childIndex);
+ final String url = client.translateVaadinUri(open
+ .getStringAttribute("src"));
+ final String target = open.getStringAttribute("name");
+ if (target == null) {
+ // source will be opened to this browser window, but we may have
+ // to finish rendering this window in case this is a download
+ // (and window stays open).
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ VView.goTo(url);
+ }
+ });
+ } else if ("_self".equals(target)) {
+ // This window is closing (for sure). Only other opens are
+ // relevant in this change. See #3558, #2144
+ isClosed = true;
+ VView.goTo(url);
+ } else {
+ String options;
+ if (open.hasAttribute("border")) {
+ if (open.getStringAttribute("border").equals("minimal")) {
+ options = "menubar=yes,location=no,status=no";
+ } else {
+ options = "menubar=no,location=no,status=no";
+ }
+
+ } else {
+ options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes";
+ }
+
+ if (open.hasAttribute("width")) {
+ int w = open.getIntAttribute("width");
+ options += ",width=" + w;
+ }
+ if (open.hasAttribute("height")) {
+ int h = open.getIntAttribute("height");
+ options += ",height=" + h;
+ }
+
+ Window.open(url, target, options);
+ }
+ childIndex++;
+ }
+ if (isClosed) {
+ // don't render the content, something else will be opened to this
+ // browser view
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ // Draw this application level window
+ UIDL childUidl = uidl.getChildUIDL(childIndex);
+ final VPaintableWidget lo = client.getPaintable(childUidl);
+
+ if (getWidgetForPaintable().layout != null) {
+ if (getWidgetForPaintable().layout != lo) {
+ // remove old
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ // add new
+ getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+ } else {
+ getWidgetForPaintable().setWidget(lo.getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+
+ getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
+ if (!childUidl.getBooleanAttribute("cached")) {
+ getWidgetForPaintable().updateParentFrameSize();
+ }
+
+ // Save currently open subwindows to track which will need to be closed
+ final HashSet<VWindow> removedSubWindows = new HashSet<VWindow>(
+ getWidgetForPaintable().subWindows);
+
+ // Handle other UIDL children
+ while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) {
+ String tag = childUidl.getTag().intern();
+ if (tag == "actions") {
+ if (getWidgetForPaintable().actionHandler == null) {
+ getWidgetForPaintable().actionHandler = new ShortcutActionHandler(
+ getWidgetForPaintable().id, client);
+ }
+ getWidgetForPaintable().actionHandler
+ .updateActionMap(childUidl);
+ } else if (tag == "execJS") {
+ String script = childUidl.getStringAttribute("script");
+ VView.eval(script);
+ } else if (tag == "notifications") {
+ for (final Iterator<?> it = childUidl.getChildIterator(); it
+ .hasNext();) {
+ final UIDL notification = (UIDL) it.next();
+ VNotification.showNotification(client, notification);
+ }
+ } else {
+ // subwindows
+ final VWindowPaintable w = (VWindowPaintable) client
+ .getPaintable(childUidl);
+ VWindow windowWidget = w.getWidgetForPaintable();
+ if (getWidgetForPaintable().subWindows.contains(windowWidget)) {
+ removedSubWindows.remove(windowWidget);
+ } else {
+ getWidgetForPaintable().subWindows.add(windowWidget);
+ }
+ w.updateFromUIDL(childUidl, client);
+ }
+ }
+
+ // Close old windows which where not in UIDL anymore
+ for (final Iterator<VWindow> rem = removedSubWindows.iterator(); rem
+ .hasNext();) {
+ final VWindow w = rem.next();
+ client.unregisterPaintable(VPaintableMap.get(getConnection())
+ .getPaintable(w));
+ getWidgetForPaintable().subWindows.remove(w);
+ w.hide();
+ }
+
+ if (uidl.hasAttribute("focused")) {
+ // set focused component when render phase is finished
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ VPaintableWidget paintable = (VPaintableWidget) uidl
+ .getPaintableAttribute("focused", getConnection());
+
+ final Widget toBeFocused = paintable
+ .getWidgetForPaintable();
+ /*
+ * Two types of Widgets can be focused, either implementing
+ * GWT HasFocus of a thinner Vaadin specific Focusable
+ * interface.
+ */
+ if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) {
+ final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused;
+ toBeFocusedWidget.setFocus(true);
+ } else if (toBeFocused instanceof Focusable) {
+ ((Focusable) toBeFocused).focus();
+ } else {
+ VConsole.log("Could not focus component");
+ }
+ }
+ });
+ }
+
+ // Add window listeners on first paint, to prevent premature
+ // variablechanges
+ if (firstPaint) {
+ Window.addWindowClosingHandler(getWidgetForPaintable());
+ Window.addResizeHandler(getWidgetForPaintable());
+ }
+
+ getWidgetForPaintable().onResize();
+
+ // finally set scroll position from UIDL
+ if (uidl.hasVariable("scrollTop")) {
+ getWidgetForPaintable().scrollable = true;
+ getWidgetForPaintable().scrollTop = uidl
+ .getIntVariable("scrollTop");
+ DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
+ "scrollTop", getWidgetForPaintable().scrollTop);
+ getWidgetForPaintable().scrollLeft = uidl
+ .getIntVariable("scrollLeft");
+ DOM.setElementPropertyInt(getWidgetForPaintable().getElement(),
+ "scrollLeft", getWidgetForPaintable().scrollLeft);
+ } else {
+ getWidgetForPaintable().scrollable = false;
+ }
+
+ // Safari workaround must be run after scrollTop is updated as it sets
+ // scrollTop using a deferred command.
+ if (BrowserInfo.get().isSafari()) {
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().getElement());
+ }
+
+ getWidgetForPaintable().scrollIntoView(uidl);
+
+ if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) {
+ getWidgetForPaintable().currentFragment = uidl
+ .getStringAttribute(VView.FRAGMENT_VARIABLE);
+ if (!getWidgetForPaintable().currentFragment.equals(History
+ .getToken())) {
+ History.newItem(getWidgetForPaintable().currentFragment, true);
+ }
+ } else {
+ // Initial request for which the server doesn't yet have a fragment
+ // (and haven't shown any interest in getting one)
+ getWidgetForPaintable().currentFragment = History.getToken();
+
+ // Include current fragment in the next request
+ client.updateVariable(getWidgetForPaintable().id,
+ VView.FRAGMENT_VARIABLE,
+ getWidgetForPaintable().currentFragment, false);
+ }
+
+ getWidgetForPaintable().rendering = false;
+ }
+
+ public void init(String rootPanelId,
+ ApplicationConnection applicationConnection) {
+ DOM.sinkEvents(getWidgetForPaintable().getElement(), Event.ONKEYDOWN
+ | Event.ONSCROLL);
+
+ // iview is focused when created so element needs tabIndex
+ // 1 due 0 is at the end of natural tabbing order
+ DOM.setElementProperty(getWidgetForPaintable().getElement(),
+ "tabIndex", "1");
+
+ RootPanel root = RootPanel.get(rootPanelId);
+
+ // Remove the v-app-loading or any splash screen added inside the div by
+ // the user
+ root.getElement().setInnerHTML("");
+ // For backwards compatibility with static index pages only.
+ // No longer added by AbstractApplicationServlet/Portlet
+ root.removeStyleName("v-app-loading");
+
+ String themeUri = applicationConnection.getConfiguration()
+ .getThemeUri();
+ String themeName = themeUri.substring(themeUri.lastIndexOf('/'));
+ themeName = themeName.replaceAll("[^a-zA-Z0-9]", "");
+ root.addStyleName("v-theme-" + themeName);
+
+ root.add(getWidgetForPaintable());
+
+ if (applicationConnection.getConfiguration().isStandalone()) {
+ // set focus to iview element by default to listen possible keyboard
+ // shortcuts. For embedded applications this is unacceptable as we
+ // don't want to steal focus from the main page nor we don't want
+ // side-effects from focusing (scrollIntoView).
+ getWidgetForPaintable().getElement().focus();
+ }
+
+ getWidgetForPaintable().parentFrame = VView.getParentFrame();
+ }
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP The main view never draws caption for its layout
+ }
+
+ @Override
+ public VView getWidgetForPaintable() {
+ return (VView) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VView.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
index 95ab0dc773..d4c8f74605 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
@@ -13,21 +13,17 @@ import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.DomEvent.Type;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
-import com.google.gwt.event.shared.EventHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -38,10 +34,8 @@ import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.Focusable;
import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
/**
@@ -51,7 +45,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan
*/
public class VWindow extends VOverlay implements Container,
ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler,
- FocusHandler, BlurHandler, BeforeShortcutActionListener, Focusable {
+ FocusHandler, BlurHandler, Focusable {
/**
* Minimum allowed height of a window. This refers to the content area, not
@@ -88,9 +82,9 @@ public class VWindow extends VOverlay implements Container,
public static final int Z_INDEX = 10000;
- private VPaintableWidget layout;
+ VPaintableWidget layout;
- private Element contents;
+ Element contents;
private Element header;
@@ -98,7 +92,7 @@ public class VWindow extends VOverlay implements Container,
private Element resizeBox;
- private final FocusableScrollPanel contentPanel = new FocusableScrollPanel();
+ final FocusableScrollPanel contentPanel = new FocusableScrollPanel();
private boolean dragging;
@@ -116,11 +110,11 @@ public class VWindow extends VOverlay implements Container,
private int origH;
- private Element closeBox;
+ Element closeBox;
protected ApplicationConnection client;
- private String id;
+ String id;
ShortcutActionHandler shortcutHandler;
@@ -130,13 +124,13 @@ public class VWindow extends VOverlay implements Container,
/** Last known positiony read from UIDL or updated to application connection */
private int uidlPositionY = -1;
- private boolean vaadinModality = false;
+ boolean vaadinModality = false;
- private boolean resizable = true;
+ boolean resizable = true;
private boolean draggable = true;
- private boolean resizeLazy = false;
+ boolean resizeLazy = false;
private Element modalityCurtain;
private Element draggingCurtain;
@@ -163,23 +157,13 @@ public class VWindow extends VOverlay implements Container,
private String height;
- private boolean immediate;
+ boolean immediate;
private Element wrapper, wrapper2;
- private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
- VPanel.CLICK_EVENT_IDENTIFIER) {
+ boolean visibilityChangesDisabled;
- @Override
- protected <H extends EventHandler> HandlerRegistration registerHandler(
- H handler, Type<H> type) {
- return addDomHandler(handler, type);
- }
- };
-
- private boolean visibilityChangesDisabled;
-
- private int bringToFrontSequence = -1;
+ int bringToFrontSequence = -1;
private VLazyExecutor delayedContentsSizeUpdater = new VLazyExecutor(200,
new ScheduledCommand() {
@@ -284,230 +268,12 @@ public class VWindow extends VOverlay implements Container,
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- id = uidl.getId();
- this.client = client;
-
- // Workaround needed for Testing Tools (GWT generates window DOM
- // slightly different in different browsers).
- DOM.setElementProperty(closeBox, "id", id + "_window_close");
-
- if (uidl.hasAttribute("invisible")) {
- hide();
- return;
- }
-
- if (!uidl.hasAttribute("cached")) {
- if (uidl.getBooleanAttribute("modal") != vaadinModality) {
- setVaadinModality(!vaadinModality);
- }
- if (!isAttached()) {
- setVisible(false); // hide until possible centering
- show();
- }
- if (uidl.getBooleanAttribute("resizable") != resizable) {
- setResizable(!resizable);
- }
- resizeLazy = uidl.hasAttribute(VView.RESIZE_LAZY);
-
- setDraggable(!uidl.hasAttribute("fixedposition"));
-
- // Caption must be set before required header size is measured. If
- // the caption attribute is missing the caption should be cleared.
- setCaption(uidl.getStringAttribute("caption"),
- uidl.getStringAttribute("icon"));
- }
-
- visibilityChangesDisabled = true;
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
- visibilityChangesDisabled = false;
-
- clickEventHandler.handleEventHandlerRegistration(client);
-
- immediate = uidl.hasAttribute("immediate");
-
- setClosable(!uidl.getBooleanAttribute("readonly"));
-
- // Initialize the position form UIDL
- int positionx = uidl.getIntVariable("positionx");
- int positiony = uidl.getIntVariable("positiony");
- if (positionx >= 0 || positiony >= 0) {
- if (positionx < 0) {
- positionx = 0;
- }
- if (positiony < 0) {
- positiony = 0;
- }
- setPopupPosition(positionx, positiony);
- }
-
- boolean showingUrl = false;
- int childIndex = 0;
- UIDL childUidl = uidl.getChildUIDL(childIndex++);
- while ("open".equals(childUidl.getTag())) {
- // TODO multiple opens with the same target will in practice just
- // open the last one - should we fix that somehow?
- final String parsedUri = client.translateVaadinUri(childUidl
- .getStringAttribute("src"));
- if (!childUidl.hasAttribute("name")) {
- final Frame frame = new Frame();
- DOM.setStyleAttribute(frame.getElement(), "width", "100%");
- DOM.setStyleAttribute(frame.getElement(), "height", "100%");
- DOM.setStyleAttribute(frame.getElement(), "border", "0px");
- frame.setUrl(parsedUri);
- contentPanel.setWidget(frame);
- showingUrl = true;
- } else {
- final String target = childUidl.getStringAttribute("name");
- Window.open(parsedUri, target, "");
- }
- childUidl = uidl.getChildUIDL(childIndex++);
- }
-
- final VPaintableWidget lo = client.getPaintable(childUidl);
- if (layout != null) {
- if (layout != lo) {
- // remove old
- client.unregisterPaintable(layout);
- contentPanel.remove(layout.getWidgetForPaintable());
- // add new
- if (!showingUrl) {
- contentPanel.setWidget(lo.getWidgetForPaintable());
- }
- layout = lo;
- }
- } else if (!showingUrl) {
- contentPanel.setWidget(lo.getWidgetForPaintable());
- layout = lo;
- }
-
- dynamicWidth = !uidl.hasAttribute("width");
- dynamicHeight = !uidl.hasAttribute("height");
-
- layoutRelativeWidth = uidl.hasAttribute("layoutRelativeWidth");
- layoutRelativeHeight = uidl.hasAttribute("layoutRelativeHeight");
-
- if (dynamicWidth && layoutRelativeWidth) {
- /*
- * Relative layout width, fix window width before rendering (width
- * according to caption)
- */
- setNaturalWidth();
- }
-
- layout.updateFromUIDL(childUidl, client);
- if (!dynamicHeight && layoutRelativeWidth) {
- /*
- * Relative layout width, and fixed height. Must update the size to
- * be able to take scrollbars into account (layout gets narrower
- * space if it is higher than the window) -> only vertical scrollbar
- */
- client.runDescendentsLayout(this);
- }
-
- /*
- * No explicit width is set and the layout does not have relative width
- * so fix the size according to the layout.
- */
- if (dynamicWidth && !layoutRelativeWidth) {
- setNaturalWidth();
- }
-
- if (dynamicHeight && layoutRelativeHeight) {
- // Prevent resizing until height has been fixed
- resizable = false;
- }
-
- // we may have actions and notifications
- if (uidl.getChildCount() > 1) {
- final int cnt = uidl.getChildCount();
- for (int i = 1; i < cnt; i++) {
- childUidl = uidl.getChildUIDL(i);
- if (childUidl.getTag().equals("actions")) {
- if (shortcutHandler == null) {
- shortcutHandler = new ShortcutActionHandler(id, client);
- }
- shortcutHandler.updateActionMap(childUidl);
- }
- }
-
- }
-
- // setting scrollposition must happen after children is rendered
- contentPanel.setScrollPosition(uidl.getIntVariable("scrollTop"));
- contentPanel.setHorizontalScrollPosition(uidl
- .getIntVariable("scrollLeft"));
-
- // Center this window on screen if requested
- // This has to be here because we might not know the content size before
- // everything is painted into the window
- if (uidl.getBooleanAttribute("center")) {
- // mark as centered - this is unset on move/resize
- centered = true;
- center();
- } else {
- // don't try to center the window anymore
- centered = false;
- }
- updateShadowSizeAndPosition();
- setVisible(true);
-
- boolean sizeReduced = false;
- // ensure window is not larger than browser window
- if (getOffsetWidth() > Window.getClientWidth()) {
- setWidth(Window.getClientWidth() + "px");
- sizeReduced = true;
- }
- if (getOffsetHeight() > Window.getClientHeight()) {
- setHeight(Window.getClientHeight() + "px");
- sizeReduced = true;
- }
-
- if (dynamicHeight && layoutRelativeHeight) {
- /*
- * Window height is undefined, layout is 100% high so the layout
- * should define the initial window height but on resize the layout
- * should be as high as the window. We fix the height to deal with
- * this.
- */
-
- int h = contents.getOffsetHeight() + getExtraHeight();
- int w = getElement().getOffsetWidth();
-
- client.updateVariable(id, "height", h, false);
- client.updateVariable(id, "width", w, true);
- }
-
- if (sizeReduced) {
- // If we changed the size we need to update the size of the child
- // component if it is relative (#3407)
- client.runDescendentsLayout(this);
- }
-
- Util.runWebkitOverflowAutoFix(contentPanel.getElement());
-
- client.getView().scrollIntoView(uidl);
-
- if (uidl.hasAttribute("bringToFront")) {
- /*
- * Focus as a side-efect. Will be overridden by
- * ApplicationConnection if another component was focused by the
- * server side.
- */
- contentPanel.focus();
- bringToFrontSequence = uidl.getIntAttribute("bringToFront");
- deferOrdering();
- }
- }
-
/**
* Calling this method will defer ordering algorithm, to order windows based
* on servers bringToFront and modality instructions. Non changed windows
* will be left intact.
*/
- private static void deferOrdering() {
+ static void deferOrdering() {
if (!orderingDefered) {
orderingDefered = true;
Scheduler.get().scheduleFinally(new Command() {
@@ -562,7 +328,7 @@ public class VWindow extends VOverlay implements Container,
}
}
- private void setDraggable(boolean draggable) {
+ void setDraggable(boolean draggable) {
if (this.draggable == draggable) {
return;
}
@@ -573,7 +339,7 @@ public class VWindow extends VOverlay implements Container,
}
private void setCursorProperties() {
- if (!this.draggable) {
+ if (!draggable) {
header.getStyle().setProperty("cursor", "default");
footer.getStyle().setProperty("cursor", "default");
} else {
@@ -582,7 +348,7 @@ public class VWindow extends VOverlay implements Container,
}
}
- private void setNaturalWidth() {
+ void setNaturalWidth() {
/*
* Use max(layout width, window width) i.e layout content width or
* caption width. We remove the previous set width so the width is
@@ -676,7 +442,7 @@ public class VWindow extends VOverlay implements Container,
super.hide();
}
- private void setVaadinModality(boolean modality) {
+ void setVaadinModality(boolean modality) {
vaadinModality = modality;
if (vaadinModality) {
if (isAttached()) {
@@ -767,7 +533,7 @@ public class VWindow extends VOverlay implements Container,
return curtain;
}
- private void setResizable(boolean resizability) {
+ void setResizable(boolean resizability) {
resizable = resizability;
if (resizability) {
DOM.setElementProperty(footer, "className", CLASSNAME + "-footer");
@@ -832,7 +598,7 @@ public class VWindow extends VOverlay implements Container,
if (client != null && header.isOrHasChild(target)) {
// Handle window caption tooltips
- client.handleTooltipEvent(event, this);
+ client.handleWidgetTooltipEvent(event, this);
}
if (resizing || resizeBox == target) {
@@ -877,7 +643,7 @@ public class VWindow extends VOverlay implements Container,
}
private void onResizeEvent(Event event) {
- if (resizable) {
+ if (resizable && Util.isTouchEventOrLeftMouseButton(event)) {
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
case Event.ONTOUCHSTART:
@@ -1088,12 +854,16 @@ public class VWindow extends VOverlay implements Container,
private int extraH = 0;
- private int getExtraHeight() {
+ int getExtraHeight() {
extraH = header.getOffsetHeight() + footer.getOffsetHeight();
return extraH;
}
private void onDragEvent(Event event) {
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
+
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
if (event.getTouches().length() > 1) {
@@ -1205,7 +975,7 @@ public class VWindow extends VOverlay implements Container,
}
public RenderSpace getAllocatedSpace(Widget child) {
- if (child == layout) {
+ if (child == layout.getWidgetForPaintable()) {
return renderSpace;
} else {
// Exception ??
@@ -1214,7 +984,7 @@ public class VWindow extends VOverlay implements Container,
}
public boolean hasChildComponent(Widget component) {
- if (component == layout) {
+ if (component == layout.getWidgetForPaintable()) {
return true;
} else {
return false;
@@ -1238,10 +1008,6 @@ public class VWindow extends VOverlay implements Container,
return true;
}
- public void updateCaption(VPaintableWidget component, UIDL uidl) {
- // NOP, window has own caption, layout captio not rendered
- }
-
public ShortcutActionHandler getShortcutActionHandler() {
return shortcutHandler;
}
@@ -1263,28 +1029,19 @@ public class VWindow extends VOverlay implements Container,
}
public void onBlur(BlurEvent event) {
- if (client.hasEventListeners(this, EventId.BLUR)) {
+ if (client.hasWidgetEventListeners(this, EventId.BLUR)) {
client.updateVariable(id, EventId.BLUR, "", true);
}
}
public void onFocus(FocusEvent event) {
- if (client.hasEventListeners(this, EventId.FOCUS)) {
+ if (client.hasWidgetEventListeners(this, EventId.FOCUS)) {
client.updateVariable(id, EventId.FOCUS, "", true);
}
}
- public void onBeforeShortcutAction(Event e) {
- // NOP, nothing to update just avoid workaround ( causes excess
- // blur/focus )
- }
-
public void focus() {
contentPanel.focus();
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
new file mode 100644
index 0000000000..633e28d0c3
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java
@@ -0,0 +1,299 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.DomEvent.Type;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Frame;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+
+public class VWindowPaintable extends VAbstractPaintableWidgetContainer
+ implements BeforeShortcutActionListener {
+
+ private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
+
+ private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
+ CLICK_EVENT_IDENTIFIER) {
+
+ @Override
+ protected <H extends EventHandler> HandlerRegistration registerHandler(
+ H handler, Type<H> type) {
+ return getWidgetForPaintable().addDomHandler(handler, type);
+ }
+ };
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().id = uidl.getId();
+ getWidgetForPaintable().client = client;
+
+ // Workaround needed for Testing Tools (GWT generates window DOM
+ // slightly different in different browsers).
+ DOM.setElementProperty(getWidgetForPaintable().closeBox, "id",
+ getWidgetForPaintable().id + "_window_close");
+
+ if (uidl.hasAttribute("invisible")) {
+ getWidgetForPaintable().hide();
+ return;
+ }
+
+ if (!uidl.hasAttribute("cached")) {
+ if (uidl.getBooleanAttribute("modal") != getWidgetForPaintable().vaadinModality) {
+ getWidgetForPaintable().setVaadinModality(
+ !getWidgetForPaintable().vaadinModality);
+ }
+ if (!getWidgetForPaintable().isAttached()) {
+ getWidgetForPaintable().setVisible(false); // hide until
+ // possible centering
+ getWidgetForPaintable().show();
+ }
+ if (uidl.getBooleanAttribute("resizable") != getWidgetForPaintable().resizable) {
+ getWidgetForPaintable().setResizable(
+ !getWidgetForPaintable().resizable);
+ }
+ getWidgetForPaintable().resizeLazy = uidl
+ .hasAttribute(VView.RESIZE_LAZY);
+
+ getWidgetForPaintable().setDraggable(
+ !uidl.hasAttribute("fixedposition"));
+
+ // Caption must be set before required header size is measured. If
+ // the caption attribute is missing the caption should be cleared.
+ getWidgetForPaintable().setCaption(
+ uidl.getStringAttribute("caption"),
+ uidl.getStringAttribute("icon"));
+ }
+
+ getWidgetForPaintable().visibilityChangesDisabled = true;
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+ getWidgetForPaintable().visibilityChangesDisabled = false;
+
+ clickEventHandler.handleEventHandlerRegistration(client);
+
+ getWidgetForPaintable().immediate = uidl.hasAttribute("immediate");
+
+ getWidgetForPaintable().setClosable(
+ !uidl.getBooleanAttribute("readonly"));
+
+ // Initialize the position form UIDL
+ int positionx = uidl.getIntVariable("positionx");
+ int positiony = uidl.getIntVariable("positiony");
+ if (positionx >= 0 || positiony >= 0) {
+ if (positionx < 0) {
+ positionx = 0;
+ }
+ if (positiony < 0) {
+ positiony = 0;
+ }
+ getWidgetForPaintable().setPopupPosition(positionx, positiony);
+ }
+
+ boolean showingUrl = false;
+ int childIndex = 0;
+ UIDL childUidl = uidl.getChildUIDL(childIndex++);
+ while ("open".equals(childUidl.getTag())) {
+ // TODO multiple opens with the same target will in practice just
+ // open the last one - should we fix that somehow?
+ final String parsedUri = client.translateVaadinUri(childUidl
+ .getStringAttribute("src"));
+ if (!childUidl.hasAttribute("name")) {
+ final Frame frame = new Frame();
+ DOM.setStyleAttribute(frame.getElement(), "width", "100%");
+ DOM.setStyleAttribute(frame.getElement(), "height", "100%");
+ DOM.setStyleAttribute(frame.getElement(), "border", "0px");
+ frame.setUrl(parsedUri);
+ getWidgetForPaintable().contentPanel.setWidget(frame);
+ showingUrl = true;
+ } else {
+ final String target = childUidl.getStringAttribute("name");
+ Window.open(parsedUri, target, "");
+ }
+ childUidl = uidl.getChildUIDL(childIndex++);
+ }
+
+ final VPaintableWidget lo = client.getPaintable(childUidl);
+ if (getWidgetForPaintable().layout != null) {
+ if (getWidgetForPaintable().layout != lo) {
+ // remove old
+ client.unregisterPaintable(getWidgetForPaintable().layout);
+ getWidgetForPaintable().contentPanel
+ .remove(getWidgetForPaintable().layout
+ .getWidgetForPaintable());
+ // add new
+ if (!showingUrl) {
+ getWidgetForPaintable().contentPanel.setWidget(lo
+ .getWidgetForPaintable());
+ }
+ getWidgetForPaintable().layout = lo;
+ }
+ } else if (!showingUrl) {
+ getWidgetForPaintable().contentPanel.setWidget(lo
+ .getWidgetForPaintable());
+ getWidgetForPaintable().layout = lo;
+ }
+
+ getWidgetForPaintable().dynamicWidth = !uidl.hasAttribute("width");
+ getWidgetForPaintable().dynamicHeight = !uidl.hasAttribute("height");
+
+ getWidgetForPaintable().layoutRelativeWidth = uidl
+ .hasAttribute("layoutRelativeWidth");
+ getWidgetForPaintable().layoutRelativeHeight = uidl
+ .hasAttribute("layoutRelativeHeight");
+
+ if (getWidgetForPaintable().dynamicWidth
+ && getWidgetForPaintable().layoutRelativeWidth) {
+ /*
+ * Relative layout width, fix window width before rendering (width
+ * according to caption)
+ */
+ getWidgetForPaintable().setNaturalWidth();
+ }
+
+ getWidgetForPaintable().layout.updateFromUIDL(childUidl, client);
+ if (!getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeWidth) {
+ /*
+ * Relative layout width, and fixed height. Must update the size to
+ * be able to take scrollbars into account (layout gets narrower
+ * space if it is higher than the window) -> only vertical scrollbar
+ */
+ client.runDescendentsLayout(getWidgetForPaintable());
+ }
+
+ /*
+ * No explicit width is set and the layout does not have relative width
+ * so fix the size according to the layout.
+ */
+ if (getWidgetForPaintable().dynamicWidth
+ && !getWidgetForPaintable().layoutRelativeWidth) {
+ getWidgetForPaintable().setNaturalWidth();
+ }
+
+ if (getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeHeight) {
+ // Prevent resizing until height has been fixed
+ getWidgetForPaintable().resizable = false;
+ }
+
+ // we may have actions and notifications
+ if (uidl.getChildCount() > 1) {
+ final int cnt = uidl.getChildCount();
+ for (int i = 1; i < cnt; i++) {
+ childUidl = uidl.getChildUIDL(i);
+ if (childUidl.getTag().equals("actions")) {
+ if (getWidgetForPaintable().shortcutHandler == null) {
+ getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler(
+ getId(), client);
+ }
+ getWidgetForPaintable().shortcutHandler
+ .updateActionMap(childUidl);
+ }
+ }
+
+ }
+
+ // setting scrollposition must happen after children is rendered
+ getWidgetForPaintable().contentPanel.setScrollPosition(uidl
+ .getIntVariable("scrollTop"));
+ getWidgetForPaintable().contentPanel.setHorizontalScrollPosition(uidl
+ .getIntVariable("scrollLeft"));
+
+ // Center this window on screen if requested
+ // This has to be here because we might not know the content size before
+ // everything is painted into the window
+ if (uidl.getBooleanAttribute("center")) {
+ // mark as centered - this is unset on move/resize
+ getWidgetForPaintable().centered = true;
+ getWidgetForPaintable().center();
+ } else {
+ // don't try to center the window anymore
+ getWidgetForPaintable().centered = false;
+ }
+ getWidgetForPaintable().updateShadowSizeAndPosition();
+ getWidgetForPaintable().setVisible(true);
+
+ boolean sizeReduced = false;
+ // ensure window is not larger than browser window
+ if (getWidgetForPaintable().getOffsetWidth() > Window.getClientWidth()) {
+ getWidgetForPaintable().setWidth(Window.getClientWidth() + "px");
+ sizeReduced = true;
+ }
+ if (getWidgetForPaintable().getOffsetHeight() > Window
+ .getClientHeight()) {
+ getWidgetForPaintable().setHeight(Window.getClientHeight() + "px");
+ sizeReduced = true;
+ }
+
+ if (getWidgetForPaintable().dynamicHeight
+ && getWidgetForPaintable().layoutRelativeHeight) {
+ /*
+ * Window height is undefined, layout is 100% high so the layout
+ * should define the initial window height but on resize the layout
+ * should be as high as the window. We fix the height to deal with
+ * this.
+ */
+
+ int h = getWidgetForPaintable().contents.getOffsetHeight()
+ + getWidgetForPaintable().getExtraHeight();
+ int w = getWidgetForPaintable().getElement().getOffsetWidth();
+
+ client.updateVariable(getId(), "height", h, false);
+ client.updateVariable(getId(), "width", w, true);
+ }
+
+ if (sizeReduced) {
+ // If we changed the size we need to update the size of the child
+ // component if it is relative (#3407)
+ client.runDescendentsLayout(getWidgetForPaintable());
+ }
+
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().contentPanel
+ .getElement());
+
+ client.getView().getWidgetForPaintable().scrollIntoView(uidl);
+
+ if (uidl.hasAttribute("bringToFront")) {
+ /*
+ * Focus as a side-efect. Will be overridden by
+ * ApplicationConnection if another component was focused by the
+ * server side.
+ */
+ getWidgetForPaintable().contentPanel.focus();
+ getWidgetForPaintable().bringToFrontSequence = uidl
+ .getIntAttribute("bringToFront");
+ VWindow.deferOrdering();
+ }
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP, window has own caption, layout captio not rendered
+ }
+
+ public void onBeforeShortcutAction(Event e) {
+ // NOP, nothing to update just avoid workaround ( causes excess
+ // blur/focus )
+ }
+
+ @Override
+ public VWindow getWidgetForPaintable() {
+ return (VWindow) super.getWidgetForPaintable();
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VWindow.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
index 269afde25d..c57f705c75 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
@@ -1,71 +1,71 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client.ui.label;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.PreElement;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
-
-public class VLabelPaintable extends VAbstractPaintableWidget {
- public VLabelPaintable() {
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- boolean sinkOnloads = false;
-
- final String mode = uidl.getStringAttribute("mode");
- if (mode == null || "text".equals(mode)) {
- getWidgetForPaintable().setText(uidl.getChildString(0));
- } else if ("pre".equals(mode)) {
- PreElement preElement = Document.get().createPreElement();
- preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));
- // clear existing content
- getWidgetForPaintable().setHTML("");
- // add preformatted text to dom
- getWidgetForPaintable().getElement().appendChild(preElement);
- } else if ("uidl".equals(mode)) {
- getWidgetForPaintable().setHTML(uidl.getChildrenAsXML());
- } else if ("xhtml".equals(mode)) {
- UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);
- if (content.getChildCount() > 0) {
- getWidgetForPaintable().setHTML(content.getChildString(0));
- } else {
- getWidgetForPaintable().setHTML("");
- }
- sinkOnloads = true;
- } else if ("xml".equals(mode)) {
- getWidgetForPaintable().setHTML(
- uidl.getChildUIDL(0).getChildString(0));
- } else if ("raw".equals(mode)) {
- getWidgetForPaintable().setHTML(
- uidl.getChildUIDL(0).getChildString(0));
- sinkOnloads = true;
- } else {
- getWidgetForPaintable().setText("");
- }
- if (sinkOnloads) {
- Util.sinkOnloadForImages(getWidgetForPaintable().getElement());
- }
- }
-
- @Override
- protected Widget createWidget() {
- return GWT.create(VLabel.class);
- }
-
- @Override
- public VLabel getWidgetForPaintable() {
- return (VLabel) super.getWidgetForPaintable();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.label;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.PreElement;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+
+public class VLabelPaintable extends VAbstractPaintableWidget {
+ public VLabelPaintable() {
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ boolean sinkOnloads = false;
+
+ final String mode = uidl.getStringAttribute("mode");
+ if (mode == null || "text".equals(mode)) {
+ getWidgetForPaintable().setText(uidl.getChildString(0));
+ } else if ("pre".equals(mode)) {
+ PreElement preElement = Document.get().createPreElement();
+ preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));
+ // clear existing content
+ getWidgetForPaintable().setHTML("");
+ // add preformatted text to dom
+ getWidgetForPaintable().getElement().appendChild(preElement);
+ } else if ("uidl".equals(mode)) {
+ getWidgetForPaintable().setHTML(uidl.getChildrenAsXML());
+ } else if ("xhtml".equals(mode)) {
+ UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);
+ if (content.getChildCount() > 0) {
+ getWidgetForPaintable().setHTML(content.getChildString(0));
+ } else {
+ getWidgetForPaintable().setHTML("");
+ }
+ sinkOnloads = true;
+ } else if ("xml".equals(mode)) {
+ getWidgetForPaintable().setHTML(
+ uidl.getChildUIDL(0).getChildString(0));
+ } else if ("raw".equals(mode)) {
+ getWidgetForPaintable().setHTML(
+ uidl.getChildUIDL(0).getChildString(0));
+ sinkOnloads = true;
+ } else {
+ getWidgetForPaintable().setText("");
+ }
+ if (sinkOnloads) {
+ Util.sinkOnloadForImages(getWidgetForPaintable().getElement());
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VLabel.class);
+ }
+
+ @Override
+ public VLabel getWidgetForPaintable() {
+ return (VLabel) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java
index 85f48859a4..9b38ba23ae 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java
@@ -3,6 +3,7 @@
*/
package com.vaadin.terminal.gwt.client.ui.layout;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -17,7 +18,6 @@ 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.Container;
-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.VMarginInfo;
@@ -28,7 +28,7 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
protected ApplicationConnection client = null;
- protected DivElement root;
+ public DivElement root;
public static final int ORIENTATION_VERTICAL = 0;
public static final int ORIENTATION_HORIZONTAL = 1;
@@ -40,15 +40,15 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
protected final Spacing spacingFromCSS = new Spacing(12, 12);
protected final Spacing activeSpacing = new Spacing(0, 0);
- private boolean dynamicWidth;
+ boolean dynamicWidth;
- private boolean dynamicHeight;
+ boolean dynamicHeight;
private final DivElement clearElement = Document.get().createDivElement();
private String lastStyleName = "";
- private boolean marginsNeedsRecalculation = false;
+ boolean marginsNeedsRecalculation = false;
protected String STYLENAME_SPACING = "";
protected String STYLENAME_MARGIN_TOP = "";
@@ -105,32 +105,6 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
return widgetToComponentContainer.containsKey(component);
}
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
-
- // Only non-cached UIDL:s can introduce changes
- if (uidl.getBooleanAttribute("cached")) {
- return;
- }
-
- /**
- * Margin and spacind detection depends on classNames and must be set
- * before setting size. Here just update the details from UIDL and from
- * overridden setStyleName run actual margin detections.
- */
- updateMarginAndSpacingInfo(uidl);
-
- /*
- * This call should be made first. Ensure correct implementation, handle
- * size etc.
- */
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- handleDynamicDimensions(uidl);
- }
-
@Override
public void setStyleName(String styleName) {
super.setStyleName(styleName);
@@ -159,27 +133,6 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
}
}
- private void handleDynamicDimensions(UIDL uidl) {
- String w = uidl.hasAttribute("width") ? uidl
- .getStringAttribute("width") : "";
-
- String h = uidl.hasAttribute("height") ? uidl
- .getStringAttribute("height") : "";
-
- if (w.equals("")) {
- dynamicWidth = true;
- } else {
- dynamicWidth = false;
- }
-
- if (h.equals("")) {
- dynamicHeight = true;
- } else {
- dynamicHeight = false;
- }
-
- }
-
@Override
public void setHeight(String height) {
super.setHeight(height);
@@ -195,7 +148,7 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
}
}
- protected void addOrMoveChild(ChildComponentContainer childComponent,
+ public void addOrMoveChild(ChildComponentContainer childComponent,
int position) {
if (childComponent.getParent() == this) {
if (getWidgetIndex(childComponent) != position) {
@@ -235,33 +188,22 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
}
- protected ChildComponentContainer getComponentContainer(Widget child) {
+ public Collection<ChildComponentContainer> getComponentContainers() {
+ return widgetToComponentContainer.values();
+ }
+
+ public ChildComponentContainer getComponentContainer(Widget child) {
return widgetToComponentContainer.get(child);
}
- protected boolean isDynamicWidth() {
+ public boolean isDynamicWidth() {
return dynamicWidth;
}
- protected boolean isDynamicHeight() {
+ public boolean isDynamicHeight() {
return dynamicHeight;
}
- private void updateMarginAndSpacingInfo(UIDL uidl) {
- if (!uidl.hasAttribute("invisible")) {
- int bitMask = uidl.getIntAttribute("margins");
- if (activeMarginsInfo.getBitMask() != bitMask) {
- activeMarginsInfo = new VMarginInfo(bitMask);
- marginsNeedsRecalculation = true;
- }
- boolean spacing = uidl.getBooleanAttribute("spacing");
- if (spacing != spacingEnabled) {
- marginsNeedsRecalculation = true;
- spacingEnabled = spacing;
- }
- }
- }
-
private static DivElement measurement;
private static DivElement measurement2;
private static DivElement measurement3;
@@ -342,7 +284,7 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container
return (ChildComponentContainer) getChildren().get(0);
}
- protected void removeChildrenAfter(int pos) {
+ public void removeChildrenAfter(int pos) {
// Remove all children after position "pos" but leave the clear element
// in place
diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java
new file mode 100644
index 0000000000..c41652fb3d
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayoutPaintable.java
@@ -0,0 +1,84 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.layout;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidgetContainer;
+import com.vaadin.terminal.gwt.client.ui.VMarginInfo;
+
+public abstract class CellBasedLayoutPaintable extends
+ VAbstractPaintableWidgetContainer {
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+
+ // Only non-cached UIDL:s can introduce changes
+ if (uidl.getBooleanAttribute("cached")) {
+ return;
+ }
+
+ /**
+ * Margin and spacind detection depends on classNames and must be set
+ * before setting size. Here just update the details from UIDL and from
+ * overridden setStyleName run actual margin detections.
+ */
+ updateMarginAndSpacingInfo(uidl);
+
+ /*
+ * This call should be made first. Ensure correct implementation, handle
+ * size etc.
+ */
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ handleDynamicDimensions(uidl);
+ }
+
+ private void handleDynamicDimensions(UIDL uidl) {
+ String w = uidl.hasAttribute("width") ? uidl
+ .getStringAttribute("width") : "";
+
+ String h = uidl.hasAttribute("height") ? uidl
+ .getStringAttribute("height") : "";
+
+ if (w.equals("")) {
+ getWidgetForPaintable().dynamicWidth = true;
+ } else {
+ getWidgetForPaintable().dynamicWidth = false;
+ }
+
+ if (h.equals("")) {
+ getWidgetForPaintable().dynamicHeight = true;
+ } else {
+ getWidgetForPaintable().dynamicHeight = false;
+ }
+
+ }
+
+ void updateMarginAndSpacingInfo(UIDL uidl) {
+ if (!uidl.hasAttribute("invisible")) {
+ int bitMask = uidl.getIntAttribute("margins");
+ if (getWidgetForPaintable().activeMarginsInfo.getBitMask() != bitMask) {
+ getWidgetForPaintable().activeMarginsInfo = new VMarginInfo(
+ bitMask);
+ getWidgetForPaintable().marginsNeedsRecalculation = true;
+ }
+ boolean spacing = uidl.getBooleanAttribute("spacing");
+ if (spacing != getWidgetForPaintable().spacingEnabled) {
+ getWidgetForPaintable().marginsNeedsRecalculation = true;
+ getWidgetForPaintable().spacingEnabled = spacing;
+ }
+ }
+ }
+
+ @Override
+ protected abstract CellBasedLayout createWidget();
+
+ @Override
+ public CellBasedLayout getWidgetForPaintable() {
+ return (CellBasedLayout) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
index 35d3247f9b..c1678369b3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java
@@ -17,7 +17,6 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -27,12 +26,10 @@ import com.google.gwt.user.client.ui.RichTextArea;
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.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.ui.Field;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler;
-import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
/**
@@ -41,9 +38,8 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan
* @author Vaadin Ltd.
*
*/
-public class VRichTextArea extends Composite implements VPaintableWidget, Field,
- ChangeHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
- BeforeShortcutActionListener, Focusable {
+public class VRichTextArea extends Composite implements Field, ChangeHandler,
+ BlurHandler, KeyPressHandler, KeyDownHandler, Focusable {
/**
* The input node CSS classname.
@@ -54,13 +50,13 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
protected ApplicationConnection client;
- private boolean immediate = false;
+ boolean immediate = false;
- private RichTextArea rta;
+ RichTextArea rta;
private VRichTextToolbar formatter;
- private HTML html = new HTML();
+ HTML html = new HTML();
private final FlowPanel fp = new FlowPanel();
@@ -69,15 +65,15 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
private int extraHorizontalPixels = -1;
private int extraVerticalPixels = -1;
- private int maxLength = -1;
+ int maxLength = -1;
private int toolbarNaturalWidth = 500;
- private HandlerRegistration keyPressHandler;
+ HandlerRegistration keyPressHandler;
private ShortcutActionHandlerOwner hasShortcutActionHandler;
- private String currentValue = "";
+ String currentValue = "";
private boolean readOnly = false;
@@ -127,48 +123,7 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
}
}
- public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
- this.client = client;
- id = uidl.getId();
-
- if (uidl.hasVariable("text")) {
- currentValue = uidl.getStringVariable("text");
- if (rta.isAttached()) {
- rta.setHTML(currentValue);
- } else {
- html.setHTML(currentValue);
- }
- }
- if (!uidl.hasAttribute("cached")) {
- setEnabled(!uidl.getBooleanAttribute("disabled"));
- }
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- setReadOnly(uidl.getBooleanAttribute("readonly"));
- immediate = uidl.getBooleanAttribute("immediate");
- int newMaxLength = uidl.hasAttribute("maxLength") ? uidl
- .getIntAttribute("maxLength") : -1;
- if (newMaxLength >= 0) {
- if (maxLength == -1) {
- keyPressHandler = rta.addKeyPressHandler(this);
- }
- maxLength = newMaxLength;
- } else if (maxLength != -1) {
- getElement().setAttribute("maxlength", "");
- maxLength = -1;
- keyPressHandler.removeHandler();
- }
-
- if (uidl.hasAttribute("selectAll")) {
- selectAll();
- }
-
- }
-
- private void selectAll() {
+ void selectAll() {
/*
* There is a timing issue if trying to select all immediately on first
* render. Simple deferred command is not enough. Using Timer with
@@ -190,7 +145,7 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
}.schedule(320);
}
- private void setReadOnly(boolean b) {
+ void setReadOnly(boolean b) {
if (isReadOnly() != b) {
swapEditableArea();
readOnly = b;
@@ -346,7 +301,8 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
if (shortcutHandler != null) {
shortcutHandler
.handleKeyboardEvent(com.google.gwt.user.client.Event
- .as(event.getNativeEvent()), this);
+ .as(event.getNativeEvent()),
+ VPaintableMap.get(client).getPaintable(this));
}
}
@@ -364,10 +320,6 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
return hasShortcutActionHandler;
}
- public void onBeforeShortcutAction(Event e) {
- synchronizeContentToServer();
- }
-
public int getTabIndex() {
return rta.getTabIndex();
}
@@ -394,8 +346,4 @@ public class VRichTextArea extends Composite implements VPaintableWidget, Field,
rta.setTabIndex(index);
}
- public Widget getWidgetForPaintable() {
- return this;
- }
-
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java
new file mode 100644
index 0000000000..ec83f294f2
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextAreaPaintable.java
@@ -0,0 +1,79 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.richtextarea;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+
+public class VRichTextAreaPaintable extends VAbstractPaintableWidget implements
+ BeforeShortcutActionListener {
+
+ public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().id = uidl.getId();
+
+ if (uidl.hasVariable("text")) {
+ getWidgetForPaintable().currentValue = uidl
+ .getStringVariable("text");
+ if (getWidgetForPaintable().rta.isAttached()) {
+ getWidgetForPaintable().rta
+ .setHTML(getWidgetForPaintable().currentValue);
+ } else {
+ getWidgetForPaintable().html
+ .setHTML(getWidgetForPaintable().currentValue);
+ }
+ }
+ if (!uidl.hasAttribute("cached")) {
+ getWidgetForPaintable().setEnabled(
+ !uidl.getBooleanAttribute("disabled"));
+ }
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().setReadOnly(
+ uidl.getBooleanAttribute("readonly"));
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+ int newMaxLength = uidl.hasAttribute("maxLength") ? uidl
+ .getIntAttribute("maxLength") : -1;
+ if (newMaxLength >= 0) {
+ if (getWidgetForPaintable().maxLength == -1) {
+ getWidgetForPaintable().keyPressHandler = getWidgetForPaintable().rta
+ .addKeyPressHandler(getWidgetForPaintable());
+ }
+ getWidgetForPaintable().maxLength = newMaxLength;
+ } else if (getWidgetForPaintable().maxLength != -1) {
+ getWidgetForPaintable().getElement().setAttribute("maxlength", "");
+ getWidgetForPaintable().maxLength = -1;
+ getWidgetForPaintable().keyPressHandler.removeHandler();
+ }
+
+ if (uidl.hasAttribute("selectAll")) {
+ getWidgetForPaintable().selectAll();
+ }
+
+ }
+
+ public void onBeforeShortcutAction(Event e) {
+ getWidgetForPaintable().synchronizeContentToServer();
+ }
+
+ @Override
+ public VRichTextArea getWidgetForPaintable() {
+ return (VRichTextArea) super.getWidgetForPaintable();
+ };
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VRichTextArea.class);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java b/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
index fad5220eb7..d3095512bb 100644
--- a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
+++ b/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
@@ -18,6 +18,7 @@ import java.util.logging.Logger;
import com.vaadin.terminal.Sizeable.Unit;
import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.AbstractSplitPanel;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CustomComponent;
@@ -26,7 +27,6 @@ import com.vaadin.ui.GridLayout;
import com.vaadin.ui.GridLayout.Area;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Panel;
-import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
@@ -449,7 +449,7 @@ public class ComponentSizeValidator implements Serializable {
}
}
- if (parent instanceof Panel || parent instanceof SplitPanel
+ if (parent instanceof Panel || parent instanceof AbstractSplitPanel
|| parent instanceof TabSheet
|| parent instanceof CustomComponent) {
// height undefined, we know how how component works and no
@@ -552,7 +552,7 @@ public class ComponentSizeValidator implements Serializable {
* the component width
*/
return hasNonRelativeWidthComponent((Form) parent);
- } else if (parent instanceof SplitPanel
+ } else if (parent instanceof AbstractSplitPanel
|| parent instanceof TabSheet
|| parent instanceof CustomComponent) {
// FIXME Could we use com.vaadin package name here and
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java b/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
index 93627c1ff1..2c9828b66b 100644
--- a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
+++ b/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
@@ -1,175 +1,175 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.portlet.ClientDataRequest;
-import javax.portlet.PortletRequest;
-import javax.portlet.ResourceRequest;
-
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedRequest;
-
-/**
- * Wrapper for {@link PortletRequest} and its subclasses.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedRequest
- * @see WrappedPortletResponse
- */
-public class WrappedPortletRequest implements WrappedRequest {
-
- private final PortletRequest request;
- private final DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a portlet request and an associated deployment configuration
- *
- * @param request
- * the portlet request to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedPortletRequest(PortletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- this.request = request;
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- public Object getAttribute(String name) {
- return request.getAttribute(name);
- }
-
- public int getContentLength() {
- try {
- return ((ClientDataRequest) request).getContentLength();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content lenght only available for ClientDataRequests");
- }
- }
-
- public InputStream getInputStream() throws IOException {
- try {
- return ((ClientDataRequest) request).getPortletInputStream();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Input data only available for ClientDataRequests");
- }
- }
-
- public String getParameter(String name) {
- return request.getParameter(name);
- }
-
- public Map<String, String[]> getParameterMap() {
- return request.getParameterMap();
- }
-
- public void setAttribute(String name, Object o) {
- request.setAttribute(name, o);
- }
-
- public String getRequestPathInfo() {
- if (request instanceof ResourceRequest) {
- return ((ResourceRequest) request).getResourceID();
- } else {
- return null;
- }
- }
-
- public int getSessionMaxInactiveInterval() {
- return request.getPortletSession().getMaxInactiveInterval();
- }
-
- public Object getSessionAttribute(String name) {
- return request.getPortletSession().getAttribute(name);
- }
-
- public void setSessionAttribute(String name, Object attribute) {
- request.getPortletSession().setAttribute(name, attribute);
- }
-
- /**
- * Gets the original, unwrapped portlet request.
- *
- * @return the unwrapped portlet request
- */
- public PortletRequest getPortletRequest() {
- return request;
- }
-
- public String getContentType() {
- try {
- return ((ResourceRequest) request).getContentType();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content type only available for ResourceRequests");
- }
- }
-
- public BrowserDetails getBrowserDetails() {
- // No browserDetails available for normal requests
- return null;
- }
-
- public Locale getLocale() {
- return request.getLocale();
- }
-
- public String getRemoteAddr() {
- return null;
- }
-
- public boolean isSecure() {
- return request.isSecure();
- }
-
- public String getHeader(String string) {
- return null;
- }
-
- /**
- * Reads a portal property from the portal context of the wrapped request.
- *
- * @param name
- * a string with the name of the portal property to get
- * @return a string with the value of the property, or <code>null</code> if
- * the property is not defined
- */
- public String getPortalProperty(String name) {
- return request.getPortalContext().getProperty(name);
- }
-
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- /**
- * Helper method to get a <code>WrappedPortlettRequest</code> from a
- * <code>WrappedRequest</code>. Aside from casting, this method also takes
- * care of situations where there's another level of wrapping.
- *
- * @param request
- * a wrapped request
- * @return a wrapped portlet request
- * @throws ClassCastException
- * if the wrapped request doesn't wrap a portlet request
- */
- public static WrappedPortletRequest cast(WrappedRequest request) {
- if (request instanceof CombinedRequest) {
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- return (WrappedPortletRequest) request;
- }
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceRequest;
+
+import com.vaadin.terminal.CombinedRequest;
+import com.vaadin.terminal.DeploymentConfiguration;
+import com.vaadin.terminal.WrappedRequest;
+
+/**
+ * Wrapper for {@link PortletRequest} and its subclasses.
+ *
+ * @author Vaadin Ltd.
+ * @since 7.0
+ *
+ * @see WrappedRequest
+ * @see WrappedPortletResponse
+ */
+public class WrappedPortletRequest implements WrappedRequest {
+
+ private final PortletRequest request;
+ private final DeploymentConfiguration deploymentConfiguration;
+
+ /**
+ * Wraps a portlet request and an associated deployment configuration
+ *
+ * @param request
+ * the portlet request to wrap
+ * @param deploymentConfiguration
+ * the associated deployment configuration
+ */
+ public WrappedPortletRequest(PortletRequest request,
+ DeploymentConfiguration deploymentConfiguration) {
+ this.request = request;
+ this.deploymentConfiguration = deploymentConfiguration;
+ }
+
+ public Object getAttribute(String name) {
+ return request.getAttribute(name);
+ }
+
+ public int getContentLength() {
+ try {
+ return ((ClientDataRequest) request).getContentLength();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Content lenght only available for ClientDataRequests");
+ }
+ }
+
+ public InputStream getInputStream() throws IOException {
+ try {
+ return ((ClientDataRequest) request).getPortletInputStream();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Input data only available for ClientDataRequests");
+ }
+ }
+
+ public String getParameter(String name) {
+ return request.getParameter(name);
+ }
+
+ public Map<String, String[]> getParameterMap() {
+ return request.getParameterMap();
+ }
+
+ public void setAttribute(String name, Object o) {
+ request.setAttribute(name, o);
+ }
+
+ public String getRequestPathInfo() {
+ if (request instanceof ResourceRequest) {
+ return ((ResourceRequest) request).getResourceID();
+ } else {
+ return null;
+ }
+ }
+
+ public int getSessionMaxInactiveInterval() {
+ return request.getPortletSession().getMaxInactiveInterval();
+ }
+
+ public Object getSessionAttribute(String name) {
+ return request.getPortletSession().getAttribute(name);
+ }
+
+ public void setSessionAttribute(String name, Object attribute) {
+ request.getPortletSession().setAttribute(name, attribute);
+ }
+
+ /**
+ * Gets the original, unwrapped portlet request.
+ *
+ * @return the unwrapped portlet request
+ */
+ public PortletRequest getPortletRequest() {
+ return request;
+ }
+
+ public String getContentType() {
+ try {
+ return ((ResourceRequest) request).getContentType();
+ } catch (ClassCastException e) {
+ throw new IllegalStateException(
+ "Content type only available for ResourceRequests");
+ }
+ }
+
+ public BrowserDetails getBrowserDetails() {
+ // No browserDetails available for normal requests
+ return null;
+ }
+
+ public Locale getLocale() {
+ return request.getLocale();
+ }
+
+ public String getRemoteAddr() {
+ return null;
+ }
+
+ public boolean isSecure() {
+ return request.isSecure();
+ }
+
+ public String getHeader(String string) {
+ return null;
+ }
+
+ /**
+ * Reads a portal property from the portal context of the wrapped request.
+ *
+ * @param name
+ * a string with the name of the portal property to get
+ * @return a string with the value of the property, or <code>null</code> if
+ * the property is not defined
+ */
+ public String getPortalProperty(String name) {
+ return request.getPortalContext().getProperty(name);
+ }
+
+ public DeploymentConfiguration getDeploymentConfiguration() {
+ return deploymentConfiguration;
+ }
+
+ /**
+ * Helper method to get a <code>WrappedPortlettRequest</code> from a
+ * <code>WrappedRequest</code>. Aside from casting, this method also takes
+ * care of situations where there's another level of wrapping.
+ *
+ * @param request
+ * a wrapped request
+ * @return a wrapped portlet request
+ * @throws ClassCastException
+ * if the wrapped request doesn't wrap a portlet request
+ */
+ public static WrappedPortletRequest cast(WrappedRequest request) {
+ if (request instanceof CombinedRequest) {
+ CombinedRequest combinedRequest = (CombinedRequest) request;
+ request = combinedRequest.getSecondRequest();
+ }
+ return (WrappedPortletRequest) request;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
index aeef1951c8..2150748b54 100644
--- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
@@ -24,7 +24,7 @@ import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.vaadin.terminal.Paintable;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.ui.VView;
+import com.vaadin.terminal.gwt.client.ui.VViewPaintable;
import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.ClientWidget.LoadStyle;
import com.vaadin.ui.Root;
@@ -258,7 +258,7 @@ public class WidgetMapGenerator extends Generator {
if (widgetsWithInstantiator.contains(clientClass)) {
continue;
}
- if (clientClass == VView.class) {
+ if (clientClass == VViewPaintable.class) {
// VView's are not instantiated by widgetset
continue;
}
@@ -374,7 +374,7 @@ public class WidgetMapGenerator extends Generator {
sourceWriter.print("else ");
}
sourceWriter
- .println("return com.vaadin.terminal.gwt.client.ui.VUnknownComponent.class;");
+ .println("return com.vaadin.terminal.gwt.client.ui.VUnknownComponentPaintable.class;");
sourceWriter.outdent();
sourceWriter.println("}");
@@ -384,7 +384,7 @@ public class WidgetMapGenerator extends Generator {
Class<? extends Paintable> class1) {
Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass;
if (Root.class == class1) {
- clientClass = VView.class;
+ clientClass = VViewPaintable.class;
} else {
ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
clientClass = annotation.value();
diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java
index d6f9897664..c75073c02b 100644
--- a/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/src/com/vaadin/ui/AbsoluteLayout.java
@@ -17,7 +17,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
+import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayoutPaintable;
/**
* AbsoluteLayout is a layout implementation that mimics html absolute
@@ -25,7 +25,7 @@ import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
*
*/
@SuppressWarnings("serial")
-@ClientWidget(VAbsoluteLayout.class)
+@ClientWidget(VAbsoluteLayoutPaintable.class)
public class AbsoluteLayout extends AbstractLayout implements
LayoutClickNotifier {
diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java
index 8bba9fc46d..fc3ef5056d 100644
--- a/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/src/com/vaadin/ui/AbstractOrderedLayout.java
@@ -54,7 +54,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
@Override
public void addComponent(Component c) {
// Add to components before calling super.addComponent
- // so that it is available to AttachListeners
+ // so that it is available to AttachListeners
components.add(c);
try {
super.addComponent(c);
@@ -75,7 +75,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
public void addComponentAsFirst(Component c) {
// If c is already in this, we must remove it before proceeding
// see ticket #7668
- if (c.getParent() == this) {
+ if(c.getParent() == this) {
removeComponent(c);
}
components.addFirst(c);
@@ -100,9 +100,9 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
public void addComponent(Component c, int index) {
// If c is already in this, we must remove it before proceeding
// see ticket #7668
- if (c.getParent() == this) {
+ if(c.getParent() == this) {
// When c is removed, all components after it are shifted down
- if (index > getComponentIndex(c)) {
+ if(index > getComponentIndex(c)) {
index--;
}
removeComponent(c);
diff --git a/src/com/vaadin/ui/AbstractSplitPanel.java b/src/com/vaadin/ui/AbstractSplitPanel.java
index e0a2d24aaa..e03e73a781 100644
--- a/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/src/com/vaadin/ui/AbstractSplitPanel.java
@@ -15,7 +15,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanel;
+import com.vaadin.terminal.gwt.client.ui.VAbstractSplitPanelPaintable;
import com.vaadin.tools.ReflectTools;
/**
@@ -43,7 +43,7 @@ public abstract class AbstractSplitPanel extends AbstractLayout {
private boolean locked = false;
- private static final String SPLITTER_CLICK_EVENT = VSplitPanel.SPLITTER_CLICK_EVENT_IDENTIFIER;
+ private static final String SPLITTER_CLICK_EVENT = VAbstractSplitPanelPaintable.SPLITTER_CLICK_EVENT_IDENTIFIER;
/**
* Modifiable and Serializable Iterator for the components, used by
diff --git a/src/com/vaadin/ui/Accordion.java b/src/com/vaadin/ui/Accordion.java
index 5cf805615c..4ee75326ff 100644
--- a/src/com/vaadin/ui/Accordion.java
+++ b/src/com/vaadin/ui/Accordion.java
@@ -3,7 +3,7 @@
*/
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VAccordion;
+import com.vaadin.terminal.gwt.client.ui.VAccordionPaintable;
/**
* An accordion is a component similar to a {@link TabSheet}, but with a
@@ -16,8 +16,7 @@ import com.vaadin.terminal.gwt.client.ui.VAccordion;
*
* @see TabSheet
*/
-@SuppressWarnings("serial")
-@ClientWidget(VAccordion.class)
+@ClientWidget(VAccordionPaintable.class)
public class Accordion extends TabSheet {
}
diff --git a/src/com/vaadin/ui/ComboBox.java b/src/com/vaadin/ui/ComboBox.java
index 0fb8b9d873..013fe6ab85 100644
--- a/src/com/vaadin/ui/ComboBox.java
+++ b/src/com/vaadin/ui/ComboBox.java
@@ -1,129 +1,130 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
-
-/**
- * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's
- * turned of by default to avoid mistakes. Items are filtered based on user
- * input, and loaded dynamically ("lazy-loading") from the server. You can turn
- * on newItemsAllowed and change filtering mode (and also turn it off), but you
- * can not turn on multi-select mode.
- *
- */
-@SuppressWarnings("serial")
-@ClientWidget(VFilterSelect.class)
-public class ComboBox extends Select {
-
- private String inputPrompt = null;
-
- /**
- * If text input is not allowed, the ComboBox behaves like a pretty
- * NativeSelect - the user can not enter any text and clicking the text
- * field opens the drop down with options
- */
- private boolean textInputAllowed = true;
-
- public ComboBox() {
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Collection<?> options) {
- super(caption, options);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Container dataSource) {
- super(caption, dataSource);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption) {
- super(caption);
- setMultiSelect(false);
- setNewItemsAllowed(false);
- }
-
- @Override
- public void setMultiSelect(boolean multiSelect) {
- if (multiSelect && !isMultiSelect()) {
- throw new UnsupportedOperationException("Multiselect not supported");
- }
- super.setMultiSelect(multiSelect);
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the
- * select would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- * the desired input prompt, or null to disable
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- super.paintContent(target);
-
- if (!textInputAllowed) {
- target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
- }
- }
-
- /**
- * Sets whether it is possible to input text into the field or whether the
- * field area of the component is just used to show what is selected. By
- * disabling text input, the comboBox will work in the same way as a
- * {@link NativeSelect}
- *
- * @see #isTextInputAllowed()
- *
- * @param textInputAllowed
- * true to allow entering text, false to just show the current
- * selection
- */
- public void setTextInputAllowed(boolean textInputAllowed) {
- this.textInputAllowed = textInputAllowed;
- requestRepaint();
- }
-
- /**
- * Returns true if the user can enter text into the field to either filter
- * the selections or enter a new value if {@link #isNewItemsAllowed()}
- * returns true. If text input is disabled, the comboBox will work in the
- * same way as a {@link NativeSelect}
- *
- * @return
- */
- public boolean isTextInputAllowed() {
- return textInputAllowed;
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Collection;
+
+import com.vaadin.data.Container;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelectPaintable;
+
+/**
+ * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's
+ * turned of by default to avoid mistakes. Items are filtered based on user
+ * input, and loaded dynamically ("lazy-loading") from the server. You can turn
+ * on newItemsAllowed and change filtering mode (and also turn it off), but you
+ * can not turn on multi-select mode.
+ *
+ */
+@SuppressWarnings("serial")
+@ClientWidget(VFilterSelectPaintable.class)
+public class ComboBox extends Select {
+
+ private String inputPrompt = null;
+
+ /**
+ * If text input is not allowed, the ComboBox behaves like a pretty
+ * NativeSelect - the user can not enter any text and clicking the text
+ * field opens the drop down with options
+ */
+ private boolean textInputAllowed = true;
+
+ public ComboBox() {
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption, Collection<?> options) {
+ super(caption, options);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption, Container dataSource) {
+ super(caption, dataSource);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ public ComboBox(String caption) {
+ super(caption);
+ setMultiSelect(false);
+ setNewItemsAllowed(false);
+ }
+
+ @Override
+ public void setMultiSelect(boolean multiSelect) {
+ if (multiSelect && !isMultiSelect()) {
+ throw new UnsupportedOperationException("Multiselect not supported");
+ }
+ super.setMultiSelect(multiSelect);
+ }
+
+ /**
+ * Gets the current input prompt.
+ *
+ * @see #setInputPrompt(String)
+ * @return the current input prompt, or null if not enabled
+ */
+ public String getInputPrompt() {
+ return inputPrompt;
+ }
+
+ /**
+ * Sets the input prompt - a textual prompt that is displayed when the
+ * select would otherwise be empty, to prompt the user for input.
+ *
+ * @param inputPrompt
+ * the desired input prompt, or null to disable
+ */
+ public void setInputPrompt(String inputPrompt) {
+ this.inputPrompt = inputPrompt;
+ requestRepaint();
+ }
+
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ if (inputPrompt != null) {
+ target.addAttribute("prompt", inputPrompt);
+ }
+ super.paintContent(target);
+
+ if (!textInputAllowed) {
+ target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
+ }
+ }
+
+ /**
+ * Sets whether it is possible to input text into the field or whether the
+ * field area of the component is just used to show what is selected. By
+ * disabling text input, the comboBox will work in the same way as a
+ * {@link NativeSelect}
+ *
+ * @see #isTextInputAllowed()
+ *
+ * @param textInputAllowed
+ * true to allow entering text, false to just show the current
+ * selection
+ */
+ public void setTextInputAllowed(boolean textInputAllowed) {
+ this.textInputAllowed = textInputAllowed;
+ requestRepaint();
+ }
+
+ /**
+ * Returns true if the user can enter text into the field to either filter
+ * the selections or enter a new value if {@link #isNewItemsAllowed()}
+ * returns true. If text input is disabled, the comboBox will work in the
+ * same way as a {@link NativeSelect}
+ *
+ * @return
+ */
+ public boolean isTextInputAllowed() {
+ return textInputAllowed;
+ }
+
+}
diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java
index b9432df6b6..ebfee5a787 100644
--- a/src/com/vaadin/ui/CssLayout.java
+++ b/src/com/vaadin/ui/CssLayout.java
@@ -14,7 +14,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Paintable;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.ui.VCssLayout;
+import com.vaadin.terminal.gwt.client.ui.VCssLayoutPaintable;
/**
* CssLayout is a layout component that can be used in browser environment only.
@@ -57,7 +57,7 @@ import com.vaadin.terminal.gwt.client.ui.VCssLayout;
* @since 6.1 brought in from "FastLayouts" incubator project
*
*/
-@ClientWidget(VCssLayout.class)
+@ClientWidget(VCssLayoutPaintable.class)
public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
private static final String CLICK_EVENT = EventId.LAYOUT_CLICK;
diff --git a/src/com/vaadin/ui/CustomComponent.java b/src/com/vaadin/ui/CustomComponent.java
index 0f891ac0fa..7aba34b6bb 100644
--- a/src/com/vaadin/ui/CustomComponent.java
+++ b/src/com/vaadin/ui/CustomComponent.java
@@ -9,7 +9,7 @@ import java.util.Iterator;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VCustomComponent;
+import com.vaadin.terminal.gwt.client.ui.VCustomComponentPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -27,7 +27,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VCustomComponent.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VCustomComponentPaintable.class, loadStyle = LoadStyle.EAGER)
public class CustomComponent extends AbstractComponentContainer {
/**
diff --git a/src/com/vaadin/ui/CustomField.java b/src/com/vaadin/ui/CustomField.java
index 72f863ca8b..73f9050363 100644
--- a/src/com/vaadin/ui/CustomField.java
+++ b/src/com/vaadin/ui/CustomField.java
@@ -11,7 +11,7 @@ import java.util.Iterator;
import com.vaadin.data.Property;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VCustomComponent;
+import com.vaadin.terminal.gwt.client.ui.VCustomComponentPaintable;
/**
* A {@link Field} whose UI content can be constructed by the user, enabling the
@@ -35,7 +35,7 @@ import com.vaadin.terminal.gwt.client.ui.VCustomComponent;
*
* @since 7.0
*/
-@ClientWidget(VCustomComponent.class)
+@ClientWidget(VCustomComponentPaintable.class)
public abstract class CustomField<T> extends AbstractField<T> implements
ComponentContainer {
diff --git a/src/com/vaadin/ui/CustomLayout.java b/src/com/vaadin/ui/CustomLayout.java
index dc473fb549..fb0c369969 100644
--- a/src/com/vaadin/ui/CustomLayout.java
+++ b/src/com/vaadin/ui/CustomLayout.java
@@ -12,7 +12,7 @@ import java.util.Iterator;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VCustomLayout;
+import com.vaadin.terminal.gwt.client.ui.VCustomLayoutPaintable;
/**
* <p>
@@ -44,7 +44,7 @@ import com.vaadin.terminal.gwt.client.ui.VCustomLayout;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VCustomLayout.class)
+@ClientWidget(VCustomLayoutPaintable.class)
public class CustomLayout extends AbstractLayout {
private static final int BUFFER_SIZE = 10000;
diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java
index b3f54a0a78..9589414f4d 100644
--- a/src/com/vaadin/ui/DateField.java
+++ b/src/com/vaadin/ui/DateField.java
@@ -27,7 +27,7 @@ import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VDateField;
-import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
+import com.vaadin.terminal.gwt.client.ui.VPopupCalendarPaintable;
/**
* <p>
@@ -50,7 +50,7 @@ import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VPopupCalendar.class)
+@ClientWidget(VPopupCalendarPaintable.class)
public class DateField extends AbstractField<Date> implements
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java
index c6522f15c7..512b70e118 100644
--- a/src/com/vaadin/ui/DragAndDropWrapper.java
+++ b/src/com/vaadin/ui/DragAndDropWrapper.java
@@ -22,11 +22,12 @@ import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.StreamVariable;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper;
+import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapperPaintable;
import com.vaadin.terminal.gwt.client.ui.dd.HorizontalDropLocation;
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
@SuppressWarnings("serial")
-@ClientWidget(VDragAndDropWrapper.class)
+@ClientWidget(VDragAndDropWrapperPaintable.class)
public class DragAndDropWrapper extends CustomComponent implements DropTarget,
DragSource {
diff --git a/src/com/vaadin/ui/Embedded.java b/src/com/vaadin/ui/Embedded.java
index dc14cc6ef8..f655b55711 100644
--- a/src/com/vaadin/ui/Embedded.java
+++ b/src/com/vaadin/ui/Embedded.java
@@ -14,7 +14,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.ui.VEmbedded;
+import com.vaadin.terminal.gwt.client.ui.VEmbeddedPaintable;
/**
* Component for embedding external objects.
@@ -25,10 +25,10 @@ import com.vaadin.terminal.gwt.client.ui.VEmbedded;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VEmbedded.class)
+@ClientWidget(VEmbeddedPaintable.class)
public class Embedded extends AbstractComponent {
- private static final String CLICK_EVENT = VEmbedded.CLICK_EVENT_IDENTIFIER;
+ private static final String CLICK_EVENT = VEmbeddedPaintable.CLICK_EVENT_IDENTIFIER;
/**
* General object type.
diff --git a/src/com/vaadin/ui/Form.java b/src/com/vaadin/ui/Form.java
index 47210e1aed..c79804c7e7 100644
--- a/src/com/vaadin/ui/Form.java
+++ b/src/com/vaadin/ui/Form.java
@@ -27,7 +27,7 @@ import com.vaadin.terminal.CompositeErrorMessage;
import com.vaadin.terminal.ErrorMessage;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VForm;
+import com.vaadin.terminal.gwt.client.ui.VFormPaintable;
/**
* Form component provides easy way of creating and managing sets fields.
@@ -62,8 +62,7 @@ import com.vaadin.terminal.gwt.client.ui.VForm;
* @deprecated Use {@link FieldGroup} instead of {@link Form} for more
* flexibility.
*/
-@SuppressWarnings("serial")
-@ClientWidget(VForm.class)
+@ClientWidget(VFormPaintable.class)
@Deprecated
public class Form extends AbstractField<Object> implements Item.Editor,
Buffered, Item, Validatable, Action.Notifier {
diff --git a/src/com/vaadin/ui/FormLayout.java b/src/com/vaadin/ui/FormLayout.java
index eecf3372bb..c5c211924e 100644
--- a/src/com/vaadin/ui/FormLayout.java
+++ b/src/com/vaadin/ui/FormLayout.java
@@ -4,7 +4,7 @@
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VFormLayout;
+import com.vaadin.terminal.gwt.client.ui.VFormLayoutPaintable;
/**
* FormLayout is used by {@link Form} to layout fields. It may also be used
@@ -21,7 +21,7 @@ import com.vaadin.terminal.gwt.client.ui.VFormLayout;
* bottom are by default on.
*
*/
-@ClientWidget(VFormLayout.class)
+@ClientWidget(VFormLayoutPaintable.class)
public class FormLayout extends AbstractOrderedLayout {
public FormLayout() {
diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java
index 24a57d462b..4588328345 100644
--- a/src/com/vaadin/ui/GridLayout.java
+++ b/src/com/vaadin/ui/GridLayout.java
@@ -18,7 +18,7 @@ import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.ui.VGridLayout;
+import com.vaadin.terminal.gwt.client.ui.VGridLayoutPaintable;
/**
* <p>
@@ -41,7 +41,7 @@ import com.vaadin.terminal.gwt.client.ui.VGridLayout;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VGridLayout.class)
+@ClientWidget(VGridLayoutPaintable.class)
public class GridLayout extends AbstractLayout implements
Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier {
diff --git a/src/com/vaadin/ui/HorizontalLayout.java b/src/com/vaadin/ui/HorizontalLayout.java
index ed1cad8184..ba685ec410 100644
--- a/src/com/vaadin/ui/HorizontalLayout.java
+++ b/src/com/vaadin/ui/HorizontalLayout.java
@@ -3,7 +3,7 @@
*/
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VHorizontalLayout;
+import com.vaadin.terminal.gwt.client.ui.VHorizontalLayoutPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -18,7 +18,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @since 5.3
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VHorizontalLayout.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VHorizontalLayoutPaintable.class, loadStyle = LoadStyle.EAGER)
public class HorizontalLayout extends AbstractOrderedLayout {
public HorizontalLayout() {
diff --git a/src/com/vaadin/ui/HorizontalSplitPanel.java b/src/com/vaadin/ui/HorizontalSplitPanel.java
index d9368635df..d4a1e7cc0e 100644
--- a/src/com/vaadin/ui/HorizontalSplitPanel.java
+++ b/src/com/vaadin/ui/HorizontalSplitPanel.java
@@ -3,7 +3,7 @@
*/
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
+import com.vaadin.terminal.gwt.client.ui.VHorizontalSplitPanelPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -29,7 +29,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @VERSION@
* @since 6.5
*/
-@ClientWidget(value = VSplitPanelHorizontal.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VHorizontalSplitPanelPaintable.class, loadStyle = LoadStyle.EAGER)
public class HorizontalSplitPanel extends AbstractSplitPanel {
public HorizontalSplitPanel() {
super();
diff --git a/src/com/vaadin/ui/InlineDateField.java b/src/com/vaadin/ui/InlineDateField.java
index 0bf7924d34..b4160604ff 100644
--- a/src/com/vaadin/ui/InlineDateField.java
+++ b/src/com/vaadin/ui/InlineDateField.java
@@ -1,48 +1,48 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector inline.
- *
- * </p>
- *
- * @see DateField
- * @see PopupDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@ClientWidget(VDateFieldCalendar.class)
-public class InlineDateField extends DateField {
-
- public InlineDateField() {
- super();
- }
-
- public InlineDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public InlineDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public InlineDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public InlineDateField(String caption) {
- super(caption);
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Date;
+
+import com.vaadin.data.Property;
+import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendarPaintable;
+
+/**
+ * <p>
+ * A date entry component, which displays the actual date selector inline.
+ *
+ * </p>
+ *
+ * @see DateField
+ * @see PopupDateField
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 5.0
+ */
+@ClientWidget(VDateFieldCalendarPaintable.class)
+public class InlineDateField extends DateField {
+
+ public InlineDateField() {
+ super();
+ }
+
+ public InlineDateField(Property dataSource) throws IllegalArgumentException {
+ super(dataSource);
+ }
+
+ public InlineDateField(String caption, Date value) {
+ super(caption, value);
+ }
+
+ public InlineDateField(String caption, Property dataSource) {
+ super(caption, dataSource);
+ }
+
+ public InlineDateField(String caption) {
+ super(caption);
+ }
+
+}
diff --git a/src/com/vaadin/ui/Link.java b/src/com/vaadin/ui/Link.java
index 99d742ec17..0b11151be7 100644
--- a/src/com/vaadin/ui/Link.java
+++ b/src/com/vaadin/ui/Link.java
@@ -7,7 +7,7 @@ package com.vaadin.ui;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.VLink;
+import com.vaadin.terminal.gwt.client.ui.VLinkPaintable;
/**
* Link is used to create external or internal URL links.
@@ -18,7 +18,7 @@ import com.vaadin.terminal.gwt.client.ui.VLink;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VLink.class)
+@ClientWidget(VLinkPaintable.class)
public class Link extends AbstractComponent {
/* Target window border type constant: No window border */
diff --git a/src/com/vaadin/ui/ListSelect.java b/src/com/vaadin/ui/ListSelect.java
index 5c879f00f5..cf0e6773f2 100644
--- a/src/com/vaadin/ui/ListSelect.java
+++ b/src/com/vaadin/ui/ListSelect.java
@@ -9,14 +9,14 @@ import java.util.Collection;
import com.vaadin.data.Container;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VListSelect;
+import com.vaadin.terminal.gwt.client.ui.VListSelectPaintable;
/**
* This is a simple list select without, for instance, support for new items,
* lazyloading, and other advanced features.
*/
@SuppressWarnings("serial")
-@ClientWidget(VListSelect.class)
+@ClientWidget(VListSelectPaintable.class)
public class ListSelect extends AbstractSelect {
private int columns = 0;
diff --git a/src/com/vaadin/ui/NativeSelect.java b/src/com/vaadin/ui/NativeSelect.java
index e701d212b4..b0070426ad 100644
--- a/src/com/vaadin/ui/NativeSelect.java
+++ b/src/com/vaadin/ui/NativeSelect.java
@@ -9,7 +9,7 @@ import java.util.Collection;
import com.vaadin.data.Container;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VNativeSelect;
+import com.vaadin.terminal.gwt.client.ui.VNativeSelectPaintable;
/**
* This is a simple drop-down select without, for instance, support for
@@ -18,7 +18,7 @@ import com.vaadin.terminal.gwt.client.ui.VNativeSelect;
* better choice.
*/
@SuppressWarnings("serial")
-@ClientWidget(VNativeSelect.class)
+@ClientWidget(VNativeSelectPaintable.class)
public class NativeSelect extends AbstractSelect {
// width in characters, mimics TextField
diff --git a/src/com/vaadin/ui/OptionGroup.java b/src/com/vaadin/ui/OptionGroup.java
index 884e58824a..ddacc31554 100644
--- a/src/com/vaadin/ui/OptionGroup.java
+++ b/src/com/vaadin/ui/OptionGroup.java
@@ -18,12 +18,13 @@ import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VOptionGroup;
+import com.vaadin.terminal.gwt.client.ui.VOptionGroupPaintable;
/**
* Configures select to be used as an option group.
*/
@SuppressWarnings("serial")
-@ClientWidget(VOptionGroup.class)
+@ClientWidget(VOptionGroupPaintable.class)
public class OptionGroup extends AbstractSelect implements
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java
index a69413c28b..390279a62f 100644
--- a/src/com/vaadin/ui/Panel.java
+++ b/src/com/vaadin/ui/Panel.java
@@ -16,7 +16,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Scrollable;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.ui.VPanel;
+import com.vaadin.terminal.gwt.client.ui.VPanelPaintable;
import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.themes.Reindeer;
import com.vaadin.ui.themes.Runo;
@@ -30,12 +30,12 @@ import com.vaadin.ui.themes.Runo;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VPanel.class)
+@ClientWidget(VPanelPaintable.class)
public class Panel extends AbstractComponentContainer implements Scrollable,
ComponentContainer.ComponentAttachListener,
ComponentContainer.ComponentDetachListener, Action.Notifier, Focusable {
- private static final String CLICK_EVENT = VPanel.CLICK_EVENT_IDENTIFIER;
+ private static final String CLICK_EVENT = VPanelPaintable.CLICK_EVENT_IDENTIFIER;
/**
* Removes extra decorations from the Panel.
@@ -559,6 +559,7 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
/*
* ACTIONS
*/
+ @Override
protected ActionManager getActionManager() {
if (actionManager == null) {
actionManager = new ActionManager(this);
diff --git a/src/com/vaadin/ui/PasswordField.java b/src/com/vaadin/ui/PasswordField.java
index 99874147d5..d5be4f378d 100644
--- a/src/com/vaadin/ui/PasswordField.java
+++ b/src/com/vaadin/ui/PasswordField.java
@@ -4,13 +4,13 @@
package com.vaadin.ui;
import com.vaadin.data.Property;
-import com.vaadin.terminal.gwt.client.ui.VPasswordField;
+import com.vaadin.terminal.gwt.client.ui.VPasswordFieldPaintable;
/**
* A field that is used to enter secret text information like passwords. The
* entered text is not displayed on the screen.
*/
-@ClientWidget(VPasswordField.class)
+@ClientWidget(VPasswordFieldPaintable.class)
public class PasswordField extends AbstractTextField {
/**
diff --git a/src/com/vaadin/ui/PopupDateField.java b/src/com/vaadin/ui/PopupDateField.java
index d25608a4c4..3688d4035f 100644
--- a/src/com/vaadin/ui/PopupDateField.java
+++ b/src/com/vaadin/ui/PopupDateField.java
@@ -1,80 +1,80 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector as a popup.
- *
- * </p>
- *
- * @see DateField
- * @see InlineDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-public class PopupDateField extends DateField {
-
- private String inputPrompt = null;
-
- public PopupDateField() {
- super();
- }
-
- public PopupDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public PopupDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public PopupDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public PopupDateField(String caption) {
- super(caption);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
-
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the field
- * would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
-}
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.Date;
+
+import com.vaadin.data.Property;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+
+/**
+ * <p>
+ * A date entry component, which displays the actual date selector as a popup.
+ *
+ * </p>
+ *
+ * @see DateField
+ * @see InlineDateField
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 5.0
+ */
+public class PopupDateField extends DateField {
+
+ private String inputPrompt = null;
+
+ public PopupDateField() {
+ super();
+ }
+
+ public PopupDateField(Property dataSource) throws IllegalArgumentException {
+ super(dataSource);
+ }
+
+ public PopupDateField(String caption, Date value) {
+ super(caption, value);
+ }
+
+ public PopupDateField(String caption, Property dataSource) {
+ super(caption, dataSource);
+ }
+
+ public PopupDateField(String caption) {
+ super(caption);
+ }
+
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ super.paintContent(target);
+
+ if (inputPrompt != null) {
+ target.addAttribute("prompt", inputPrompt);
+ }
+ }
+
+ /**
+ * Gets the current input prompt.
+ *
+ * @see #setInputPrompt(String)
+ * @return the current input prompt, or null if not enabled
+ */
+ public String getInputPrompt() {
+ return inputPrompt;
+ }
+
+ /**
+ * Sets the input prompt - a textual prompt that is displayed when the field
+ * would otherwise be empty, to prompt the user for input.
+ *
+ * @param inputPrompt
+ */
+ public void setInputPrompt(String inputPrompt) {
+ this.inputPrompt = inputPrompt;
+ requestRepaint();
+ }
+
+}
diff --git a/src/com/vaadin/ui/PopupView.java b/src/com/vaadin/ui/PopupView.java
index fcad727510..5637ef69d7 100644
--- a/src/com/vaadin/ui/PopupView.java
+++ b/src/com/vaadin/ui/PopupView.java
@@ -10,7 +10,7 @@ import java.util.Map;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VPopupView;
+import com.vaadin.terminal.gwt.client.ui.VPopupViewPaintable;
/**
*
@@ -22,7 +22,7 @@ import com.vaadin.terminal.gwt.client.ui.VPopupView;
* @author Vaadin Ltd.
*/
@SuppressWarnings("serial")
-@ClientWidget(VPopupView.class)
+@ClientWidget(VPopupViewPaintable.class)
public class PopupView extends AbstractComponentContainer {
private Content content;
diff --git a/src/com/vaadin/ui/ProgressIndicator.java b/src/com/vaadin/ui/ProgressIndicator.java
index cc17333cc4..9152a3adab 100644
--- a/src/com/vaadin/ui/ProgressIndicator.java
+++ b/src/com/vaadin/ui/ProgressIndicator.java
@@ -8,7 +8,7 @@ import com.vaadin.data.Property;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VProgressIndicator;
+import com.vaadin.terminal.gwt.client.ui.VProgressIndicatorPaintable;
/**
* <code>ProgressIndicator</code> is component that shows user state of a
@@ -25,7 +25,7 @@ import com.vaadin.terminal.gwt.client.ui.VProgressIndicator;
* @since 4
*/
@SuppressWarnings("serial")
-@ClientWidget(VProgressIndicator.class)
+@ClientWidget(VProgressIndicatorPaintable.class)
public class ProgressIndicator extends AbstractField<Number> implements
Property.Viewer, Property.ValueChangeListener {
diff --git a/src/com/vaadin/ui/RichTextArea.java b/src/com/vaadin/ui/RichTextArea.java
index ea22a6b54b..240063caf3 100644
--- a/src/com/vaadin/ui/RichTextArea.java
+++ b/src/com/vaadin/ui/RichTextArea.java
@@ -10,7 +10,7 @@ import java.util.Map;
import com.vaadin.data.Property;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
+import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextAreaPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -20,7 +20,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* {@link RichTextArea} may produce unexpected results as formatting is counted
* into length of field.
*/
-@ClientWidget(value = VRichTextArea.class, loadStyle = LoadStyle.LAZY)
+@ClientWidget(value = VRichTextAreaPaintable.class, loadStyle = LoadStyle.LAZY)
public class RichTextArea extends AbstractField<String> {
/**
diff --git a/src/com/vaadin/ui/Select.java b/src/com/vaadin/ui/Select.java
index 0ea331dc40..38785f3ab9 100644
--- a/src/com/vaadin/ui/Select.java
+++ b/src/com/vaadin/ui/Select.java
@@ -23,7 +23,7 @@ import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
+import com.vaadin.terminal.gwt.client.ui.VFilterSelectPaintable;
/**
* <p>
@@ -44,7 +44,7 @@ import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VFilterSelect.class)
+@ClientWidget(VFilterSelectPaintable.class)
public class Select extends AbstractSelect implements AbstractSelect.Filtering,
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
diff --git a/src/com/vaadin/ui/SplitPanel.java b/src/com/vaadin/ui/SplitPanel.java
deleted file mode 100644
index bae1bf7ce0..0000000000
--- a/src/com/vaadin/ui/SplitPanel.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
-import com.vaadin.ui.ClientWidget.LoadStyle;
-
-/**
- * SplitPanel.
- *
- * <code>SplitPanel</code> is a component container, that can contain two
- * components (possibly containers) which are split by divider element.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- * @deprecated in 6.5. Use {@link HorizontalSplitPanel} or
- * {@link VerticalSplitPanel} instead.
- */
-@Deprecated
-@ClientWidget(value = VSplitPanelHorizontal.class, loadStyle = LoadStyle.EAGER)
-public class SplitPanel extends AbstractSplitPanel {
-
- /* Predefined orientations */
-
- /**
- * Components are to be laid out vertically.
- */
- public static final int ORIENTATION_VERTICAL = 0;
-
- /**
- * Components are to be laid out horizontally.
- */
- public static final int ORIENTATION_HORIZONTAL = 1;
-
- /**
- * Orientation of the layout.
- */
- private int orientation;
-
- /**
- * Creates a new split panel. The orientation of the panels is
- * <code>ORIENTATION_VERTICAL</code>.
- */
- public SplitPanel() {
- super();
- orientation = ORIENTATION_VERTICAL;
- setSizeFull();
- }
-
- /**
- * Create a new split panels. The orientation of the panel is given as
- * parameters.
- *
- * @param orientation
- * the Orientation of the layout.
- */
- public SplitPanel(int orientation) {
- this();
- setOrientation(orientation);
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
-
- if (orientation == ORIENTATION_VERTICAL) {
- target.addAttribute("vertical", true);
- }
-
- }
-
- /**
- * Gets the orientation of the split panel.
- *
- * @return the Value of property orientation.
- *
- */
- public int getOrientation() {
- return orientation;
- }
-
- /**
- * Sets the orientation of the split panel.
- *
- * @param orientation
- * the New value of property orientation.
- */
- public void setOrientation(int orientation) {
-
- // Checks the validity of the argument
- if (orientation < ORIENTATION_VERTICAL
- || orientation > ORIENTATION_HORIZONTAL) {
- throw new IllegalArgumentException();
- }
-
- this.orientation = orientation;
- requestRepaint();
- }
-
-}
diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java
index a13c336943..e256c51cfd 100644
--- a/src/com/vaadin/ui/TabSheet.java
+++ b/src/com/vaadin/ui/TabSheet.java
@@ -20,6 +20,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.ui.VTabsheet;
+import com.vaadin.terminal.gwt.client.ui.VTabsheetPaintable;
import com.vaadin.terminal.gwt.server.CommunicationManager;
import com.vaadin.ui.themes.Reindeer;
import com.vaadin.ui.themes.Runo;
@@ -53,8 +54,7 @@ import com.vaadin.ui.themes.Runo;
* @VERSION@
* @since 3.0
*/
-@SuppressWarnings("serial")
-@ClientWidget(VTabsheet.class)
+@ClientWidget(VTabsheetPaintable.class)
public class TabSheet extends AbstractComponentContainer {
/**
diff --git a/src/com/vaadin/ui/TextArea.java b/src/com/vaadin/ui/TextArea.java
index e1e5aeabd4..a5e6bb5630 100644
--- a/src/com/vaadin/ui/TextArea.java
+++ b/src/com/vaadin/ui/TextArea.java
@@ -7,12 +7,12 @@ package com.vaadin.ui;
import com.vaadin.data.Property;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VTextArea;
+import com.vaadin.terminal.gwt.client.ui.VTextAreaPaintable;
/**
* A text field that supports multi line editing.
*/
-@ClientWidget(VTextArea.class)
+@ClientWidget(VTextAreaPaintable.class)
public class TextArea extends AbstractTextField {
private static final int DEFAULT_ROWS = 5;
diff --git a/src/com/vaadin/ui/TextField.java b/src/com/vaadin/ui/TextField.java
index e154aaad17..a3d873336c 100644
--- a/src/com/vaadin/ui/TextField.java
+++ b/src/com/vaadin/ui/TextField.java
@@ -5,7 +5,7 @@
package com.vaadin.ui;
import com.vaadin.data.Property;
-import com.vaadin.terminal.gwt.client.ui.VTextField;
+import com.vaadin.terminal.gwt.client.ui.VTextFieldPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -29,7 +29,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VTextField.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VTextFieldPaintable.class, loadStyle = LoadStyle.EAGER)
public class TextField extends AbstractTextField {
/**
diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java
index 554afda97c..4ea66cc6bf 100644
--- a/src/com/vaadin/ui/Tree.java
+++ b/src/com/vaadin/ui/Tree.java
@@ -45,6 +45,7 @@ import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.ui.VTree;
+import com.vaadin.terminal.gwt.client.ui.VTreePaintable;
import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
import com.vaadin.terminal.gwt.client.ui.dd.VTargetInSubtree;
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
@@ -60,7 +61,7 @@ import com.vaadin.tools.ReflectTools;
* @since 3.0
*/
@SuppressWarnings({ "serial", "deprecation" })
-@ClientWidget(VTree.class)
+@ClientWidget(VTreePaintable.class)
public class Tree extends AbstractSelect implements Container.Hierarchical,
Action.Container, ItemClickSource, ItemClickNotifier, DragSource,
DropTarget {
diff --git a/src/com/vaadin/ui/TwinColSelect.java b/src/com/vaadin/ui/TwinColSelect.java
index 1c1fe07a5c..fbdd825a66 100644
--- a/src/com/vaadin/ui/TwinColSelect.java
+++ b/src/com/vaadin/ui/TwinColSelect.java
@@ -10,13 +10,14 @@ import com.vaadin.data.Container;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.gwt.client.ui.VTwinColSelect;
+import com.vaadin.terminal.gwt.client.ui.VTwinColSelectPaintable;
/**
* Multiselect component with two lists: left side for available items and right
* side for selected items.
*/
@SuppressWarnings("serial")
-@ClientWidget(VTwinColSelect.class)
+@ClientWidget(VTwinColSelectPaintable.class)
public class TwinColSelect extends AbstractSelect {
private int columns = 0;
diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java
index 9d684291a5..08a8023ad5 100644
--- a/src/com/vaadin/ui/Upload.java
+++ b/src/com/vaadin/ui/Upload.java
@@ -15,7 +15,7 @@ import java.util.Map;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.StreamVariable.StreamingProgressEvent;
-import com.vaadin.terminal.gwt.client.ui.VUpload;
+import com.vaadin.terminal.gwt.client.ui.VUploadPaintable;
import com.vaadin.terminal.gwt.server.NoInputStreamException;
import com.vaadin.terminal.gwt.server.NoOutputStreamException;
import com.vaadin.ui.ClientWidget.LoadStyle;
@@ -61,7 +61,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VUpload.class, loadStyle = LoadStyle.LAZY)
+@ClientWidget(value = VUploadPaintable.class, loadStyle = LoadStyle.LAZY)
public class Upload extends AbstractComponent implements Component.Focusable {
/**
diff --git a/src/com/vaadin/ui/VerticalLayout.java b/src/com/vaadin/ui/VerticalLayout.java
index c40aeaea30..0c5de43bbd 100644
--- a/src/com/vaadin/ui/VerticalLayout.java
+++ b/src/com/vaadin/ui/VerticalLayout.java
@@ -3,7 +3,7 @@
*/
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VVerticalLayout;
+import com.vaadin.terminal.gwt.client.ui.VVerticalLayoutPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -19,7 +19,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* @since 5.3
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VVerticalLayout.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VVerticalLayoutPaintable.class, loadStyle = LoadStyle.EAGER)
public class VerticalLayout extends AbstractOrderedLayout {
public VerticalLayout() {
diff --git a/src/com/vaadin/ui/VerticalSplitPanel.java b/src/com/vaadin/ui/VerticalSplitPanel.java
index 699bd9287c..46e9d681e8 100644
--- a/src/com/vaadin/ui/VerticalSplitPanel.java
+++ b/src/com/vaadin/ui/VerticalSplitPanel.java
@@ -3,7 +3,7 @@
*/
package com.vaadin.ui;
-import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
+import com.vaadin.terminal.gwt.client.ui.VVerticalSplitPanelPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -23,7 +23,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* </pre>
*
*/
-@ClientWidget(value = VSplitPanelVertical.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VVerticalSplitPanelPaintable.class, loadStyle = LoadStyle.EAGER)
public class VerticalSplitPanel extends AbstractSplitPanel {
public VerticalSplitPanel() {
diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java
index a860d371b0..e6c8642b84 100644
--- a/src/com/vaadin/ui/Window.java
+++ b/src/com/vaadin/ui/Window.java
@@ -23,7 +23,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.gwt.client.ui.VView;
-import com.vaadin.terminal.gwt.client.ui.VWindow;
+import com.vaadin.terminal.gwt.client.ui.VWindowPaintable;
/**
* A component that represents an application (browser native) window or a sub
@@ -71,7 +71,7 @@ import com.vaadin.terminal.gwt.client.ui.VWindow;
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(VWindow.class)
+@ClientWidget(VWindowPaintable.class)
public class Window extends Panel implements FocusNotifier, BlurNotifier {
/**