Fixed locale loading and parsing (now supports all possible locales found from JVM). svn changeset:1821/svn branch:trunktags/6.7.0.beta1
@@ -329,6 +329,14 @@ public class Client implements EntryPoint { | |||
else if (uidl.hasAttribute("readonly")) | |||
enabled = !uidl.getBooleanAttribute("readonly"); | |||
((FocusWidget) component).setEnabled(enabled); | |||
} else { | |||
boolean enabled = true; | |||
if (uidl.hasAttribute("disabled")) | |||
enabled = !uidl.getBooleanAttribute("disabled"); | |||
if(!enabled) | |||
component.addStyleName("i-disabled"); | |||
else | |||
component.removeStyleName("i-disabled"); | |||
} | |||
boolean visible = !uidl.getBooleanAttribute("invisible"); | |||
component.setVisible(visible); |
@@ -92,6 +92,39 @@ public class DateTimeService { | |||
return 0; | |||
} | |||
public boolean isTwelveHourClock() { | |||
try { | |||
return LocaleService.isTwelveHourClock(currentLocale); | |||
} catch (LocaleNotLoadedException e) { | |||
// TODO redirect to console | |||
System.out.println(e + ":" + e.getMessage()); | |||
} | |||
return false; | |||
} | |||
public String getClockDelimeter() { | |||
try { | |||
return LocaleService.getClockDelimiter(currentLocale); | |||
} catch (LocaleNotLoadedException e) { | |||
// TODO redirect to console | |||
System.out.println(e + ":" + e.getMessage()); | |||
} | |||
return ":"; | |||
} | |||
public String[] getAmPmStrings() { | |||
try { | |||
return LocaleService.getAmPmStrings(currentLocale); | |||
} catch (LocaleNotLoadedException e) { | |||
// TODO redirect to console | |||
System.out.println(e + ":" + e.getMessage()); | |||
} | |||
String[] temp = new String[2]; | |||
temp[0] = "AM"; | |||
temp[1] = "PM"; | |||
return temp; | |||
} | |||
public int getStartWeekDay(Date date){ | |||
Date dateForFirstOfThisMonth = new Date(date.getYear(), date.getMonth(), 1); | |||
int firstDay; |
@@ -12,7 +12,7 @@ import com.google.gwt.json.client.JSONString; | |||
/** | |||
* Date / time etc. localisation service for all widgets. | |||
* Should cache all loaded locales as JSON strings. | |||
* Caches all loaded locales as JSONObjects. | |||
* | |||
* @author IT Mill Ltd. | |||
* | |||
@@ -148,5 +148,16 @@ public class LocaleService { | |||
return hmd.stringValue(); | |||
} else throw new LocaleNotLoadedException(locale); | |||
} | |||
public static String[] getAmPmStrings(String locale) throws LocaleNotLoadedException { | |||
if(cache.containsKey(locale)) { | |||
JSONObject l = (JSONObject) cache.get(locale); | |||
JSONArray ampm = (JSONArray) l.get("ampm"); | |||
String[] temp = new String[2]; | |||
temp[0] = ((JSONString)ampm.get(0)).stringValue(); | |||
temp[1] = ((JSONString)ampm.get(1)).stringValue(); | |||
return temp; | |||
} else throw new LocaleNotLoadedException(locale); | |||
} | |||
} |
@@ -5,21 +5,18 @@ import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
public class ICalendar extends IDateField { | |||
private ICalendarPanel body; | |||
private String locale; | |||
private ICalendarPanel date; | |||
public ICalendar() { | |||
super(); | |||
body = new ICalendarPanel(this); | |||
container.add(body); | |||
setStyleName(CLASSNAME+"-calendar"); | |||
date = new ICalendarPanel(this); | |||
add(date); | |||
} | |||
public void updateFromUIDL(UIDL uidl, Client client) { | |||
super.updateFromUIDL(uidl, client); | |||
boolean needsRedraw = (locale == null || !locale.equals(currentLocale)); | |||
body.updateCalendar(needsRedraw); | |||
locale = currentLocale; | |||
date.updateCalendar(); | |||
} | |||
} |
@@ -2,66 +2,119 @@ package com.itmill.toolkit.terminal.gwt.client.ui; | |||
import java.util.Date; | |||
import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Event; | |||
import com.google.gwt.user.client.Timer; | |||
import com.google.gwt.user.client.ui.ClickListener; | |||
import com.google.gwt.user.client.ui.FlexTable; | |||
import com.google.gwt.user.client.ui.MouseListener; | |||
import com.google.gwt.user.client.ui.MouseListenerCollection; | |||
import com.google.gwt.user.client.ui.SourcesMouseEvents; | |||
import com.google.gwt.user.client.ui.SourcesTableEvents; | |||
import com.google.gwt.user.client.ui.TableListener; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.itmill.toolkit.terminal.gwt.client.DateTimeService; | |||
import com.itmill.toolkit.terminal.gwt.client.LocaleService; | |||
public class ICalendarPanel extends FlexTable implements ClickListener { | |||
public class ICalendarPanel extends FlexTable implements MouseListener, ClickListener { | |||
private IDateField datefield; | |||
private IButton prevYear; | |||
private IButton nextYear; | |||
private IButton prevMonth; | |||
private IButton nextMonth; | |||
private IEventButton prevYear; | |||
private IEventButton nextYear; | |||
private IEventButton prevMonth; | |||
private IEventButton nextMonth; | |||
private ITime time; | |||
/* Needed to identify resolution changes */ | |||
private int resolution = IDateField.RESOLUTION_YEAR; | |||
/* Needed to identify locale changes */ | |||
private String locale = LocaleService.getDefaultLocale(); | |||
public ICalendarPanel(IDateField parent) { | |||
datefield = parent; | |||
// Force table size | |||
setText(0, 0, ""); | |||
setText(7, 6, ""); | |||
buildCalendar(true); | |||
setStyleName(datefield.CLASSNAME+"-calendarpanel"); | |||
//buildCalendar(true); | |||
addTableListener(new DateClickListener(this)); | |||
} | |||
public void buildCalendar(boolean forceRedraw) { | |||
buildCalendarHeader(forceRedraw); | |||
buildCalendarBody(); | |||
private void buildCalendar(boolean forceRedraw) { | |||
boolean needsMonth = datefield.currentResolution > IDateField.RESOLUTION_YEAR; | |||
boolean needsBody = datefield.currentResolution >= IDateField.RESOLUTION_DAY; | |||
boolean needsTime = datefield.currentResolution >= IDateField.RESOLUTION_HOUR; | |||
buildCalendarHeader(forceRedraw, needsMonth); | |||
clearCalendarBody(!needsBody); | |||
if(needsBody) | |||
buildCalendarBody(); | |||
if(needsTime) | |||
buildTime(forceRedraw); | |||
else if(time != null) { | |||
remove(time); | |||
time = null; | |||
} | |||
} | |||
private void clearCalendarBody() { | |||
for (int row=2; row < 8; row++){ | |||
for (int col=0; col < 7; col++){ | |||
setText(row, col, ""); | |||
private void clearCalendarBody(boolean remove) { | |||
if(!remove) { | |||
for (int row = 2; row < 8; row++) { | |||
for (int col = 0; col < 7; col++) { | |||
setHTML(row, col, " "); | |||
} | |||
} | |||
} else if(getRowCount() > 2) { | |||
while(getRowCount() > 2) | |||
removeRow(2); | |||
} | |||
} | |||
private void buildCalendarHeader(boolean forceRedraw) { | |||
private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) { | |||
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); | |||
if(prevMonth == null) { // Only do once | |||
prevYear = new IEventButton(); prevYear.setHTML("«"); | |||
nextYear = new IEventButton(); nextYear.setHTML("»"); | |||
prevYear.addMouseListener(this); nextYear.addMouseListener(this); | |||
prevYear.addClickListener(this); nextYear.addClickListener(this); | |||
setWidget(0, 0, prevYear); | |||
setWidget(0, 4, nextYear); | |||
if(needsMonth) { | |||
prevMonth = new IEventButton(); prevMonth.setHTML("‹"); | |||
nextMonth = new IEventButton(); nextMonth.setHTML("›"); | |||
prevMonth.addMouseListener(this); nextMonth.addMouseListener(this); | |||
prevMonth.addClickListener(this); nextMonth.addClickListener(this); | |||
setWidget(0, 3, nextMonth); | |||
setWidget(0, 1, prevMonth); | |||
} | |||
getFlexCellFormatter().setColSpan(0, 2, 3); | |||
} else if(!needsMonth){ | |||
// Remove month traverse buttons | |||
prevMonth.removeClickListener(this); | |||
prevMonth.removeMouseListener(this); | |||
nextMonth.removeClickListener(this); | |||
nextMonth.removeMouseListener(this); | |||
remove(prevMonth); | |||
remove(nextMonth); | |||
prevMonth = null; nextMonth = null; | |||
} | |||
// Print weekday names | |||
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)); | |||
if(datefield.currentResolution > IDateField.RESOLUTION_MONTH) | |||
setHTML(1,i, "<strong>" + datefield.dts.getShortDay(day) + "</strong>"); | |||
else | |||
setHTML(1,i, ""); | |||
} | |||
} | |||
String monthName = datefield.dts.getMonth(datefield.date.getMonth()); | |||
String monthName = needsMonth? datefield.dts.getMonth(datefield.date.getMonth()) : ""; | |||
int year = datefield.date.getYear()+1900; | |||
setText(0, 2, monthName + " " + year); | |||
setHTML(0, 2, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-month\">" + monthName + " " + year + "</span>"); | |||
} | |||
private void buildCalendarBody() { | |||
@@ -69,55 +122,159 @@ public class ICalendarPanel extends FlexTable implements ClickListener { | |||
int startWeekDay = datefield.dts.getStartWeekDay(date); | |||
int numDays = DateTimeService.getNumberOfDaysInMonth(date); | |||
int dayCount = 0; | |||
Date today = new Date(); | |||
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){ | |||
if(!(row == 2 && col < startWeekDay)) { | |||
if(dayCount < numDays){ | |||
int selectedDate = ++dayCount; | |||
//cellValues[row][col] = selectedDate +""; | |||
//if(true == isSelectedDate(date, selectedDate)){ | |||
//setHTML(row, col, "<font class='currentDate'>" + selectedDate+"<font>"); | |||
//}else{ | |||
setText(row, col, ""+selectedDate); | |||
//} | |||
if(date.getDate() == dayCount){ | |||
setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day-selected\">" + selectedDate + "</span>"); | |||
} else if(today.getDate() == dayCount && today.getMonth() == date.getMonth() && today.getYear() == date.getYear()){ | |||
setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day-today\">" + selectedDate + "</span>"); | |||
} else { | |||
setHTML(row, col, "<span class=\""+datefield.CLASSNAME+"-calendarpanel-day\">" + selectedDate + "</span>"); | |||
} | |||
} else { | |||
setText(row, col, ""); | |||
//cellValues[row][col] = ""; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
private void buildTime(boolean forceRedraw) { | |||
if(time == null) { | |||
time = new ITime(datefield); | |||
setText(8,0,""); // Add new row | |||
getFlexCellFormatter().setColSpan(8, 0, 7); | |||
setWidget(8, 0, time); | |||
} | |||
time.updateTime(forceRedraw); | |||
} | |||
/** | |||
* | |||
* @param forceRedraw Build all from scratch, in case of e.g. locale changes | |||
*/ | |||
public void updateCalendar(boolean forceRedraw) { | |||
clearCalendarBody(); | |||
buildCalendar(forceRedraw); | |||
public void updateCalendar() { | |||
// Locale and resolution changes force a complete redraw | |||
buildCalendar(locale != datefield.currentLocale || resolution != datefield.currentResolution); | |||
locale = datefield.currentLocale; | |||
resolution = datefield.currentResolution; | |||
} | |||
public void onClick(Widget sender) { | |||
processClickEvent(sender); | |||
} | |||
private void processClickEvent(Widget sender) { | |||
if(!datefield.enabled || datefield.readonly) | |||
return; | |||
if(sender == prevYear) { | |||
datefield.date.setYear(datefield.date.getYear()-1); | |||
datefield.client.updateVariable(datefield.id, "year", datefield.date.getYear()+1900, datefield.immediate); | |||
updateCalendar(false); | |||
updateCalendar(); | |||
} 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); | |||
updateCalendar(); | |||
} 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); | |||
updateCalendar(); | |||
} 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); | |||
updateCalendar(); | |||
} | |||
} | |||
private Timer timer; | |||
public void onMouseDown(final Widget sender, int x, int y) { | |||
if(sender instanceof IEventButton) { | |||
timer = new Timer() { | |||
public void run() { | |||
processClickEvent(sender); | |||
} | |||
}; | |||
timer.scheduleRepeating(100); | |||
} | |||
} | |||
public void onMouseEnter(Widget sender) {} | |||
public void onMouseLeave(Widget sender) { | |||
if(timer != null) | |||
timer.cancel(); | |||
} | |||
public void onMouseMove(Widget sender, int x, int y) {} | |||
public void onMouseUp(Widget sender, int x, int y) { | |||
if(timer != null) | |||
timer.cancel(); | |||
} | |||
private class IEventButton extends IButton implements SourcesMouseEvents { | |||
private MouseListenerCollection mouseListeners; | |||
public IEventButton() { | |||
super(); | |||
sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK | |||
| Event.MOUSEEVENTS); | |||
} | |||
public void addMouseListener(MouseListener listener) { | |||
if (mouseListeners == null) { | |||
mouseListeners = new MouseListenerCollection(); | |||
} | |||
mouseListeners.add(listener); | |||
} | |||
public void removeMouseListener(MouseListener listener) { | |||
if (mouseListeners != null) | |||
mouseListeners.remove(listener); | |||
} | |||
public void onBrowserEvent(Event event) { | |||
super.onBrowserEvent(event); | |||
switch (DOM.eventGetType(event)) { | |||
case Event.ONMOUSEDOWN: | |||
case Event.ONMOUSEUP: | |||
case Event.ONMOUSEMOVE: | |||
case Event.ONMOUSEOVER: | |||
case Event.ONMOUSEOUT: | |||
if (mouseListeners != null) { | |||
mouseListeners.fireMouseEvent(this, event); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
private class DateClickListener implements TableListener { | |||
private ICalendarPanel cal; | |||
public DateClickListener(ICalendarPanel panel) { | |||
cal = panel; | |||
} | |||
public void onCellClicked(SourcesTableEvents sender, int row, int col) { | |||
if(sender != cal || row < 2 || row > 7 || !cal.datefield.enabled || cal.datefield.readonly) | |||
return; | |||
Integer day = new Integer(cal.getText(row, col)); | |||
cal.datefield.date.setDate(day.intValue()); | |||
cal.datefield.client.updateVariable(cal.datefield.id, "day", cal.datefield.date.getDate(), cal.datefield.immediate); | |||
// No need to update calendar header | |||
cal.clearCalendarBody(false); | |||
cal.buildCalendarBody(); | |||
} | |||
} | |||
} |
@@ -2,7 +2,6 @@ package com.itmill.toolkit.terminal.gwt.client.ui; | |||
import java.util.Date; | |||
import com.google.gwt.user.client.ui.Composite; | |||
import com.google.gwt.user.client.ui.FlowPanel; | |||
import com.itmill.toolkit.terminal.gwt.client.Client; | |||
import com.itmill.toolkit.terminal.gwt.client.DateTimeService; | |||
@@ -10,15 +9,13 @@ 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 { | |||
public class IDateField extends FlowPanel implements Paintable { | |||
public static final String CLASSNAME = "i-datefield"; | |||
String id; | |||
Client client; | |||
protected FlowPanel container; | |||
protected boolean immediate; | |||
@@ -33,13 +30,19 @@ public class IDateField extends Composite implements Paintable { | |||
protected String currentLocale; | |||
protected boolean readonly; | |||
protected boolean enabled; | |||
protected Date date; | |||
/* For easy access, because java.util.Date doesn't have getMilliseconds method */ | |||
private int milliseconds = 0; | |||
protected DateTimeService dts; | |||
public IDateField() { | |||
container = new FlowPanel(); | |||
initWidget(container); | |||
setStyleName(CLASSNAME); | |||
date = new Date(); | |||
dts = new DateTimeService(); | |||
} | |||
@@ -51,8 +54,11 @@ public class IDateField extends Composite implements Paintable { | |||
// Save details | |||
this.client = client; | |||
id = uidl.getId(); | |||
immediate = uidl.getBooleanAttribute("immediate"); | |||
this.id = uidl.getId(); | |||
this.immediate = uidl.getBooleanAttribute("immediate"); | |||
readonly = uidl.getBooleanAttribute("readonly"); | |||
enabled = !uidl.getBooleanAttribute("disabled"); | |||
if(uidl.hasAttribute("locale")) { | |||
String locale = uidl.getStringAttribute("locale"); | |||
@@ -60,61 +66,74 @@ public class IDateField extends Composite implements Paintable { | |||
dts.setLocale(locale); | |||
currentLocale = locale; | |||
} catch (LocaleNotLoadedException e) { | |||
dts = new DateTimeService(); | |||
currentLocale = dts.getLocale(); | |||
// TODO redirect this to console | |||
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; | |||
if(uidl.hasAttribute("day")) | |||
newResolution = RESOLUTION_DAY; | |||
if(uidl.hasAttribute("hour")) | |||
newResolution = RESOLUTION_HOUR; | |||
if(uidl.hasAttribute("min")) | |||
newResolution = RESOLUTION_MIN; | |||
if(uidl.hasAttribute("sec")) | |||
newResolution = RESOLUTION_SEC; | |||
if(uidl.hasAttribute("msec")) | |||
int newResolution; | |||
if(uidl.hasVariable("msec")) | |||
newResolution = RESOLUTION_MSEC; | |||
if(currentResolution > newResolution) | |||
container.clear(); | |||
else if(uidl.hasVariable("sec")) | |||
newResolution = RESOLUTION_SEC; | |||
else if(uidl.hasVariable("min")) | |||
newResolution = RESOLUTION_MIN; | |||
else if(uidl.hasVariable("hour")) | |||
newResolution = RESOLUTION_HOUR; | |||
else if(uidl.hasVariable("day")) | |||
newResolution = RESOLUTION_DAY; | |||
else if(uidl.hasVariable("month")) | |||
newResolution = RESOLUTION_MONTH; | |||
else | |||
newResolution = RESOLUTION_YEAR; | |||
currentResolution = newResolution; | |||
int year = uidl.getIntAttribute("year"); | |||
int month = uidl.getIntAttribute("month"); | |||
int day = uidl.getIntAttribute("day"); | |||
int hour = uidl.getIntAttribute("hour"); | |||
int min = uidl.getIntAttribute("min"); | |||
int sec = uidl.getIntAttribute("sec"); | |||
int msec = uidl.getIntAttribute("msec"); | |||
int year = uidl.getIntVariable("year"); | |||
int month = (currentResolution >= RESOLUTION_MONTH)? uidl.getIntVariable("month") : -1; | |||
int day = (currentResolution >= RESOLUTION_DAY)? uidl.getIntVariable("day") : -1; | |||
int hour = (currentResolution >= RESOLUTION_HOUR)? uidl.getIntVariable("hour") : -1; | |||
int min = (currentResolution >= RESOLUTION_MIN)? uidl.getIntVariable("min") : -1; | |||
int sec = (currentResolution >= RESOLUTION_SEC)? uidl.getIntVariable("sec") : -1; | |||
int msec = (currentResolution >= RESOLUTION_MSEC)? uidl.getIntVariable("msec") : -1; | |||
date = new Date((long) buildDate(year, month, day, hour, min, sec, msec)); | |||
// Construct new date for this datefield | |||
date = new Date((long) buildTime(year, month, day, hour, min, sec, msec)); | |||
milliseconds = msec<0? 0 : msec; | |||
} | |||
/* | |||
* We need this redundant native function because | |||
* GWT hasn't implemented setMilliseconds to the Date class. | |||
* Java's Date object doesn't have a setMilliseconds method. | |||
*/ | |||
private native double buildDate(int y, int m, int d, int h, int mi, int s, int ms) /*-{ | |||
private static native double buildTime(int y, int m, int d, int h, int mi, int s, int ms) /*-{ | |||
try { | |||
var date = new Date(); | |||
if(y) date.setFullYear(y-1900); | |||
if(m) date.setMonth(m-1); | |||
if(d) date.setDate(d); | |||
if(h) date.setHour(h); | |||
if(mi) date.setMinutes(mi); | |||
if(s) date.setSeconds(s); | |||
if(ms) date.setMilliseconds(ms); | |||
if(y && y >= 0) date.setFullYear(y); | |||
if(m && m >= 1) date.setMonth(m-1); | |||
if(d && d >= 0) date.setDate(d); | |||
if(h && h >= 0) date.setHours(h); | |||
if(mi && mi >= 0) date.setMinutes(mi); | |||
if(s && s >= 0) date.setSeconds(s); | |||
if(ms && ms >= 0) date.setMilliseconds(ms); | |||
return date.getTime(); | |||
} catch (e) { | |||
console.error(e); | |||
// TODO print some error message on the console | |||
//console.log(e); | |||
return (new Date()).getTime(); | |||
} | |||
}-*/; | |||
public int getMilliseconds() { | |||
return milliseconds; | |||
} | |||
public void setMilliseconds(int ms) { | |||
long time = (long) buildTime(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), ms); | |||
date = new Date(time); | |||
milliseconds = ms; | |||
} | |||
} |
@@ -8,10 +8,17 @@ import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
public class ILabel extends HTML implements Paintable { | |||
public static final String CLASSNAME = "i-label"; | |||
public ILabel() { | |||
super(); | |||
} | |||
public ILabel(String text) { | |||
super(text); | |||
setStyleName(CLASSNAME); | |||
} | |||
public void updateFromUIDL(UIDL uidl, Client client) { | |||
setStyleName(CLASSNAME); | |||
if (client.updateComponent(this, uidl, true)) | |||
return; |
@@ -26,9 +26,9 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
if(uidl.hasVariable("year")) { | |||
int selectedYear = uidl.getIntVariable("year"); | |||
int y = container.getWidgetIndex(year); | |||
int y = getWidgetIndex(year); | |||
if(y > -1 || !currentLocale.equals(uidl.getStringAttribute("locale"))) { | |||
year = (ListBox) container.getWidget(y); | |||
year = (ListBox) getWidget(y); | |||
// Deselect old value | |||
year.setItemSelected(year.getSelectedIndex(), false); | |||
// and select new | |||
@@ -47,14 +47,14 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
year.setSelectedIndex(year.getItemCount()-1); | |||
} | |||
year.addChangeListener(this); | |||
container.add(year); | |||
add(year); | |||
} | |||
} | |||
if(uidl.hasVariable("month")) { | |||
int selectedMonth = uidl.getIntVariable("month"); | |||
int y = container.getWidgetIndex(month); | |||
int y = getWidgetIndex(month); | |||
if(y > -1) { | |||
month = (ListBox) container.getWidget(y); | |||
month = (ListBox) getWidget(y); | |||
// Deselect old value | |||
month.setItemSelected(month.getSelectedIndex(), false); | |||
// and select new | |||
@@ -73,14 +73,14 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
month.setSelectedIndex(month.getItemCount()-1); | |||
} | |||
month.addChangeListener(this); | |||
container.add(month); | |||
add(month); | |||
} | |||
} | |||
if(uidl.hasVariable("day")) { | |||
int selectedMonth = uidl.getIntVariable("day"); | |||
int y = container.getWidgetIndex(day); | |||
int y = getWidgetIndex(day); | |||
if(y > -1) { | |||
day = (ListBox) container.getWidget(y); | |||
day = (ListBox) getWidget(y); | |||
// Deselect old value | |||
day.setItemSelected(day.getSelectedIndex(), false); | |||
// and select new | |||
@@ -99,7 +99,7 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
day.setSelectedIndex(day.getItemCount()-1); | |||
} | |||
day.addChangeListener(this); | |||
container.add(day); | |||
add(day); | |||
} | |||
} | |||
} |
@@ -0,0 +1,193 @@ | |||
package com.itmill.toolkit.terminal.gwt.client.ui; | |||
import com.google.gwt.user.client.ui.ChangeListener; | |||
import com.google.gwt.user.client.ui.FlowPanel; | |||
import com.google.gwt.user.client.ui.ListBox; | |||
import com.google.gwt.user.client.ui.Widget; | |||
public class ITime extends FlowPanel implements ChangeListener { | |||
private IDateField datefield; | |||
private ListBox hours; | |||
private ListBox mins; | |||
private ListBox sec; | |||
private ListBox msec; | |||
private ListBox ampm; | |||
private int resolution = IDateField.RESOLUTION_HOUR; | |||
private boolean readonly; | |||
public ITime(IDateField parent) { | |||
super(); | |||
datefield = parent; | |||
setStyleName(IDateField.CLASSNAME+"-time"); | |||
} | |||
private void buildTime(boolean redraw) { | |||
boolean thc = datefield.dts.isTwelveHourClock(); | |||
if(redraw) { | |||
clear(); | |||
int numHours = thc?12:24; | |||
hours = new ListBox(); | |||
hours.setStyleName(ISelect.CLASSNAME); | |||
for(int i=0; i<numHours; i++) | |||
hours.addItem((i<10)?"0"+i:""+i); | |||
hours.addChangeListener(this); | |||
if(thc) { | |||
ampm = new ListBox(); | |||
ampm.setStyleName(ISelect.CLASSNAME); | |||
String[] ampmText = datefield.dts.getAmPmStrings(); | |||
ampm.addItem(ampmText[0]); | |||
ampm.addItem(ampmText[1]); | |||
ampm.addChangeListener(this); | |||
} | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) { | |||
mins = new ListBox(); | |||
mins.setStyleName(ISelect.CLASSNAME); | |||
for(int i=0; i<60; i++) | |||
mins.addItem((i<10)?"0"+i:""+i); | |||
mins.addChangeListener(this); | |||
} | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) { | |||
sec = new ListBox(); | |||
sec.setStyleName(ISelect.CLASSNAME); | |||
for(int i=0; i<60; i++) | |||
sec.addItem((i<10)?"0"+i:""+i); | |||
sec.addChangeListener(this); | |||
} | |||
if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) { | |||
msec = new ListBox(); | |||
msec.setStyleName(ISelect.CLASSNAME); | |||
for(int i=0; i<1000; i++) { | |||
if(i<10) | |||
msec.addItem("00"+i); | |||
else if(i<100) | |||
msec.addItem("0"+i); | |||
else msec.addItem(""+i); | |||
} | |||
msec.addChangeListener(this); | |||
} | |||
// Update times | |||
if(thc) { | |||
int h = datefield.date.getHours(); | |||
ampm.setSelectedIndex(h<12? 0 : 1); | |||
h -= ampm.getSelectedIndex()*12; | |||
hours.setSelectedIndex(h); | |||
} else | |||
hours.setSelectedIndex(datefield.date.getHours()); | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) | |||
mins.setSelectedIndex(datefield.date.getMinutes()); | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) | |||
sec.setSelectedIndex(datefield.date.getSeconds()); | |||
if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) | |||
msec.setSelectedIndex(datefield.getMilliseconds()); | |||
if(thc) | |||
ampm.setSelectedIndex(datefield.date.getHours()<12?0:1); | |||
String delimiter = datefield.dts.getClockDelimeter(); | |||
boolean ro = datefield.readonly; | |||
if(ro) { | |||
int h = datefield.date.getHours(); | |||
if(thc) h -= h<12? 0 : 12; | |||
add(new ILabel(h<10? "0"+h : ""+h)); | |||
} else add(hours); | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) { | |||
add(new ILabel(delimiter)); | |||
if(ro) { | |||
int m = mins.getSelectedIndex(); | |||
add(new ILabel(m<10? "0"+m : ""+m)); | |||
} | |||
else add(mins); | |||
} | |||
if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) { | |||
add(new ILabel(delimiter)); | |||
if(ro) { | |||
int s = sec.getSelectedIndex(); | |||
add(new ILabel(s<10? "0"+s : ""+s)); | |||
} | |||
else add(sec); | |||
} | |||
if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) { | |||
add(new ILabel(".")); | |||
if(ro) { | |||
int m = datefield.getMilliseconds(); | |||
String ms = m<100? "0"+m : ""+m; | |||
add(new ILabel(m<10? "0"+ms : ms)); | |||
} | |||
else add(msec); | |||
} | |||
if(datefield.currentResolution == IDateField.RESOLUTION_HOUR) { | |||
add(new ILabel(delimiter+"00")); // o'clock | |||
} | |||
if(thc) { | |||
add(new ILabel(" ")); | |||
if(ro) add(new ILabel(ampm.getItemText(datefield.date.getHours()<12? 0 : 1))); | |||
else add(ampm); | |||
} | |||
if(ro) return; | |||
} | |||
boolean enabled = datefield.enabled; | |||
hours.setEnabled(enabled); | |||
if(mins != null) mins.setEnabled(enabled); | |||
if(sec != null) sec.setEnabled(enabled); | |||
if(msec != null) msec.setEnabled(enabled); | |||
if(ampm != null) ampm.setEnabled(enabled); | |||
} | |||
public void updateTime(boolean redraw) { | |||
buildTime(redraw || resolution != datefield.currentResolution | |||
|| readonly != datefield.readonly); | |||
resolution = datefield.currentResolution; | |||
readonly = datefield.readonly; | |||
} | |||
public void onChange(Widget sender) { | |||
if(sender == hours) { | |||
int h = hours.getSelectedIndex(); | |||
if(datefield.dts.isTwelveHourClock()) | |||
h = h + ampm.getSelectedIndex()*12; | |||
datefield.date.setHours(h); | |||
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate); | |||
//updateTime(false); | |||
} | |||
else if(sender == mins) { | |||
int m = mins.getSelectedIndex(); | |||
datefield.date.setMinutes(m); | |||
datefield.client.updateVariable(datefield.id, "min", m, datefield.immediate); | |||
//updateTime(false); | |||
} | |||
else if(sender == sec) { | |||
int s = sec.getSelectedIndex(); | |||
datefield.date.setSeconds(s); | |||
datefield.client.updateVariable(datefield.id, "sec", s, datefield.immediate); | |||
//updateTime(false); | |||
} | |||
else if(sender == msec) { | |||
int ms = msec.getSelectedIndex(); | |||
datefield.setMilliseconds(ms); | |||
datefield.client.updateVariable(datefield.id, "msec", ms, datefield.immediate); | |||
//updateTime(false); | |||
} | |||
else if(sender == ampm) { | |||
int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12; | |||
datefield.date.setHours(h); | |||
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate); | |||
//updateTime(false); | |||
} | |||
} | |||
} |
@@ -2,4 +2,5 @@ | |||
@import "textfield/css/textfield.css"; | |||
@import "select/css/select.css"; | |||
@import "panel/css/panel.css"; | |||
@import "tabsheet/css/tabsheet.css"; | |||
@import "tabsheet/css/tabsheet.css"; | |||
@import "datefield/css/datefield.css"; |
@@ -14,6 +14,11 @@ input, select, textarea, button { | |||
select { | |||
padding: 0; | |||
margin: 0; | |||
} | |||
.i-disabled { | |||
opacity: 0.3; | |||
filter: alpha(opacity:30); | |||
} | |||
/* TODO move table styles to separate file */ |
@@ -0,0 +1,71 @@ | |||
.i-datefield-calendarpanel { | |||
width: 22em; | |||
} | |||
.i-datefield-calendarpanel table { | |||
width: 100%; | |||
} | |||
.i-datefield-calendarpanel td { | |||
width: 14.2%; | |||
text-align: center; | |||
padding: 0; | |||
} | |||
.i-datefield-calendarpanel .i-button { | |||
width: 22px; | |||
height: 22px; | |||
font-size: 1.1em; | |||
padding: 0; | |||
line-height: 1em; | |||
} | |||
.i-datefield-calendarpanel-month { | |||
font-size: 1.1em; | |||
} | |||
.i-datefield-calendarpanel-day { | |||
cursor: pointer; | |||
padding: 0 3px; | |||
} | |||
.i-datefield-calendarpanel-day-today { | |||
font-weight: bold; | |||
border: 1px solid #aaa; | |||
padding: 0 3px; | |||
cursor: pointer; | |||
} | |||
.i-disabled .i-datefield-calendarpanel-day, | |||
.i-disabled .i-datefield-calendarpanel-day-today { | |||
cursor: default; | |||
} | |||
.i-datefield-calendarpanel-day-selected { | |||
font-weight: bold; | |||
color: #fff; | |||
padding: 0 3px; | |||
background-color: #1C3E6E; | |||
cursor: default; | |||
} | |||
.i-datefield-time { | |||
white-space: nowrap; | |||
} | |||
.i-datefield-time .i-label { | |||
display: inline; | |||
} | |||
.i-datefield-calendar { | |||
border: 1px solid #29528a; | |||
padding: 5px; | |||
background: #fff; | |||
} | |||
.i-datefield-calendar:before { | |||
display: block; | |||
height: 2px; | |||
overflow: hidden; | |||
background: transparent url(../../panel/img/top-right-small.png) no-repeat right top; | |||
content: url(../../panel/img/top-left-small.png); | |||
margin: -6px -6px 3px -6px; | |||
} | |||
.i-datefield-calendar:after { | |||
display: block; | |||
height: 2px; | |||
overflow: hidden; | |||
background: transparent url(../../panel/img/bottom-right.png) no-repeat right top; | |||
content: url(../../panel/img/bottom-left.png); | |||
margin: 5px -6px -6px -6px; | |||
} |
@@ -108,7 +108,7 @@ public class AjaxApplicationManager implements | |||
public AjaxApplicationManager(Application application) { | |||
this.application = application; | |||
requireLocale(application.getLocale().getLanguage()); | |||
requireLocale(application.getLocale().toString()); | |||
} | |||
/** | |||
@@ -233,7 +233,7 @@ public class AjaxApplicationManager implements | |||
// Reset sent locales | |||
locales = null; | |||
requireLocale(application.getLocale().getLanguage()); | |||
requireLocale(application.getLocale().toString()); | |||
// Adds all non-native windows | |||
for (Iterator i = window.getApplication().getWindows() | |||
@@ -397,6 +397,12 @@ public class AjaxApplicationManager implements | |||
} | |||
outWriter.print("}"); | |||
/* ----------------------------- | |||
* Sending Locale sensitive date | |||
* ----------------------------- | |||
*/ | |||
// Store JVM default locale for later restoration | |||
// (we'll have to change the default locale for a while) | |||
Locale jvmDefault = Locale.getDefault(); | |||
@@ -405,7 +411,7 @@ public class AjaxApplicationManager implements | |||
outWriter.print(", \"locales\":["); | |||
for(;pendingLocalesIndex < locales.size(); pendingLocalesIndex++) { | |||
Locale l = new Locale((String) locales.get(pendingLocalesIndex)); | |||
Locale l = generateLocale((String) locales.get(pendingLocalesIndex)); | |||
// Locale name | |||
outWriter.print("{\"name\":\"" + l.toString() + "\","); | |||
@@ -495,7 +501,10 @@ public class AjaxApplicationManager implements | |||
//outWriter.print("\"tf\":\"" + timeformat + "\","); | |||
outWriter.print("\"thc\":" + twelve_hour_clock + ","); | |||
outWriter.print("\"hmd\":\"" + hour_min_delimiter + "\""); | |||
if(twelve_hour_clock) { | |||
String[] ampm = dfs.getAmPmStrings(); | |||
outWriter.print(",\"ampm\":[\""+ampm[0]+"\",\""+ampm[1]+"\"]"); | |||
} | |||
outWriter.print("}"); | |||
if(pendingLocalesIndex < locales.size()-1) | |||
outWriter.print(","); | |||
@@ -904,10 +913,20 @@ public class AjaxApplicationManager implements | |||
public void requireLocale(String value) { | |||
if(locales == null) { | |||
locales = new ArrayList(); | |||
locales.add(application.getLocale().getLanguage()); | |||
locales.add(application.getLocale().toString()); | |||
pendingLocalesIndex = 0; | |||
} | |||
if(!locales.contains(value)) | |||
locales.add(value); | |||
} | |||
private Locale generateLocale(String value) { | |||
String[] temp = value.split("_"); | |||
if(temp.length == 1) | |||
return new Locale(temp[0]); | |||
else if(temp.length == 2) | |||
return new Locale(temp[0], temp[1]); | |||
else | |||
return new Locale(temp[0], temp[1], temp[2]); | |||
} | |||
} |
@@ -433,9 +433,9 @@ public class AjaxJsonPaintTarget implements PaintTarget, AjaxPaintTarget { | |||
* content is written. | |||
* | |||
* @param name | |||
* the Boolean attribute name. | |||
* the String attribute name. | |||
* @param value | |||
* the Boolean attribute value. | |||
* the String attribute value. | |||
* | |||
* @throws PaintException | |||
* if the paint operation failed. |
@@ -316,7 +316,7 @@ public class DateField extends AbstractField { | |||
if (newDate != oldDate | |||
&& (newDate == null || !newDate.equals(oldDate))) | |||
setValue(newDate); | |||
setValue(newDate, true); // Don't require a repaint, client updates itself | |||
} | |||
} | |||
@@ -348,17 +348,22 @@ public class DateField extends AbstractField { | |||
*/ | |||
public void setValue(Object newValue) throws Property.ReadOnlyException, | |||
Property.ConversionException { | |||
setValue(newValue, false); | |||
} | |||
public void setValue(Object newValue, boolean repaintIsNotNeeded) throws Property.ReadOnlyException, | |||
Property.ConversionException { | |||
// Allows setting dates directly | |||
if (newValue == null || newValue instanceof Date) | |||
super.setValue(newValue); | |||
super.setValue(newValue, repaintIsNotNeeded); | |||
else { | |||
// Try to parse as string | |||
try { | |||
SimpleDateFormat parser = new SimpleDateFormat(); | |||
Date val = parser.parse(newValue.toString()); | |||
super.setValue(val); | |||
super.setValue(val, repaintIsNotNeeded); | |||
} catch (ParseException e) { | |||
throw new Property.ConversionException(e.getMessage()); | |||
} |