From 28ca6dc78a4e0982c65fbbfea0b815d4ebc01169 Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Thu, 5 Jul 2007 12:10:21 +0000 Subject: [PATCH] Localization services from serverside (AjaxApplicationManager), cached on clientside (LocaleService). 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 --- .../toolkit/terminal/gwt/client/Client.java | 36 +--- .../terminal/gwt/client/DateTimeService.java | 124 +++++++++++-- .../gwt/client/DefaultWidgetFactory.java | 14 +- .../gwt/client/LocaleNotLoadedException.java | 13 ++ .../terminal/gwt/client/LocaleService.java | 169 +++++++++++++----- .../terminal/gwt/client/ui/ICalendar.java | 25 +++ .../gwt/client/ui/ICalendarPanel.java | 123 +++++++++++++ .../terminal/gwt/client/ui/IDateField.java | 130 +++++++------- .../gwt/client/ui/IPopupCalendar.java | 5 + .../terminal/gwt/client/ui/ITextualDate.java | 113 ++++++++++++ .../terminal/web/AjaxApplicationManager.java | 134 +++++++++++++- .../terminal/web/AjaxJsonPaintTarget.java | 3 + 12 files changed, 723 insertions(+), 166 deletions(-) create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/LocaleNotLoadedException.java create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/Client.java b/src/com/itmill/toolkit/terminal/gwt/client/Client.java index c0ceeefa30..556d4cf66f 100755 --- a/src/com/itmill/toolkit/terminal/gwt/client/Client.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/Client.java @@ -42,6 +42,8 @@ public class Client implements EntryPoint { private HashMap paintables = new HashMap(); private WidgetFactory widgetFactory = new DefaultWidgetFactory(); + + private LocaleService locale; /** * This is the entry point method. @@ -121,6 +123,13 @@ public class Client implements EntryPoint { 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"); @@ -353,31 +362,4 @@ public class Client implements EntryPoint { 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; - } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DateTimeService.java b/src/com/itmill/toolkit/terminal/gwt/client/DateTimeService.java index 05d2d15ff8..a5781c2fe5 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/DateTimeService.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/DateTimeService.java @@ -1,44 +1,132 @@ package com.itmill.toolkit.terminal.gwt.client; +import java.util.Date; + /** - * This class provides date/time parsing services to all components. + * This class provides date/time parsing services to + * all components on the client side. * - * @author Jouni Koivuviita + * @author IT Mill Ltd. * */ public class DateTimeService { - private LocaleService localeService; - private String currentLocale; - public DateTimeService(Client client) { - localeService = new LocaleService(client); + private static int [] maxDaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + /** + * Creates a new date time service with the application default locale. + */ + public DateTimeService() { + currentLocale = LocaleService.getDefaultLocale(); } - public DateTimeService(Client client, String locale) { - this(client); + /** + * Creates a new date time service with a given locale. + * + * @param locale e.g. fi, en etc. + * @throws LocaleNotLoadedException + */ + public DateTimeService(String locale) throws LocaleNotLoadedException { setLocale(locale); } - public void setLocale(String locale) { - currentLocale = locale; + public void setLocale(String locale) throws LocaleNotLoadedException { + if(LocaleService.getAvailableLocales().contains(locale)) + currentLocale = locale; + else throw new LocaleNotLoadedException(locale); } public String getLocale() { return currentLocale; } - public String getMonth(int month) throws Exception { - if(currentLocale != null) - return localeService.getMonthNames(currentLocale)[month]; - else throw new Exception("No locale specified."); + public String getMonth(int month) { + try { + return LocaleService.getMonthNames(currentLocale)[month]; + } catch (LocaleNotLoadedException e) { + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + return null; + } + + public String getShortMonth(int month) { + try { + return LocaleService.getShortMonthNames(currentLocale)[month]; + } catch (LocaleNotLoadedException e) { + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + return null; + } + + public String getDay(int day) { + try { + return LocaleService.getDayNames(currentLocale)[day]; + } catch (LocaleNotLoadedException e) { + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + return null; + } + + public String getShortDay(int day) { + try { + return LocaleService.getShortDayNames(currentLocale)[day]; + } catch (LocaleNotLoadedException e) { + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + return null; + } + + public int getFirstDayOfWeek() { + try { + return LocaleService.getFirstDayOfWeek(currentLocale); + } catch (LocaleNotLoadedException e) { + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + return 0; + } + + public int getStartWeekDay(Date date){ + Date dateForFirstOfThisMonth = new Date(date.getYear(), date.getMonth(), 1); + int firstDay; + try { + firstDay = LocaleService.getFirstDayOfWeek(currentLocale); + } catch (LocaleNotLoadedException e) { + firstDay = 0; + // TODO redirect to console + System.out.println(e + ":" + e.getMessage()); + } + int start = dateForFirstOfThisMonth.getDay() - firstDay; + if(start < 0) start = 6; + return start; + } + + public static int getNumberOfDaysInMonth(Date date){ + int month = date.getMonth(); + if(month == 1 && true == isLeapYear(date)) + return 29; + return maxDaysInMonth[month]; } - public String getShortMonth(int month) throws Exception { - if(currentLocale != null) - return localeService.getShortMonthNames(currentLocale)[month]; - else throw new Exception("No locale specified."); + public static boolean isLeapYear(Date date){ + // Instantiate the date for 1st March of that year + Date firstMarch = new Date(date.getYear(), 2, 1); + + // Go back 1 day + long firstMarchTime = firstMarch.getTime(); + long lastDayTimeFeb = firstMarchTime - (24*60*60*1000); // NUM_MILLISECS_A_DAY + + //Instantiate new Date with this time + Date febLastDay = new Date(lastDayTimeFeb); + + // Check for date in this new instance + return (29 == febLastDay.getDate()) ? true : false; } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java index 0a22858281..f76f6c7a3e 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java @@ -3,10 +3,10 @@ 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.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; @@ -14,11 +14,13 @@ import com.itmill.toolkit.terminal.gwt.client.ui.ILabel; 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; @@ -82,8 +84,14 @@ public class DefaultWidgetFactory implements WidgetFactory { } 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(); } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/LocaleNotLoadedException.java b/src/com/itmill/toolkit/terminal/gwt/client/LocaleNotLoadedException.java new file mode 100644 index 0000000000..af962b9b74 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/LocaleNotLoadedException.java @@ -0,0 +1,13 @@ +package com.itmill.toolkit.terminal.gwt.client; + +public class LocaleNotLoadedException extends Exception { + + /** + * Serial generated by Eclipse. + */ + private static final long serialVersionUID = 2005227056545210838L; + + public LocaleNotLoadedException(String locale) { + super(locale); + } +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/LocaleService.java b/src/com/itmill/toolkit/terminal/gwt/client/LocaleService.java index 3d369dd37b..fdd6b99b8d 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/LocaleService.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/LocaleService.java @@ -2,80 +2,151 @@ package com.itmill.toolkit.terminal.gwt.client; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONBoolean; +import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; +import com.google.gwt.json.client.JSONString; /** * Date / time etc. localisation service for all widgets. * Should cache all loaded locales as JSON strings. * - * @author Jouni Koivuviita + * @author IT Mill Ltd. * */ public class LocaleService { - private Client client; + private static Map cache = new HashMap(); + private static String defaultLocale; + + public static void addLocale(JSONObject json) { + String key = ((JSONString)json.get("name")).stringValue(); + if(cache.containsKey(key)) + cache.remove(key); + cache.put(key, json); + if(cache.size()==1) + setDefaultLocale(key); + } + + public static void setDefaultLocale(String locale) { + defaultLocale = locale; + } - private Map cache = new HashMap(); + public static String getDefaultLocale() { + return defaultLocale; + } + + public static Set getAvailableLocales() { + return cache.keySet(); + } + + public static String[] getMonthNames(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONArray mn = (JSONArray) l.get("mn"); + String[] temp = new String[12]; + temp[0] = ((JSONString)mn.get(0)).stringValue(); + temp[1] = ((JSONString)mn.get(1)).stringValue(); + temp[2] = ((JSONString)mn.get(2)).stringValue(); + temp[3] = ((JSONString)mn.get(3)).stringValue(); + temp[4] = ((JSONString)mn.get(4)).stringValue(); + temp[5] = ((JSONString)mn.get(5)).stringValue(); + temp[6] = ((JSONString)mn.get(6)).stringValue(); + temp[7] = ((JSONString)mn.get(7)).stringValue(); + temp[8] = ((JSONString)mn.get(8)).stringValue(); + temp[9] = ((JSONString)mn.get(9)).stringValue(); + temp[10] = ((JSONString)mn.get(10)).stringValue(); + temp[11] = ((JSONString)mn.get(11)).stringValue(); + return temp; + } else throw new LocaleNotLoadedException(locale); + } - public LocaleService(Client client){ - this.client = client; + public static String[] getShortMonthNames(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONArray smn = (JSONArray) l.get("smn"); + String[] temp = new String[12]; + temp[0] = ((JSONString)smn.get(0)).stringValue(); + temp[1] = ((JSONString)smn.get(1)).stringValue(); + temp[2] = ((JSONString)smn.get(2)).stringValue(); + temp[3] = ((JSONString)smn.get(3)).stringValue(); + temp[4] = ((JSONString)smn.get(4)).stringValue(); + temp[5] = ((JSONString)smn.get(5)).stringValue(); + temp[6] = ((JSONString)smn.get(6)).stringValue(); + temp[7] = ((JSONString)smn.get(7)).stringValue(); + temp[8] = ((JSONString)smn.get(8)).stringValue(); + temp[9] = ((JSONString)smn.get(9)).stringValue(); + temp[10] = ((JSONString)smn.get(10)).stringValue(); + temp[11] = ((JSONString)smn.get(11)).stringValue(); + return temp; + } else throw new LocaleNotLoadedException(locale); } - private void loadLocale(String locale) { - JSONObject resp = client.getLocale(locale); - cache.put(locale, resp); + public static String[] getDayNames(String locale) throws LocaleNotLoadedException{ + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONArray dn = (JSONArray) l.get("dn"); + String[] temp = new String[7]; + temp[0] = ((JSONString)dn.get(0)).stringValue(); + temp[1] = ((JSONString)dn.get(1)).stringValue(); + temp[2] = ((JSONString)dn.get(2)).stringValue(); + temp[3] = ((JSONString)dn.get(3)).stringValue(); + temp[4] = ((JSONString)dn.get(4)).stringValue(); + temp[5] = ((JSONString)dn.get(5)).stringValue(); + temp[6] = ((JSONString)dn.get(6)).stringValue(); + return temp; + } else throw new LocaleNotLoadedException(locale); } - public String[] getMonthNames(String locale) { - // TODO - //if(cache.containsKey(locale)) - //else loadLocale(locale); - String[] temp = new String[12]; - temp[0] = "tammi"; temp[1] = "helmi"; temp[2] = "maalis"; temp[3] = "huhti"; - temp[4] = "touko"; temp[5] = "kesä"; temp[6] = "heinä"; temp[7] = "elo"; - temp[8] = "syys"; temp[9] = "loka"; temp[10] = "marras"; temp[11] = "joulu"; - return temp; + public static String[] getShortDayNames(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONArray sdn = (JSONArray) l.get("sdn"); + String[] temp = new String[7]; + temp[0] = ((JSONString)sdn.get(0)).stringValue(); + temp[1] = ((JSONString)sdn.get(1)).stringValue(); + temp[2] = ((JSONString)sdn.get(2)).stringValue(); + temp[3] = ((JSONString)sdn.get(3)).stringValue(); + temp[4] = ((JSONString)sdn.get(4)).stringValue(); + temp[5] = ((JSONString)sdn.get(5)).stringValue(); + temp[6] = ((JSONString)sdn.get(6)).stringValue(); + return temp; + } else throw new LocaleNotLoadedException(locale); } - public String[] getShortMonthNames(String locale) { - // TODO - //if(cache.containsKey(locale)) - //else loadLocale(locale); - String[] temp = new String[12]; - temp[0] = "tam"; temp[1] = "hel"; temp[2] = "maa"; temp[3] = "huh"; - temp[4] = "tou"; temp[5] = "kes"; temp[6] = "hei"; temp[7] = "elo"; - temp[8] = "syy"; temp[9] = "lok"; temp[10] = "mar"; temp[11] = "jou"; - return temp; + public static int getFirstDayOfWeek(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONNumber fdow = (JSONNumber) l.get("fdow"); + return (int) fdow.getValue(); + } else throw new LocaleNotLoadedException(locale); } - public String[] getDayNames(String locale) { - // TODO - //if(cache.containsKey(locale)) - //else loadLocale(locale); - String[] temp = new String[7]; - temp[1] = "maanatai"; temp[2] = "tiistai"; temp[3] = "keskiviikko"; - temp[4] = "torstai"; temp[5] = "perjantai"; temp[6] = "lauantai"; - temp[0] = "sunnuntai"; - return temp; + public static String getDateFormat(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONString df = (JSONString) l.get("df"); + return df.stringValue(); + } else throw new LocaleNotLoadedException(locale); } - public String[] getShortDayNames(String locale) { - // TODO - //if(cache.containsKey(locale)) - //else loadLocale(locale); - String[] temp = new String[7]; - temp[1] = "ma"; temp[2] = "ti"; temp[3] = "ke"; - temp[4] = "to"; temp[5] = "pe"; temp[6] = "la"; - temp[0] = "su"; - return temp; + public static boolean isTwelveHourClock(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONBoolean thc = (JSONBoolean) l.get("thc"); + return thc.booleanValue(); + } else throw new LocaleNotLoadedException(locale); } - public int getFirstDayOfWeek(String locale) { - // TODO - //if(cache.containsKey(locale)) - //else loadLocale(locale); - return 1; + public static String getClockDelimiter(String locale) throws LocaleNotLoadedException { + if(cache.containsKey(locale)) { + JSONObject l = (JSONObject) cache.get(locale); + JSONString hmd = (JSONString) l.get("hmd"); + return hmd.stringValue(); + } else throw new LocaleNotLoadedException(locale); } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java new file mode 100644 index 0000000000..1213c18099 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java @@ -0,0 +1,25 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import com.itmill.toolkit.terminal.gwt.client.Client; +import com.itmill.toolkit.terminal.gwt.client.UIDL; + +public class ICalendar extends IDateField { + + private ICalendarPanel body; + + private String locale; + + public ICalendar() { + super(); + body = new ICalendarPanel(this); + container.add(body); + } + + public void updateFromUIDL(UIDL uidl, Client client) { + super.updateFromUIDL(uidl, client); + boolean needsRedraw = (locale == null || !locale.equals(currentLocale)); + body.updateCalendar(needsRedraw); + locale = currentLocale; + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java new file mode 100644 index 0000000000..32f60a7edd --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendarPanel.java @@ -0,0 +1,123 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import java.util.Date; + +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.Widget; +import com.itmill.toolkit.terminal.gwt.client.DateTimeService; + +public class ICalendarPanel extends FlexTable implements ClickListener { + + private IDateField datefield; + + private IButton prevYear; + private IButton nextYear; + private IButton prevMonth; + private IButton nextMonth; + + public ICalendarPanel(IDateField parent) { + datefield = parent; + // Force table size + setText(0, 0, ""); + setText(7, 6, ""); + buildCalendar(true); + } + + public void buildCalendar(boolean forceRedraw) { + buildCalendarHeader(forceRedraw); + buildCalendarBody(); + } + + private void clearCalendarBody() { + for (int row=2; row < 8; row++){ + for (int col=0; col < 7; col++){ + setText(row, col, ""); + } + } + } + + private void buildCalendarHeader(boolean forceRedraw) { + if(forceRedraw) { + prevYear = new IButton(); prevYear.setText("«"); + nextYear = new IButton(); nextYear.setText("»"); + prevMonth = new IButton(); prevMonth.setText("‹"); + nextMonth = new IButton(); nextMonth.setText("›"); + prevYear.addClickListener(this); nextYear.addClickListener(this); + prevMonth.addClickListener(this); nextMonth.addClickListener(this);setWidget(0, 0, prevYear); + + setWidget(0, 1, prevMonth); + setWidget(0, 3, nextMonth); + setWidget(0, 4, nextYear); + getFlexCellFormatter().setColSpan(0, 2, 3); + + int firstDay = datefield.dts.getFirstDayOfWeek(); + for(int i = 0; i < 7; i++) { + int day = i + firstDay; + if(day > 6) day = 0; + setText(1,i, datefield.dts.getShortDay(day)); + } + } + + String monthName = datefield.dts.getMonth(datefield.date.getMonth()); + int year = datefield.date.getYear()+1900; + setText(0, 2, monthName + " " + year); + } + + private void buildCalendarBody() { + Date date = datefield.date; + int startWeekDay = datefield.dts.getStartWeekDay(date); + int numDays = DateTimeService.getNumberOfDaysInMonth(date); + int dayCount = 0; + for (int row = 2; row < 8; row++){ + for (int col = 0; col < 7; col++){ + if(row == 2 && col < startWeekDay){ + setText(row, col, ""); + //cellValues[row][col] = ""; + } else { + if(numDays > dayCount){ + int selectedDate = ++dayCount; + //cellValues[row][col] = selectedDate +""; + //if(true == isSelectedDate(date, selectedDate)){ + //setHTML(row, col, "" + selectedDate+""); + //}else{ + setText(row, col, ""+selectedDate); + //} + } else { + setText(row, col, ""); + //cellValues[row][col] = ""; + } + } + } + } + } + + /** + * + * @param forceRedraw Build all from scratch, in case of e.g. locale changes + */ + public void updateCalendar(boolean forceRedraw) { + clearCalendarBody(); + buildCalendar(forceRedraw); + } + + public void onClick(Widget sender) { + if(sender == prevYear) { + datefield.date.setYear(datefield.date.getYear()-1); + datefield.client.updateVariable(datefield.id, "year", datefield.date.getYear()+1900, datefield.immediate); + updateCalendar(false); + } else if(sender == nextYear) { + datefield.date.setYear(datefield.date.getYear()+1); + datefield.client.updateVariable(datefield.id, "year", datefield.date.getYear()+1900, datefield.immediate); + updateCalendar(false); + } else if(sender == prevMonth) { + datefield.date.setMonth(datefield.date.getMonth()-1); + datefield.client.updateVariable(datefield.id, "month", datefield.date.getMonth()+1, datefield.immediate); + updateCalendar(false); + } else if(sender == nextMonth) { + datefield.date.setMonth(datefield.date.getMonth()+1); + datefield.client.updateVariable(datefield.id, "month", datefield.date.getMonth()+1, datefield.immediate); + updateCalendar(false); + } + } +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java index 802853e6fe..f4d980df17 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateField.java @@ -2,61 +2,46 @@ package com.itmill.toolkit.terminal.gwt.client.ui; import java.util.Date; -import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.ListBox; -import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.Client; +import com.itmill.toolkit.terminal.gwt.client.DateTimeService; +import com.itmill.toolkit.terminal.gwt.client.LocaleNotLoadedException; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -public class IDateField extends Composite implements Paintable, ChangeListener { - - - /* - * This implementation is old already. - * We should use the DateTimeService class (which is a draft) to get - * locale specific strings and use them to build the datefield - * and its different styles (with inheritance of course). - * - * Drafting usage patterns: - * - * DateTimeService dts = new DateTimeService(client, "fi_FI"); - * String month = dts.getMonth(0); // Returns "January" - * String day = dts.getDay(19); // Returns e.g. "sunday" - * String dateformat = dts.getDateFormat(); // Returns something like MM_/_DD_/_YYYY - * String timeformat = dts.getTimeFormat(); // Returns something like HH_:_MM - * String date = dts.parseDate(new Date()); // Returns e.g. 6/19/2007 14:32 - * String date = dts.parseFullDate(new Date()); // Returns e.g. Tuesday 6th June 2007 14:32 - */ - - +public class IDateField extends Composite implements Paintable { + public static final String CLASSNAME = "i-datefield"; String id; Client client; + + protected FlowPanel container; - private boolean immediate; + protected boolean immediate; - private FlowPanel container; + protected static int RESOLUTION_YEAR = 0; + protected static int RESOLUTION_MONTH = 1; + protected static int RESOLUTION_DAY = 2; + protected static int RESOLUTION_HOUR = 3; + protected static int RESOLUTION_MIN = 4; + protected static int RESOLUTION_SEC = 5; + protected static int RESOLUTION_MSEC = 6; + protected int currentResolution = RESOLUTION_YEAR; - private ListBox year; + protected String currentLocale; - private static int RESOLUTION_YEAR = 0; - private static int RESOLUTION_MONTH = 1; - private static int RESOLUTION_DAY = 2; - private static int RESOLUTION_HOUR = 3; - private static int RESOLUTION_MIN = 4; - private static int RESOLUTION_SEC = 5; - private static int RESOLUTION_MSEC = 6; - - private int currentResolution = RESOLUTION_YEAR; + protected Date date; + + protected DateTimeService dts; public IDateField() { container = new FlowPanel(); initWidget(container); + date = new Date(); + dts = new DateTimeService(); } public void updateFromUIDL(UIDL uidl, Client client) { @@ -69,6 +54,18 @@ public class IDateField extends Composite implements Paintable, ChangeListener { id = uidl.getId(); immediate = uidl.getBooleanAttribute("immediate"); + if(uidl.hasAttribute("locale")) { + String locale = uidl.getStringAttribute("locale"); + try { + dts.setLocale(locale); + currentLocale = locale; + } catch (LocaleNotLoadedException e) { + dts = new DateTimeService(); + currentLocale = dts.getLocale(); + System.out.println("Tried to use an unloaded locale \"" + locale + "\". Using default locale (" + currentLocale + ")."); + } + } + int newResolution = RESOLUTION_YEAR; if(uidl.hasAttribute("month")) newResolution = RESOLUTION_MONTH; @@ -86,41 +83,38 @@ public class IDateField extends Composite implements Paintable, ChangeListener { if(currentResolution > newResolution) container.clear(); - if(uidl.hasVariable("year")) { - int selectedYear = uidl.getIntVariable("year"); - int y = container.getWidgetIndex(year); - if(y > -1) { - year = (ListBox) container.getWidget(y); - // Deselect old value - year.setItemSelected(year.getSelectedIndex(), false); - // and select new - for(int i=0; i < year.getItemCount(); i++) - if(year.getValue(i).equals(""+selectedYear)) { - year.setSelectedIndex(i); - break; - } - } else { - year = new ListBox(); - year.setStyleName(ISelect.CLASSNAME); - int today = 1900 + (new Date()).getYear(); - for(int i=1970; i -1 || !currentLocale.equals(uidl.getStringAttribute("locale"))) { + year = (ListBox) container.getWidget(y); + // Deselect old value + year.setItemSelected(year.getSelectedIndex(), false); + // and select new + for(int i=0; i < year.getItemCount(); i++) + if(year.getValue(i).equals(""+selectedYear)) { + year.setSelectedIndex(i); + break; + } + } else { + year = new ListBox(); + year.setStyleName(ISelect.CLASSNAME); + int today = 1900 + (new Date()).getYear(); + for(int i=1970; i -1) { + month = (ListBox) container.getWidget(y); + // Deselect old value + month.setItemSelected(month.getSelectedIndex(), false); + // and select new + for(int i=0; i < month.getItemCount(); i++) + if(month.getValue(i).equals(""+selectedMonth)) { + month.setSelectedIndex(i); + break; + } + } else { + month = new ListBox(); + month.setStyleName(ISelect.CLASSNAME); + int today = (new Date()).getMonth(); + for(int i=0; i<12; i++) { + month.addItem(""+(i+1), ""+i); + if(i == selectedMonth) + month.setSelectedIndex(month.getItemCount()-1); + } + month.addChangeListener(this); + container.add(month); + } + } + if(uidl.hasVariable("day")) { + int selectedMonth = uidl.getIntVariable("day"); + int y = container.getWidgetIndex(day); + if(y > -1) { + day = (ListBox) container.getWidget(y); + // Deselect old value + day.setItemSelected(day.getSelectedIndex(), false); + // and select new + for(int i=0; i