]> source.dussan.org Git - vaadin-framework.git/commitdiff
Refactoring, client classes moved to subpackages
authorMarc Englund <marc.englund@itmill.com>
Fri, 17 Aug 2007 08:30:54 +0000 (08:30 +0000)
committerMarc Englund <marc.englund@itmill.com>
Fri, 17 Aug 2007 08:30:54 +0000 (08:30 +0000)
svn changeset:2046/svn branch:trunk

src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java [deleted file]
src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IEntryCalendar.java [deleted file]
src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITime.java [deleted file]
src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java [new file with mode: 0644]

index 7a2c7a21363ebc5c027467cce5e0dc2b3905b0b0..ad3de9b975cb87f4a5327fc345de3956cf90b863 100644 (file)
@@ -8,7 +8,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IComponent;
 import com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout;
 import com.itmill.toolkit.terminal.gwt.client.ui.IDateFieldCalendar;
 import com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded;
-import com.itmill.toolkit.terminal.gwt.client.ui.IEntryCalendar;
+import com.itmill.toolkit.terminal.gwt.client.ui.ICalendar;
 import com.itmill.toolkit.terminal.gwt.client.ui.IForm;
 import com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout;
 import com.itmill.toolkit.terminal.gwt.client.ui.ILabel;
@@ -113,9 +113,9 @@ public class DefaultWidgetFactory implements WidgetFactory {
        } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IDateFieldCalendar"
                .equals(className)) {
            return new IDateFieldCalendar();
-       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IEntryCalendar"
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICalendar"
                .equals(className)) {
-           return new IEntryCalendar();
+           return new ICalendar();
        } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate"
                .equals(className)) {
            return new ITextualDate();
@@ -210,7 +210,7 @@ public class DefaultWidgetFactory implements WidgetFactory {
                return "com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar";
            }
        } else if ("calendarfield".equals(tag)) {
-           return "com.itmill.toolkit.terminal.gwt.client.ui.IEntryCalendar";
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ICalendar";
        } else if ("slider".equals(tag)) {
            return "com.itmill.toolkit.terminal.gwt.client.ui.ISlider";
        } else if ("form".equals(tag)) {
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java
new file mode 100644 (file)
index 0000000..23a5e7c
--- /dev/null
@@ -0,0 +1,164 @@
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.SourcesTableEvents;\r
+import com.google.gwt.user.client.ui.TableListener;\r
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
+\r
+public class ICalendar extends IDateField {\r
+\r
+    private ICalendarPanel calPanel;\r
+\r
+    private FlexTable hourTable;\r
+\r
+    private EntrySource entrySource;\r
+\r
+    private TableListener ftListener = new HourTableListener();\r
+\r
+    private int realResolution = RESOLUTION_DAY;\r
+\r
+    public ICalendar() {\r
+       super();\r
+       setStyleName(CLASSNAME + "-entrycalendar");\r
+       calPanel = new ICalendarPanel(this);\r
+       add(calPanel);\r
+       this.entrySource = new EntrySource();\r
+       calPanel.setCalendarEntrySource(this.entrySource);\r
+       calPanel.addTableListener(new TableListener() {\r
+           public void onCellClicked(SourcesTableEvents sender, int row,\r
+                   int cell) {\r
+               buildDayView(date);\r
+           }\r
+       });\r
+    }\r
+\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+       super.updateFromUIDL(uidl, client);\r
+       // We want to draw our own hour list\r
+       this.realResolution = currentResolution;\r
+       this.currentResolution = RESOLUTION_DAY;\r
+       if (uidl.hasAttribute("min")) {\r
+           String mins = uidl.getStringAttribute("min");\r
+           long min = (mins != null ? Long.parseLong(mins) : 0);\r
+           String maxs = uidl.getStringAttribute("max");\r
+           long max = (maxs != null ? Long.parseLong(maxs) : 0);\r
+           Date minDate = (min > 0 ? new Date(min) : null);\r
+           Date maxDate = (max > 0 ? new Date(max) : null);\r
+           calPanel.setLimits(minDate, maxDate);\r
+       }\r
+       for (Iterator cit = uidl.getChildIterator(); cit.hasNext();) {\r
+           UIDL child = (UIDL) cit.next();\r
+           if (child.getTag().equals("items")) {\r
+               for (Iterator iit = child.getChildIterator(); iit.hasNext();) {\r
+                   UIDL item = (UIDL) iit.next();\r
+                   this.entrySource.addItem(item);\r
+               }\r
+               break;\r
+           }\r
+       }\r
+       calPanel.updateCalendar();\r
+       buildDayView(this.date);\r
+    }\r
+\r
+    protected void buildDayView(Date date) {\r
+       boolean firstRender = false;\r
+       if (this.hourTable == null) {\r
+           hourTable = new FlexTable();\r
+           firstRender = true;\r
+           hourTable.addTableListener(this.ftListener);\r
+       }\r
+       Date curr = new Date(date.getTime());\r
+       for (int i = 0; i < 24; i++) {\r
+           curr.setHours(i);\r
+           String style = (i % 2 == 0 ? "even" : "odd");\r
+           if (realResolution >= RESOLUTION_HOUR) {\r
+               if (this.date != null && this.date.getHours() == i) {\r
+                   style = "selected";\r
+               }\r
+           }\r
+           hourTable.getRowFormatter().setStyleName(i,\r
+                   getStyleName() + "-row-" + style);\r
+           if (firstRender) {\r
+               String hstr = (i < 10 ? "0" : "") + i + ":00";\r
+               if (this.dts.isTwelveHourClock()) {\r
+                   String ampm = (i < 12 ? "am" : "pm");\r
+                   hstr = (i <= 12 ? i : i - 12) + ":00 " + ampm;\r
+               }\r
+               hourTable.setHTML(i, 0, "<span class=\"" + getStyleName()\r
+                       + "-time\" >" + hstr + "</span>");\r
+           }\r
+           List entries = this.entrySource.getEntries(curr,\r
+                   DateTimeService.RESOLUTION_HOUR);\r
+           if (entries != null) {\r
+               String text = "";\r
+               for (Iterator it = entries.iterator(); it.hasNext();) {\r
+                   String title = ((ICalendarEntry) it.next()).getTitle();\r
+                   text += (text == "" ? "" : ", ")\r
+                           + (title != null ? title : "?");\r
+               }\r
+               hourTable.setHTML(i, 1, "<span class=\"" + getStyleName()\r
+                       + "-title\" >" + text + "</span>");\r
+           }\r
+       }\r
+\r
+       this.calPanel.getFlexCellFormatter().setColSpan(8, 0, 7);\r
+       this.calPanel.setWidget(8, 0, hourTable);\r
+    }\r
+\r
+    private class HourTableListener implements TableListener {\r
+\r
+       public void onCellClicked(SourcesTableEvents sender, int row, int cell) {\r
+           if (realResolution < RESOLUTION_HOUR || date == null) {\r
+               return;\r
+           }\r
+           date.setHours(row);\r
+           client.updateVariable(id, "hour", row, immediate);\r
+       }\r
+\r
+    }\r
+\r
+    private class EntrySource implements ICalendarPanel.CalendarEntrySource {\r
+\r
+       private HashMap items = new HashMap();\r
+\r
+       public void addItem(UIDL item) {\r
+           Integer id = new Integer(item.getIntAttribute("id"));\r
+           long start = Long.parseLong(item.getStringAttribute("start"));\r
+           Date startDate = new Date(start);\r
+           long end = Long.parseLong(item.getStringAttribute("end"));\r
+           Date endDate = (end > 0 && end != start ? new Date(end) : new Date(\r
+                   start));\r
+           String title = item.getStringAttribute("title");\r
+           boolean notime = item.getBooleanAttribute("notime");\r
+           if (items.containsKey(id)) {\r
+               items.remove(id);\r
+           }\r
+           items.put(id, new ICalendarEntry(startDate, endDate, title, notime));\r
+       }\r
+\r
+       public List getEntries(Date date, int resolution) {\r
+           ArrayList res = new ArrayList();\r
+           for (Iterator it = this.items.values().iterator(); it.hasNext();) {\r
+               ICalendarEntry item = (ICalendarEntry) it.next();\r
+               if (DateTimeService.isInRange(date, item.getStart(), item\r
+                       .getEnd(), resolution)) {\r
+                   res.add(item);\r
+               }\r
+           }\r
+\r
+           return res;\r
+       }\r
+\r
+    }\r
+\r
+}\r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java
deleted file mode 100644 (file)
index 8f3dc8a..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-package com.itmill.toolkit.terminal.gwt.client.ui;\r
-\r
-import java.util.Date;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.Timer;\r
-import com.google.gwt.user.client.ui.ClickListener;\r
-import com.google.gwt.user.client.ui.FlexTable;\r
-import com.google.gwt.user.client.ui.MouseListener;\r
-import com.google.gwt.user.client.ui.MouseListenerCollection;\r
-import com.google.gwt.user.client.ui.SourcesMouseEvents;\r
-import com.google.gwt.user.client.ui.SourcesTableEvents;\r
-import com.google.gwt.user.client.ui.TableListener;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
-import com.itmill.toolkit.terminal.gwt.client.LocaleService;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
-\r
-public class ICalendarPanel extends FlexTable implements MouseListener,\r
-       ClickListener {\r
-\r
-    private IDateField datefield;\r
-\r
-    private IEventButton prevYear;\r
-    private IEventButton nextYear;\r
-    private IEventButton prevMonth;\r
-    private IEventButton nextMonth;\r
-\r
-    private ITime time;\r
-\r
-    private Date minDate = null;\r
-    private Date maxDate = null;\r
-\r
-    private CalendarEntrySource entrySource;\r
-\r
-    /* Needed to identify resolution changes */\r
-    private int resolution = IDateField.RESOLUTION_YEAR;\r
-\r
-    /* Needed to identify locale changes */\r
-    private String locale = LocaleService.getDefaultLocale();\r
-\r
-    public ICalendarPanel(IDateField parent) {\r
-       datefield = parent;\r
-       setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
-       // buildCalendar(true);\r
-       addTableListener(new DateClickListener(this));\r
-    }\r
-\r
-    public ICalendarPanel(IDateField parent, Date min, Date max) {\r
-       datefield = parent;\r
-       setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
-       // buildCalendar(true);\r
-       addTableListener(new DateClickListener(this));\r
-    }\r
-\r
-    private void buildCalendar(boolean forceRedraw) {\r
-       boolean needsMonth = datefield.currentResolution > IDateField.RESOLUTION_YEAR;\r
-       boolean needsBody = datefield.currentResolution >= IDateField.RESOLUTION_DAY;\r
-       boolean needsTime = datefield.currentResolution >= IDateField.RESOLUTION_HOUR;\r
-       buildCalendarHeader(forceRedraw, needsMonth);\r
-       clearCalendarBody(!needsBody);\r
-       if (needsBody)\r
-           buildCalendarBody();\r
-       if (needsTime)\r
-           buildTime(forceRedraw);\r
-       else if (time != null) {\r
-           remove(time);\r
-           time = null;\r
-       }\r
-    }\r
-\r
-    private void clearCalendarBody(boolean remove) {\r
-       if (!remove) {\r
-           for (int row = 2; row < 8; row++) {\r
-               for (int col = 0; col < 7; col++) {\r
-                   setHTML(row, col, "&nbsp;");\r
-               }\r
-           }\r
-       } else if (getRowCount() > 2) {\r
-           while (getRowCount() > 2)\r
-               removeRow(2);\r
-       }\r
-    }\r
-\r
-    private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {\r
-       // Can't draw a calendar without a date :)\r
-       if (datefield.date == null)\r
-           datefield.date = new Date();\r
-\r
-       if (forceRedraw) {\r
-           if (prevMonth == null) { // Only do once\r
-               prevYear = new IEventButton();\r
-               prevYear.setHTML("&laquo;");\r
-               nextYear = new IEventButton();\r
-               nextYear.setHTML("&raquo;");\r
-               prevYear.addMouseListener(this);\r
-               nextYear.addMouseListener(this);\r
-               prevYear.addClickListener(this);\r
-               nextYear.addClickListener(this);\r
-               setWidget(0, 0, prevYear);\r
-               setWidget(0, 4, nextYear);\r
-\r
-               if (needsMonth) {\r
-                   prevMonth = new IEventButton();\r
-                   prevMonth.setHTML("&lsaquo;");\r
-                   nextMonth = new IEventButton();\r
-                   nextMonth.setHTML("&rsaquo;");\r
-                   prevMonth.addMouseListener(this);\r
-                   nextMonth.addMouseListener(this);\r
-                   prevMonth.addClickListener(this);\r
-                   nextMonth.addClickListener(this);\r
-                   setWidget(0, 3, nextMonth);\r
-                   setWidget(0, 1, prevMonth);\r
-               }\r
-\r
-               getFlexCellFormatter().setColSpan(0, 2, 3);\r
-           } else if (!needsMonth) {\r
-               // Remove month traverse buttons\r
-               prevMonth.removeClickListener(this);\r
-               prevMonth.removeMouseListener(this);\r
-               nextMonth.removeClickListener(this);\r
-               nextMonth.removeMouseListener(this);\r
-               remove(prevMonth);\r
-               remove(nextMonth);\r
-               prevMonth = null;\r
-               nextMonth = null;\r
-           }\r
-\r
-           // Print weekday names\r
-           int firstDay = datefield.dts.getFirstDayOfWeek();\r
-           for (int i = 0; i < 7; i++) {\r
-               int day = i + firstDay;\r
-               if (day > 6)\r
-                   day = 0;\r
-               if (datefield.currentResolution > IDateField.RESOLUTION_MONTH)\r
-                   setHTML(1, i, "<strong>" + datefield.dts.getShortDay(day)\r
-                           + "</strong>");\r
-               else\r
-                   setHTML(1, i, "");\r
-           }\r
-       }\r
-\r
-       String monthName = needsMonth ? datefield.dts.getMonth(datefield.date\r
-               .getMonth()) : "";\r
-       int year = datefield.date.getYear() + 1900;\r
-       setHTML(0, 2, "<span class=\"" + datefield.CLASSNAME\r
-               + "-calendarpanel-month\">" + monthName + " " + year\r
-               + "</span>");\r
-    }\r
-\r
-    private void buildCalendarBody() {\r
-       Date date = datefield.date;\r
-       if (date == null)\r
-           date = new Date();\r
-       int startWeekDay = datefield.dts.getStartWeekDay(date);\r
-       int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
-       int dayCount = 0;\r
-       Date today = new Date();\r
-       Date curr = new Date(date.getTime());\r
-       for (int row = 2; row < 8; row++) {\r
-           for (int col = 0; col < 7; col++) {\r
-               if (!(row == 2 && col < startWeekDay)) {\r
-                   if (dayCount < numDays) {\r
-                       int selectedDate = ++dayCount;\r
-                       String title = "";\r
-                       if (this.entrySource != null) {\r
-                           curr.setDate(dayCount);\r
-                           List entries = this.entrySource\r
-                                   .getEntries(curr,IDateField.RESOLUTION_DAY);\r
-                           if (entries != null) {\r
-                               for (Iterator it = entries.iterator(); it.hasNext();) {\r
-                                   ICalendarEntry entry = (ICalendarEntry)it.next();\r
-                                   title += (title.length() > 0 ? "\n" : "") + entry.getStringForDate(curr);\r
-                               }\r
-                           }\r
-                       }\r
-                       String baseclass = datefield.CLASSNAME\r
-                               + "-calendarpanel-day";\r
-                       String cssClass = baseclass;\r
-                       if (!isEnabledDate(curr)) {\r
-                           cssClass += " " + baseclass + "-disabled";\r
-                       }\r
-                       if (date.getDate() == dayCount) {\r
-                           cssClass += " " + baseclass + "-selected";\r
-                       }\r
-                       if (today.getDate() == dayCount\r
-                               && today.getMonth() == date.getMonth()\r
-                               && today.getYear() == date.getYear()) {\r
-                           cssClass += " " + baseclass + "-today";\r
-                       }\r
-                       if (title.length() > 0)\r
-                           cssClass += " " + baseclass + "-entry";\r
-                       setHTML(row, col, "<span title=\"" + title\r
-                               + "\" class=\"" + cssClass + "\">"\r
-                               + selectedDate + "</span>");\r
-                   } else {\r
-                       break;\r
-                   }\r
-                   \r
-               }\r
-           }\r
-       }\r
-    }\r
-\r
-    private void buildTime(boolean forceRedraw) {\r
-       if (time == null) {\r
-           time = new ITime(datefield);\r
-           setText(8, 0, ""); // Add new row\r
-           getFlexCellFormatter().setColSpan(8, 0, 7);\r
-           setWidget(8, 0, time);\r
-       }\r
-       time.updateTime(forceRedraw);\r
-    }\r
-\r
-    /**\r
-     * \r
-     * @param forceRedraw\r
-     *                Build all from scratch, in case of e.g. locale changes\r
-     */\r
-    public void updateCalendar() {\r
-       // Locale and resolution changes force a complete redraw\r
-       buildCalendar(locale != datefield.currentLocale\r
-               || resolution != datefield.currentResolution);\r
-       if (datefield instanceof ITextualDate)\r
-           ((ITextualDate) datefield).buildDate();\r
-       locale = datefield.currentLocale;\r
-       resolution = datefield.currentResolution;\r
-    }\r
-\r
-    public void onClick(Widget sender) {\r
-       processClickEvent(sender);\r
-    }\r
-    \r
-    private boolean isEnabledDate(Date date) {\r
-       if ((this.minDate != null && date.before(this.minDate))\r
-               || (this.maxDate != null && date.after(this.maxDate))) {\r
-          return false;\r
-       }\r
-       return true;\r
-    }\r
-\r
-    private void processClickEvent(Widget sender) {\r
-       if (!datefield.enabled || datefield.readonly)\r
-           return;\r
-       \r
-       if (sender == prevYear) {\r
-           datefield.date.setYear(datefield.date.getYear() - 1);\r
-           datefield.client.updateVariable(datefield.id, "year",\r
-                   datefield.date.getYear() + 1900, datefield.immediate);\r
-           updateCalendar();\r
-       } else if (sender == nextYear) {\r
-           datefield.date.setYear(datefield.date.getYear() + 1);\r
-           datefield.client.updateVariable(datefield.id, "year",\r
-                   datefield.date.getYear() + 1900, datefield.immediate);\r
-           updateCalendar();\r
-       } else if (sender == prevMonth) {\r
-           datefield.date.setMonth(datefield.date.getMonth() - 1);\r
-           datefield.client.updateVariable(datefield.id, "month",\r
-                   datefield.date.getMonth() + 1, datefield.immediate);\r
-           updateCalendar();\r
-       } else if (sender == nextMonth) {\r
-           datefield.date.setMonth(datefield.date.getMonth() + 1);\r
-           datefield.client.updateVariable(datefield.id, "month",\r
-                   datefield.date.getMonth() + 1, datefield.immediate);\r
-           updateCalendar();\r
-       }\r
-    }\r
-\r
-    private Timer timer;\r
-\r
-    public void onMouseDown(final Widget sender, int x, int y) {\r
-       if (sender instanceof IEventButton) {\r
-           timer = new Timer() {\r
-               public void run() {\r
-                   processClickEvent(sender);\r
-               }\r
-           };\r
-           timer.scheduleRepeating(100);\r
-       }\r
-    }\r
-\r
-    public void onMouseEnter(Widget sender) {\r
-    }\r
-\r
-    public void onMouseLeave(Widget sender) {\r
-       if (timer != null)\r
-           timer.cancel();\r
-    }\r
-\r
-    public void onMouseMove(Widget sender, int x, int y) {\r
-    }\r
-\r
-    public void onMouseUp(Widget sender, int x, int y) {\r
-       if (timer != null)\r
-           timer.cancel();\r
-    }\r
-\r
-    private class IEventButton extends IButton implements SourcesMouseEvents {\r
-\r
-       private MouseListenerCollection mouseListeners;\r
-\r
-       public IEventButton() {\r
-           super();\r
-           sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK\r
-                   | Event.MOUSEEVENTS);\r
-       }\r
-\r
-       public void addMouseListener(MouseListener listener) {\r
-           if (mouseListeners == null) {\r
-               mouseListeners = new MouseListenerCollection();\r
-           }\r
-           mouseListeners.add(listener);\r
-       }\r
-\r
-       public void removeMouseListener(MouseListener listener) {\r
-           if (mouseListeners != null)\r
-               mouseListeners.remove(listener);\r
-       }\r
-\r
-       public void onBrowserEvent(Event event) {\r
-           super.onBrowserEvent(event);\r
-           switch (DOM.eventGetType(event)) {\r
-           case Event.ONMOUSEDOWN:\r
-           case Event.ONMOUSEUP:\r
-           case Event.ONMOUSEMOVE:\r
-           case Event.ONMOUSEOVER:\r
-           case Event.ONMOUSEOUT:\r
-               if (mouseListeners != null) {\r
-                   mouseListeners.fireMouseEvent(this, event);\r
-               }\r
-               break;\r
-           }\r
-       }\r
-    }\r
-\r
-    private class DateClickListener implements TableListener {\r
-\r
-       private ICalendarPanel cal;\r
-\r
-       public DateClickListener(ICalendarPanel panel) {\r
-           cal = panel;\r
-       }\r
-\r
-       public void onCellClicked(SourcesTableEvents sender, int row, int col) {\r
-           if (sender != cal || row < 2 || row > 7 || !cal.datefield.enabled\r
-                   || cal.datefield.readonly)\r
-               return;\r
-\r
-           String text = cal.getText(row, col);\r
-           if (text.equals(" "))\r
-               return;\r
-\r
-           Integer day = new Integer(text);\r
-           \r
-           Date newDate = new Date(cal.datefield.date.getTime());\r
-           newDate.setDate(day.intValue());\r
-           if (!isEnabledDate(newDate)) {\r
-               return;\r
-           }\r
-           cal.datefield.date.setTime(newDate.getTime());\r
-           cal.datefield.client.updateVariable(cal.datefield.id, "day",\r
-                   cal.datefield.date.getDate(), cal.datefield.immediate);\r
-\r
-           updateCalendar();\r
-       }\r
-\r
-    }\r
-\r
-    public void setLimits(Date min, Date max) {\r
-       if (min != null ) {\r
-               Date d = new Date(min.getTime());\r
-               d.setHours(0);\r
-               d.setMinutes(0);\r
-               d.setSeconds(1);\r
-               this.minDate = d;\r
-       } else {\r
-           this.minDate = null;\r
-       }\r
-       if (max != null) {\r
-               Date d = new Date(max.getTime());\r
-               d.setHours(24);\r
-               d.setMinutes(59);\r
-               d.setSeconds(59);\r
-               this.maxDate = d;\r
-       }else {\r
-           this.maxDate = null;\r
-       }\r
-    }\r
-\r
-    public void setCalendarEntrySource(CalendarEntrySource entrySource) {\r
-       this.entrySource = entrySource;\r
-    }\r
-\r
-    public CalendarEntrySource getCalendarEntrySource() {\r
-       return this.entrySource;\r
-    }\r
-\r
-    public interface CalendarEntrySource {\r
-       public List getEntries(Date date, int resolution);\r
-    }\r
-\r
-}\r
index fbed7063b15088577f73b807ca09780a3a20ae3d..43c17e0a5453df21eca5b91cb0c9cb304bb03469 100644 (file)
@@ -19,13 +19,14 @@ public class IDateField extends FlowPanel implements Paintable {
        \r
        protected boolean immediate;\r
        \r
-       static int RESOLUTION_YEAR = 0;\r
-       static int RESOLUTION_MONTH = 1;\r
-       static int RESOLUTION_DAY = 2;\r
-       static int RESOLUTION_HOUR = 3;\r
-       static int RESOLUTION_MIN = 4;\r
-       static int RESOLUTION_SEC = 5;\r
-       static int RESOLUTION_MSEC = 6;\r
+       public static int RESOLUTION_YEAR = 0;\r
+       public static int RESOLUTION_MONTH = 1;\r
+       public static int RESOLUTION_DAY = 2;\r
+       public static int RESOLUTION_HOUR = 3;\r
+       public static int RESOLUTION_MIN = 4;\r
+       public static int RESOLUTION_SEC = 5;\r
+       public static int RESOLUTION_MSEC = 6;\r
+       \r
        protected int currentResolution = RESOLUTION_YEAR;\r
        \r
        protected String currentLocale;\r
@@ -130,4 +131,51 @@ public class IDateField extends FlowPanel implements Paintable {
                date.setTime(date.getTime() / 1000 * 1000 + ms);\r
        }\r
 \r
+       public int getCurrentResolution() {\r
+           return currentResolution;\r
+       }\r
+\r
+       public void setCurrentResolution(int currentResolution) {\r
+           this.currentResolution = currentResolution;\r
+       }\r
+\r
+       public String getCurrentLocale() {\r
+           return currentLocale;\r
+       }\r
+\r
+       public void setCurrentLocale(String currentLocale) {\r
+           this.currentLocale = currentLocale;\r
+       }\r
+\r
+       public Date getCurrentDate() {\r
+           return date;\r
+       }\r
+\r
+       public void setCurrentDate(Date date) {\r
+           this.date = date;\r
+       }\r
+\r
+       public boolean isImmediate() {\r
+           return immediate;\r
+       }\r
+\r
+       public boolean isReadonly() {\r
+           return readonly;\r
+       }\r
+\r
+       public boolean isEnabled() {\r
+           return enabled;\r
+       }\r
+\r
+       public DateTimeService getDateTimeService() {\r
+           return dts;\r
+       }\r
+\r
+       public String getId() {\r
+           return id;\r
+       }\r
+\r
+       public ApplicationConnection getClient() {\r
+           return client;\r
+       }\r
 }\r
index 150f96c504f593f17da3db8847d937e0a7167a4e..949ab1d9672dfc7c188b54901bd190364c2b92ba 100644 (file)
@@ -2,6 +2,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 \r
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
 import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
 \r
 public class IDateFieldCalendar extends IDateField {\r
        \r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IEntryCalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IEntryCalendar.java
deleted file mode 100644 (file)
index 6119e8f..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-package com.itmill.toolkit.terminal.gwt.client.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import com.google.gwt.user.client.ui.FlexTable;\r
-import com.google.gwt.user.client.ui.SourcesTableEvents;\r
-import com.google.gwt.user.client.ui.TableListener;\r
-import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
-import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
-import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
-\r
-public class IEntryCalendar extends IDateField {\r
-\r
-    private ICalendarPanel calPanel;\r
-\r
-    private FlexTable hourTable;\r
-\r
-    private EntrySource entrySource;\r
-\r
-    private TableListener ftListener = new HourTableListener();\r
-\r
-    private int realResolution = RESOLUTION_DAY;\r
-\r
-    public IEntryCalendar() {\r
-       super();\r
-       setStyleName(CLASSNAME + "-entrycalendar");\r
-       calPanel = new ICalendarPanel(this);\r
-       add(calPanel);\r
-       this.entrySource = new EntrySource();\r
-       calPanel.setCalendarEntrySource(this.entrySource);\r
-       calPanel.addTableListener(new TableListener() {\r
-           public void onCellClicked(SourcesTableEvents sender, int row,\r
-                   int cell) {\r
-               buildDayView(date);\r
-           }\r
-       });\r
-    }\r
-\r
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-       super.updateFromUIDL(uidl, client);\r
-       // We want to draw our own hour list\r
-       this.realResolution = currentResolution;\r
-       this.currentResolution = RESOLUTION_DAY;\r
-       if (uidl.hasAttribute("min")) {\r
-           String mins = uidl.getStringAttribute("min");\r
-           long min = (mins != null ? Long.parseLong(mins) : 0);\r
-           String maxs = uidl.getStringAttribute("max");\r
-           long max = (maxs != null ? Long.parseLong(maxs) : 0);\r
-           Date minDate = (min > 0 ? new Date(min) : null);\r
-           Date maxDate = (max > 0 ? new Date(max) : null);\r
-           calPanel.setLimits(minDate, maxDate);\r
-       }\r
-       for (Iterator cit = uidl.getChildIterator(); cit.hasNext();) {\r
-           UIDL child = (UIDL) cit.next();\r
-           if (child.getTag().equals("items")) {\r
-               for (Iterator iit = child.getChildIterator(); iit.hasNext();) {\r
-                   UIDL item = (UIDL) iit.next();\r
-                   this.entrySource.addItem(item);\r
-               }\r
-               break;\r
-           }\r
-       }\r
-       calPanel.updateCalendar();\r
-       buildDayView(this.date);\r
-    }\r
-\r
-    protected void buildDayView(Date date) {\r
-       boolean firstRender = false;\r
-       if (this.hourTable == null) {\r
-           hourTable = new FlexTable();\r
-           firstRender = true;\r
-           hourTable.addTableListener(this.ftListener);\r
-       }\r
-       Date curr = new Date(date.getTime());\r
-       for (int i = 0; i < 24; i++) {\r
-           curr.setHours(i);\r
-           String style = (i % 2 == 0 ? "even" : "odd");\r
-           if (realResolution >= RESOLUTION_HOUR) {\r
-               if (this.date != null && this.date.getHours() == i) {\r
-                   style = "selected";\r
-               }\r
-           }\r
-           hourTable.getRowFormatter().setStyleName(i,\r
-                   getStyleName() + "-row-" + style);\r
-           if (firstRender) {\r
-               String hstr = (i < 10 ? "0" : "") + i + ":00";\r
-               if (this.dts.isTwelveHourClock()) {\r
-                   String ampm = (i < 12 ? "am" : "pm");\r
-                   hstr = (i <= 12 ? i : i - 12) + ":00 " + ampm;\r
-               }\r
-               hourTable.setHTML(i, 0, "<span class=\"" + getStyleName()\r
-                       + "-time\" >" + hstr + "</span>");\r
-           }\r
-           List entries = this.entrySource.getEntries(curr,\r
-                   DateTimeService.RESOLUTION_HOUR);\r
-           if (entries != null) {\r
-               String text = "";\r
-               for (Iterator it = entries.iterator(); it.hasNext();) {\r
-                   String title = ((ICalendarEntry) it.next()).getTitle();\r
-                   text += (text == "" ? "" : ", ")\r
-                           + (title != null ? title : "?");\r
-               }\r
-               hourTable.setHTML(i, 1, "<span class=\"" + getStyleName()\r
-                       + "-title\" >" + text + "</span>");\r
-           }\r
-       }\r
-\r
-       this.calPanel.getFlexCellFormatter().setColSpan(8, 0, 7);\r
-       this.calPanel.setWidget(8, 0, hourTable);\r
-    }\r
-\r
-    private class HourTableListener implements TableListener {\r
-\r
-       public void onCellClicked(SourcesTableEvents sender, int row, int cell) {\r
-           if (realResolution < RESOLUTION_HOUR || date == null) {\r
-               return;\r
-           }\r
-           date.setHours(row);\r
-           client.updateVariable(id, "hour", row, immediate);\r
-       }\r
-\r
-    }\r
-\r
-    private class EntrySource implements ICalendarPanel.CalendarEntrySource {\r
-\r
-       private HashMap items = new HashMap();\r
-\r
-       public void addItem(UIDL item) {\r
-           Integer id = new Integer(item.getIntAttribute("id"));\r
-           long start = Long.parseLong(item.getStringAttribute("start"));\r
-           Date startDate = new Date(start);\r
-           long end = Long.parseLong(item.getStringAttribute("end"));\r
-           Date endDate = (end > 0 && end != start ? new Date(end) : new Date(\r
-                   start));\r
-           String title = item.getStringAttribute("title");\r
-           boolean notime = item.getBooleanAttribute("notime");\r
-           if (items.containsKey(id)) {\r
-               items.remove(id);\r
-           }\r
-           items.put(id, new ICalendarEntry(startDate, endDate, title, notime));\r
-       }\r
-\r
-       public List getEntries(Date date, int resolution) {\r
-           ArrayList res = new ArrayList();\r
-           for (Iterator it = this.items.values().iterator(); it.hasNext();) {\r
-               ICalendarEntry item = (ICalendarEntry) it.next();\r
-               if (DateTimeService.isInRange(date, item.getStart(), item\r
-                       .getEnd(), resolution)) {\r
-                   res.add(item);\r
-               }\r
-           }\r
-\r
-           return res;\r
-       }\r
-\r
-    }\r
-\r
-}\r
index b4343225e3650a2d0f989107de1d6e17467bfb06..acf4ea0827b26f3bca9a5295a989dbdc9ed3bbba 100644 (file)
@@ -7,6 +7,7 @@ import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
 import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
 import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
 \r
 public class IPopupCalendar extends ITextualDate implements Paintable, ClickListener, PopupListener {\r
        \r
index e929a86ff13ca5f315a4db40835de8f932256ba6..09b6dd5351a27fc56930822b60a2a929a06bcfda 100644 (file)
@@ -30,7 +30,7 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene
                buildDate();\r
        }\r
 \r
-       protected void buildDate() {\r
+       public void buildDate() {\r
                dl = new DateLocale();\r
                DateLocale.setLocale(currentLocale);\r
                \r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITime.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITime.java
deleted file mode 100644 (file)
index 09ea351..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-package com.itmill.toolkit.terminal.gwt.client.ui;\r
-\r
-import com.google.gwt.user.client.ui.ChangeListener;\r
-import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.google.gwt.user.client.ui.ListBox;\r
-import com.google.gwt.user.client.ui.Widget;\r
-\r
-public class ITime extends FlowPanel implements ChangeListener {\r
-       \r
-       private IDateField datefield;\r
-       \r
-       private ListBox hours;\r
-       \r
-       private ListBox mins;\r
-       \r
-       private ListBox sec;\r
-       \r
-       private ListBox msec;\r
-       \r
-       private ListBox ampm;\r
-       \r
-       private int resolution = IDateField.RESOLUTION_HOUR;\r
-       \r
-       private boolean readonly;\r
-       \r
-       public ITime(IDateField parent) {\r
-               super();\r
-               datefield = parent;\r
-               setStyleName(IDateField.CLASSNAME+"-time");\r
-       }\r
-       \r
-       private void buildTime(boolean redraw) {\r
-               boolean thc = datefield.dts.isTwelveHourClock();\r
-               if(redraw) {\r
-                       clear();\r
-                       int numHours = thc?12:24;\r
-                       hours = new ListBox();\r
-                       hours.setStyleName(ISelect.CLASSNAME);\r
-                       for(int i=0; i<numHours; i++)\r
-                               hours.addItem((i<10)?"0"+i:""+i);\r
-                       hours.addChangeListener(this);\r
-                       if(thc) {\r
-                               ampm = new ListBox();\r
-                               ampm.setStyleName(ISelect.CLASSNAME);\r
-                               String[] ampmText = datefield.dts.getAmPmStrings();\r
-                               ampm.addItem(ampmText[0]);\r
-                               ampm.addItem(ampmText[1]);\r
-                               ampm.addChangeListener(this);\r
-                       }\r
-                       \r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) {\r
-                               mins = new ListBox();\r
-                               mins.setStyleName(ISelect.CLASSNAME);\r
-                               for(int i=0; i<60; i++)\r
-                                       mins.addItem((i<10)?"0"+i:""+i);\r
-                               mins.addChangeListener(this);\r
-                       }\r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) {\r
-                               sec = new ListBox();\r
-                               sec.setStyleName(ISelect.CLASSNAME);\r
-                               for(int i=0; i<60; i++)\r
-                                       sec.addItem((i<10)?"0"+i:""+i);\r
-                               sec.addChangeListener(this);\r
-                       }\r
-                       if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) {\r
-                               msec = new ListBox();\r
-                               msec.setStyleName(ISelect.CLASSNAME);\r
-                               for(int i=0; i<1000; i++) {\r
-                                       if(i<10)\r
-                                               msec.addItem("00"+i);\r
-                                       else if(i<100)\r
-                                               msec.addItem("0"+i);\r
-                                       else msec.addItem(""+i);\r
-                               }\r
-                               msec.addChangeListener(this);\r
-                       }\r
-                       \r
-                       String delimiter = datefield.dts.getClockDelimeter();\r
-                       boolean ro = datefield.readonly;\r
-                       \r
-                       if(ro) {\r
-                               int h = 0;\r
-                               if(datefield.date != null)\r
-                                       h = datefield.date.getHours();\r
-                               if(thc) h -= h<12? 0 : 12;\r
-                               add(new ILabel(h<10? "0"+h : ""+h));\r
-                       } else add(hours);\r
-                       \r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) {\r
-                               add(new ILabel(delimiter));\r
-                               if(ro) {\r
-                                       int m = mins.getSelectedIndex();\r
-                                       add(new ILabel(m<10? "0"+m : ""+m));\r
-                               }\r
-                               else add(mins);\r
-                       }\r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) {\r
-                               add(new ILabel(delimiter));\r
-                               if(ro) {\r
-                                       int s = sec.getSelectedIndex();\r
-                                       add(new ILabel(s<10? "0"+s : ""+s));\r
-                               }\r
-                               else add(sec);\r
-                       }\r
-                       if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) {\r
-                               add(new ILabel("."));\r
-                               if(ro) {\r
-                                       int m = datefield.getMilliseconds();\r
-                                       String ms = m<100? "0"+m : ""+m;\r
-                                       add(new ILabel(m<10? "0"+ms : ms));\r
-                               }\r
-                               else add(msec);\r
-                       }\r
-                       if(datefield.currentResolution == IDateField.RESOLUTION_HOUR) {\r
-                               add(new ILabel(delimiter+"00")); // o'clock\r
-                       }\r
-                       if(thc) {\r
-                               add(new ILabel("&nbsp;"));\r
-                               if(ro) add(new ILabel(ampm.getItemText(datefield.date.getHours()<12? 0 : 1)));\r
-                               else add(ampm);\r
-                       }\r
-                       \r
-                       if(ro) return;\r
-               }\r
-               \r
-               // Update times\r
-               if(thc) {\r
-                       int h = datefield.date.getHours();\r
-                       ampm.setSelectedIndex(h<12? 0 : 1);\r
-                       h -= ampm.getSelectedIndex()*12;\r
-                       hours.setSelectedIndex(h);\r
-               } else\r
-                       hours.setSelectedIndex(datefield.date.getHours());\r
-               if(datefield.currentResolution >= IDateField.RESOLUTION_MIN)\r
-                       mins.setSelectedIndex(datefield.date.getMinutes());\r
-               if(datefield.currentResolution >= IDateField.RESOLUTION_SEC)\r
-                       sec.setSelectedIndex(datefield.date.getSeconds());\r
-               if(datefield.currentResolution == IDateField.RESOLUTION_MSEC)\r
-                       msec.setSelectedIndex(datefield.getMilliseconds());\r
-               if(thc)\r
-                       ampm.setSelectedIndex(datefield.date.getHours()<12?0:1);\r
-               \r
-               if(datefield.readonly && !redraw) {\r
-                       // Do complete redraw when in read-only status\r
-                       clear();\r
-                       String delimiter = datefield.dts.getClockDelimeter();\r
-                       \r
-                       int h = datefield.date.getHours();\r
-                       if(thc) h -= h<12? 0 : 12;\r
-                       add(new ILabel(h<10? "0"+h : ""+h));\r
-                       \r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) {\r
-                               add(new ILabel(delimiter));\r
-                               int m = mins.getSelectedIndex();\r
-                               add(new ILabel(m<10? "0"+m : ""+m));\r
-                       }\r
-                       if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) {\r
-                               add(new ILabel(delimiter));\r
-                               int s = sec.getSelectedIndex();\r
-                               add(new ILabel(s<10? "0"+s : ""+s));\r
-                       }\r
-                       if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) {\r
-                               add(new ILabel("."));\r
-                               int m = datefield.getMilliseconds();\r
-                               String ms = m<100? "0"+m : ""+m;\r
-                               add(new ILabel(m<10? "0"+ms : ms));\r
-                       }\r
-                       if(datefield.currentResolution == IDateField.RESOLUTION_HOUR) {\r
-                               add(new ILabel(delimiter+"00")); // o'clock\r
-                       }\r
-                       if(thc) {\r
-                               add(new ILabel("&nbsp;"));\r
-                               add(new ILabel(ampm.getItemText(datefield.date.getHours()<12? 0 : 1)));\r
-                       }\r
-               }\r
-               \r
-               boolean enabled = datefield.enabled;\r
-               hours.setEnabled(enabled);\r
-               if(mins != null) mins.setEnabled(enabled);\r
-               if(sec != null) sec.setEnabled(enabled);\r
-               if(msec != null) msec.setEnabled(enabled);\r
-               if(ampm != null) ampm.setEnabled(enabled);\r
-               \r
-       }\r
-\r
-       public void updateTime(boolean redraw) {\r
-               buildTime(redraw || resolution != datefield.currentResolution \r
-                                               || readonly != datefield.readonly);\r
-               if(datefield instanceof ITextualDate)\r
-                       ((ITextualDate) datefield).buildDate();\r
-               resolution = datefield.currentResolution;\r
-               readonly = datefield.readonly;\r
-       }\r
-\r
-       public void onChange(Widget sender) {\r
-               if(sender == hours) {\r
-                       int h = hours.getSelectedIndex();\r
-                       if(datefield.dts.isTwelveHourClock())\r
-                               h = h + ampm.getSelectedIndex()*12;\r
-                       datefield.date.setHours(h);\r
-                       datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate);\r
-                       updateTime(false);\r
-               }\r
-               else if(sender == mins) {\r
-                       int m = mins.getSelectedIndex();\r
-                       datefield.date.setMinutes(m);\r
-                       datefield.client.updateVariable(datefield.id, "min", m, datefield.immediate);\r
-                       updateTime(false);\r
-               }\r
-               else if(sender == sec) {\r
-                       int s = sec.getSelectedIndex();\r
-                       datefield.date.setSeconds(s);\r
-                       datefield.client.updateVariable(datefield.id, "sec", s, datefield.immediate);\r
-                       updateTime(false);\r
-               }\r
-               else if(sender == msec) {\r
-                       int ms = msec.getSelectedIndex();\r
-                       datefield.setMilliseconds(ms);\r
-                       datefield.client.updateVariable(datefield.id, "msec", ms, datefield.immediate);\r
-                       updateTime(false);\r
-               }\r
-               else if(sender == ampm) {\r
-                       int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12;\r
-                       datefield.date.setHours(h);\r
-                       datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate);\r
-                       updateTime(false);\r
-               }\r
-       }\r
-\r
-}\r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java
new file mode 100644 (file)
index 0000000..df4c32b
--- /dev/null
@@ -0,0 +1,412 @@
+package com.itmill.toolkit.terminal.gwt.client.ui.datefield;\r
+\r
+import java.util.Date;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Timer;\r
+import com.google.gwt.user.client.ui.ClickListener;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.MouseListener;\r
+import com.google.gwt.user.client.ui.MouseListenerCollection;\r
+import com.google.gwt.user.client.ui.SourcesMouseEvents;\r
+import com.google.gwt.user.client.ui.SourcesTableEvents;\r
+import com.google.gwt.user.client.ui.TableListener;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+import com.itmill.toolkit.terminal.gwt.client.LocaleService;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.IButton;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
+\r
+public class ICalendarPanel extends FlexTable implements MouseListener,\r
+       ClickListener {\r
+\r
+    private IDateField datefield;\r
+\r
+    private IEventButton prevYear;\r
+    private IEventButton nextYear;\r
+    private IEventButton prevMonth;\r
+    private IEventButton nextMonth;\r
+\r
+    private ITime time;\r
+\r
+    private Date minDate = null;\r
+    private Date maxDate = null;\r
+\r
+    private CalendarEntrySource entrySource;\r
+\r
+    /* Needed to identify resolution changes */\r
+    private int resolution = IDateField.RESOLUTION_YEAR;\r
+\r
+    /* Needed to identify locale changes */\r
+    private String locale = LocaleService.getDefaultLocale();\r
+\r
+    public ICalendarPanel(IDateField parent) {\r
+       datefield = parent;\r
+       setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
+       // buildCalendar(true);\r
+       addTableListener(new DateClickListener(this));\r
+    }\r
+\r
+    public ICalendarPanel(IDateField parent, Date min, Date max) {\r
+       datefield = parent;\r
+       setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
+       // buildCalendar(true);\r
+       addTableListener(new DateClickListener(this));\r
+    }\r
+\r
+    private void buildCalendar(boolean forceRedraw) {\r
+       boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR;\r
+       boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY;\r
+       boolean needsTime = datefield.getCurrentResolution() >= IDateField.RESOLUTION_HOUR;\r
+       buildCalendarHeader(forceRedraw, needsMonth);\r
+       clearCalendarBody(!needsBody);\r
+       if (needsBody)\r
+           buildCalendarBody();\r
+       if (needsTime)\r
+           buildTime(forceRedraw);\r
+       else if (time != null) {\r
+           remove(time);\r
+           time = null;\r
+       }\r
+    }\r
+\r
+    private void clearCalendarBody(boolean remove) {\r
+       if (!remove) {\r
+           for (int row = 2; row < 8; row++) {\r
+               for (int col = 0; col < 7; col++) {\r
+                   setHTML(row, col, "&nbsp;");\r
+               }\r
+           }\r
+       } else if (getRowCount() > 2) {\r
+           while (getRowCount() > 2)\r
+               removeRow(2);\r
+       }\r
+    }\r
+\r
+    private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {\r
+       // Can't draw a calendar without a date :)\r
+       if (datefield.getCurrentDate() == null)\r
+           datefield.setCurrentDate(new Date());\r
+\r
+       if (forceRedraw) {\r
+           if (prevMonth == null) { // Only do once\r
+               prevYear = new IEventButton();\r
+               prevYear.setHTML("&laquo;");\r
+               nextYear = new IEventButton();\r
+               nextYear.setHTML("&raquo;");\r
+               prevYear.addMouseListener(this);\r
+               nextYear.addMouseListener(this);\r
+               prevYear.addClickListener(this);\r
+               nextYear.addClickListener(this);\r
+               setWidget(0, 0, prevYear);\r
+               setWidget(0, 4, nextYear);\r
+\r
+               if (needsMonth) {\r
+                   prevMonth = new IEventButton();\r
+                   prevMonth.setHTML("&lsaquo;");\r
+                   nextMonth = new IEventButton();\r
+                   nextMonth.setHTML("&rsaquo;");\r
+                   prevMonth.addMouseListener(this);\r
+                   nextMonth.addMouseListener(this);\r
+                   prevMonth.addClickListener(this);\r
+                   nextMonth.addClickListener(this);\r
+                   setWidget(0, 3, nextMonth);\r
+                   setWidget(0, 1, prevMonth);\r
+               }\r
+\r
+               getFlexCellFormatter().setColSpan(0, 2, 3);\r
+           } else if (!needsMonth) {\r
+               // Remove month traverse buttons\r
+               prevMonth.removeClickListener(this);\r
+               prevMonth.removeMouseListener(this);\r
+               nextMonth.removeClickListener(this);\r
+               nextMonth.removeMouseListener(this);\r
+               remove(prevMonth);\r
+               remove(nextMonth);\r
+               prevMonth = null;\r
+               nextMonth = null;\r
+           }\r
+\r
+           // Print weekday names\r
+           int firstDay = datefield.getDateTimeService().getFirstDayOfWeek();\r
+           for (int i = 0; i < 7; i++) {\r
+               int day = i + firstDay;\r
+               if (day > 6)\r
+                   day = 0;\r
+               if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH)\r
+                   setHTML(1, i, "<strong>"\r
+                           + datefield.getDateTimeService().getShortDay(day)\r
+                           + "</strong>");\r
+               else\r
+                   setHTML(1, i, "");\r
+           }\r
+       }\r
+\r
+       String monthName = needsMonth ? datefield.getDateTimeService()\r
+               .getMonth(datefield.getCurrentDate().getMonth()) : "";\r
+       int year = datefield.getCurrentDate().getYear() + 1900;\r
+       setHTML(0, 2, "<span class=\"" + datefield.CLASSNAME\r
+               + "-calendarpanel-month\">" + monthName + " " + year\r
+               + "</span>");\r
+    }\r
+\r
+    private void buildCalendarBody() {\r
+       Date date = datefield.getCurrentDate();\r
+       if (date == null)\r
+           date = new Date();\r
+       int startWeekDay = datefield.getDateTimeService().getStartWeekDay(date);\r
+       int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
+       int dayCount = 0;\r
+       Date today = new Date();\r
+       Date curr = new Date(date.getTime());\r
+       for (int row = 2; row < 8; row++) {\r
+           for (int col = 0; col < 7; col++) {\r
+               if (!(row == 2 && col < startWeekDay)) {\r
+                   if (dayCount < numDays) {\r
+                       int selectedDate = ++dayCount;\r
+                       String title = "";\r
+                       if (this.entrySource != null) {\r
+                           curr.setDate(dayCount);\r
+                           List entries = this.entrySource.getEntries(curr,\r
+                                   IDateField.RESOLUTION_DAY);\r
+                           if (entries != null) {\r
+                               for (Iterator it = entries.iterator(); it\r
+                                       .hasNext();) {\r
+                                   ICalendarEntry entry = (ICalendarEntry) it\r
+                                           .next();\r
+                                   title += (title.length() > 0 ? "\n" : "")\r
+                                           + entry.getStringForDate(curr);\r
+                               }\r
+                           }\r
+                       }\r
+                       String baseclass = datefield.CLASSNAME\r
+                               + "-calendarpanel-day";\r
+                       String cssClass = baseclass;\r
+                       if (!isEnabledDate(curr)) {\r
+                           cssClass += " " + baseclass + "-disabled";\r
+                       }\r
+                       if (date.getDate() == dayCount) {\r
+                           cssClass += " " + baseclass + "-selected";\r
+                       }\r
+                       if (today.getDate() == dayCount\r
+                               && today.getMonth() == date.getMonth()\r
+                               && today.getYear() == date.getYear()) {\r
+                           cssClass += " " + baseclass + "-today";\r
+                       }\r
+                       if (title.length() > 0)\r
+                           cssClass += " " + baseclass + "-entry";\r
+                       setHTML(row, col, "<span title=\"" + title\r
+                               + "\" class=\"" + cssClass + "\">"\r
+                               + selectedDate + "</span>");\r
+                   } else {\r
+                       break;\r
+                   }\r
+\r
+               }\r
+           }\r
+       }\r
+    }\r
+\r
+    private void buildTime(boolean forceRedraw) {\r
+       if (time == null) {\r
+           time = new ITime(datefield);\r
+           setText(8, 0, ""); // Add new row\r
+           getFlexCellFormatter().setColSpan(8, 0, 7);\r
+           setWidget(8, 0, time);\r
+       }\r
+       time.updateTime(forceRedraw);\r
+    }\r
+\r
+    /**\r
+     * \r
+     * @param forceRedraw\r
+     *                Build all from scratch, in case of e.g. locale changes\r
+     */\r
+    public void updateCalendar() {\r
+       // Locale and resolution changes force a complete redraw\r
+       buildCalendar(locale != datefield.getCurrentLocale()\r
+               || resolution != datefield.getCurrentResolution());\r
+       if (datefield instanceof ITextualDate)\r
+           ((ITextualDate) datefield).buildDate();\r
+       locale = datefield.getCurrentLocale();\r
+       resolution = datefield.getCurrentResolution();\r
+    }\r
+\r
+    public void onClick(Widget sender) {\r
+       processClickEvent(sender);\r
+    }\r
+\r
+    private boolean isEnabledDate(Date date) {\r
+       if ((this.minDate != null && date.before(this.minDate))\r
+               || (this.maxDate != null && date.after(this.maxDate))) {\r
+           return false;\r
+       }\r
+       return true;\r
+    }\r
+\r
+    private void processClickEvent(Widget sender) {\r
+       if (!datefield.isEnabled() || datefield.isReadonly())\r
+           return;\r
+\r
+       if (sender == prevYear) {\r
+           datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() - 1);\r
+           datefield.getClient().updateVariable(datefield.getId(), "year",\r
+                   datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
+           updateCalendar();\r
+       } else if (sender == nextYear) {\r
+           datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() + 1);\r
+           datefield.getClient().updateVariable(datefield.getId(), "year",\r
+                   datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
+           updateCalendar();\r
+       } else if (sender == prevMonth) {\r
+           datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() - 1);\r
+           datefield.getClient().updateVariable(datefield.getId(), "month",\r
+                   datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
+           updateCalendar();\r
+       } else if (sender == nextMonth) {\r
+           datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() + 1);\r
+           datefield.getClient().updateVariable(datefield.getId(), "month",\r
+                   datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
+           updateCalendar();\r
+       }\r
+    }\r
+\r
+    private Timer timer;\r
+\r
+    public void onMouseDown(final Widget sender, int x, int y) {\r
+       if (sender instanceof IEventButton) {\r
+           timer = new Timer() {\r
+               public void run() {\r
+                   processClickEvent(sender);\r
+               }\r
+           };\r
+           timer.scheduleRepeating(100);\r
+       }\r
+    }\r
+\r
+    public void onMouseEnter(Widget sender) {\r
+    }\r
+\r
+    public void onMouseLeave(Widget sender) {\r
+       if (timer != null)\r
+           timer.cancel();\r
+    }\r
+\r
+    public void onMouseMove(Widget sender, int x, int y) {\r
+    }\r
+\r
+    public void onMouseUp(Widget sender, int x, int y) {\r
+       if (timer != null)\r
+           timer.cancel();\r
+    }\r
+\r
+    private class IEventButton extends IButton implements SourcesMouseEvents {\r
+\r
+       private MouseListenerCollection mouseListeners;\r
+\r
+       public IEventButton() {\r
+           super();\r
+           sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK\r
+                   | Event.MOUSEEVENTS);\r
+       }\r
+\r
+       public void addMouseListener(MouseListener listener) {\r
+           if (mouseListeners == null) {\r
+               mouseListeners = new MouseListenerCollection();\r
+           }\r
+           mouseListeners.add(listener);\r
+       }\r
+\r
+       public void removeMouseListener(MouseListener listener) {\r
+           if (mouseListeners != null)\r
+               mouseListeners.remove(listener);\r
+       }\r
+\r
+       public void onBrowserEvent(Event event) {\r
+           super.onBrowserEvent(event);\r
+           switch (DOM.eventGetType(event)) {\r
+           case Event.ONMOUSEDOWN:\r
+           case Event.ONMOUSEUP:\r
+           case Event.ONMOUSEMOVE:\r
+           case Event.ONMOUSEOVER:\r
+           case Event.ONMOUSEOUT:\r
+               if (mouseListeners != null) {\r
+                   mouseListeners.fireMouseEvent(this, event);\r
+               }\r
+               break;\r
+           }\r
+       }\r
+    }\r
+\r
+    private class DateClickListener implements TableListener {\r
+\r
+       private ICalendarPanel cal;\r
+\r
+       public DateClickListener(ICalendarPanel panel) {\r
+           cal = panel;\r
+       }\r
+\r
+       public void onCellClicked(SourcesTableEvents sender, int row, int col) {\r
+           if (sender != cal || row < 2 || row > 7 || !cal.datefield.isEnabled()\r
+                   || cal.datefield.isReadonly())\r
+               return;\r
+\r
+           String text = cal.getText(row, col);\r
+           if (text.equals(" "))\r
+               return;\r
+\r
+           Integer day = new Integer(text);\r
+\r
+           Date newDate = new Date(cal.datefield.getCurrentDate().getTime());\r
+           newDate.setDate(day.intValue());\r
+           if (!isEnabledDate(newDate)) {\r
+               return;\r
+           }\r
+           cal.datefield.getCurrentDate().setTime(newDate.getTime());\r
+           cal.datefield.getClient().updateVariable(cal.datefield.getId(), "day",\r
+                   cal.datefield.getCurrentDate().getDate(), cal.datefield.isImmediate());\r
+\r
+           updateCalendar();\r
+       }\r
+\r
+    }\r
+\r
+    public void setLimits(Date min, Date max) {\r
+       if (min != null) {\r
+           Date d = new Date(min.getTime());\r
+           d.setHours(0);\r
+           d.setMinutes(0);\r
+           d.setSeconds(1);\r
+           this.minDate = d;\r
+       } else {\r
+           this.minDate = null;\r
+       }\r
+       if (max != null) {\r
+           Date d = new Date(max.getTime());\r
+           d.setHours(24);\r
+           d.setMinutes(59);\r
+           d.setSeconds(59);\r
+           this.maxDate = d;\r
+       } else {\r
+           this.maxDate = null;\r
+       }\r
+    }\r
+\r
+    public void setCalendarEntrySource(CalendarEntrySource entrySource) {\r
+       this.entrySource = entrySource;\r
+    }\r
+\r
+    public CalendarEntrySource getCalendarEntrySource() {\r
+       return this.entrySource;\r
+    }\r
+\r
+    public interface CalendarEntrySource {\r
+       public List getEntries(Date date, int resolution);\r
+    }\r
+\r
+}\r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java
new file mode 100644 (file)
index 0000000..2b36966
--- /dev/null
@@ -0,0 +1,234 @@
+package com.itmill.toolkit.terminal.gwt.client.ui.datefield;\r
+\r
+import com.google.gwt.user.client.ui.ChangeListener;\r
+import com.google.gwt.user.client.ui.FlowPanel;\r
+import com.google.gwt.user.client.ui.ListBox;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.ILabel;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.ISelect;\r
+import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate;\r
+\r
+public class ITime extends FlowPanel implements ChangeListener {\r
+       \r
+       private IDateField datefield;\r
+       \r
+       private ListBox hours;\r
+       \r
+       private ListBox mins;\r
+       \r
+       private ListBox sec;\r
+       \r
+       private ListBox msec;\r
+       \r
+       private ListBox ampm;\r
+       \r
+       private int resolution = IDateField.RESOLUTION_HOUR;\r
+       \r
+       private boolean readonly;\r
+       \r
+       public ITime(IDateField parent) {\r
+               super();\r
+               datefield = parent;\r
+               setStyleName(IDateField.CLASSNAME+"-time");\r
+       }\r
+       \r
+       private void buildTime(boolean redraw) {\r
+               boolean thc = datefield.getDateTimeService().isTwelveHourClock();\r
+               if(redraw) {\r
+                       clear();\r
+                       int numHours = thc?12:24;\r
+                       hours = new ListBox();\r
+                       hours.setStyleName(ISelect.CLASSNAME);\r
+                       for(int i=0; i<numHours; i++)\r
+                               hours.addItem((i<10)?"0"+i:""+i);\r
+                       hours.addChangeListener(this);\r
+                       if(thc) {\r
+                               ampm = new ListBox();\r
+                               ampm.setStyleName(ISelect.CLASSNAME);\r
+                               String[] ampmText = datefield.getDateTimeService().getAmPmStrings();\r
+                               ampm.addItem(ampmText[0]);\r
+                               ampm.addItem(ampmText[1]);\r
+                               ampm.addChangeListener(this);\r
+                       }\r
+                       \r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+                               mins = new ListBox();\r
+                               mins.setStyleName(ISelect.CLASSNAME);\r
+                               for(int i=0; i<60; i++)\r
+                                       mins.addItem((i<10)?"0"+i:""+i);\r
+                               mins.addChangeListener(this);\r
+                       }\r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+                               sec = new ListBox();\r
+                               sec.setStyleName(ISelect.CLASSNAME);\r
+                               for(int i=0; i<60; i++)\r
+                                       sec.addItem((i<10)?"0"+i:""+i);\r
+                               sec.addChangeListener(this);\r
+                       }\r
+                       if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+                               msec = new ListBox();\r
+                               msec.setStyleName(ISelect.CLASSNAME);\r
+                               for(int i=0; i<1000; i++) {\r
+                                       if(i<10)\r
+                                               msec.addItem("00"+i);\r
+                                       else if(i<100)\r
+                                               msec.addItem("0"+i);\r
+                                       else msec.addItem(""+i);\r
+                               }\r
+                               msec.addChangeListener(this);\r
+                       }\r
+                       \r
+                       String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
+                       boolean ro = datefield.isReadonly();\r
+                       \r
+                       if(ro) {\r
+                               int h = 0;\r
+                               if(datefield.getCurrentDate() != null)\r
+                                       h = datefield.getCurrentDate().getHours();\r
+                               if(thc) h -= h<12? 0 : 12;\r
+                               add(new ILabel(h<10? "0"+h : ""+h));\r
+                       } else add(hours);\r
+                       \r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+                               add(new ILabel(delimiter));\r
+                               if(ro) {\r
+                                       int m = mins.getSelectedIndex();\r
+                                       add(new ILabel(m<10? "0"+m : ""+m));\r
+                               }\r
+                               else add(mins);\r
+                       }\r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+                               add(new ILabel(delimiter));\r
+                               if(ro) {\r
+                                       int s = sec.getSelectedIndex();\r
+                                       add(new ILabel(s<10? "0"+s : ""+s));\r
+                               }\r
+                               else add(sec);\r
+                       }\r
+                       if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+                               add(new ILabel("."));\r
+                               if(ro) {\r
+                                       int m = datefield.getMilliseconds();\r
+                                       String ms = m<100? "0"+m : ""+m;\r
+                                       add(new ILabel(m<10? "0"+ms : ms));\r
+                               }\r
+                               else add(msec);\r
+                       }\r
+                       if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
+                               add(new ILabel(delimiter+"00")); // o'clock\r
+                       }\r
+                       if(thc) {\r
+                               add(new ILabel("&nbsp;"));\r
+                               if(ro) add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
+                               else add(ampm);\r
+                       }\r
+                       \r
+                       if(ro) return;\r
+               }\r
+               \r
+               // Update times\r
+               if(thc) {\r
+                       int h = datefield.getCurrentDate().getHours();\r
+                       ampm.setSelectedIndex(h<12? 0 : 1);\r
+                       h -= ampm.getSelectedIndex()*12;\r
+                       hours.setSelectedIndex(h);\r
+               } else\r
+                       hours.setSelectedIndex(datefield.getCurrentDate().getHours());\r
+               if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN)\r
+                       mins.setSelectedIndex(datefield.getCurrentDate().getMinutes());\r
+               if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC)\r
+                       sec.setSelectedIndex(datefield.getCurrentDate().getSeconds());\r
+               if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC)\r
+                       msec.setSelectedIndex(datefield.getMilliseconds());\r
+               if(thc)\r
+                       ampm.setSelectedIndex(datefield.getCurrentDate().getHours()<12?0:1);\r
+               \r
+               if(datefield.isReadonly() && !redraw) {\r
+                       // Do complete redraw when in read-only status\r
+                       clear();\r
+                       String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
+                       \r
+                       int h = datefield.getCurrentDate().getHours();\r
+                       if(thc) h -= h<12? 0 : 12;\r
+                       add(new ILabel(h<10? "0"+h : ""+h));\r
+                       \r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+                               add(new ILabel(delimiter));\r
+                               int m = mins.getSelectedIndex();\r
+                               add(new ILabel(m<10? "0"+m : ""+m));\r
+                       }\r
+                       if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+                               add(new ILabel(delimiter));\r
+                               int s = sec.getSelectedIndex();\r
+                               add(new ILabel(s<10? "0"+s : ""+s));\r
+                       }\r
+                       if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+                               add(new ILabel("."));\r
+                               int m = datefield.getMilliseconds();\r
+                               String ms = m<100? "0"+m : ""+m;\r
+                               add(new ILabel(m<10? "0"+ms : ms));\r
+                       }\r
+                       if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
+                               add(new ILabel(delimiter+"00")); // o'clock\r
+                       }\r
+                       if(thc) {\r
+                               add(new ILabel("&nbsp;"));\r
+                               add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
+                       }\r
+               }\r
+               \r
+               boolean enabled = datefield.isEnabled();\r
+               hours.setEnabled(enabled);\r
+               if(mins != null) mins.setEnabled(enabled);\r
+               if(sec != null) sec.setEnabled(enabled);\r
+               if(msec != null) msec.setEnabled(enabled);\r
+               if(ampm != null) ampm.setEnabled(enabled);\r
+               \r
+       }\r
+\r
+       public void updateTime(boolean redraw) {\r
+               buildTime(redraw || resolution != datefield.getCurrentResolution() \r
+                                               || readonly != datefield.isReadonly());\r
+               if(datefield instanceof ITextualDate)\r
+                       ((ITextualDate) datefield).buildDate();\r
+               resolution = datefield.getCurrentResolution();\r
+               readonly = datefield.isReadonly();\r
+       }\r
+\r
+       public void onChange(Widget sender) {\r
+               if(sender == hours) {\r
+                       int h = hours.getSelectedIndex();\r
+                       if(datefield.getDateTimeService().isTwelveHourClock())\r
+                               h = h + ampm.getSelectedIndex()*12;\r
+                       datefield.getCurrentDate().setHours(h);\r
+                       datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
+                       updateTime(false);\r
+               }\r
+               else if(sender == mins) {\r
+                       int m = mins.getSelectedIndex();\r
+                       datefield.getCurrentDate().setMinutes(m);\r
+                       datefield.getClient().updateVariable(datefield.getId(), "min", m, datefield.isImmediate());\r
+                       updateTime(false);\r
+               }\r
+               else if(sender == sec) {\r
+                       int s = sec.getSelectedIndex();\r
+                       datefield.getCurrentDate().setSeconds(s);\r
+                       datefield.getClient().updateVariable(datefield.getId(), "sec", s, datefield.isImmediate());\r
+                       updateTime(false);\r
+               }\r
+               else if(sender == msec) {\r
+                       int ms = msec.getSelectedIndex();\r
+                       datefield.setMilliseconds(ms);\r
+                       datefield.getClient().updateVariable(datefield.getId(), "msec", ms, datefield.isImmediate());\r
+                       updateTime(false);\r
+               }\r
+               else if(sender == ampm) {\r
+                       int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12;\r
+                       datefield.getCurrentDate().setHours(h);\r
+                       datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
+                       updateTime(false);\r
+               }\r
+       }\r
+\r
+}\r