DateTimeService for all components, provides localised month and daynames etc.
New IDateField implementation: one superclass, which different proper implementations extend.
Partially working version of "calendar"-style for DateField.
svn changeset:1816/svn branch:trunk
private HashMap paintables = new HashMap();
private WidgetFactory widgetFactory = new DefaultWidgetFactory();
+
+ private LocaleService locale;
/**
* This is the entry point method.
String key = (String) i.next();
resourcesMap.put(key, ((JSONString)resources.get(key)).stringValue());
}
+
+ // Store locale data
+ if(((JSONObject)json).containsKey("locales")) {
+ JSONArray l = (JSONArray) ((JSONObject) json).get("locales");
+ for(int i=0; i < l.size(); i++)
+ LocaleService.addLocale((JSONObject) l.get(i));
+ }
// Process changes
JSONArray changes = (JSONArray) ((JSONObject) json).get("changes");
public String getResource(String name) {
return (String) resourcesMap.get(name);
}
-
- public JSONObject getLocale(String locale) {
- // TODO should perform synchronous call to server to fetch
- // locale specific strings
- // (GWT only supports synchrounous requests from v. 1.4)
- console.log("Loading a new locale: " + locale);
- rb = new RequestBuilder(RequestBuilder.POST, appUri
- + "/locale/?requestId=" + (Math.random()) + "&" + locale);
- /*try {
- rb.sendRequest(locale, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- console.error("Got error");
- }
-
- public void onResponseReceived(Request request,
- Response response) {
- handleReceivedJSONMessage(response);
- }
-
- });
-
- } catch (RequestException e) {
- console.error(e.getMessage());
- }*/
- // TODO
- return null;
- }
}
package com.itmill.toolkit.terminal.gwt.client;\r
\r
+import java.util.Date;\r
+\r
/**\r
- * This class provides date/time parsing services to all components.\r
+ * This class provides date/time parsing services to \r
+ * all components on the client side.\r
* \r
- * @author Jouni Koivuviita\r
+ * @author IT Mill Ltd.\r
*\r
*/\r
public class DateTimeService {\r
\r
- private LocaleService localeService;\r
- \r
private String currentLocale;\r
\r
- public DateTimeService(Client client) {\r
- localeService = new LocaleService(client);\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
- public DateTimeService(Client client, String locale) {\r
- this(client);\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) {\r
- currentLocale = locale;\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) throws Exception {\r
- if(currentLocale != null)\r
- return localeService.getMonthNames(currentLocale)[month];\r
- else throw new Exception("No locale specified.");\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 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 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 String getShortMonth(int month) throws Exception {\r
- if(currentLocale != null)\r
- return localeService.getShortMonthNames(currentLocale)[month];\r
- else throw new Exception("No locale specified.");\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
}\r
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.IDateField;
import com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded;
import com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout;
import com.itmill.toolkit.terminal.gwt.client.ui.IHorizontalLayout;
import com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup;
import com.itmill.toolkit.terminal.gwt.client.ui.IPanel;
import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField;
+import com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar;
import com.itmill.toolkit.terminal.gwt.client.ui.ISelect;
import com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging;
import com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet;
import com.itmill.toolkit.terminal.gwt.client.ui.ITextArea;
import com.itmill.toolkit.terminal.gwt.client.ui.ITextField;
+import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate;
import com.itmill.toolkit.terminal.gwt.client.ui.ITree;
import com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect;
import com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent;
}
return new ITablePaging();
}
- if("datefield".equals(tag))
- return new IDateField();
+ if("datefield".equals(tag)) {
+ if(uidl.hasAttribute("style"))
+ if("calendar".equals(uidl.getStringAttribute("style")))
+ return new ICalendar();
+ else if("text".equals(uidl.getStringAttribute("style")))
+ return new ITextualDate();
+ return new IPopupCalendar();
+ }
return new IUnknownComponent();
}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;\r
+\r
+public class LocaleNotLoadedException extends Exception {\r
+ \r
+ /**\r
+ * Serial generated by Eclipse.\r
+ */\r
+ private static final long serialVersionUID = 2005227056545210838L;\r
+\r
+ public LocaleNotLoadedException(String locale) {\r
+ super(locale);\r
+ }\r
+}\r
\r
import java.util.HashMap;\r
import java.util.Map;\r
+import java.util.Set;\r
\r
+import com.google.gwt.json.client.JSONArray;\r
+import com.google.gwt.json.client.JSONBoolean;\r
+import com.google.gwt.json.client.JSONNumber;\r
import com.google.gwt.json.client.JSONObject;\r
+import com.google.gwt.json.client.JSONString;\r
\r
/**\r
* Date / time etc. localisation service for all widgets.\r
* Should cache all loaded locales as JSON strings.\r
* \r
- * @author Jouni Koivuviita\r
+ * @author IT Mill Ltd.\r
*\r
*/\r
public class LocaleService {\r
\r
- private Client client;\r
+ private static Map cache = new HashMap();\r
+ private static String defaultLocale;\r
+\r
+ public static void addLocale(JSONObject json) {\r
+ String key = ((JSONString)json.get("name")).stringValue();\r
+ if(cache.containsKey(key))\r
+ cache.remove(key);\r
+ cache.put(key, json);\r
+ if(cache.size()==1)\r
+ setDefaultLocale(key);\r
+ }\r
+\r
+ public static void setDefaultLocale(String locale) {\r
+ defaultLocale = locale;\r
+ }\r
\r
- private Map cache = new HashMap();\r
+ public static String getDefaultLocale() {\r
+ return defaultLocale;\r
+ }\r
+ \r
+ public static Set getAvailableLocales() {\r
+ return cache.keySet();\r
+ }\r
+ \r
+ public static String[] getMonthNames(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONArray mn = (JSONArray) l.get("mn");\r
+ String[] temp = new String[12];\r
+ temp[0] = ((JSONString)mn.get(0)).stringValue();\r
+ temp[1] = ((JSONString)mn.get(1)).stringValue();\r
+ temp[2] = ((JSONString)mn.get(2)).stringValue();\r
+ temp[3] = ((JSONString)mn.get(3)).stringValue();\r
+ temp[4] = ((JSONString)mn.get(4)).stringValue();\r
+ temp[5] = ((JSONString)mn.get(5)).stringValue();\r
+ temp[6] = ((JSONString)mn.get(6)).stringValue();\r
+ temp[7] = ((JSONString)mn.get(7)).stringValue();\r
+ temp[8] = ((JSONString)mn.get(8)).stringValue();\r
+ temp[9] = ((JSONString)mn.get(9)).stringValue();\r
+ temp[10] = ((JSONString)mn.get(10)).stringValue();\r
+ temp[11] = ((JSONString)mn.get(11)).stringValue(); \r
+ return temp;\r
+ } else throw new LocaleNotLoadedException(locale);\r
+ }\r
\r
- public LocaleService(Client client){\r
- this.client = client;\r
+ public static String[] getShortMonthNames(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONArray smn = (JSONArray) l.get("smn");\r
+ String[] temp = new String[12];\r
+ temp[0] = ((JSONString)smn.get(0)).stringValue();\r
+ temp[1] = ((JSONString)smn.get(1)).stringValue();\r
+ temp[2] = ((JSONString)smn.get(2)).stringValue();\r
+ temp[3] = ((JSONString)smn.get(3)).stringValue();\r
+ temp[4] = ((JSONString)smn.get(4)).stringValue();\r
+ temp[5] = ((JSONString)smn.get(5)).stringValue();\r
+ temp[6] = ((JSONString)smn.get(6)).stringValue();\r
+ temp[7] = ((JSONString)smn.get(7)).stringValue();\r
+ temp[8] = ((JSONString)smn.get(8)).stringValue();\r
+ temp[9] = ((JSONString)smn.get(9)).stringValue();\r
+ temp[10] = ((JSONString)smn.get(10)).stringValue();\r
+ temp[11] = ((JSONString)smn.get(11)).stringValue(); \r
+ return temp;\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- private void loadLocale(String locale) {\r
- JSONObject resp = client.getLocale(locale);\r
- cache.put(locale, resp);\r
+ public static String[] getDayNames(String locale) throws LocaleNotLoadedException{\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONArray dn = (JSONArray) l.get("dn");\r
+ String[] temp = new String[7];\r
+ temp[0] = ((JSONString)dn.get(0)).stringValue();\r
+ temp[1] = ((JSONString)dn.get(1)).stringValue();\r
+ temp[2] = ((JSONString)dn.get(2)).stringValue();\r
+ temp[3] = ((JSONString)dn.get(3)).stringValue();\r
+ temp[4] = ((JSONString)dn.get(4)).stringValue();\r
+ temp[5] = ((JSONString)dn.get(5)).stringValue();\r
+ temp[6] = ((JSONString)dn.get(6)).stringValue(); \r
+ return temp;\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- public String[] getMonthNames(String locale) {\r
- // TODO\r
- //if(cache.containsKey(locale))\r
- //else loadLocale(locale);\r
- String[] temp = new String[12];\r
- temp[0] = "tammi"; temp[1] = "helmi"; temp[2] = "maalis"; temp[3] = "huhti";\r
- temp[4] = "touko"; temp[5] = "kesä"; temp[6] = "heinä"; temp[7] = "elo";\r
- temp[8] = "syys"; temp[9] = "loka"; temp[10] = "marras"; temp[11] = "joulu";\r
- return temp;\r
+ public static String[] getShortDayNames(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONArray sdn = (JSONArray) l.get("sdn");\r
+ String[] temp = new String[7];\r
+ temp[0] = ((JSONString)sdn.get(0)).stringValue();\r
+ temp[1] = ((JSONString)sdn.get(1)).stringValue();\r
+ temp[2] = ((JSONString)sdn.get(2)).stringValue();\r
+ temp[3] = ((JSONString)sdn.get(3)).stringValue();\r
+ temp[4] = ((JSONString)sdn.get(4)).stringValue();\r
+ temp[5] = ((JSONString)sdn.get(5)).stringValue();\r
+ temp[6] = ((JSONString)sdn.get(6)).stringValue();\r
+ return temp;\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- public String[] getShortMonthNames(String locale) {\r
- // TODO\r
- //if(cache.containsKey(locale))\r
- //else loadLocale(locale);\r
- String[] temp = new String[12];\r
- temp[0] = "tam"; temp[1] = "hel"; temp[2] = "maa"; temp[3] = "huh";\r
- temp[4] = "tou"; temp[5] = "kes"; temp[6] = "hei"; temp[7] = "elo";\r
- temp[8] = "syy"; temp[9] = "lok"; temp[10] = "mar"; temp[11] = "jou";\r
- return temp;\r
+ public static int getFirstDayOfWeek(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONNumber fdow = (JSONNumber) l.get("fdow");\r
+ return (int) fdow.getValue();\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- public String[] getDayNames(String locale) {\r
- // TODO\r
- //if(cache.containsKey(locale))\r
- //else loadLocale(locale);\r
- String[] temp = new String[7];\r
- temp[1] = "maanatai"; temp[2] = "tiistai"; temp[3] = "keskiviikko";\r
- temp[4] = "torstai"; temp[5] = "perjantai"; temp[6] = "lauantai";\r
- temp[0] = "sunnuntai";\r
- return temp;\r
+ public static String getDateFormat(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONString df = (JSONString) l.get("df");\r
+ return df.stringValue();\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- public String[] getShortDayNames(String locale) {\r
- // TODO\r
- //if(cache.containsKey(locale))\r
- //else loadLocale(locale);\r
- String[] temp = new String[7];\r
- temp[1] = "ma"; temp[2] = "ti"; temp[3] = "ke";\r
- temp[4] = "to"; temp[5] = "pe"; temp[6] = "la";\r
- temp[0] = "su";\r
- return temp;\r
+ public static boolean isTwelveHourClock(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONBoolean thc = (JSONBoolean) l.get("thc");\r
+ return thc.booleanValue();\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
- public int getFirstDayOfWeek(String locale) {\r
- // TODO\r
- //if(cache.containsKey(locale))\r
- //else loadLocale(locale);\r
- return 1;\r
+ public static String getClockDelimiter(String locale) throws LocaleNotLoadedException {\r
+ if(cache.containsKey(locale)) {\r
+ JSONObject l = (JSONObject) cache.get(locale);\r
+ JSONString hmd = (JSONString) l.get("hmd");\r
+ return hmd.stringValue();\r
+ } else throw new LocaleNotLoadedException(locale);\r
}\r
\r
}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.itmill.toolkit.terminal.gwt.client.Client;\r
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+\r
+public class ICalendar extends IDateField {\r
+ \r
+ private ICalendarPanel body;\r
+ \r
+ private String locale;\r
+ \r
+ public ICalendar() {\r
+ super();\r
+ body = new ICalendarPanel(this);\r
+ container.add(body);\r
+ }\r
+ \r
+ public void updateFromUIDL(UIDL uidl, Client client) {\r
+ super.updateFromUIDL(uidl, client);\r
+ boolean needsRedraw = (locale == null || !locale.equals(currentLocale));\r
+ body.updateCalendar(needsRedraw);\r
+ locale = currentLocale;\r
+ }\r
+\r
+}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import java.util.Date;\r
+\r
+import com.google.gwt.user.client.ui.ClickListener;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+\r
+public class ICalendarPanel extends FlexTable implements ClickListener {\r
+ \r
+ private IDateField datefield;\r
+ \r
+ private IButton prevYear;\r
+ private IButton nextYear;\r
+ private IButton prevMonth;\r
+ private IButton nextMonth;\r
+ \r
+ public ICalendarPanel(IDateField parent) {\r
+ datefield = parent;\r
+ // Force table size\r
+ setText(0, 0, "");\r
+ setText(7, 6, "");\r
+ buildCalendar(true);\r
+ }\r
+ \r
+ public void buildCalendar(boolean forceRedraw) {\r
+ buildCalendarHeader(forceRedraw);\r
+ buildCalendarBody();\r
+ }\r
+ \r
+ private void clearCalendarBody() {\r
+ for (int row=2; row < 8; row++){\r
+ for (int col=0; col < 7; col++){\r
+ setText(row, col, "");\r
+ }\r
+ }\r
+ }\r
+ \r
+ private void buildCalendarHeader(boolean forceRedraw) {\r
+ if(forceRedraw) {\r
+ prevYear = new IButton(); prevYear.setText("«");\r
+ nextYear = new IButton(); nextYear.setText("»");\r
+ prevMonth = new IButton(); prevMonth.setText("‹");\r
+ nextMonth = new IButton(); nextMonth.setText("›");\r
+ prevYear.addClickListener(this); nextYear.addClickListener(this);\r
+ prevMonth.addClickListener(this); nextMonth.addClickListener(this);setWidget(0, 0, prevYear);\r
+ \r
+ setWidget(0, 1, prevMonth);\r
+ setWidget(0, 3, nextMonth);\r
+ setWidget(0, 4, nextYear);\r
+ getFlexCellFormatter().setColSpan(0, 2, 3);\r
+ \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
+ setText(1,i, datefield.dts.getShortDay(day));\r
+ }\r
+ }\r
+ \r
+ String monthName = datefield.dts.getMonth(datefield.date.getMonth());\r
+ int year = datefield.date.getYear()+1900;\r
+ setText(0, 2, monthName + " " + year);\r
+ }\r
+ \r
+ private void buildCalendarBody() {\r
+ Date date = datefield.date;\r
+ int startWeekDay = datefield.dts.getStartWeekDay(date);\r
+ int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
+ int dayCount = 0;\r
+ for (int row = 2; row < 8; row++){\r
+ for (int col = 0; col < 7; col++){\r
+ if(row == 2 && col < startWeekDay){\r
+ setText(row, col, "");\r
+ //cellValues[row][col] = ""; \r
+ } else {\r
+ if(numDays > dayCount){\r
+ int selectedDate = ++dayCount;\r
+ //cellValues[row][col] = selectedDate +"";\r
+ //if(true == isSelectedDate(date, selectedDate)){\r
+ //setHTML(row, col, "<font class='currentDate'>" + selectedDate+"<font>");\r
+ //}else{\r
+ setText(row, col, ""+selectedDate);\r
+ //}\r
+ } else {\r
+ setText(row, col, "");\r
+ //cellValues[row][col] = ""; \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * \r
+ * @param forceRedraw Build all from scratch, in case of e.g. locale changes\r
+ */\r
+ public void updateCalendar(boolean forceRedraw) {\r
+ clearCalendarBody();\r
+ buildCalendar(forceRedraw);\r
+ }\r
+ \r
+ public void onClick(Widget sender) {\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(false);\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(false);\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(false);\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(false);\r
+ }\r
+ }\r
+}\r
\r
import java.util.Date;\r
\r
-import com.google.gwt.user.client.ui.ChangeListener;\r
import com.google.gwt.user.client.ui.Composite;\r
import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.google.gwt.user.client.ui.ListBox;\r
-import com.google.gwt.user.client.ui.Widget;\r
import com.itmill.toolkit.terminal.gwt.client.Client;\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+import com.itmill.toolkit.terminal.gwt.client.LocaleNotLoadedException;\r
import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
\r
-public class IDateField extends Composite implements Paintable, ChangeListener {\r
- \r
- \r
- /*\r
- * This implementation is old already.\r
- * We should use the DateTimeService class (which is a draft) to get \r
- * locale specific strings and use them to build the datefield \r
- * and its different styles (with inheritance of course).\r
- * \r
- * Drafting usage patterns:\r
- * \r
- * DateTimeService dts = new DateTimeService(client, "fi_FI");\r
- * String month = dts.getMonth(0); // Returns "January"\r
- * String day = dts.getDay(19); // Returns e.g. "sunday"\r
- * String dateformat = dts.getDateFormat(); // Returns something like MM_/_DD_/_YYYY\r
- * String timeformat = dts.getTimeFormat(); // Returns something like HH_:_MM\r
- * String date = dts.parseDate(new Date()); // Returns e.g. 6/19/2007 14:32\r
- * String date = dts.parseFullDate(new Date()); // Returns e.g. Tuesday 6th June 2007 14:32\r
- */\r
- \r
- \r
+public class IDateField extends Composite implements Paintable {\r
+\r
public static final String CLASSNAME = "i-datefield";\r
\r
String id;\r
\r
Client client;\r
+\r
+ protected FlowPanel container;\r
\r
- private boolean immediate;\r
+ protected boolean immediate;\r
\r
- private FlowPanel container;\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
+ protected int currentResolution = RESOLUTION_YEAR;\r
\r
- private ListBox year;\r
+ protected String currentLocale;\r
\r
- private static int RESOLUTION_YEAR = 0;\r
- private static int RESOLUTION_MONTH = 1;\r
- private static int RESOLUTION_DAY = 2;\r
- private static int RESOLUTION_HOUR = 3;\r
- private static int RESOLUTION_MIN = 4;\r
- private static int RESOLUTION_SEC = 5;\r
- private static int RESOLUTION_MSEC = 6;\r
-\r
- private int currentResolution = RESOLUTION_YEAR;\r
+ protected Date date;\r
+ \r
+ protected DateTimeService dts;\r
\r
public IDateField() {\r
container = new FlowPanel();\r
initWidget(container);\r
+ date = new Date();\r
+ dts = new DateTimeService();\r
}\r
\r
public void updateFromUIDL(UIDL uidl, Client client) {\r
id = uidl.getId();\r
immediate = uidl.getBooleanAttribute("immediate");\r
\r
+ if(uidl.hasAttribute("locale")) {\r
+ String locale = uidl.getStringAttribute("locale");\r
+ try {\r
+ dts.setLocale(locale);\r
+ currentLocale = locale;\r
+ } catch (LocaleNotLoadedException e) {\r
+ dts = new DateTimeService();\r
+ currentLocale = dts.getLocale();\r
+ System.out.println("Tried to use an unloaded locale \"" + locale + "\". Using default locale (" + currentLocale + ").");\r
+ }\r
+ }\r
+ \r
int newResolution = RESOLUTION_YEAR;\r
if(uidl.hasAttribute("month"))\r
newResolution = RESOLUTION_MONTH;\r
if(currentResolution > newResolution)\r
container.clear();\r
\r
- if(uidl.hasVariable("year")) {\r
- int selectedYear = uidl.getIntVariable("year");\r
- int y = container.getWidgetIndex(year);\r
- if(y > -1) {\r
- year = (ListBox) container.getWidget(y);\r
- // Deselect old value\r
- year.setItemSelected(year.getSelectedIndex(), false);\r
- // and select new\r
- for(int i=0; i < year.getItemCount(); i++)\r
- if(year.getValue(i).equals(""+selectedYear)) {\r
- year.setSelectedIndex(i);\r
- break;\r
- }\r
- } else {\r
- year = new ListBox();\r
- year.setStyleName(ISelect.CLASSNAME);\r
- int today = 1900 + (new Date()).getYear();\r
- for(int i=1970; i<today+400; i++) {\r
- year.addItem(""+i, ""+i);\r
- if(i == selectedYear)\r
- year.setSelectedIndex(year.getItemCount()-1);\r
- }\r
- year.addChangeListener(this);\r
- container.add(year);\r
- }\r
- }\r
+ currentResolution = newResolution;\r
\r
+ int year = uidl.getIntAttribute("year");\r
+ int month = uidl.getIntAttribute("month");\r
+ int day = uidl.getIntAttribute("day");\r
+ int hour = uidl.getIntAttribute("hour");\r
+ int min = uidl.getIntAttribute("min");\r
+ int sec = uidl.getIntAttribute("sec");\r
+ int msec = uidl.getIntAttribute("msec");\r
\r
- currentResolution = newResolution;\r
- }\r
-\r
- public void onChange(Widget sender) {\r
- if(sender == year && client != null)\r
- client.updateVariable(id, "year", year.getValue(year.getSelectedIndex()), immediate);\r
+ date = new Date((long) buildDate(year, month, day, hour, min, sec, msec));\r
\r
}\r
+ \r
+ /*\r
+ * We need this redundant native function because \r
+ * GWT hasn't implemented setMilliseconds to the Date class.\r
+ */\r
+ private native double buildDate(int y, int m, int d, int h, int mi, int s, int ms) /*-{\r
+ try {\r
+ var date = new Date();\r
+ if(y) date.setFullYear(y-1900);\r
+ if(m) date.setMonth(m-1);\r
+ if(d) date.setDate(d);\r
+ if(h) date.setHour(h);\r
+ if(mi) date.setMinutes(mi);\r
+ if(s) date.setSeconds(s);\r
+ if(ms) date.setMilliseconds(ms);\r
+ return date.getTime();\r
+ } catch (e) {\r
+ console.error(e);\r
+ }\r
+ }-*/;\r
\r
}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+public class IPopupCalendar extends IDateField {\r
+\r
+}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import java.util.Date;\r
+\r
+import com.google.gwt.user.client.ui.ChangeListener;\r
+import com.google.gwt.user.client.ui.ListBox;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.itmill.toolkit.terminal.gwt.client.Client;\r
+import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+\r
+public class ITextualDate extends IDateField implements Paintable, ChangeListener {\r
+ \r
+ private ListBox year;\r
+ \r
+ private ListBox month;\r
+ \r
+ private ListBox day;\r
+ \r
+ public ITextualDate() {\r
+ \r
+ }\r
+ \r
+ public void updateFromUIDL(UIDL uidl, Client client) {\r
+ super.updateFromUIDL(uidl, client);\r
+ \r
+ if(uidl.hasVariable("year")) {\r
+ int selectedYear = uidl.getIntVariable("year");\r
+ int y = container.getWidgetIndex(year);\r
+ if(y > -1 || !currentLocale.equals(uidl.getStringAttribute("locale"))) {\r
+ year = (ListBox) container.getWidget(y);\r
+ // Deselect old value\r
+ year.setItemSelected(year.getSelectedIndex(), false);\r
+ // and select new\r
+ for(int i=0; i < year.getItemCount(); i++)\r
+ if(year.getValue(i).equals(""+selectedYear)) {\r
+ year.setSelectedIndex(i);\r
+ break;\r
+ }\r
+ } else {\r
+ year = new ListBox();\r
+ year.setStyleName(ISelect.CLASSNAME);\r
+ int today = 1900 + (new Date()).getYear();\r
+ for(int i=1970; i<today+400; i++) {\r
+ year.addItem(""+i, ""+i);\r
+ if(i == selectedYear)\r
+ year.setSelectedIndex(year.getItemCount()-1);\r
+ }\r
+ year.addChangeListener(this);\r
+ container.add(year);\r
+ }\r
+ }\r
+ if(uidl.hasVariable("month")) {\r
+ int selectedMonth = uidl.getIntVariable("month");\r
+ int y = container.getWidgetIndex(month);\r
+ if(y > -1) {\r
+ month = (ListBox) container.getWidget(y);\r
+ // Deselect old value\r
+ month.setItemSelected(month.getSelectedIndex(), false);\r
+ // and select new\r
+ for(int i=0; i < month.getItemCount(); i++)\r
+ if(month.getValue(i).equals(""+selectedMonth)) {\r
+ month.setSelectedIndex(i);\r
+ break;\r
+ }\r
+ } else {\r
+ month = new ListBox();\r
+ month.setStyleName(ISelect.CLASSNAME);\r
+ int today = (new Date()).getMonth();\r
+ for(int i=0; i<12; i++) {\r
+ month.addItem(""+(i+1), ""+i);\r
+ if(i == selectedMonth)\r
+ month.setSelectedIndex(month.getItemCount()-1);\r
+ }\r
+ month.addChangeListener(this);\r
+ container.add(month);\r
+ }\r
+ }\r
+ if(uidl.hasVariable("day")) {\r
+ int selectedMonth = uidl.getIntVariable("day");\r
+ int y = container.getWidgetIndex(day);\r
+ if(y > -1) {\r
+ day = (ListBox) container.getWidget(y);\r
+ // Deselect old value\r
+ day.setItemSelected(day.getSelectedIndex(), false);\r
+ // and select new\r
+ for(int i=0; i <day.getItemCount(); i++)\r
+ if(day.getValue(i).equals(""+selectedMonth)) {\r
+ day.setSelectedIndex(i);\r
+ break;\r
+ }\r
+ } else {\r
+ day = new ListBox();\r
+ day.setStyleName(ISelect.CLASSNAME);\r
+ int today = (new Date()).getDay();\r
+ for(int i=0; i<31; i++) {\r
+ day.addItem(""+(i+1), ""+i);\r
+ if(i == selectedMonth)\r
+ day.setSelectedIndex(day.getItemCount()-1);\r
+ }\r
+ day.addChangeListener(this);\r
+ container.add(day);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void onChange(Widget sender) {\r
+ if(sender == year && client != null)\r
+ client.updateVariable(id, "year", year.getValue(year.getSelectedIndex()), immediate);\r
+ \r
+ }\r
+\r
+}\r
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
+import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
private Set removedWindows = new HashSet();
private PaintTarget paintTarget;
+
+ private List locales;
+
+ private int pendingLocalesIndex;
public AjaxApplicationManager(Application application) {
this.application = application;
+ requireLocale(application.getLocale().getLanguage());
}
/**
if (repaintAll) {
paintables = new LinkedHashSet();
paintables.add(window);
+
+ // Reset sent locales
+ locales = null;
+ requireLocale(application.getLocale().getLanguage());
// Adds all non-native windows
for (Iterator i = window.getApplication().getWindows()
}
}
outWriter.print("}");
-
+
+ // Store JVM default locale for later restoration
+ // (we'll have to change the default locale for a while)
+ Locale jvmDefault = Locale.getDefault();
+
+ // Send locale informations to client
+ outWriter.print(", \"locales\":[");
+ for(;pendingLocalesIndex < locales.size(); pendingLocalesIndex++) {
+
+ Locale l = new Locale((String) locales.get(pendingLocalesIndex));
+ // Locale name
+ outWriter.print("{\"name\":\"" + l.toString() + "\",");
+
+ /*
+ * Month names (both short and full)
+ */
+ DateFormatSymbols dfs = new DateFormatSymbols(l);
+ String[] short_months = dfs.getShortMonths();
+ String[] months = dfs.getMonths();
+ outWriter.print("\"smn\":[\"" + // ShortMonthNames
+ short_months[0] + "\",\"" +
+ short_months[1] + "\",\"" +
+ short_months[2] + "\",\"" +
+ short_months[3] + "\",\"" +
+ short_months[4] + "\",\"" +
+ short_months[5] + "\",\"" +
+ short_months[6] + "\",\"" +
+ short_months[7] + "\",\"" +
+ short_months[8] + "\",\"" +
+ short_months[9] + "\",\"" +
+ short_months[10] + "\",\"" +
+ short_months[11] + "\"" +
+ "],");
+ outWriter.print("\"mn\":[\"" + // MonthNames
+ months[0] + "\",\"" +
+ months[1] + "\",\"" +
+ months[2] + "\",\"" +
+ months[3] + "\",\"" +
+ months[4] + "\",\"" +
+ months[5] + "\",\"" +
+ months[6] + "\",\"" +
+ months[7] + "\",\"" +
+ months[8] + "\",\"" +
+ months[9] + "\",\"" +
+ months[10] + "\",\"" +
+ months[11] + "\"" +
+ "],");
+
+ /*
+ * Weekday names (both short and full)
+ */
+ String[] short_days = dfs.getShortWeekdays();
+ String[] days = dfs.getWeekdays();
+ outWriter.print("\"sdn\":[\"" + // ShortDayNames
+ short_days[1] + "\",\"" +
+ short_days[2] + "\",\"" +
+ short_days[3] + "\",\"" +
+ short_days[4] + "\",\"" +
+ short_days[5] + "\",\"" +
+ short_days[6] + "\",\"" +
+ short_days[7] + "\"" +
+ "],");
+ outWriter.print("\"dn\":[\"" + // DayNames
+ days[1] + "\",\"" +
+ days[2] + "\",\"" +
+ days[3] + "\",\"" +
+ days[4] + "\",\"" +
+ days[5] + "\",\"" +
+ days[6] + "\",\"" +
+ days[7] + "\"" +
+ "],");
+
+ /*
+ * First day of week (0 = sunday, 1 = monday)
+ */
+ Calendar cal = new GregorianCalendar(l);
+ outWriter.print("\"fdow\":" + (cal.getFirstDayOfWeek() - 1) + ",");
+
+ /*
+ * Date formatting (MM/DD/YYYY etc.)
+ */
+ // Force our locale as JVM default for a while (SimpleDateFormat uses JVM default)
+ Locale.setDefault(l);
+ String df = new SimpleDateFormat().toPattern();
+ // TODO we suppose all formats separate date and time with a whitespace
+ String dateformat = df.substring(0,df.indexOf(" "));
+ outWriter.print("\"df\":\"" + dateformat + "\",");
+
+ /*
+ * Time formatting (24 or 12 hour clock and AM/PM suffixes)
+ */
+ String timeformat = df.substring(df.indexOf(" ")+1, df.length()); // Doesn't return second or milliseconds
+ // We use timeformat to determine 12/24-hour clock
+ boolean twelve_hour_clock = timeformat.contains("a");
+ // TODO there are other possibilities as well, like 'h' in french (ignore them, too complicated)
+ String hour_min_delimiter = timeformat.contains(".")? "." : ":";
+ //outWriter.print("\"tf\":\"" + timeformat + "\",");
+ outWriter.print("\"thc\":" + twelve_hour_clock + ",");
+ outWriter.print("\"hmd\":\"" + hour_min_delimiter + "\"");
+
+ outWriter.print("}");
+ if(pendingLocalesIndex < locales.size()-1)
+ outWriter.print(",");
+ }
+ outWriter.print("]"); // Close locales
+
+ // Restore JVM default locale
+ Locale.setDefault(jvmDefault);
+
outWriter.flush();
outWriter.close();
out.flush();
return this.owner;
}
}
+
+ public void requireLocale(String value) {
+ if(locales == null) {
+ locales = new ArrayList();
+ locales.add(application.getLocale().getLanguage());
+ pendingLocalesIndex = 0;
+ }
+ if(!locales.contains(value))
+ locales.add(value);
+ }
}
if (customLayoutArgumentsOpen && "style".equals(name))
getPreCachedResources().add("layout/" + value + ".html");
+
+ if(name.equals("locale"))
+ manager.requireLocale(value);
}