Author: [EMAIL PROTECTED]
Date: Fri Nov 21 21:23:04 2008
New Revision: 4165

Added:
     
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
     
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java
     
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java
Modified:
     
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
     
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java
     
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java
     
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java
    branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java
     
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java

Log:
Makes DateBox implement ValueChange, and makes it, like, work. Adds unit  
tests for DateBox and DatePicker. Removes some broken event handling  
methods from DateBox that aren't worth fixing b/c they can be done directly  
to its textbox instead. Adds notiong of an autoHidePartner to PopupPanel,  
to keep picker from disappearing during mouse events in the date box text  
field. Should be generally useful.

Modified:  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
==============================================================================
---  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
      
(original)
+++  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
      
Fri Nov 21 21:23:04 2008
@@ -6,7 +6,7 @@
      <inherits name="com.google.gwt.user.theme.standard.StandardResources"/>

      <!-- Specify the app entry point class.                   -->
-    <entry-point  
class='com.google.gwt.museum.client.defaultmuseum.VisualsForDatePicker'/>
+    <entry-point  
class='com.google.gwt.museum.client.defaultmuseum.VisualsForDateBox'/>
      <source path="client/common"/>
      <source path="client/defaultmuseum"/>
      <source path="client/viewer"/>

Modified:  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java
==============================================================================
---  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java
      
(original)
+++  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java
      
Fri Nov 21 21:23:04 2008
@@ -26,11 +26,14 @@
  import com.google.gwt.i18n.client.DateTimeFormat;
  import com.google.gwt.museum.client.common.AbstractIssue;
  import com.google.gwt.user.client.ui.Button;
+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.VerticalPanel;
  import com.google.gwt.user.client.ui.Widget;
  import com.google.gwt.user.datepicker.client.DateBox;
+import com.google.gwt.user.datepicker.client.DatePicker;
+import com.google.gwt.user.datepicker.client.DateBox.InvalidDateReporter;

  import java.util.Date;

@@ -38,20 +41,42 @@
   * Visuals for date box.
   */
  public class VisualsForDateBox extends AbstractIssue {
-
+
    @Override
    public Widget createIssue() {
-    return dateRange();
+    VerticalPanel v = new VerticalPanel();
+    v.add(new HTML("<div style='height:25px'></div>"));
+    v.add(dateRange());
+    v.add(new HTML("<div style='height:25px'></div>"));
+    final Label startErrors = makeErrorLabel();
+
+    Widget errorReportingDateBox = dateRange(new  
DateBox.InvalidDateReporter() {
+      public void clearError() {
+        startErrors.setText("");
+      }
+      public void reportError(String input) {
+        startErrors.setText("\"" + input + "\" is not a date");
+      }
+    });
+
+    v.add(errorReportingDateBox);
+    v.add(startErrors);
+
+    return v;
    }

    @Override
    public String getInstructions() {
-    return "Click on first date box, see that date picker is displayed,  
use arrow keys to navigate to second date box, select a date";
+    return "Click on first date box, see that date picker is displayed, "
+        + "use arrow keys to navigate to second date box, select a date. "
+        + "The second set includes an error display, see that it notices "
+        + "when you type garbage, and that its error message is cleared"
+        + "when you empty the field or provide a valid date.";
    }

    @Override
    public String getSummary() {
-   return "date box visual test";
+    return "date box visual test";
    }

    @Override
@@ -60,28 +85,32 @@
    }

    private Widget dateRange() {
+    return dateRange(null);
+  }
+
+  private Widget dateRange(InvalidDateReporter invalidDateReporter) {
      VerticalPanel v = new VerticalPanel();
      HorizontalPanel p = new HorizontalPanel();
      v.add(p);
-    final DateBox start = new DateBox();
-    start.setWidth("15em");
-    final DateBox end = new DateBox();
-    end.setWidth("15em");
+    final DateBox start = newDateBox(invalidDateReporter);
+    start.setWidth("13em");
+    final DateBox end = newDateBox(invalidDateReporter);
+    end.setWidth("13em");
      start.setAnimationEnabled(true);

      end.setAnimationEnabled(true);

-    start.addKeyDownHandler(new KeyDownHandler() {
+    start.getTextBox().addKeyDownHandler(new KeyDownHandler() {
        public void onKeyDown(KeyDownEvent e) {
          if (e.getNativeKeyCode() == KeyCodes.KEY_RIGHT
-            && start.getCursorPos() == start.getText().length()) {
+            && start.getCursorPos() ==  
start.getTextBox().getText().length()) {
            start.hideDatePicker();
            end.setFocus(true);
          }
        }
      });

-    end.addKeyDownHandler(new KeyDownHandler() {
+    end.getTextBox().addKeyDownHandler(new KeyDownHandler() {
        public void onKeyDown(KeyDownEvent e) {
          if ((e.getNativeKeyCode() == KeyCodes.KEY_LEFT)
              && end.getCursorPos() == 0) {
@@ -97,13 +126,15 @@
        }
      });

-    start.showDate(new Date());
+    start.setValue(new Date());

      p.add(start);
      Label l = new Label(" - ");
      l.setStyleName("filler");
      p.add(l);
      p.add(end);
+    final Label value = new Label();
+    p.add(value);
      HorizontalPanel h2 = new HorizontalPanel();
      v.add(h2);
      h2.add(new Button("Short format", new ClickHandler() {
@@ -120,12 +151,38 @@
        }
      }));

-    h2.add(new Button("clear", new ClickHandler() {
+    h2.add(new Button("Clear", new ClickHandler() {
        public void onClick(ClickEvent sender) {
-        start.clear();
-        end.clear();
+        start.setValue(null);
+        end.setValue(null);
+      }
+    }));
+
+    h2.add(new Button("Get Value", new ClickHandler() {
+      public void onClick(ClickEvent event) {
+        DateTimeFormat f = DateTimeFormat.getShortDateFormat();
+        Date d1 = start.getValue();
+        Date d2 = end.getValue();
+        value.setText("Start: \""
+            + (d1 == null ? "null" : f.format(d1))
+            + "\" End:\""
+            + (d2 == null ? "null" : f.format(d2))
+            + "\"");
        }
      }));
      return v;
+  }
+
+  private Label makeErrorLabel() {
+    final Label startErrors = new Label();
+    startErrors.getElement().getStyle().setProperty("color", "red");
+    return startErrors;
+  }
+
+  private DateBox newDateBox(InvalidDateReporter invalidDateReporter) {
+    DateBox dateBox =
+        invalidDateReporter == null ? new DateBox() : new DateBox(
+            new DatePicker(), invalidDateReporter);
+    return dateBox;
    }
  }

Modified:  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java
==============================================================================
---  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java
   
(original)
+++  
branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java
   
Fri Nov 21 21:23:04 2008
@@ -16,7 +16,16 @@

  package com.google.gwt.museum.client.defaultmuseum;

+import com.google.gwt.event.logical.shared.HighlightEvent;
+import com.google.gwt.event.logical.shared.HighlightHandler;
+import com.google.gwt.event.logical.shared.ShowRangeEvent;
+import com.google.gwt.event.logical.shared.ShowRangeHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.i18n.client.DateTimeFormat;
  import com.google.gwt.museum.client.common.AbstractIssue;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.VerticalPanel;
  import com.google.gwt.user.client.ui.Widget;
  import com.google.gwt.user.datepicker.client.DatePicker;

@@ -29,9 +38,35 @@

    @Override
    public Widget createIssue() {
+    VerticalPanel p = new VerticalPanel();
      DatePicker picker = new DatePicker();
-    picker.setValue(new Date());
-    return picker;
+    p.add(picker);
+    final Label value = new Label("value");
+    p.add(value);
+    final Label highlight = new Label("highlight");
+    p.add(highlight);
+    final Label range = new Label("range");
+    p.add(range);
+    picker.addValueChangeHandler(new ValueChangeHandler<Date>() {
+      public void onValueChange(ValueChangeEvent<Date> event) {
+         
value.setText(DateTimeFormat.getShortDateFormat().format(event.getValue()));
+      }
+    });
+    picker.addHighlightHandler(new HighlightHandler<Date>() {
+      public void onHighlight(HighlightEvent<Date> event) {
+         
highlight.setText(DateTimeFormat.getShortDateFormat().format(event.getHighlighted()));
+     }
+    });
+    picker.addShowRangeHandler(new ShowRangeHandler<Date>() {
+      public void onShowRange(ShowRangeEvent<Date> event) {
+        Date start = event.getStart();
+        Date end = event.getEnd();
+        DateTimeFormat format = DateTimeFormat.getShortDateFormat();
+        range.setText(format.format(start) + " - " + format.format(end));
+      }
+    });
+//    picker.setValue(new Date());
+    return p;
    };

    @Override

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java  
 
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java  
 
Fri Nov 21 21:23:04 2008
@@ -272,6 +272,8 @@
    private String desiredWidth;

    private boolean isAnimationEnabled = false;
+
+  private Element autoHidePartner;

    /**
     * The [EMAIL PROTECTED] ResizeAnimation} used to open and close the [EMAIL 
PROTECTED]  
PopupPanel}s.
@@ -454,6 +456,7 @@
      return modal;
    }

+  @SuppressWarnings("deprecation")
    public boolean onEventPreview(Event event) {
      Element target = DOM.eventGetTarget(event);

@@ -485,7 +488,7 @@
            return true;
          }

-        if (!eventTargetsPopup && autoHide) {
+        if (!eventTargetsPopup && shouldAutoHide(event)) {
            hide(true);
            return true;
          }
@@ -503,7 +506,8 @@
          // If it's an outside click and auto-hide is enabled:
          // hide the popup and _don't_ eat the event. ONMOUSEDOWN is used to
          // prevent problems with showing a popup in response to a  
mousedown.
-        if (!eventTargetsPopup && autoHide && (type == Event.ONMOUSEDOWN))  
{
+        if (!eventTargetsPopup && shouldAutoHide(event)
+            && (type == Event.ONMOUSEDOWN)) {
            hide(true);
            return true;
          }
@@ -581,6 +585,15 @@
    }

    /**
+   * If the auto hide partner is non null, its mouse events will
+   * not hide a panel set to autohide.
+   * @param element new auto hide partner
+   */
+  public void setAutoHidePartner(Element element) {
+    this.autoHidePartner = element;
+  }
+
+  /**
     * Sets the height of the panel's child widget. If the panel's child  
widget
     * has not been set, the height passed in will be cached and used to set  
the
     * height immediately after the child widget is set.
@@ -613,7 +626,7 @@
    public void setModal(boolean modal) {
      this.modal = modal;
    }
-
+
    /**
     * Sets the popup's position relative to the browser's client area. The
     * popup's position may be set before calling [EMAIL PROTECTED] #show()}.
@@ -820,7 +833,12 @@
        elt.blur();
      }
    }-*/;
-
+
+  private boolean eventInPartner(Event event) {
+    return autoHidePartner != null
+      && autoHidePartner.isOrHasChild(event.getTarget());
+  }
+
    /**
     * Positions the popup, called after the offset width and height of the  
popup are known.
     *
@@ -948,6 +966,11 @@
        top += relativeObject.getOffsetHeight();
      }
      setPopupPosition(left, top);
+  }
+
+  private boolean shouldAutoHide(Event event) {
+    boolean shouldAutoHide = autoHide && !eventInPartner(event);
+    return shouldAutoHide;
    }

  }

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java
      
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java
      
Fri Nov 21 21:23:04 2008
@@ -22,7 +22,6 @@
  import com.google.gwt.event.dom.client.ClickHandler;
  import com.google.gwt.event.dom.client.FocusEvent;
  import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.HasKeyDownHandlers;
  import com.google.gwt.event.dom.client.KeyCodes;
  import com.google.gwt.event.dom.client.KeyDownEvent;
  import com.google.gwt.event.dom.client.KeyDownHandler;
@@ -33,8 +32,8 @@
  import com.google.gwt.user.client.Command;
  import com.google.gwt.user.client.DeferredCommand;
  import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.FlowPanel;
  import com.google.gwt.user.client.ui.HasAnimation;
+import com.google.gwt.user.client.ui.HasValue;
  import com.google.gwt.user.client.ui.PopupPanel;
  import com.google.gwt.user.client.ui.TextBox;

@@ -43,26 +42,97 @@
  /**
   * A simple date box.
   */
-public class DateBox extends Composite implements HasKeyDownHandlers,
-    HasAnimation {
+public class DateBox extends Composite implements HasAnimation,  
HasValue<Date> {
+
+  /**
+   * Implemented by a delegate to report errors parsing date values from  
the
+   * user's input.
+   */
+  public interface InvalidDateReporter {
+    /**
+     * Called when a valid date has been parsed, or the datebox has been
+     * cleared.
+     */
+    void clearError();
+
+    /**
+     * Given an unparseable string, explain the situation to the user.
+     *
+     * @param input what the user typed
+     */
+    void reportError(String input);
+  }
+
+  private class DateBoxHandler implements ValueChangeHandler<Date>,
+      FocusHandler, BlurHandler, ClickHandler, KeyDownHandler {
+
+    public void onBlur(BlurEvent event) {
+      if (!popup.isVisible()) {
+        updateDateFromTextBox();
+      }
+    }
+
+    public void onClick(ClickEvent event) {
+      showDatePicker();
+    }
+
+    public void onFocus(FocusEvent event) {
+      if (allowDPShow) {
+        showDatePicker();
+      }
+    }
+
+    public void onKeyDown(KeyDownEvent event) {
+      switch (event.getNativeKeyCode()) {
+        case KeyCodes.KEY_ENTER:
+        case KeyCodes.KEY_TAB:
+        case KeyCodes.KEY_ESCAPE:
+        case KeyCodes.KEY_UP:
+          updateDateFromTextBox();
+          hideDatePicker();
+          break;
+        case KeyCodes.KEY_DOWN:
+          showDatePicker();
+          break;
+      }
+    }
+
+    public void onValueChange(ValueChangeEvent<Date> event) {
+      setValue(event.getValue());
+      hideDatePicker();
+      preventDatePickerPopup();
+      box.setFocus(true);
+    }
+  }

    /**
     * Default style name.
     */
    public static final String DEFAULT_STYLENAME = "gwt-DateBox";
-  private static final DateTimeFormat DEFAULT_FORMATTER =  
DateTimeFormat.getMediumDateFormat();
-  private boolean dirtyText = false;
-  private PopupPanel popup = new PopupPanel();
-  private TextBox box = new TextBox();
-  private DatePicker picker;
-  private DateTimeFormat dateFormatter;
+
+  public static final InvalidDateReporter DEFAULT_INVALID_DATE_REPORTER =
+      new InvalidDateReporter() {
+        public void clearError() { }
+        public void reportError(String input) {  }
+      };
+  private static final DateTimeFormat DEFAULT_FORMATTER =
+      DateTimeFormat.getMediumDateFormat();
+
+  private final PopupPanel popup;
+  private final TextBox box = new TextBox();
+  private final DatePicker picker;
+
+  private final InvalidDateReporter invalidDateReporter;
+  private DateTimeFormat dateFormatter = DEFAULT_FORMATTER;
+
    private boolean allowDPShow = true;

    /**
-   * Create a new date box.
+   * Create a new date box with a new [EMAIL PROTECTED] DatePicker} and the
+   * [EMAIL PROTECTED] #DEFAULT_INVALID_DATE_REPORTER}, which does nothing.
     */
    public DateBox() {
-    this(new DatePicker());
+    this(new DatePicker(), DEFAULT_INVALID_DATE_REPORTER);
    }

    /**
@@ -70,69 +140,16 @@
     *
     * @param picker the picker to drop down from the date box
     */
-  public DateBox(final DatePicker picker) {
-    this(picker, DEFAULT_FORMATTER);
-  }
-
-  /**
-   * Constructor.
-   *
-   * @param picker the picker to drop down
-   * @param formatter date time formatter to use for parsing the dates in  
this
-   *          date box
-   */
-  public DateBox(final DatePicker picker, DateTimeFormat formatter) {
-    FlowPanel p = new FlowPanel();
-    this.dateFormatter = formatter;
-    p.add(box);
+  public DateBox(DatePicker picker, InvalidDateReporter  
invalidDateReporter) {
      this.picker = picker;
+    this.invalidDateReporter = invalidDateReporter;
+    this.popup = new PopupPanel();
+    popup.setAutoHideEnabled(true);
+    popup.setAutoHidePartner(box.getElement());
      popup.setWidget(picker);
-    initWidget(p);
+    initWidget(box);
      setStyleName(DEFAULT_STYLENAME);

-    class DateBoxHandler implements ValueChangeHandler<Date>, FocusHandler,
-        BlurHandler, ClickHandler, KeyDownHandler {
-
-      public void onBlur(BlurEvent event) {
-        if (dirtyText) {
-          updateDateFromTextBox();
-        }
-      }
-
-      public void onClick(ClickEvent event) {
-        showCurrentDate();
-      }
-
-      public void onFocus(FocusEvent event) {
-        if (allowDPShow) {
-          showCurrentDate();
-        }
-      }
-
-      public void onKeyDown(KeyDownEvent event) {
-        switch (event.getNativeKeyCode()) {
-          case KeyCodes.KEY_ENTER:
-          case KeyCodes.KEY_TAB:
-          case KeyCodes.KEY_ESCAPE:
-          case KeyCodes.KEY_UP:
-            updateDateFromTextBox();
-            popup.hide();
-            break;
-          case KeyCodes.KEY_DOWN:
-            showCurrentDate();
-            break;
-          default:
-            dirtyText = true;
-        }
-      }
-
-      public void onValueChange(ValueChangeEvent<Date> event) {
-        setText(event.getValue());
-        hideDatePicker();
-        preventDatePickerPopup();
-        box.setFocus(true);
-      }
-    }
      DateBoxHandler handler = new DateBoxHandler();
      picker.addValueChangeHandler(handler);
      box.addFocusHandler(handler);
@@ -141,16 +158,9 @@
      box.addKeyDownHandler(handler);
    }

-  public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
-    return addHandler(handler, KeyDownEvent.getType());
-  }
-
-  /**
-   * Clears the current selection.
-   */
-  public void clear() {
-    picker.setValue(null, false);
-    box.setText("");
+  public HandlerRegistration addValueChangeHandler(
+      ValueChangeHandler<Date> handler) {
+    return addHandler(handler, ValueChangeEvent.getType());
    }

    /**
@@ -182,21 +192,23 @@
    }

    /**
-   * Get current text in text box.
+   * Get text box.
     *
-   * @return the text in the date box
+   * @return the text box used to enter the formatted date
     */
-  public String getText() {
-    return box.getText();
+  public TextBox getTextBox() {
+    return box;
    }

    /**
-   * Get text box.
+   * Get the date displayed, or null if the text box is empty, or cannot
+   * be interpretted. The [EMAIL PROTECTED] InvalidDateReporter} may fire as a 
side
+   * effect of this call.
     *
-   * @return the text box used to enter the formatted date
+   * @return the Date
     */
-  public TextBox getTextBox() {
-    return box;
+  public Date getValue() {
+    return parseDate(true);
    }

    /**
@@ -233,21 +245,17 @@

    /**
     * Sets the date format to the given format. If date box is not empty,
-   * contents of date box will be replaced with current date in new format.
+   * contents of date box will be replaced with current date in new  
format. If
+   * the date cannot be parsed, the current value will be preserved and the
+   * InvalidDateReporter notified as usual.
     *
     * @param format format.
     */
    public void setDateFormat(DateTimeFormat format) {
      if (format != dateFormatter) {
+      Date date = getValue();
        dateFormatter = format;
-      String cur = box.getText();
-      if (cur != null && cur.length() != 0) {
-        try {
-          box.setText(dateFormatter.format(picker.getValue()));
-        } catch (IllegalArgumentException e) {
-          box.setText("");
-        }
-      }
+      setValue(date);
      }
    }

@@ -259,7 +267,7 @@
    public void setEnabled(boolean enabled) {
      box.setEnabled(enabled);
    }
-
+
    /**
     * Explicitly focus/unfocus this widget. Only one widget can have focus  
at a
     * time, and the widget that does will receive all keyboard events.
@@ -283,21 +291,35 @@
    }

    /**
-   * Parses the current date box's value and shows that date.
+   * Set the date.
     */
-  public void showCurrentDate() {
-    Date current = null;
+  public void setValue(Date date) {
+    setValue(date, false);
+  }

-    String value = box.getText().trim();
-    if (!value.equals("")) {
-      try {
-        current = dateFormatter.parse(value);
-      } catch (IllegalArgumentException e) {
-        // Does not trigger error reporting because user has not left the  
text
-        // box yet.
-      }
+  public void setValue(Date date, boolean fireEvents) {
+    Date oldDate = getValue();
+
+    if (date == null) {
+      picker.setValue(null);
+      box.setText("");
+    } else {
+      picker.setValue(date, false);
+      picker.setCurrentMonth(date);
+      setDate(date);
      }
+
+    invalidDateReporter.clearError();
+    if (fireEvents) {
+      ValueChangeEvent.fireIfNotEqual(this, oldDate, date);
+    }
+  }

+  /**
+   * Parses the current date box's value and shows that date.
+   */
+  public void showDatePicker() {
+    Date current = parseDate(false);
      if (current == null) {
        current = new Date();
      }
@@ -305,16 +327,19 @@
      popup.showRelativeTo(this);
    }

-  /**
-   * Show the given date.
-   *
-   * @param date picker
-   */
-  public void showDate(Date date) {
-    picker.setValue(date, false);
-    picker.setCurrentMonth(date);
-    setText(date);
-    dirtyText = false;
+  private Date parseDate(boolean reportError) {
+    Date d = null;
+    String text = box.getText().trim();
+    if (!text.equals("")) {
+      try {
+        d = dateFormatter.parse(text);
+      } catch (IllegalArgumentException exception) {
+        if (reportError) {
+          invalidDateReporter.reportError(text);
+        }
+      }
+    }
+    return d;
    }

    private void preventDatePickerPopup() {
@@ -326,23 +351,18 @@
      });
    }

-  private void setText(Date value) {
+  /**
+   * Does the actual work of setting the date. Performs no validation,
+   * fires no events.
+   */
+  private void setDate(Date value) {
      box.setText(dateFormatter.format(value));
-    dirtyText = false;
    }
-
+
    private void updateDateFromTextBox() {
-    String text = box.getText().trim();
-    if (text.equals("")) {
-      return;
+    Date parsedDate = parseDate(true);
+    if (parsedDate != null) {
+      setValue(parsedDate);
      }
-    try {
-      Date d = dateFormatter.parse(text);
-      showDate(d);
-    } catch (IllegalArgumentException exception) {
-      // TODO(ECC) use new reporter interface here.
-    }
-    dirtyText = false;
    }
-
  }

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
   
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
   
Fri Nov 21 21:23:04 2008
@@ -243,7 +243,7 @@
    public HandlerRegistration addHighlightHandler(HighlightHandler<Date>  
handler) {
      return addHandler(handler, HighlightEvent.getType());
    }
-
+
    public HandlerRegistration addShowRangeHandler(ShowRangeHandler<Date>  
handler) {
      return addHandler(handler, ShowRangeEvent.getType());
    }
@@ -258,7 +258,7 @@
    public HandlerRegistration addShowRangeHandlerAndFire(
        ShowRangeHandler<Date> handler) {
      ShowRangeEvent<Date> event = new ShowRangeEvent<Date>(
-        getView().getFirstDate(), getView().getLastDate()) {
+      getView().getFirstDate(), getView().getLastDate()) {
      };
      handler.onShowRange(event);
      return addShowRangeHandler(handler);
@@ -498,7 +498,7 @@
     * @param newValue the new value
     */
    public final void setValue(Date newValue) {
-    setValue(newValue, true);
+    setValue(newValue, false);
    }

    /**
@@ -518,7 +518,9 @@
      if (value != null) {
        addGlobalStyleToDate(css().dayIsValue(), value);
      }
-    ValueChangeEvent.fire(this, newValue);
+    if (fireEvents) {
+      ValueChangeEvent.fireIfNotEqual(this, oldValue, newValue);
+    }
    }

    /**
@@ -558,7 +560,7 @@
      getMonthSelector().refresh();
      ShowRangeEvent.fire(this, getFirstDate(), getLastDate());
    }
-
+
    /**
     * Sets up the date picker.
     */
@@ -584,13 +586,12 @@
    /**
     * Sets the highlighted date.
     *
-   * @param highlighted highlighted date
+   * @param highlightedDate highlighted date
     */
    void setHighlightedDate(Date highlighted) {
      this.highlighted = highlighted;
      HighlightEvent.fire(this, highlighted);
    }
-
    private boolean assertVisible(Date date, Date... moreDates) {
      assert isDateVisible(date) : date + " must be visible";
      if (moreDates != null) {

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java
  
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java
  
Fri Nov 21 21:23:04 2008
@@ -24,7 +24,7 @@

  /**
   * Simple calendar view. Not extensible as we wish to evolve it freely over
- * time. Please copy though, as we like it getting used.
+ * time.
   */

  @SuppressWarnings(/* Date manipulation required */{"deprecation"})
@@ -71,7 +71,7 @@
        @Override
        public void onSelected(boolean selected) {
          if (selected) {
-          getDatePicker().setValue(getValue());
+          getDatePicker().setValue(getValue(), true);
            if (isFiller()) {
              getDatePicker().setCurrentMonth(getValue());
            }

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java
         
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java
         
Fri Nov 21 21:23:04 2008
@@ -23,9 +23,8 @@
  import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;

  /**
- * A simple [EMAIL PROTECTED] MonthSelector} used for the default date picker. 
Not  
part of
- * the public API as we wish to evolve it freely over time. Please copy  
though,
- * as we like it getting used.
+ * A simple [EMAIL PROTECTED] MonthSelector} used for the default date picker. 
Not
+ * extensible as we wish to evolve it freely over time.
   */

  public final class DefaultMonthSelector extends MonthSelector {

Modified:  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java
==============================================================================
---  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java
        
(original)
+++  
branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java
        
Fri Nov 21 21:23:04 2008
@@ -28,9 +28,9 @@
  /**
   * Creates a mapping from elements to their associated ui objects.
   *
- * @param <MappedType> the type that the element is mapped to
+ * @param <T> the type that the element is mapped to
   */
-class ElementMapper<MappedType extends UIObject> {
+class ElementMapper<T extends UIObject> {

    private static class FreeNode {
      int index;
@@ -57,7 +57,7 @@

    private ElementMapper.FreeNode freeList = null;

-  private final ArrayList<MappedType> uiObjectList = new  
ArrayList<MappedType>();
+  private final ArrayList<T> uiObjectList = new ArrayList<T>();

    /**
     * Returns the uiObject associated with the given element.
@@ -65,7 +65,7 @@
     * @param elem uiObject's element
     * @return the uiObject
     */
-  public MappedType get(Element elem) {
+  public T get(Element elem) {
      int index = getIndex(elem);
      if (index < 0) {
        return null;
@@ -78,7 +78,7 @@
     *
     * @param uiObject uiObject to add
     */
-  public void put(MappedType uiObject) {
+  public void put(T uiObject) {
      int index;
      if (freeList == null) {
        index = uiObjectList.size();
@@ -106,9 +106,9 @@
     *
     * @return the iterator
     */
-  public Iterator<MappedType> iterator() {
+  public Iterator<T> iterator() {

-    return new Iterator() {
+    return new Iterator<T>() {
        int lastIndex = -1;
        int nextIndex = -1;
        {
@@ -119,11 +119,11 @@
          return nextIndex < uiObjectList.size();
        }

-      public Object next() {
+      public T next() {
          if (!hasNext()) {
            throw new NoSuchElementException();
          }
-        Object result = uiObjectList.get(nextIndex);
+        T result = uiObjectList.get(nextIndex);
          lastIndex = nextIndex;
          findNext();
          return result;
@@ -133,6 +133,7 @@
          if (lastIndex < 0) {
            throw new IllegalStateException();
          }
+        // TODO(ecc) ???
          Widget w = (Widget) uiObjectList.get(lastIndex);
          assert (w.getParent() instanceof HTMLTable);
          w.removeFromParent();

Modified: branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java
==============================================================================
--- branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java   
(original)
+++ branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java  Fri  
Nov 21 21:23:04 2008
@@ -26,6 +26,8 @@
  import com.google.gwt.user.client.ui.CompositeTest;
  import com.google.gwt.user.client.ui.CustomButtonTest;
  import com.google.gwt.user.client.ui.DOMTest;
+import com.google.gwt.user.client.ui.DateBoxTest;
+import com.google.gwt.user.client.ui.DatePickerTest;
  import com.google.gwt.user.client.ui.DeckPanelTest;
  import com.google.gwt.user.client.ui.DecoratedPopupTest;
  import com.google.gwt.user.client.ui.DecoratedStackPanelTest;
@@ -94,6 +96,8 @@
      suite.addTestSuite(CompositeTest.class);
      suite.addTestSuite(CookieTest.class);
      suite.addTestSuite(CustomButtonTest.class);
+    suite.addTestSuite(DateBoxTest.class);
+    suite.addTestSuite(DatePickerTest.class);
      suite.addTestSuite(DeckPanelTest.class);
      suite.addTestSuite(DecoratedPopupTest.class);
      suite.addTestSuite(DecoratedStackPanelTest.class);

Added:  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
==============================================================================
--- (empty file)
+++  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
         
Fri Nov 21 21:23:04 2008
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
+ * use this file except in compliance with the License. You may obtain a  
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.datepicker.client.DateBox;
+
+/**
+ * Tests DateBox.
+ */
+public class DateBoxTest extends GWTTestCase {
+  public String getModuleName() {
+    return "com.google.gwt.user.User";
+  }
+
+  public void testValueChangeEvent() {
+    DateBox db = new DateBox();
+    RootPanel.get().add(db);
+    new DateValueChangeTester(db).run();
+  }
+}

Added:  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java
==============================================================================
--- (empty file)
+++  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java
      
Fri Nov 21 21:23:04 2008
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
+ * use this file except in compliance with the License. You may obtain a  
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.datepicker.client.DatePicker;
+
+/**
+ * Tests DatePicker.
+ */
+public class DatePickerTest extends GWTTestCase {
+  private DatePicker dp;
+
+  public String getModuleName() {
+    return "com.google.gwt.user.User";
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    super.gwtSetUp();
+    dp = new DatePicker();
+    RootPanel.get().add(dp);
+  }
+
+  public void testValueChangeEvent() {
+    new DateValueChangeTester(dp).run();
+  }
+}

Added:  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java
==============================================================================
--- (empty file)
+++  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java
       
Fri Nov 21 21:23:04 2008
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
+ * use this file except in compliance with the License. You may obtain a  
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+
+import junit.framework.TestCase;
+
+import java.util.Date;
+
+/**
+ * Handy tool for testing classes that implement [EMAIL PROTECTED] 
HasValue<Date>}.
+ */
+public class DateValueChangeTester {
+  static class Handler implements ValueChangeHandler<Date> {
+    Date received = null;
+
+    public void onValueChange(ValueChangeEvent<Date> event) {
+      received = event.getValue();
+    }
+  }
+
+  private final HasValue<Date> subject;
+  public DateValueChangeTester(HasValue<Date> subject) {
+    this.subject = subject;
+  }
+
+  @SuppressWarnings("deprecation")
+  public void run() {
+    subject.setValue(null);
+    TestCase.assertNull(subject.getValue());
+
+    Date able = new Date(1999, 5, 15);
+    subject.setValue(able);
+    TestCase.assertEquals(able, subject.getValue());
+
+    DateValueChangeTester.Handler h = new Handler();
+    subject.addValueChangeHandler(h);
+
+    subject.setValue(able);
+    TestCase.assertNull(h.received);
+
+    Date baker = new Date(1965, 12, 7);
+    subject.setValue(baker);
+    TestCase.assertNull(h.received);
+
+    subject.setValue(baker, true);
+    TestCase.assertNull(h.received);
+
+    subject.setValue(able, true);
+    TestCase.assertEquals(able, h.received);
+
+    subject.setValue(baker, true);
+    TestCase.assertEquals(baker, h.received);
+  }
+}
\ No newline at end of file

Modified:  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
==============================================================================
---  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
         
(original)
+++  
branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
         
Fri Nov 21 21:23:04 2008
@@ -104,16 +104,19 @@
      Handler h = new Handler();
      tb.addValueChangeHandler(h);
      tb.setText("able");
+    assertEquals("able", tb.getValue());
      assertNull(h.received);
-
+
      tb.setValue("able");
+    assertEquals("able", tb.getValue());
      assertNull(h.received);
      tb.setValue("baker");
      assertNull(h.received);

      tb.setValue("baker", true);
+    assertEquals("baker", tb.getValue());
      assertNull(h.received);
-
+
      tb.setValue("able", true);
      assertEquals("able", h.received);


--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to