]> source.dussan.org Git - vaadin-framework.git/commitdiff
Calendar component added + demo and refactoring.
authorMarc Englund <marc.englund@itmill.com>
Fri, 17 Aug 2007 08:01:06 +0000 (08:01 +0000)
committerMarc Englund <marc.englund@itmill.com>
Fri, 17 Aug 2007 08:01:06 +0000 (08:01 +0000)
svn changeset:2043/svn branch:trunk

src/com/itmill/toolkit/demo/HelloWorld.java
src/com/itmill/toolkit/demo/util/SampleCalendarDatabase.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/DateTimeService.java
src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java [deleted file]
src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/ui/IEntryCalendar.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java [new file with mode: 0644]
src/com/itmill/toolkit/ui/CalendarField.java [new file with mode: 0644]

index d4ab04e48602afce1485053b9188e10d397c8360..e2001a73cd1c8952cd9c8dc95886eb3a2e2a0ec7 100644 (file)
@@ -1,6 +1,13 @@
 package com.itmill.toolkit.demo;
 
-import com.itmill.toolkit.ui.*;
+import java.util.Date;
+
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.CalendarField;
+import com.itmill.toolkit.ui.DateField;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.OrderedLayout;
+import com.itmill.toolkit.ui.Window;
 
 /**
  * The classic "hello, world!" example for IT Mill Toolkit. The class simply
@@ -19,8 +26,10 @@ public class HelloWorld extends com.itmill.toolkit.Application {
         * com.itmill.toolkit.service.Application class. It will be automatically
         * called by the framework when a user accesses the application.
         */
+       OrderedLayout l;
        public void init() {
 
+               setTheme("demo");
                /*
                 * - Create new window for the application - Give the window a visible
                 * title - Set the window to be the main window of the application
@@ -28,15 +37,44 @@ public class HelloWorld extends com.itmill.toolkit.Application {
                Window main = new Window("Hello window");
                setMainWindow(main);
 
+               main.addComponent(new DateField());
+               main.addComponent(new CalendarField());
+               
                /*
                 * - Create a label with the classic text - Add the label to the main
                 * window
                 */
-               main.addComponent(new Label("Hello World!"));
+               main.addComponent(new Label("Hello4 World!"));
+               
+               l = new OrderedLayout();
+               main.addComponent(l);
+               l.addComponent(new Button("foo",this,"foo"));
+               l.addComponent(new Button("asd",this,"asd"));
 
                /*
                 * And that's it! The framework will display the main window and its
                 * contents when the application is accessed with the terminal.
                 */
        }
+       
+       public void foo() {
+           long s = new Date().getTime();
+           System.out.println("> foo: " + s);
+           try {
+               Thread.currentThread().sleep(5000);
+           } catch (Exception e) {
+               
+           }
+           System.out.println("< foo: " + s);  
+       }
+       public void asd() {
+           long s = new Date().getTime();
+           System.out.println("> asd: " + s);
+           try {
+               Thread.currentThread().sleep(5000);
+           } catch (Exception e) {
+               
+           }
+           System.out.println("< asd: " + s);  
+       }
 }
diff --git a/src/com/itmill/toolkit/demo/util/SampleCalendarDatabase.java b/src/com/itmill/toolkit/demo/util/SampleCalendarDatabase.java
new file mode 100644 (file)
index 0000000..d27756b
--- /dev/null
@@ -0,0 +1,162 @@
+package com.itmill.toolkit.demo.util;
+
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+
+/**
+ * Creates temporary database named toolkit with sample table named employee and
+ * populates it with data. By default we use HSQLDB. Ensure that you have
+ * hsqldb.jar under WEB-INF/lib directory. Database is will be created into
+ * memory.
+ * 
+ * @author IT Mill Ltd.
+ * 
+ */
+public class SampleCalendarDatabase {
+
+    public static final int ENTRYCOUNT = 100;
+
+    public static final String DB_TABLE_NAME = "calendar";
+    public static final String PROPERTY_ID_START = "EVENTSTART";
+    public static final String PROPERTY_ID_END = "EVENTEND";
+    public static final String PROPERTY_ID_TITLE = "TITLE";
+    public static final String PROPERTY_ID_NOTIME = "NOTIME";
+    
+    private Connection connection = null;
+
+    private static final String[] titles = new String[] { "Meeting", "Dentist",
+           "Haircut", "Bank", "Birthday", "Library", "Rent", "Acme test", "Party" };
+
+    /**
+     * Create temporary database.
+     * 
+     */
+    public SampleCalendarDatabase() {
+       // connect to SQL database
+       connect();
+
+       // initialize SQL database
+       createTables();
+
+       // test by executing sample JDBC query
+       testDatabase();
+    }
+
+    /**
+     * Creates sample table named employee and populates it with data.Use the
+     * specified database connection.
+     * 
+     * @param connection
+     */
+    public SampleCalendarDatabase(Connection connection) {
+       // initialize SQL database
+       createTables();
+
+       // test by executing sample JDBC query
+       testDatabase();
+    }
+
+    /**
+     * Connect to SQL database. In this sample we use HSQLDB and an toolkit
+     * named database in implicitly created into system memory.
+     * 
+     */
+    private void connect() {
+       // use memory-Only Database
+       String url = "jdbc:hsqldb:mem:toolkit";
+       try {
+           Class.forName("org.hsqldb.jdbcDriver").newInstance();
+           connection = DriverManager.getConnection(url, "sa", "");
+       } catch (Exception e) {
+           throw new RuntimeException(e);
+       }
+    }
+
+    /**
+     * use for SQL commands CREATE, DROP, INSERT and UPDATE
+     * 
+     * @param expression
+     * @throws SQLException
+     */
+    public void update(String expression) throws SQLException {
+       Statement st = null;
+       st = connection.createStatement();
+       int i = st.executeUpdate(expression);
+       if (i == -1) {
+           System.out.println("SampleDatabase error : " + expression);
+       }
+       st.close();
+    }
+
+    /**
+     * Create test table and few rows. Issue note: using capitalized column
+     * names as HSQLDB returns column names in capitalized form with this demo.
+     * 
+     */
+    private void createTables() {
+       try {
+           String stmt = null;
+           stmt = "CREATE TABLE "+DB_TABLE_NAME+" ( ID INTEGER IDENTITY, TITLE VARCHAR(100), "
+                   + "EVENTSTART DATETIME, EVENTEND DATETIME, NOTIME BOOLEAN  )";
+           update(stmt);
+           for (int j = 0; j < ENTRYCOUNT; j++) {
+               Timestamp start = new Timestamp(new java.util.Date().getTime());
+               start.setDate((int)((Math.random()-0.4) * 200));
+               start.setMinutes(0);
+               start.setHours(8+(int)Math.random()*12);
+               Timestamp end = new Timestamp(start.getTime());
+               if (Math.random()<0.7) {
+                   long t = end.getTime();
+                   long hour = 60 * 60 * 1000;
+                   t = t + hour + (long)(Math.round(Math.random() * 3 * hour));
+                   end.setTime(t);
+               }
+
+               stmt = "INSERT INTO "+DB_TABLE_NAME+"(TITLE, EVENTSTART, EVENTEND, NOTIME) VALUES ("
+                       + "'"
+                       + titles[(int) (Math.round(Math.random() * (titles.length - 1)))]
+                       + "','"
+                       + start
+                       + "','"
+                       + end
+                       + "',"
+                       + (Math.random()>0.7)
+                       + ")";
+               update(stmt);
+           }
+       } catch (SQLException e) {
+           if (e.toString().indexOf("Table already exists") == -1)
+               throw new RuntimeException(e);
+       }
+    }
+
+    /**
+     * Test database connection with simple SELECT command.
+     * 
+     */
+    private String testDatabase() {
+       String result = null;
+       try {
+           Statement stmt = connection.createStatement(
+                   ResultSet.TYPE_SCROLL_INSENSITIVE,
+                   ResultSet.CONCUR_UPDATABLE);
+           ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM "+DB_TABLE_NAME);
+           rs.next();
+           result = "rowcount for table test is " + rs.getObject(1).toString();
+           stmt.close();
+       } catch (SQLException e) {
+           throw new RuntimeException(e);
+       }
+       return result;
+    }
+
+    public Connection getConnection() {
+       return connection;
+    }
+
+}
index 77429b0a04b00d1de8aded2f9b81c87c3cf6b67a..10e2a3183727fa0b1d4e4a39da59c2b5a042a3a7 100644 (file)
@@ -2,174 +2,250 @@ package com.itmill.toolkit.terminal.gwt.client;
 \r
 import java.util.Date;\r
 \r
+import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;\r
+\r
 /**\r
- * This class provides date/time parsing services to \r
- * all components on the client side.\r
+ * This class provides date/time parsing services to all components on the\r
+ * client side.\r
  * \r
  * @author IT Mill Ltd.\r
- *\r
+ * \r
  */\r
 public class DateTimeService {\r
-       \r
-       private String currentLocale;\r
-       \r
-       private static int [] maxDaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r
-       \r
-       /**\r
-        * Creates a new date time service with the application default locale.\r
-        */\r
-       public DateTimeService() {\r
-               currentLocale = LocaleService.getDefaultLocale();\r
-       }\r
-       \r
-       /**\r
-        * Creates a new date time service with a given locale.\r
-        * \r
-        * @param locale e.g. fi, en etc.\r
-        * @throws LocaleNotLoadedException\r
-        */\r
-       public DateTimeService(String locale) throws LocaleNotLoadedException {\r
-               setLocale(locale);\r
-       }\r
-       \r
-       public void setLocale(String locale) throws LocaleNotLoadedException {\r
-               if(LocaleService.getAvailableLocales().contains(locale))\r
-                       currentLocale = locale;\r
-               else throw new LocaleNotLoadedException(locale);\r
-       }\r
-       \r
-       public String getLocale() {\r
-               return currentLocale;\r
-       }\r
-       \r
-       public String getMonth(int month) {\r
-               try {\r
-                       return LocaleService.getMonthNames(currentLocale)[month];\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public String getShortMonth(int month) {\r
-               try {\r
-                       return LocaleService.getShortMonthNames(currentLocale)[month];\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public String getDay(int day) {\r
-               try {\r
-                       return LocaleService.getDayNames(currentLocale)[day];\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public String getShortDay(int day) {\r
-               try {\r
-                       return LocaleService.getShortDayNames(currentLocale)[day];\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public int getFirstDayOfWeek() {\r
-               try {\r
-                       return LocaleService.getFirstDayOfWeek(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return 0;\r
-       }\r
-       \r
-       public boolean isTwelveHourClock() {\r
-               try {\r
-                       return LocaleService.isTwelveHourClock(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       public String getClockDelimeter() {\r
-               try {\r
-                       return LocaleService.getClockDelimiter(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return ":";\r
-       }\r
-       \r
-       public String[] getAmPmStrings() {\r
-               try {\r
-                       return LocaleService.getAmPmStrings(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               String[] temp = new String[2];\r
-               temp[0] = "AM";\r
-               temp[1] = "PM";\r
-               return temp;\r
-       }\r
-       \r
-       public int getStartWeekDay(Date date){\r
-               Date dateForFirstOfThisMonth = new Date(date.getYear(), date.getMonth(), 1);\r
-               int firstDay;\r
-               try {\r
-                       firstDay = LocaleService.getFirstDayOfWeek(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       firstDay = 0;\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               int start = dateForFirstOfThisMonth.getDay() - firstDay;\r
-               if(start < 0) start = 6;\r
-               return start;\r
-       }\r
-       \r
-       public String getDateFormat() {\r
-               try {\r
-                       return LocaleService.getDateFormat(currentLocale);\r
-               } catch (LocaleNotLoadedException e) {\r
-                       // TODO redirect to console\r
-                       System.out.println(e + ":" + e.getMessage());\r
-               }\r
-               return "M/d/yy";\r
-       }\r
-       \r
-       public static int getNumberOfDaysInMonth(Date date){\r
-               int month = date.getMonth();\r
-               if(month == 1 && true == isLeapYear(date))\r
-                       return 29;\r
-               return maxDaysInMonth[month]; \r
-       }\r
-       \r
-       public static boolean isLeapYear(Date date){\r
-               // Instantiate the date for 1st March of that year\r
-               Date firstMarch = new Date(date.getYear(), 2, 1);\r
-\r
-               // Go back 1 day\r
-               long firstMarchTime = firstMarch.getTime();\r
-               long lastDayTimeFeb = firstMarchTime - (24*60*60*1000); // NUM_MILLISECS_A_DAY\r
-               \r
-               //Instantiate new Date with this time\r
-               Date febLastDay = new Date(lastDayTimeFeb);\r
-               \r
-               // Check for date in this new instance\r
-               return (29 == febLastDay.getDate()) ? true : false;\r
-       }\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
+    private String currentLocale;\r
+\r
+    private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,\r
+           31, 30, 31 };\r
+\r
+    /**\r
+     * Creates a new date time service with the application default locale.\r
+     */\r
+    public DateTimeService() {\r
+       currentLocale = LocaleService.getDefaultLocale();\r
+    }\r
+\r
+    /**\r
+     * Creates a new date time service with a given locale.\r
+     * \r
+     * @param locale\r
+     *                e.g. fi, en etc.\r
+     * @throws LocaleNotLoadedException\r
+     */\r
+    public DateTimeService(String locale) throws LocaleNotLoadedException {\r
+       setLocale(locale);\r
+    }\r
+\r
+    public void setLocale(String locale) throws LocaleNotLoadedException {\r
+       if (LocaleService.getAvailableLocales().contains(locale))\r
+           currentLocale = locale;\r
+       else\r
+           throw new LocaleNotLoadedException(locale);\r
+    }\r
+\r
+    public String getLocale() {\r
+       return currentLocale;\r
+    }\r
+\r
+    public String getMonth(int month) {\r
+       try {\r
+           return LocaleService.getMonthNames(currentLocale)[month];\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return null;\r
+    }\r
+\r
+    public String getShortMonth(int month) {\r
+       try {\r
+           return LocaleService.getShortMonthNames(currentLocale)[month];\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return null;\r
+    }\r
+\r
+    public String getDay(int day) {\r
+       try {\r
+           return LocaleService.getDayNames(currentLocale)[day];\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return null;\r
+    }\r
+\r
+    public String getShortDay(int day) {\r
+       try {\r
+           return LocaleService.getShortDayNames(currentLocale)[day];\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return null;\r
+    }\r
+\r
+    public int getFirstDayOfWeek() {\r
+       try {\r
+           return LocaleService.getFirstDayOfWeek(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return 0;\r
+    }\r
+\r
+    public boolean isTwelveHourClock() {\r
+       try {\r
+           return LocaleService.isTwelveHourClock(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return false;\r
+    }\r
+\r
+    public String getClockDelimeter() {\r
+       try {\r
+           return LocaleService.getClockDelimiter(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return ":";\r
+    }\r
+\r
+    public String[] getAmPmStrings() {\r
+       try {\r
+           return LocaleService.getAmPmStrings(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       String[] temp = new String[2];\r
+       temp[0] = "AM";\r
+       temp[1] = "PM";\r
+       return temp;\r
+    }\r
+\r
+    public int getStartWeekDay(Date date) {\r
+       Date dateForFirstOfThisMonth = new Date(date.getYear(),\r
+               date.getMonth(), 1);\r
+       int firstDay;\r
+       try {\r
+           firstDay = LocaleService.getFirstDayOfWeek(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           firstDay = 0;\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       int start = dateForFirstOfThisMonth.getDay() - firstDay;\r
+       if (start < 0)\r
+           start = 6;\r
+       return start;\r
+    }\r
+\r
+    public String getDateFormat() {\r
+       try {\r
+           return LocaleService.getDateFormat(currentLocale);\r
+       } catch (LocaleNotLoadedException e) {\r
+           // TODO redirect to console\r
+           System.out.println(e + ":" + e.getMessage());\r
+       }\r
+       return "M/d/yy";\r
+    }\r
+\r
+    public static int getNumberOfDaysInMonth(Date date) {\r
+       int month = date.getMonth();\r
+       if (month == 1 && true == isLeapYear(date))\r
+           return 29;\r
+       return maxDaysInMonth[month];\r
+    }\r
+\r
+    public static boolean isLeapYear(Date date) {\r
+       // Instantiate the date for 1st March of that year\r
+       Date firstMarch = new Date(date.getYear(), 2, 1);\r
+\r
+       // Go back 1 day\r
+       long firstMarchTime = firstMarch.getTime();\r
+       long lastDayTimeFeb = firstMarchTime - (24 * 60 * 60 * 1000); // NUM_MILLISECS_A_DAY\r
+\r
+       // Instantiate new Date with this time\r
+       Date febLastDay = new Date(lastDayTimeFeb);\r
+\r
+       // Check for date in this new instance\r
+       return (29 == febLastDay.getDate()) ? true : false;\r
+    }\r
+\r
+    public static boolean isSameDay(Date d1, Date d2) {\r
+       return (getDayInt(d1) == getDayInt(d2));\r
+    }\r
+\r
+    public static boolean isInRange(Date date, Date rangeStart, Date rangeEnd,\r
+           int resolution) {\r
+       Date s;\r
+       Date e;\r
+       if (rangeStart.after(rangeEnd)) {\r
+           s = rangeEnd;\r
+           e = rangeStart;\r
+       } else {\r
+           e = rangeEnd;\r
+           s = rangeStart;\r
+       }\r
+       if (date.getYear() < s.getYear() || date.getYear() > e.getYear()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_YEAR) {\r
+           return true;\r
+       }\r
+       if (date.getMonth() < s.getMonth() || date.getMonth() > e.getMonth()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_MONTH) {\r
+           return true;\r
+       }\r
+       if (date.getDate() < s.getDate() || date.getDate() > e.getDate()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_DAY) {\r
+           return true;\r
+       }\r
+       if (date.getHours() < s.getHours() || date.getHours() > e.getHours()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_HOUR) {\r
+           return true;\r
+       }\r
+       if (date.getMinutes() < s.getMinutes()\r
+               || date.getMinutes() > e.getMinutes()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_MIN) {\r
+           return true;\r
+       }\r
+       if (date.getSeconds() < s.getSeconds()\r
+               || date.getSeconds() > e.getSeconds()) {\r
+           return false;\r
+       } else if (resolution == RESOLUTION_SEC) {\r
+           return true;\r
+       }\r
+       if (date.getTime() < s.getTime() || date.getTime() > e.getTime()) {\r
+           return false;\r
+       } else {\r
+           return true;\r
+       }\r
+    }\r
+\r
+    private static int getDayInt(Date date) {\r
+       int y = date.getYear();\r
+       int m = date.getMonth();\r
+       int d = date.getDate();\r
+\r
+       return ((y + 1900) * 10000 + m * 100 + d) * 1000000000;\r
+    }\r
 \r
 }\r
index 10263d9dcbbe426ba4645607d676e4c40e88c793..7a2c7a21363ebc5c027467cce5e0dc2b3905b0b0 100644 (file)
@@ -3,11 +3,12 @@ package com.itmill.toolkit.terminal.gwt.client;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ui.IButton;
-import com.itmill.toolkit.terminal.gwt.client.ui.ICalendar;
 import com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox;
 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.IForm;
 import com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout;
 import com.itmill.toolkit.terminal.gwt.client.ui.ILabel;
@@ -35,229 +36,199 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IWindow;
 
 public class DefaultWidgetFactory implements WidgetFactory {
 
-       public Widget createWidget(UIDL uidl) {
+    public Widget createWidget(UIDL uidl) {
 
-               String className = resolveWidgetTypeName(uidl);
+       String className = resolveWidgetTypeName(uidl);
 
-               if ("com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox".equals(className)) {
-                       return new ICheckBox();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IButton".equals(className)) {
-                       return new IButton();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IView".equals(className)) {
-                       // TODO remove IView?
-                       return new IView();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IWindow".equals(className)) {
-                       return new IWindow();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutVertical".equals(className)) {
-                       return new IOrderedLayoutVertical();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutHorizontal".equals(className)) {
-                       return new IOrderedLayoutHorizontal();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ILabel".equals(className)) {
-                       return new ILabel();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ILink".equals(className)) {
-                       return new ILink();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout".equals(className)) {
-                       return new IGridLayout();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITree".equals(className)) {
-                       return new ITree();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup".equals(className)) {
-                       return new IOptionGroup();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect".equals(className)) {
-                       return new ITwinColSelect();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ISelect".equals(className)) {
-                       return new ISelect();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPanel".equals(className)) {
-                       return new IPanel();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IComponent".equals(className)) {
-                       return new IComponent();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet".equals(className)) {
-                       return new ITabsheet();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded".equals(className)) {
-                       return new IEmbedded();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout".equals(className)) {
-                       return new ICustomLayout();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextArea".equals(className)) {
-                       return new ITextArea();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField".equals(className)) {
-                       return new IPasswordField();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextField".equals(className)) {
-                       return new ITextField();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging".equals(className)) {
-                       return new ITablePaging();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable".equals(className)) {
-                       return new IScrollTable();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICalendar".equals(className)) {
-                       return new ICalendar();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate".equals(className)) {
-                       return new ITextualDate();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar".equals(className)) {
-                       return new IPopupCalendar();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ISlider".equals(className)) {
-                       return new ISlider();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IForm".equals(className)) {
-                       return new IForm();
-               } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IUpload".equals(className)) {
-                       return new IUpload();
-               }
-               return new IUnknownComponent();
-
-               /* TODO: Class based impl, use when GWT supports
-       return (Widget)GWT.create(resolveWidgetClass(uidl));
-                */
+       if ("com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox"
+               .equals(className)) {
+           return new ICheckBox();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IButton"
+               .equals(className)) {
+           return new IButton();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IView"
+               .equals(className)) {
+           // TODO remove IView?
+           return new IView();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IWindow"
+               .equals(className)) {
+           return new IWindow();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutVertical"
+               .equals(className)) {
+           return new IOrderedLayoutVertical();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutHorizontal"
+               .equals(className)) {
+           return new IOrderedLayoutHorizontal();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ILabel"
+               .equals(className)) {
+           return new ILabel();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ILink"
+               .equals(className)) {
+           return new ILink();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout"
+               .equals(className)) {
+           return new IGridLayout();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITree"
+               .equals(className)) {
+           return new ITree();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup"
+               .equals(className)) {
+           return new IOptionGroup();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect"
+               .equals(className)) {
+           return new ITwinColSelect();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ISelect"
+               .equals(className)) {
+           return new ISelect();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPanel"
+               .equals(className)) {
+           return new IPanel();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IComponent"
+               .equals(className)) {
+           return new IComponent();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet"
+               .equals(className)) {
+           return new ITabsheet();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded"
+               .equals(className)) {
+           return new IEmbedded();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout"
+               .equals(className)) {
+           return new ICustomLayout();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextArea"
+               .equals(className)) {
+           return new ITextArea();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField"
+               .equals(className)) {
+           return new IPasswordField();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextField"
+               .equals(className)) {
+           return new ITextField();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging"
+               .equals(className)) {
+           return new ITablePaging();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable"
+               .equals(className)) {
+           return new IScrollTable();
+       } 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"
+               .equals(className)) {
+           return new IEntryCalendar();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate"
+               .equals(className)) {
+           return new ITextualDate();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar"
+               .equals(className)) {
+           return new IPopupCalendar();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ISlider"
+               .equals(className)) {
+           return new ISlider();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IForm"
+               .equals(className)) {
+           return new IForm();
+       } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IUpload"
+               .equals(className)) {
+           return new IUpload();
        }
+       return new IUnknownComponent();
 
-       private String resolveWidgetTypeName(UIDL uidl) {
+       /*
+        * TODO: Class based impl, use when GWT supports return
+        * (Widget)GWT.create(resolveWidgetClass(uidl));
+        */
+    }
 
-               String tag = uidl.getTag();
-               if ("button".equals(tag)) {
-                       if ("switch".equals(uidl.getStringAttribute("type"))) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox";
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IButton";
-                       }
-               } else if ("window".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IWindow";
-               } else if ("orderedlayout".equals(tag)) {
-                       if ("horizontal".equals(uidl.getStringAttribute("orientation"))) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutHorizontal";
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutVertical";
-                       }
-               } else if ("label".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ILabel";
-               } else if ("link".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ILink";
-               } else if ("gridlayout".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout";
-               } else if ("tree".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ITree";
-               } else if ("select".equals(tag)) {
-                       if ("optiongroup".equals(uidl.getStringAttribute("style"))) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup";
-                       } else if ("twincol".equals(uidl.getStringAttribute("style"))) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect";
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.ISelect";
-                       }
-               } else if ("panel".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IPanel";
-               } else if ("component".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IComponent";
-               } else if ("tabsheet".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet";
-               } else if ("embedded".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded";
-               } else if ("customlayout".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout";
-               } else if ("textfield".equals(tag)) {
-                       if (uidl.hasAttribute("multiline")) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.ITextArea";
-                       } else if (uidl.getBooleanAttribute("secret")) {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField";
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.ITextField";
-                       }
-               } else if ("table".equals(tag)) {
-                       if (uidl.hasAttribute("style")) {
-                               if ("paging".equals(uidl.getStringAttribute("style"))) {
-                                       return "com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging";
-                               }
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable";
-                       }
-               } else if ("datefield".equals(tag)) {
-                       if (uidl.hasAttribute("style")) {
-                               if ("calendar".equals(uidl.getStringAttribute("style"))) {
-                                       return "com.itmill.toolkit.terminal.gwt.client.ui.ICalendar";
-                               } else if ("text".equals(uidl.getStringAttribute("style"))) {
-                                       return "com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate";
-                               }
-                       } else {
-                               return "com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar";
-                       }
-               } else if ("slider".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.ISlider";
-               } else if ("form".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IForm";
-               } else if ("upload".equals(tag)) {
-                       return "com.itmill.toolkit.terminal.gwt.client.ui.IUpload";
-               }
+    private String resolveWidgetTypeName(UIDL uidl) {
 
-               return "com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent";
-
-               /* TODO: Class based impl, use when GWT supports
+       String tag = uidl.getTag();
        if ("button".equals(tag)) {
-           return IButton.class;
+           if ("switch".equals(uidl.getStringAttribute("type"))) {
+               return "com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox";
+           } else {
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IButton";
+           }
        } else if ("window".equals(tag)) {
-           return IView.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IWindow";
        } else if ("orderedlayout".equals(tag)) {
            if ("horizontal".equals(uidl.getStringAttribute("orientation"))) {
-               return IOrderedLayoutHorizontal.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutHorizontal";
            } else {
-               return IOrderedLayoutVertical.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayoutVertical";
            }
        } else if ("label".equals(tag)) {
-           return ILabel.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ILabel";
        } else if ("link".equals(tag)) {
-           return ILink.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ILink";
        } else if ("gridlayout".equals(tag)) {
-           return IGridLayout.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout";
        } else if ("tree".equals(tag)) {
-           return ITree.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ITree";
        } else if ("select".equals(tag)) {
            if ("optiongroup".equals(uidl.getStringAttribute("style"))) {
-               return IOptionGroup.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup";
            } else if ("twincol".equals(uidl.getStringAttribute("style"))) {
-               return ITwinColSelect.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect";
            } else {
-               return ISelect.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.ISelect";
            }
        } else if ("panel".equals(tag)) {
-           return IPanel.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IPanel";
        } else if ("component".equals(tag)) {
-           return IComponent.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IComponent";
        } else if ("tabsheet".equals(tag)) {
-           return ITabsheet.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet";
        } else if ("embedded".equals(tag)) {
-           return IEmbedded.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded";
        } else if ("customlayout".equals(tag)) {
-           return ICustomLayout.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout";
        } else if ("textfield".equals(tag)) {
            if (uidl.hasAttribute("multiline")) {
-               return ITextArea.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.ITextArea";
            } else if (uidl.getBooleanAttribute("secret")) {
-               return IPasswordField.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField";
            } else {
-               return ITextField.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.ITextField";
            }
        } else if ("table".equals(tag)) {
            if (uidl.hasAttribute("style")) {
                if ("paging".equals(uidl.getStringAttribute("style"))) {
-                   return ITablePaging.class;
+                   return "com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging";
                }
            } else {
-               return IScrollTable.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable";
            }
        } else if ("datefield".equals(tag)) {
            if (uidl.hasAttribute("style")) {
                if ("calendar".equals(uidl.getStringAttribute("style"))) {
-                   return ICalendar.class;
+                   return "com.itmill.toolkit.terminal.gwt.client.ui.ICalendar";
                } else if ("text".equals(uidl.getStringAttribute("style"))) {
-                   return ITextualDate.class;
+                   return "com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate";
                }
            } else {
-               return IPopupCalendar.class;
+               return "com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar";
            }
+       } else if ("calendarfield".equals(tag)) {
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IEntryCalendar";
        } else if ("slider".equals(tag)) {
-           return ISlider.class;
+           return "com.itmill.toolkit.terminal.gwt.client.ui.ISlider";
+       } else if ("form".equals(tag)) {
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IForm";
+       } else if ("upload".equals(tag)) {
+           return "com.itmill.toolkit.terminal.gwt.client.ui.IUpload";
        }
 
-       return IUnknownComponent.class;
-                */
-       }
+       return "com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent";
 
-       public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl) {
-               return GWT.getTypeName(currentWidget).equals(resolveWidgetTypeName(uidl));
-       }
+       /*
+        * TODO: use class based impl when GWT supports it
+        */
+    }
+
+    public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl) {
+       return GWT.getTypeName(currentWidget).equals(
+               resolveWidgetTypeName(uidl));
+    }
 
 }
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java
deleted file mode 100644 (file)
index 6092b0c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.itmill.toolkit.terminal.gwt.client.ui;\r
-\r
-import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
-import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-\r
-public class ICalendar extends IDateField {\r
-       \r
-       private ICalendarPanel date;\r
-       \r
-       public ICalendar() {\r
-               super();\r
-               setStyleName(CLASSNAME+"-calendar");\r
-               date = new ICalendarPanel(this);\r
-               add(date);\r
-       }\r
-       \r
-       public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-               super.updateFromUIDL(uidl, client);\r
-               date.updateCalendar();\r
-       }\r
-\r
-}\r
index 976994068c8bef497c6f062271e0740d266a50c4..8f3dc8a4809515e6b94a1a0d24ec1e3f7f2318d5 100644 (file)
@@ -1,6 +1,8 @@
 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
@@ -15,276 +17,389 @@ import com.google.gwt.user.client.ui.TableListener;
 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, 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
-       /* 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
+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
-       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
+    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 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
+    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
-       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(); prevYear.setHTML("&laquo;");\r
-                               nextYear = new IEventButton(); nextYear.setHTML("&raquo;");\r
-                               prevYear.addMouseListener(this); nextYear.addMouseListener(this);\r
-                               prevYear.addClickListener(this); nextYear.addClickListener(this);\r
-                               setWidget(0, 0, prevYear);\r
-                               setWidget(0, 4, nextYear);\r
-                               \r
-                               if(needsMonth) {\r
-                                       prevMonth = new IEventButton(); prevMonth.setHTML("&lsaquo;");\r
-                                       nextMonth = new IEventButton(); nextMonth.setHTML("&rsaquo;");\r
-                                       prevMonth.addMouseListener(this); nextMonth.addMouseListener(this);\r
-                                       prevMonth.addClickListener(this); nextMonth.addClickListener(this);\r
-                                       setWidget(0, 3, nextMonth);\r
-                                       setWidget(0, 1, prevMonth);\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
-                               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; nextMonth = null;\r
+                           }\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) day = 0;\r
-                               if(datefield.currentResolution > IDateField.RESOLUTION_MONTH)\r
-                                       setHTML(1,i, "<strong>" + datefield.dts.getShortDay(day) + "</strong>");\r
-                               else\r
-                                       setHTML(1,i, "");\r
+                       String baseclass = datefield.CLASSNAME\r
+                               + "-calendarpanel-day";\r
+                       String cssClass = baseclass;\r
+                       if (!isEnabledDate(curr)) {\r
+                           cssClass += " " + baseclass + "-disabled";\r
                        }\r
-               }\r
-               \r
-               String monthName = needsMonth? datefield.dts.getMonth(datefield.date.getMonth()) : "";\r
-               int year = datefield.date.getYear()+1900;\r
-               setHTML(0, 2, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-month\">" + monthName + " " + year + "</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
-               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
-                                               if(date.getDate() == dayCount){\r
-                                                       setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day-selected\">" + selectedDate + "</span>");\r
-                                               } else if(today.getDate() == dayCount && today.getMonth() == date.getMonth() && today.getYear() == date.getYear()){\r
-                                                       setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day-today\">" + selectedDate + "</span>");\r
-                                               } else {\r
-                                                       setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day\">" + selectedDate + "</span>");\r
-                                               }\r
-                                       } else {\r
-                                               break;\r
-                                       }\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
-       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
+    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
-       \r
-       /**\r
-        * \r
-        * @param forceRedraw 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 || resolution != datefield.currentResolution);\r
-               if(datefield instanceof ITextualDate)\r
-                       ((ITextualDate) datefield).buildDate();\r
-               locale = datefield.currentLocale;\r
-               resolution = datefield.currentResolution;\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
-       public void onClick(Widget sender) {\r
-               processClickEvent(sender);\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 void processClickEvent(Widget sender) {\r
-               if(!datefield.enabled || datefield.readonly)\r
-                       return;\r
-               if(sender == prevYear) {\r
-                       datefield.date.setYear(datefield.date.getYear()-1);\r
-                       datefield.client.updateVariable(datefield.id, "year", 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", 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", 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", datefield.date.getMonth()+1, datefield.immediate);\r
-                       updateCalendar();\r
-               }\r
-       }\r
-       \r
-       private Timer timer;\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
+    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 onMouseEnter(Widget sender) {}\r
+    public void onMouseMove(Widget sender, int x, int y) {\r
+    }\r
 \r
-       public void onMouseLeave(Widget sender) {\r
-               if(timer != null)\r
-                       timer.cancel();\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 onMouseMove(Widget sender, int x, int y) {}\r
+       public void addMouseListener(MouseListener listener) {\r
+           if (mouseListeners == null) {\r
+               mouseListeners = new MouseListenerCollection();\r
+           }\r
+           mouseListeners.add(listener);\r
+       }\r
 \r
-       public void onMouseUp(Widget sender, int x, int y) {\r
-               if(timer != null)\r
-                       timer.cancel();\r
+       public void removeMouseListener(MouseListener listener) {\r
+           if (mouseListeners != null)\r
+               mouseListeners.remove(listener);\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
+       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
-                       \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
+               break;\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
 \r
-               public void onCellClicked(SourcesTableEvents sender, int row, int col) {\r
-                       if(sender != cal || row < 2 || row > 7 || !cal.datefield.enabled || 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
-                       cal.datefield.date.setDate(day.intValue());\r
-                       cal.datefield.client.updateVariable(cal.datefield.id, "day", cal.datefield.date.getDate(), cal.datefield.immediate);\r
-                       \r
-                       updateCalendar();\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 cb24dfeee8717c18efbde3e201e112afc52d647e..fbed7063b15088577f73b807ca09780a3a20ae3d 100644 (file)
@@ -19,13 +19,13 @@ public class IDateField extends FlowPanel implements Paintable {
        \r
        protected boolean immediate;\r
        \r
-       protected static int RESOLUTION_YEAR = 0;\r
-       protected static int RESOLUTION_MONTH = 1;\r
-       protected static int RESOLUTION_DAY = 2;\r
-       protected static int RESOLUTION_HOUR = 3;\r
-       protected static int RESOLUTION_MIN = 4;\r
-       protected static int RESOLUTION_SEC = 5;\r
-       protected static int RESOLUTION_MSEC = 6;\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
        protected int currentResolution = RESOLUTION_YEAR;\r
        \r
        protected String currentLocale;\r
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java
new file mode 100644 (file)
index 0000000..150f96c
--- /dev/null
@@ -0,0 +1,22 @@
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+\r
+public class IDateFieldCalendar extends IDateField {\r
+       \r
+       private ICalendarPanel date;\r
+       \r
+       public IDateFieldCalendar() {\r
+               super();\r
+               setStyleName(CLASSNAME+"-calendar");\r
+               date = new ICalendarPanel(this);\r
+               add(date);\r
+       }\r
+       \r
+       public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+               super.updateFromUIDL(uidl, client);\r
+               date.updateCalendar();\r
+       }\r
+\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
new file mode 100644 (file)
index 0000000..6119e8f
--- /dev/null
@@ -0,0 +1,163 @@
+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
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java
new file mode 100644 (file)
index 0000000..0559cb1
--- /dev/null
@@ -0,0 +1,102 @@
+package com.itmill.toolkit.terminal.gwt.client.ui.calendar;\r
+\r
+import java.util.Date;\r
+\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+\r
+public class ICalendarEntry {\r
+    private Date start;\r
+    private Date end;\r
+    private String title;\r
+    private boolean notime;\r
+\r
+    public ICalendarEntry(Date start, Date end, String title, boolean notime) {\r
+       if (notime) {\r
+           Date d = new Date(start.getTime());\r
+           d.setSeconds(0);\r
+           d.setMinutes(0);\r
+           this.start = d;\r
+           if (end != null) {\r
+               d = new Date(end.getTime());\r
+               d.setSeconds(0);\r
+               d.setMinutes(0);\r
+               this.end = d;\r
+           } else {\r
+               end = start;\r
+           }\r
+       } else {\r
+           this.start = start;\r
+           this.end = end;\r
+       }\r
+       this.title = title;\r
+       this.notime = notime;\r
+    }\r
+\r
+    public ICalendarEntry(Date start, Date end, String title) {\r
+       this(start, end, title, false);\r
+    }\r
+\r
+    public Date getStart() {\r
+       return start;\r
+    }\r
+\r
+    public void setStart(Date start) {\r
+       this.start = start;\r
+    }\r
+\r
+    public Date getEnd() {\r
+       return end;\r
+    }\r
+\r
+    public void setEnd(Date end) {\r
+       this.end = end;\r
+    }\r
+\r
+    public String getTitle() {\r
+       return title;\r
+    }\r
+\r
+    public void setTitle(String title) {\r
+       this.title = title;\r
+    }\r
+\r
+    public boolean isNotime() {\r
+       return notime;\r
+    }\r
+\r
+    public void setNotime(boolean notime) {\r
+       this.notime = notime;\r
+    }\r
+\r
+    public String getStringForDate(Date d) {\r
+       // TODO format from DateTimeService\r
+       String s = "";\r
+       if (!notime) {\r
+           if (!DateTimeService.isSameDay(d, start)) {\r
+               s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)\r
+                       + "." + start.getDate() + " ";\r
+           }\r
+           int i = start.getHours();\r
+           s += (i < 10 ? "0" : "") + i;\r
+           s += ":";\r
+           i = start.getMinutes();\r
+           s += (i < 10 ? "0" : "") + i;\r
+           if (!start.equals(end)) {\r
+                   s += " - ";\r
+                   if (!DateTimeService.isSameDay(start, end)) {\r
+                       s += (end.getYear() + 1900) + "." + (end.getMonth() + 1) + "."\r
+                               + end.getDate() + " ";\r
+                   }\r
+                   i = end.getHours();\r
+                   s += (i < 10 ? "0" : "") + i;\r
+                   s += ":";\r
+                   i = end.getMinutes();\r
+                   s += (i < 10 ? "0" : "") + i;\r
+           }\r
+           s += " ";\r
+       }\r
+       s += title;\r
+       return s;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/src/com/itmill/toolkit/ui/CalendarField.java b/src/com/itmill/toolkit/ui/CalendarField.java
new file mode 100644 (file)
index 0000000..0650651
--- /dev/null
@@ -0,0 +1,285 @@
+package com.itmill.toolkit.ui;\r
+\r
+import java.util.Collection;\r
+import java.util.Date;\r
+import java.util.Iterator;\r
+\r
+import com.itmill.toolkit.data.Container;\r
+import com.itmill.toolkit.data.Item;\r
+import com.itmill.toolkit.data.Property;\r
+import com.itmill.toolkit.terminal.PaintException;\r
+import com.itmill.toolkit.terminal.PaintTarget;\r
+\r
+// TODO use Calendar\r
+// TODO lazyLoading\r
+// TODO check date limit when updating variables\r
+// TODO Allow item selection\r
+public class CalendarField extends DateField implements Container.Viewer {\r
+\r
+    private Date minDate;\r
+    private Date maxDate;\r
+\r
+    private Container dataSource;\r
+    private Object itemStartPropertyId;\r
+    private Object itemEndPropertyId;\r
+    private Object itemTitlePropertyId;\r
+    private Object itemNotimePropertyId;\r
+\r
+    public CalendarField() {\r
+       super();\r
+       init();\r
+    }\r
+\r
+    public CalendarField(Property dataSource) throws IllegalArgumentException {\r
+       super(dataSource);\r
+       init();\r
+    }\r
+\r
+    public CalendarField(String caption, Date value) {\r
+       super(caption, value);\r
+       init();\r
+    }\r
+\r
+    public CalendarField(String caption, Property dataSource) {\r
+       super(caption, dataSource);\r
+       init();\r
+    }\r
+\r
+    public CalendarField(String caption) {\r
+       super(caption);\r
+       init();\r
+    }\r
+\r
+    /*\r
+     * Gets the components UIDL tag string. Don't add a JavaDoc comment here, we\r
+     * use the default documentation from implemented interface.\r
+     */\r
+    public String getTag() {\r
+       return "calendarfield";\r
+    }\r
+\r
+    public void init() {\r
+       super.setResolution(RESOLUTION_HOUR);\r
+\r
+    }\r
+\r
+    /**\r
+     * Sets the resolution of the CalendarField. Only RESOLUTION_DAY and\r
+     * RESOLUTION_HOUR are supported.\r
+     * \r
+     * @param resolution\r
+     *                the resolution to set.\r
+     * @see com.itmill.toolkit.ui.DateField#setResolution(int)\r
+     */\r
+    public void setResolution(int resolution) {\r
+       if (resolution != RESOLUTION_DAY && resolution != RESOLUTION_HOUR) {\r
+           throw new IllegalArgumentException();\r
+       }\r
+       super.setResolution(resolution);\r
+    }\r
+\r
+    public void setMinimumDate(Date date) {\r
+       this.minDate = date;\r
+       requestRepaint();\r
+    }\r
+\r
+    public Date getMinimumDate() {\r
+       return minDate;\r
+    }\r
+\r
+    public void setMaximumDate(Date date) {\r
+       this.maxDate = date;\r
+       requestRepaint();\r
+    }\r
+\r
+    public Date getMaximumDate() {\r
+       return maxDate;\r
+    }\r
+\r
+    public Container getContainerDataSource() {\r
+       return this.dataSource;\r
+    }\r
+\r
+    public void setContainerDataSource(Container newDataSource) {\r
+       if (checkDataSource(newDataSource)) {\r
+           this.dataSource = newDataSource;\r
+       } else {\r
+           // TODO error message\r
+           throw new IllegalArgumentException();\r
+       }\r
+       requestRepaint();\r
+    }\r
+\r
+    private boolean checkDataSource(Container dataSource) {\r
+       /*\r
+        * if (!(dataSource instanceof Container.Sortable)) { // we really want\r
+        * the data source to be sortable return false; }\r
+        */\r
+       // Check old propertyIds\r
+       if (this.itemEndPropertyId != null) {\r
+           Class c = dataSource.getType(this.itemEndPropertyId);\r
+           if (!Date.class.isAssignableFrom(c)) {\r
+               this.itemEndPropertyId = null;\r
+           }\r
+       }\r
+       if (this.itemNotimePropertyId != null) {\r
+           Class c = dataSource.getType(this.itemNotimePropertyId);\r
+           if (!Boolean.class.isAssignableFrom(c)) {\r
+               this.itemNotimePropertyId = null;\r
+           }\r
+       }\r
+       if (this.itemStartPropertyId != null) {\r
+           Class c = dataSource.getType(this.itemStartPropertyId);\r
+           if (Date.class.isAssignableFrom(c)) {\r
+               // All we _really_ need is one date\r
+               return true;\r
+           } else {\r
+               this.itemStartPropertyId = null;\r
+           }\r
+       }\r
+       // We need at least one Date\r
+       Collection ids = dataSource.getContainerPropertyIds();\r
+       for (Iterator it = ids.iterator(); it.hasNext();) {\r
+           Object id = it.next();\r
+           Class c = dataSource.getType(id);\r
+           if (Date.class.isAssignableFrom(c)) {\r
+               this.itemStartPropertyId = id;\r
+               return true;\r
+           }\r
+       }\r
+\r
+       return false;\r
+    }\r
+\r
+    public Object getItemStartPropertyId() {\r
+       return itemStartPropertyId;\r
+    }\r
+\r
+    public void setItemStartPropertyId(Object propertyId) {\r
+       // TODO nullcheck for property id\r
+       if (this.dataSource != null\r
+               && !Date.class.isAssignableFrom(dataSource.getType(propertyId))) {\r
+           // TODO error message\r
+           throw new IllegalArgumentException();\r
+       }\r
+       this.itemStartPropertyId = propertyId;\r
+    }\r
+\r
+    public Object getItemEndPropertyId() {\r
+       return itemEndPropertyId;\r
+    }\r
+\r
+    public void setItemEndPropertyId(Object propertyId) {\r
+       // TODO nullcheck for property id\r
+       if (this.dataSource != null\r
+               && !Date.class.isAssignableFrom(dataSource.getType(propertyId))) {\r
+           // TODO error message\r
+           throw new IllegalArgumentException();\r
+       }\r
+       this.itemEndPropertyId = propertyId;\r
+    }\r
+\r
+    public Object getItemTitlePropertyId() {\r
+       return itemTitlePropertyId;\r
+    }\r
+\r
+    public void setItemTitlePropertyId(Object propertyId) {\r
+       this.itemTitlePropertyId = propertyId;\r
+    }\r
+\r
+    public Object getitemNotimePropertyId() {\r
+       return itemNotimePropertyId;\r
+    }\r
+\r
+    public void setItemNotimePropertyId(Object propertyId) {\r
+       // TODO nullcheck for property id\r
+       if (this.dataSource != null\r
+               && !Boolean.class.isAssignableFrom(dataSource.getType(propertyId))) {\r
+           // TODO error message\r
+           throw new IllegalArgumentException();\r
+       }\r
+       this.itemNotimePropertyId = propertyId;\r
+    }\r
+\r
+    /**\r
+     * Paints the content of this component.\r
+     * \r
+     * @param target\r
+     *                the Paint Event.\r
+     * @throws PaintException\r
+     *                 if the paint operation failed.\r
+     */\r
+    public void paintContent(PaintTarget target) throws PaintException {\r
+       super.paintContent(target);\r
+\r
+       if (this.minDate != null) {\r
+           target.addAttribute("min", String.valueOf(this.minDate.getTime()));\r
+       }\r
+       if (this.maxDate != null) {\r
+           target.addAttribute("max", String.valueOf(this.maxDate.getTime()));\r
+       }\r
+\r
+       if (this.dataSource != null) {\r
+           target.startTag("items");\r
+\r
+           // send one month now, the rest via lazyloading\r
+           int month = new Date().getMonth();\r
+           Object value = getValue();\r
+           if (value != null && value instanceof Date) {\r
+               month = ((Date) value).getMonth();\r
+           }\r
+\r
+           for (Iterator it = this.dataSource.getItemIds().iterator(); it\r
+                   .hasNext();) {\r
+               Object itemId = it.next();\r
+               Item item = (Item) this.dataSource.getItem(itemId);\r
+               Property p = item.getItemProperty(this.itemStartPropertyId);\r
+               Date start = (Date) p.getValue();\r
+               Date end = start; // assume same day\r
+               if (this.itemEndPropertyId != null) {\r
+                   p = item.getItemProperty(this.itemEndPropertyId);\r
+                   end = (Date) p.getValue();\r
+                   if (end == null) {\r
+                       end = start;\r
+                   } else if (end.before(start)) {\r
+                       Date tmp = start;\r
+                       start = end;\r
+                       end = tmp;\r
+                   }\r
+               }\r
+\r
+               if (start != null) {\r
+                   if ((start.getMonth() <= month || end.getMonth() >= month)) {\r
+                       target.startTag("item");\r
+                       // TODO different id!\r
+                       target.addAttribute("id", itemId.hashCode());\r
+                       target.addAttribute("start", ""+start.getTime());\r
+                       if (end != start) {\r
+                           target.addAttribute("end", ""+end.getTime());\r
+                       }\r
+                       if (this.itemTitlePropertyId != null) {\r
+                           p = item.getItemProperty(this.itemTitlePropertyId);\r
+                           Object val = p.getValue();\r
+                           if (val != null) {\r
+                               target.addAttribute("title", val.toString());\r
+                           }\r
+                       }\r
+                       if (this.itemNotimePropertyId != null) {\r
+                           p = item\r
+                                   .getItemProperty(this.itemNotimePropertyId);\r
+                           Object val = p.getValue();\r
+                           if (val != null) {\r
+                               target.addAttribute("notime", ((Boolean) val)\r
+                                       .booleanValue());\r
+                           }\r
+                       }\r
+\r
+                       target.endTag("item");\r
+                   }\r
+               }\r
+           }\r
+\r
+           target.endTag("items");\r
+       }\r
+    }\r
+}\r