* store all UI components to single package named com.itmill.toolkit.terminal.gwt.client.ui
* start all paintable UI components with letter "I", e.g. IButton
* all non-paintable classes must not begin with letter "I"
Package com.itmill.toolkit.terminal.gwt.client.util contains client-side utility classes, e.g. date and time conversions, regexp tools.
svn changeset:2344/svn branch:trunk
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import java.util.Date;\r
+\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+\r
+public class CalendarEntry {\r
+ private Date start;\r
+ private Date end;\r
+ private String title;\r
+ private String description;\r
+ private boolean notime;\r
+\r
+ public CalendarEntry(Date start, Date end, String title, String description, boolean notime) {\r
+ if (notime) {\r
+ Date d = new Date(start.getTime());\r
+ d.setSeconds(0);\r
+ d.setMinutes(0);\r
+ this.start = d;\r
+ if (end != null) {\r
+ d = new Date(end.getTime());\r
+ d.setSeconds(0);\r
+ d.setMinutes(0);\r
+ this.end = d;\r
+ } else {\r
+ end = start;\r
+ }\r
+ } else {\r
+ this.start = start;\r
+ this.end = end;\r
+ }\r
+ this.title = title;\r
+ this.description = description;\r
+ this.notime = notime;\r
+ }\r
+\r
+ public CalendarEntry(Date start, Date end, String title, String description) {\r
+ this(start, end, title, description, false);\r
+ }\r
+\r
+ public Date getStart() {\r
+ return start;\r
+ }\r
+\r
+ public void setStart(Date start) {\r
+ this.start = start;\r
+ }\r
+\r
+ public Date getEnd() {\r
+ return end;\r
+ }\r
+\r
+ public void setEnd(Date end) {\r
+ this.end = end;\r
+ }\r
+\r
+ public String getTitle() {\r
+ return title;\r
+ }\r
+\r
+ public void setTitle(String title) {\r
+ this.title = title;\r
+ }\r
+\r
+ public String getDescription() {\r
+ return description;\r
+ }\r
+\r
+ public void setDescription(String description) {\r
+ this.description = description;\r
+ }\r
+\r
+ public boolean isNotime() {\r
+ return notime;\r
+ }\r
+\r
+ public void setNotime(boolean notime) {\r
+ this.notime = notime;\r
+ }\r
+\r
+ public String getStringForDate(Date d) {\r
+ // TODO format from DateTimeService\r
+ String s = "";\r
+ if (!notime) {\r
+ if (!DateTimeService.isSameDay(d, start)) {\r
+ s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)\r
+ + "." + start.getDate() + " ";\r
+ }\r
+ int i = start.getHours();\r
+ s += (i < 10 ? "0" : "") + i;\r
+ s += ":";\r
+ i = start.getMinutes();\r
+ s += (i < 10 ? "0" : "") + i;\r
+ if (!start.equals(end)) {\r
+ s += " - ";\r
+ if (!DateTimeService.isSameDay(start, end)) {\r
+ s += (end.getYear() + 1900) + "." + (end.getMonth() + 1) + "."\r
+ + end.getDate() + " ";\r
+ }\r
+ i = end.getHours();\r
+ s += (i < 10 ? "0" : "") + i;\r
+ s += ":";\r
+ i = end.getMinutes();\r
+ s += (i < 10 ? "0" : "") + i;\r
+ }\r
+ s += " ";\r
+ }\r
+ s += title;\r
+ return s;\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import java.util.Date;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Timer;\r
+import com.google.gwt.user.client.ui.ClickListener;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.MouseListener;\r
+import com.google.gwt.user.client.ui.MouseListenerCollection;\r
+import com.google.gwt.user.client.ui.SourcesMouseEvents;\r
+import com.google.gwt.user.client.ui.SourcesTableEvents;\r
+import com.google.gwt.user.client.ui.TableListener;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
+import com.itmill.toolkit.terminal.gwt.client.LocaleService;\r
+\r
+public class CalendarPanel extends FlexTable implements MouseListener,\r
+ ClickListener {\r
+\r
+ private IDateField datefield;\r
+\r
+ private IEventButton prevYear;\r
+ private IEventButton nextYear;\r
+ private IEventButton prevMonth;\r
+ private IEventButton nextMonth;\r
+\r
+ private Time time;\r
+\r
+ private Date minDate = null;\r
+ private Date maxDate = null;\r
+\r
+ private CalendarEntrySource entrySource;\r
+\r
+ /* Needed to identify resolution changes */\r
+ private int resolution = IDateField.RESOLUTION_YEAR;\r
+\r
+ /* Needed to identify locale changes */\r
+ private String locale = LocaleService.getDefaultLocale();\r
+\r
+ public CalendarPanel(IDateField parent) {\r
+ datefield = parent;\r
+ setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
+ // buildCalendar(true);\r
+ addTableListener(new DateClickListener(this));\r
+ }\r
+\r
+ public CalendarPanel(IDateField parent, Date min, Date max) {\r
+ datefield = parent;\r
+ setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
+ // buildCalendar(true);\r
+ addTableListener(new DateClickListener(this));\r
+ }\r
+\r
+ private void buildCalendar(boolean forceRedraw) {\r
+ boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR;\r
+ boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY;\r
+ boolean needsTime = datefield.getCurrentResolution() >= IDateField.RESOLUTION_HOUR;\r
+ buildCalendarHeader(forceRedraw, needsMonth);\r
+ clearCalendarBody(!needsBody);\r
+ if (needsBody)\r
+ buildCalendarBody();\r
+ if (needsTime)\r
+ buildTime(forceRedraw);\r
+ else if (time != null) {\r
+ remove(time);\r
+ time = null;\r
+ }\r
+ }\r
+\r
+ private void clearCalendarBody(boolean remove) {\r
+ if (!remove) {\r
+ for (int row = 2; row < 8; row++) {\r
+ for (int col = 0; col < 7; col++) {\r
+ setHTML(row, col, " ");\r
+ }\r
+ }\r
+ } else if (getRowCount() > 2) {\r
+ while (getRowCount() > 2)\r
+ removeRow(2);\r
+ }\r
+ }\r
+\r
+ private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {\r
+ // Can't draw a calendar without a date :)\r
+ if (datefield.getCurrentDate() == null)\r
+ datefield.setCurrentDate(new Date());\r
+\r
+ if (forceRedraw) {\r
+ if (prevMonth == null) { // Only do once\r
+ prevYear = new IEventButton();\r
+ prevYear.setHTML("«");\r
+ nextYear = new IEventButton();\r
+ nextYear.setHTML("»");\r
+ prevYear.addMouseListener(this);\r
+ nextYear.addMouseListener(this);\r
+ prevYear.addClickListener(this);\r
+ nextYear.addClickListener(this);\r
+ setWidget(0, 0, prevYear);\r
+ setWidget(0, 4, nextYear);\r
+\r
+ if (needsMonth) {\r
+ prevMonth = new IEventButton();\r
+ prevMonth.setHTML("‹");\r
+ nextMonth = new IEventButton();\r
+ nextMonth.setHTML("›");\r
+ prevMonth.addMouseListener(this);\r
+ nextMonth.addMouseListener(this);\r
+ prevMonth.addClickListener(this);\r
+ nextMonth.addClickListener(this);\r
+ setWidget(0, 3, nextMonth);\r
+ setWidget(0, 1, prevMonth);\r
+ }\r
+\r
+ getFlexCellFormatter().setColSpan(0, 2, 3);\r
+ } else if (!needsMonth) {\r
+ // Remove month traverse buttons\r
+ prevMonth.removeClickListener(this);\r
+ prevMonth.removeMouseListener(this);\r
+ nextMonth.removeClickListener(this);\r
+ nextMonth.removeMouseListener(this);\r
+ remove(prevMonth);\r
+ remove(nextMonth);\r
+ prevMonth = null;\r
+ nextMonth = null;\r
+ }\r
+\r
+ // Print weekday names\r
+ int firstDay = datefield.getDateTimeService().getFirstDayOfWeek();\r
+ for (int i = 0; i < 7; i++) {\r
+ int day = i + firstDay;\r
+ if (day > 6)\r
+ day = 0;\r
+ if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH)\r
+ setHTML(1, i, "<strong>"\r
+ + datefield.getDateTimeService().getShortDay(day)\r
+ + "</strong>");\r
+ else\r
+ setHTML(1, i, "");\r
+ }\r
+ }\r
+\r
+ String monthName = needsMonth ? datefield.getDateTimeService()\r
+ .getMonth(datefield.getCurrentDate().getMonth()) : "";\r
+ int year = datefield.getCurrentDate().getYear() + 1900;\r
+ setHTML(0, 2, "<span class=\"" + datefield.CLASSNAME\r
+ + "-calendarpanel-month\">" + monthName + " " + year\r
+ + "</span>");\r
+ }\r
+\r
+ private void buildCalendarBody() {\r
+ Date date = datefield.getCurrentDate();\r
+ if (date == null)\r
+ date = new Date();\r
+ int startWeekDay = datefield.getDateTimeService().getStartWeekDay(date);\r
+ int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
+ int dayCount = 0;\r
+ Date today = new Date();\r
+ Date curr = new Date(date.getTime());\r
+ for (int row = 2; row < 8; row++) {\r
+ for (int col = 0; col < 7; col++) {\r
+ if (!(row == 2 && col < startWeekDay)) {\r
+ if (dayCount < numDays) {\r
+ int selectedDate = ++dayCount;\r
+ String title = "";\r
+ if (this.entrySource != null) {\r
+ curr.setDate(dayCount);\r
+ List entries = this.entrySource.getEntries(curr,\r
+ IDateField.RESOLUTION_DAY);\r
+ if (entries != null) {\r
+ for (Iterator it = entries.iterator(); it\r
+ .hasNext();) {\r
+ CalendarEntry entry = (CalendarEntry) it\r
+ .next();\r
+ title += (title.length() > 0 ? ", " : "")\r
+ + entry.getStringForDate(curr);\r
+ }\r
+ }\r
+ }\r
+ String baseclass = datefield.CLASSNAME\r
+ + "-calendarpanel-day";\r
+ String cssClass = baseclass;\r
+ if (!isEnabledDate(curr)) {\r
+ cssClass += " " + baseclass + "-disabled";\r
+ }\r
+ if (date.getDate() == dayCount) {\r
+ cssClass += " " + baseclass + "-selected";\r
+ }\r
+ if (today.getDate() == dayCount\r
+ && today.getMonth() == date.getMonth()\r
+ && today.getYear() == date.getYear()) {\r
+ cssClass += " " + baseclass + "-today";\r
+ }\r
+ if (title.length() > 0)\r
+ cssClass += " " + baseclass + "-entry";\r
+ setHTML(row, col, "<span title=\"" + title\r
+ + "\" class=\"" + cssClass + "\">"\r
+ + selectedDate + "</span>");\r
+ } else {\r
+ break;\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private void buildTime(boolean forceRedraw) {\r
+ if (time == null) {\r
+ time = new Time(datefield);\r
+ setText(8, 0, ""); // Add new row\r
+ getFlexCellFormatter().setColSpan(8, 0, 7);\r
+ setWidget(8, 0, time);\r
+ }\r
+ time.updateTime(forceRedraw);\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param forceRedraw\r
+ * Build all from scratch, in case of e.g. locale changes\r
+ */\r
+ public void updateCalendar() {\r
+ // Locale and resolution changes force a complete redraw\r
+ buildCalendar(locale != datefield.getCurrentLocale()\r
+ || resolution != datefield.getCurrentResolution());\r
+ if (datefield instanceof ITextualDate)\r
+ ((ITextualDate) datefield).buildDate();\r
+ locale = datefield.getCurrentLocale();\r
+ resolution = datefield.getCurrentResolution();\r
+ }\r
+\r
+ public void onClick(Widget sender) {\r
+ processClickEvent(sender);\r
+ }\r
+\r
+ private boolean isEnabledDate(Date date) {\r
+ if ((this.minDate != null && date.before(this.minDate))\r
+ || (this.maxDate != null && date.after(this.maxDate))) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ private void processClickEvent(Widget sender) {\r
+ if (!datefield.isEnabled() || datefield.isReadonly())\r
+ return;\r
+\r
+ if (sender == prevYear) {\r
+ datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() - 1);\r
+ datefield.getClient().updateVariable(datefield.getId(), "year",\r
+ datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
+ updateCalendar();\r
+ } else if (sender == nextYear) {\r
+ datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() + 1);\r
+ datefield.getClient().updateVariable(datefield.getId(), "year",\r
+ datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
+ updateCalendar();\r
+ } else if (sender == prevMonth) {\r
+ datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() - 1);\r
+ datefield.getClient().updateVariable(datefield.getId(), "month",\r
+ datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
+ updateCalendar();\r
+ } else if (sender == nextMonth) {\r
+ datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() + 1);\r
+ datefield.getClient().updateVariable(datefield.getId(), "month",\r
+ datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
+ updateCalendar();\r
+ }\r
+ }\r
+\r
+ private Timer timer;\r
+\r
+ public void onMouseDown(final Widget sender, int x, int y) {\r
+ if (sender instanceof IEventButton) {\r
+ timer = new Timer() {\r
+ public void run() {\r
+ processClickEvent(sender);\r
+ }\r
+ };\r
+ timer.scheduleRepeating(100);\r
+ }\r
+ }\r
+\r
+ public void onMouseEnter(Widget sender) {\r
+ }\r
+\r
+ public void onMouseLeave(Widget sender) {\r
+ if (timer != null)\r
+ timer.cancel();\r
+ }\r
+\r
+ public void onMouseMove(Widget sender, int x, int y) {\r
+ }\r
+\r
+ public void onMouseUp(Widget sender, int x, int y) {\r
+ if (timer != null)\r
+ timer.cancel();\r
+ }\r
+\r
+ private class IEventButton extends IButton implements SourcesMouseEvents {\r
+\r
+ private MouseListenerCollection mouseListeners;\r
+\r
+ public IEventButton() {\r
+ super();\r
+ sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK\r
+ | Event.MOUSEEVENTS);\r
+ }\r
+\r
+ public void addMouseListener(MouseListener listener) {\r
+ if (mouseListeners == null) {\r
+ mouseListeners = new MouseListenerCollection();\r
+ }\r
+ mouseListeners.add(listener);\r
+ }\r
+\r
+ public void removeMouseListener(MouseListener listener) {\r
+ if (mouseListeners != null)\r
+ mouseListeners.remove(listener);\r
+ }\r
+\r
+ public void onBrowserEvent(Event event) {\r
+ super.onBrowserEvent(event);\r
+ switch (DOM.eventGetType(event)) {\r
+ case Event.ONMOUSEDOWN:\r
+ case Event.ONMOUSEUP:\r
+ case Event.ONMOUSEMOVE:\r
+ case Event.ONMOUSEOVER:\r
+ case Event.ONMOUSEOUT:\r
+ if (mouseListeners != null) {\r
+ mouseListeners.fireMouseEvent(this, event);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ private class DateClickListener implements TableListener {\r
+\r
+ private CalendarPanel cal;\r
+\r
+ public DateClickListener(CalendarPanel panel) {\r
+ cal = panel;\r
+ }\r
+\r
+ public void onCellClicked(SourcesTableEvents sender, int row, int col) {\r
+ if (sender != cal || row < 2 || row > 7 || !cal.datefield.isEnabled()\r
+ || cal.datefield.isReadonly())\r
+ return;\r
+\r
+ String text = cal.getText(row, col);\r
+ if (text.equals(" "))\r
+ return;\r
+\r
+ Integer day = new Integer(text);\r
+\r
+ Date newDate = new Date(cal.datefield.getCurrentDate().getTime());\r
+ newDate.setDate(day.intValue());\r
+ if (!isEnabledDate(newDate)) {\r
+ return;\r
+ }\r
+ cal.datefield.getCurrentDate().setTime(newDate.getTime());\r
+ cal.datefield.getClient().updateVariable(cal.datefield.getId(), "day",\r
+ cal.datefield.getCurrentDate().getDate(), cal.datefield.isImmediate());\r
+\r
+ updateCalendar();\r
+ }\r
+\r
+ }\r
+\r
+ public void setLimits(Date min, Date max) {\r
+ if (min != null) {\r
+ Date d = new Date(min.getTime());\r
+ d.setHours(0);\r
+ d.setMinutes(0);\r
+ d.setSeconds(1);\r
+ this.minDate = d;\r
+ } else {\r
+ this.minDate = null;\r
+ }\r
+ if (max != null) {\r
+ Date d = new Date(max.getTime());\r
+ d.setHours(24);\r
+ d.setMinutes(59);\r
+ d.setSeconds(59);\r
+ this.maxDate = d;\r
+ } else {\r
+ this.maxDate = null;\r
+ }\r
+ }\r
+\r
+ public void setCalendarEntrySource(CalendarEntrySource entrySource) {\r
+ this.entrySource = entrySource;\r
+ }\r
+\r
+ public CalendarEntrySource getCalendarEntrySource() {\r
+ return this.entrySource;\r
+ }\r
+\r
+ public interface CalendarEntrySource {\r
+ public List getEntries(Date date, int resolution);\r
+ }\r
+\r
+}\r
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
\r
public class ICalendar extends IDateField {\r
\r
- private ICalendarPanel calPanel;\r
+ private CalendarPanel calPanel;\r
\r
private HTMLTable hourTable;\r
\r
public ICalendar() {\r
super();\r
setStyleName(CLASSNAME);\r
- calPanel = new ICalendarPanel(this);\r
+ calPanel = new CalendarPanel(this);\r
add(calPanel);\r
this.entrySource = new EntrySource();\r
calPanel.setCalendarEntrySource(this.entrySource);\r
String text = "";\r
if (entries != null) {\r
for (Iterator it = entries.iterator(); it.hasNext();) {\r
- ICalendarEntry entry = (ICalendarEntry) it.next();\r
+ CalendarEntry entry = (CalendarEntry) it.next();\r
String title = entry.getTitle();\r
String desc = entry.getDescription();\r
text += (text == "" ? "" : ", ");\r
\r
}\r
\r
- private class EntrySource implements ICalendarPanel.CalendarEntrySource {\r
+ private class EntrySource implements CalendarPanel.CalendarEntrySource {\r
\r
private HashMap items = new HashMap();\r
\r
if (items.containsKey(id)) {\r
items.remove(id);\r
}\r
- items.put(id, new ICalendarEntry(startDate, endDate, title, desc,\r
+ items.put(id, new CalendarEntry(startDate, endDate, title, desc,\r
notime));\r
}\r
\r
public List getEntries(Date date, int resolution) {\r
ArrayList res = new ArrayList();\r
for (Iterator it = this.items.values().iterator(); it.hasNext();) {\r
- ICalendarEntry item = (ICalendarEntry) it.next();\r
+ CalendarEntry item = (CalendarEntry) it.next();\r
if (DateTimeService.isInRange(date, item.getStart(), item\r
.getEnd(), resolution)) {\r
res.add(item);\r
\r
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
\r
public class IDateFieldCalendar extends IDateField {\r
\r
- private ICalendarPanel date;\r
+ private CalendarPanel date;\r
\r
public IDateFieldCalendar() {\r
super();\r
setStyleName(CLASSNAME+"-calendar");\r
- date = new ICalendarPanel(this);\r
+ date = new CalendarPanel(this);\r
add(date);\r
}\r
\r
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel;\r
\r
public class IPopupCalendar extends ITextualDate implements Paintable, ClickListener, PopupListener {\r
\r
private IButton calendarToggle;\r
\r
- private ICalendarPanel calendar;\r
+ private CalendarPanel calendar;\r
\r
private PopupPanel popup;\r
\r
calendarToggle.addClickListener(this);\r
add(calendarToggle);\r
\r
- calendar = new ICalendarPanel(this);\r
+ calendar = new CalendarPanel(this);\r
popup = new PopupPanel(true);\r
popup.setStyleName(IDateField.CLASSNAME+"-calendar");\r
popup.setWidget(calendar);\r
import com.itmill.toolkit.terminal.gwt.client.DateLocale;\r
import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.gwtwidgets.util.SimpleDateFormat;\r
+import com.itmill.toolkit.terminal.gwt.client.util.SimpleDateFormat;\r
\r
public class ITextualDate extends IDateField implements Paintable, ChangeListener {\r
\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.user.client.ui.ChangeListener;\r
+import com.google.gwt.user.client.ui.FlowPanel;\r
+import com.google.gwt.user.client.ui.ListBox;\r
+import com.google.gwt.user.client.ui.Widget;\r
+\r
+public class Time extends FlowPanel implements ChangeListener {\r
+ \r
+ private IDateField datefield;\r
+ \r
+ private ListBox hours;\r
+ \r
+ private ListBox mins;\r
+ \r
+ private ListBox sec;\r
+ \r
+ private ListBox msec;\r
+ \r
+ private ListBox ampm;\r
+ \r
+ private int resolution = IDateField.RESOLUTION_HOUR;\r
+ \r
+ private boolean readonly;\r
+ \r
+ public Time(IDateField parent) {\r
+ super();\r
+ datefield = parent;\r
+ setStyleName(IDateField.CLASSNAME+"-time");\r
+ }\r
+ \r
+ private void buildTime(boolean redraw) {\r
+ boolean thc = datefield.getDateTimeService().isTwelveHourClock();\r
+ if(redraw) {\r
+ clear();\r
+ int numHours = thc?12:24;\r
+ hours = new ListBox();\r
+ hours.setStyleName(ISelect.CLASSNAME);\r
+ for(int i=0; i<numHours; i++)\r
+ hours.addItem((i<10)?"0"+i:""+i);\r
+ hours.addChangeListener(this);\r
+ if(thc) {\r
+ ampm = new ListBox();\r
+ ampm.setStyleName(ISelect.CLASSNAME);\r
+ String[] ampmText = datefield.getDateTimeService().getAmPmStrings();\r
+ ampm.addItem(ampmText[0]);\r
+ ampm.addItem(ampmText[1]);\r
+ ampm.addChangeListener(this);\r
+ }\r
+ \r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+ mins = new ListBox();\r
+ mins.setStyleName(ISelect.CLASSNAME);\r
+ for(int i=0; i<60; i++)\r
+ mins.addItem((i<10)?"0"+i:""+i);\r
+ mins.addChangeListener(this);\r
+ }\r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+ sec = new ListBox();\r
+ sec.setStyleName(ISelect.CLASSNAME);\r
+ for(int i=0; i<60; i++)\r
+ sec.addItem((i<10)?"0"+i:""+i);\r
+ sec.addChangeListener(this);\r
+ }\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+ msec = new ListBox();\r
+ msec.setStyleName(ISelect.CLASSNAME);\r
+ for(int i=0; i<1000; i++) {\r
+ if(i<10)\r
+ msec.addItem("00"+i);\r
+ else if(i<100)\r
+ msec.addItem("0"+i);\r
+ else msec.addItem(""+i);\r
+ }\r
+ msec.addChangeListener(this);\r
+ }\r
+ \r
+ String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
+ boolean ro = datefield.isReadonly();\r
+ \r
+ if(ro) {\r
+ int h = 0;\r
+ if(datefield.getCurrentDate() != null)\r
+ h = datefield.getCurrentDate().getHours();\r
+ if(thc) h -= h<12? 0 : 12;\r
+ add(new ILabel(h<10? "0"+h : ""+h));\r
+ } else add(hours);\r
+ \r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+ add(new ILabel(delimiter));\r
+ if(ro) {\r
+ int m = mins.getSelectedIndex();\r
+ add(new ILabel(m<10? "0"+m : ""+m));\r
+ }\r
+ else add(mins);\r
+ }\r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+ add(new ILabel(delimiter));\r
+ if(ro) {\r
+ int s = sec.getSelectedIndex();\r
+ add(new ILabel(s<10? "0"+s : ""+s));\r
+ }\r
+ else add(sec);\r
+ }\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+ add(new ILabel("."));\r
+ if(ro) {\r
+ int m = datefield.getMilliseconds();\r
+ String ms = m<100? "0"+m : ""+m;\r
+ add(new ILabel(m<10? "0"+ms : ms));\r
+ }\r
+ else add(msec);\r
+ }\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
+ add(new ILabel(delimiter+"00")); // o'clock\r
+ }\r
+ if(thc) {\r
+ add(new ILabel(" "));\r
+ if(ro) add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
+ else add(ampm);\r
+ }\r
+ \r
+ if(ro) return;\r
+ }\r
+ \r
+ // Update times\r
+ if(thc) {\r
+ int h = datefield.getCurrentDate().getHours();\r
+ ampm.setSelectedIndex(h<12? 0 : 1);\r
+ h -= ampm.getSelectedIndex()*12;\r
+ hours.setSelectedIndex(h);\r
+ } else\r
+ hours.setSelectedIndex(datefield.getCurrentDate().getHours());\r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN)\r
+ mins.setSelectedIndex(datefield.getCurrentDate().getMinutes());\r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC)\r
+ sec.setSelectedIndex(datefield.getCurrentDate().getSeconds());\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC)\r
+ msec.setSelectedIndex(datefield.getMilliseconds());\r
+ if(thc)\r
+ ampm.setSelectedIndex(datefield.getCurrentDate().getHours()<12?0:1);\r
+ \r
+ if(datefield.isReadonly() && !redraw) {\r
+ // Do complete redraw when in read-only status\r
+ clear();\r
+ String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
+ \r
+ int h = datefield.getCurrentDate().getHours();\r
+ if(thc) h -= h<12? 0 : 12;\r
+ add(new ILabel(h<10? "0"+h : ""+h));\r
+ \r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
+ add(new ILabel(delimiter));\r
+ int m = mins.getSelectedIndex();\r
+ add(new ILabel(m<10? "0"+m : ""+m));\r
+ }\r
+ if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
+ add(new ILabel(delimiter));\r
+ int s = sec.getSelectedIndex();\r
+ add(new ILabel(s<10? "0"+s : ""+s));\r
+ }\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
+ add(new ILabel("."));\r
+ int m = datefield.getMilliseconds();\r
+ String ms = m<100? "0"+m : ""+m;\r
+ add(new ILabel(m<10? "0"+ms : ms));\r
+ }\r
+ if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
+ add(new ILabel(delimiter+"00")); // o'clock\r
+ }\r
+ if(thc) {\r
+ add(new ILabel(" "));\r
+ add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
+ }\r
+ }\r
+ \r
+ boolean enabled = datefield.isEnabled();\r
+ hours.setEnabled(enabled);\r
+ if(mins != null) mins.setEnabled(enabled);\r
+ if(sec != null) sec.setEnabled(enabled);\r
+ if(msec != null) msec.setEnabled(enabled);\r
+ if(ampm != null) ampm.setEnabled(enabled);\r
+ \r
+ }\r
+\r
+ public void updateTime(boolean redraw) {\r
+ buildTime(redraw || resolution != datefield.getCurrentResolution() \r
+ || readonly != datefield.isReadonly());\r
+ if(datefield instanceof ITextualDate)\r
+ ((ITextualDate) datefield).buildDate();\r
+ resolution = datefield.getCurrentResolution();\r
+ readonly = datefield.isReadonly();\r
+ }\r
+\r
+ public void onChange(Widget sender) {\r
+ if(sender == hours) {\r
+ int h = hours.getSelectedIndex();\r
+ if(datefield.getDateTimeService().isTwelveHourClock())\r
+ h = h + ampm.getSelectedIndex()*12;\r
+ datefield.getCurrentDate().setHours(h);\r
+ datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
+ updateTime(false);\r
+ }\r
+ else if(sender == mins) {\r
+ int m = mins.getSelectedIndex();\r
+ datefield.getCurrentDate().setMinutes(m);\r
+ datefield.getClient().updateVariable(datefield.getId(), "min", m, datefield.isImmediate());\r
+ updateTime(false);\r
+ }\r
+ else if(sender == sec) {\r
+ int s = sec.getSelectedIndex();\r
+ datefield.getCurrentDate().setSeconds(s);\r
+ datefield.getClient().updateVariable(datefield.getId(), "sec", s, datefield.isImmediate());\r
+ updateTime(false);\r
+ }\r
+ else if(sender == msec) {\r
+ int ms = msec.getSelectedIndex();\r
+ datefield.setMilliseconds(ms);\r
+ datefield.getClient().updateVariable(datefield.getId(), "msec", ms, datefield.isImmediate());\r
+ updateTime(false);\r
+ }\r
+ else if(sender == ampm) {\r
+ int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12;\r
+ datefield.getCurrentDate().setHours(h);\r
+ datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
+ updateTime(false);\r
+ }\r
+ }\r
+\r
+}\r
+++ /dev/null
-package com.itmill.toolkit.terminal.gwt.client.ui.calendar;\r
-\r
-import java.util.Date;\r
-\r
-import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
-\r
-public class ICalendarEntry {\r
- private Date start;\r
- private Date end;\r
- private String title;\r
- private String description;\r
- private boolean notime;\r
-\r
- public ICalendarEntry(Date start, Date end, String title, String description, boolean notime) {\r
- if (notime) {\r
- Date d = new Date(start.getTime());\r
- d.setSeconds(0);\r
- d.setMinutes(0);\r
- this.start = d;\r
- if (end != null) {\r
- d = new Date(end.getTime());\r
- d.setSeconds(0);\r
- d.setMinutes(0);\r
- this.end = d;\r
- } else {\r
- end = start;\r
- }\r
- } else {\r
- this.start = start;\r
- this.end = end;\r
- }\r
- this.title = title;\r
- this.description = description;\r
- this.notime = notime;\r
- }\r
-\r
- public ICalendarEntry(Date start, Date end, String title, String description) {\r
- this(start, end, title, description, false);\r
- }\r
-\r
- public Date getStart() {\r
- return start;\r
- }\r
-\r
- public void setStart(Date start) {\r
- this.start = start;\r
- }\r
-\r
- public Date getEnd() {\r
- return end;\r
- }\r
-\r
- public void setEnd(Date end) {\r
- this.end = end;\r
- }\r
-\r
- public String getTitle() {\r
- return title;\r
- }\r
-\r
- public void setTitle(String title) {\r
- this.title = title;\r
- }\r
-\r
- public String getDescription() {\r
- return description;\r
- }\r
-\r
- public void setDescription(String description) {\r
- this.description = description;\r
- }\r
-\r
- public boolean isNotime() {\r
- return notime;\r
- }\r
-\r
- public void setNotime(boolean notime) {\r
- this.notime = notime;\r
- }\r
-\r
- public String getStringForDate(Date d) {\r
- // TODO format from DateTimeService\r
- String s = "";\r
- if (!notime) {\r
- if (!DateTimeService.isSameDay(d, start)) {\r
- s += (start.getYear() + 1900) + "." + (start.getMonth() + 1)\r
- + "." + start.getDate() + " ";\r
- }\r
- int i = start.getHours();\r
- s += (i < 10 ? "0" : "") + i;\r
- s += ":";\r
- i = start.getMinutes();\r
- s += (i < 10 ? "0" : "") + i;\r
- if (!start.equals(end)) {\r
- s += " - ";\r
- if (!DateTimeService.isSameDay(start, end)) {\r
- s += (end.getYear() + 1900) + "." + (end.getMonth() + 1) + "."\r
- + end.getDate() + " ";\r
- }\r
- i = end.getHours();\r
- s += (i < 10 ? "0" : "") + i;\r
- s += ":";\r
- i = end.getMinutes();\r
- s += (i < 10 ? "0" : "") + i;\r
- }\r
- s += " ";\r
- }\r
- s += title;\r
- return s;\r
- }\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-package com.itmill.toolkit.terminal.gwt.client.ui.datefield;\r
-\r
-import java.util.Date;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.Timer;\r
-import com.google.gwt.user.client.ui.ClickListener;\r
-import com.google.gwt.user.client.ui.FlexTable;\r
-import com.google.gwt.user.client.ui.MouseListener;\r
-import com.google.gwt.user.client.ui.MouseListenerCollection;\r
-import com.google.gwt.user.client.ui.SourcesMouseEvents;\r
-import com.google.gwt.user.client.ui.SourcesTableEvents;\r
-import com.google.gwt.user.client.ui.TableListener;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
-import com.itmill.toolkit.terminal.gwt.client.LocaleService;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.IButton;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry;\r
-\r
-public class ICalendarPanel extends FlexTable implements MouseListener,\r
- ClickListener {\r
-\r
- private IDateField datefield;\r
-\r
- private IEventButton prevYear;\r
- private IEventButton nextYear;\r
- private IEventButton prevMonth;\r
- private IEventButton nextMonth;\r
-\r
- private ITime time;\r
-\r
- private Date minDate = null;\r
- private Date maxDate = null;\r
-\r
- private CalendarEntrySource entrySource;\r
-\r
- /* Needed to identify resolution changes */\r
- private int resolution = IDateField.RESOLUTION_YEAR;\r
-\r
- /* Needed to identify locale changes */\r
- private String locale = LocaleService.getDefaultLocale();\r
-\r
- public ICalendarPanel(IDateField parent) {\r
- datefield = parent;\r
- setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
- // buildCalendar(true);\r
- addTableListener(new DateClickListener(this));\r
- }\r
-\r
- public ICalendarPanel(IDateField parent, Date min, Date max) {\r
- datefield = parent;\r
- setStyleName(datefield.CLASSNAME + "-calendarpanel");\r
- // buildCalendar(true);\r
- addTableListener(new DateClickListener(this));\r
- }\r
-\r
- private void buildCalendar(boolean forceRedraw) {\r
- boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR;\r
- boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY;\r
- boolean needsTime = datefield.getCurrentResolution() >= IDateField.RESOLUTION_HOUR;\r
- buildCalendarHeader(forceRedraw, needsMonth);\r
- clearCalendarBody(!needsBody);\r
- if (needsBody)\r
- buildCalendarBody();\r
- if (needsTime)\r
- buildTime(forceRedraw);\r
- else if (time != null) {\r
- remove(time);\r
- time = null;\r
- }\r
- }\r
-\r
- private void clearCalendarBody(boolean remove) {\r
- if (!remove) {\r
- for (int row = 2; row < 8; row++) {\r
- for (int col = 0; col < 7; col++) {\r
- setHTML(row, col, " ");\r
- }\r
- }\r
- } else if (getRowCount() > 2) {\r
- while (getRowCount() > 2)\r
- removeRow(2);\r
- }\r
- }\r
-\r
- private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {\r
- // Can't draw a calendar without a date :)\r
- if (datefield.getCurrentDate() == null)\r
- datefield.setCurrentDate(new Date());\r
-\r
- if (forceRedraw) {\r
- if (prevMonth == null) { // Only do once\r
- prevYear = new IEventButton();\r
- prevYear.setHTML("«");\r
- nextYear = new IEventButton();\r
- nextYear.setHTML("»");\r
- prevYear.addMouseListener(this);\r
- nextYear.addMouseListener(this);\r
- prevYear.addClickListener(this);\r
- nextYear.addClickListener(this);\r
- setWidget(0, 0, prevYear);\r
- setWidget(0, 4, nextYear);\r
-\r
- if (needsMonth) {\r
- prevMonth = new IEventButton();\r
- prevMonth.setHTML("‹");\r
- nextMonth = new IEventButton();\r
- nextMonth.setHTML("›");\r
- prevMonth.addMouseListener(this);\r
- nextMonth.addMouseListener(this);\r
- prevMonth.addClickListener(this);\r
- nextMonth.addClickListener(this);\r
- setWidget(0, 3, nextMonth);\r
- setWidget(0, 1, prevMonth);\r
- }\r
-\r
- getFlexCellFormatter().setColSpan(0, 2, 3);\r
- } else if (!needsMonth) {\r
- // Remove month traverse buttons\r
- prevMonth.removeClickListener(this);\r
- prevMonth.removeMouseListener(this);\r
- nextMonth.removeClickListener(this);\r
- nextMonth.removeMouseListener(this);\r
- remove(prevMonth);\r
- remove(nextMonth);\r
- prevMonth = null;\r
- nextMonth = null;\r
- }\r
-\r
- // Print weekday names\r
- int firstDay = datefield.getDateTimeService().getFirstDayOfWeek();\r
- for (int i = 0; i < 7; i++) {\r
- int day = i + firstDay;\r
- if (day > 6)\r
- day = 0;\r
- if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH)\r
- setHTML(1, i, "<strong>"\r
- + datefield.getDateTimeService().getShortDay(day)\r
- + "</strong>");\r
- else\r
- setHTML(1, i, "");\r
- }\r
- }\r
-\r
- String monthName = needsMonth ? datefield.getDateTimeService()\r
- .getMonth(datefield.getCurrentDate().getMonth()) : "";\r
- int year = datefield.getCurrentDate().getYear() + 1900;\r
- setHTML(0, 2, "<span class=\"" + datefield.CLASSNAME\r
- + "-calendarpanel-month\">" + monthName + " " + year\r
- + "</span>");\r
- }\r
-\r
- private void buildCalendarBody() {\r
- Date date = datefield.getCurrentDate();\r
- if (date == null)\r
- date = new Date();\r
- int startWeekDay = datefield.getDateTimeService().getStartWeekDay(date);\r
- int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
- int dayCount = 0;\r
- Date today = new Date();\r
- Date curr = new Date(date.getTime());\r
- for (int row = 2; row < 8; row++) {\r
- for (int col = 0; col < 7; col++) {\r
- if (!(row == 2 && col < startWeekDay)) {\r
- if (dayCount < numDays) {\r
- int selectedDate = ++dayCount;\r
- String title = "";\r
- if (this.entrySource != null) {\r
- curr.setDate(dayCount);\r
- List entries = this.entrySource.getEntries(curr,\r
- IDateField.RESOLUTION_DAY);\r
- if (entries != null) {\r
- for (Iterator it = entries.iterator(); it\r
- .hasNext();) {\r
- ICalendarEntry entry = (ICalendarEntry) it\r
- .next();\r
- title += (title.length() > 0 ? ", " : "")\r
- + entry.getStringForDate(curr);\r
- }\r
- }\r
- }\r
- String baseclass = datefield.CLASSNAME\r
- + "-calendarpanel-day";\r
- String cssClass = baseclass;\r
- if (!isEnabledDate(curr)) {\r
- cssClass += " " + baseclass + "-disabled";\r
- }\r
- if (date.getDate() == dayCount) {\r
- cssClass += " " + baseclass + "-selected";\r
- }\r
- if (today.getDate() == dayCount\r
- && today.getMonth() == date.getMonth()\r
- && today.getYear() == date.getYear()) {\r
- cssClass += " " + baseclass + "-today";\r
- }\r
- if (title.length() > 0)\r
- cssClass += " " + baseclass + "-entry";\r
- setHTML(row, col, "<span title=\"" + title\r
- + "\" class=\"" + cssClass + "\">"\r
- + selectedDate + "</span>");\r
- } else {\r
- break;\r
- }\r
-\r
- }\r
- }\r
- }\r
- }\r
-\r
- private void buildTime(boolean forceRedraw) {\r
- if (time == null) {\r
- time = new ITime(datefield);\r
- setText(8, 0, ""); // Add new row\r
- getFlexCellFormatter().setColSpan(8, 0, 7);\r
- setWidget(8, 0, time);\r
- }\r
- time.updateTime(forceRedraw);\r
- }\r
-\r
- /**\r
- * \r
- * @param forceRedraw\r
- * Build all from scratch, in case of e.g. locale changes\r
- */\r
- public void updateCalendar() {\r
- // Locale and resolution changes force a complete redraw\r
- buildCalendar(locale != datefield.getCurrentLocale()\r
- || resolution != datefield.getCurrentResolution());\r
- if (datefield instanceof ITextualDate)\r
- ((ITextualDate) datefield).buildDate();\r
- locale = datefield.getCurrentLocale();\r
- resolution = datefield.getCurrentResolution();\r
- }\r
-\r
- public void onClick(Widget sender) {\r
- processClickEvent(sender);\r
- }\r
-\r
- private boolean isEnabledDate(Date date) {\r
- if ((this.minDate != null && date.before(this.minDate))\r
- || (this.maxDate != null && date.after(this.maxDate))) {\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- private void processClickEvent(Widget sender) {\r
- if (!datefield.isEnabled() || datefield.isReadonly())\r
- return;\r
-\r
- if (sender == prevYear) {\r
- datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() - 1);\r
- datefield.getClient().updateVariable(datefield.getId(), "year",\r
- datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
- updateCalendar();\r
- } else if (sender == nextYear) {\r
- datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() + 1);\r
- datefield.getClient().updateVariable(datefield.getId(), "year",\r
- datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate());\r
- updateCalendar();\r
- } else if (sender == prevMonth) {\r
- datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() - 1);\r
- datefield.getClient().updateVariable(datefield.getId(), "month",\r
- datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
- updateCalendar();\r
- } else if (sender == nextMonth) {\r
- datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() + 1);\r
- datefield.getClient().updateVariable(datefield.getId(), "month",\r
- datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate());\r
- updateCalendar();\r
- }\r
- }\r
-\r
- private Timer timer;\r
-\r
- public void onMouseDown(final Widget sender, int x, int y) {\r
- if (sender instanceof IEventButton) {\r
- timer = new Timer() {\r
- public void run() {\r
- processClickEvent(sender);\r
- }\r
- };\r
- timer.scheduleRepeating(100);\r
- }\r
- }\r
-\r
- public void onMouseEnter(Widget sender) {\r
- }\r
-\r
- public void onMouseLeave(Widget sender) {\r
- if (timer != null)\r
- timer.cancel();\r
- }\r
-\r
- public void onMouseMove(Widget sender, int x, int y) {\r
- }\r
-\r
- public void onMouseUp(Widget sender, int x, int y) {\r
- if (timer != null)\r
- timer.cancel();\r
- }\r
-\r
- private class IEventButton extends IButton implements SourcesMouseEvents {\r
-\r
- private MouseListenerCollection mouseListeners;\r
-\r
- public IEventButton() {\r
- super();\r
- sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK\r
- | Event.MOUSEEVENTS);\r
- }\r
-\r
- public void addMouseListener(MouseListener listener) {\r
- if (mouseListeners == null) {\r
- mouseListeners = new MouseListenerCollection();\r
- }\r
- mouseListeners.add(listener);\r
- }\r
-\r
- public void removeMouseListener(MouseListener listener) {\r
- if (mouseListeners != null)\r
- mouseListeners.remove(listener);\r
- }\r
-\r
- public void onBrowserEvent(Event event) {\r
- super.onBrowserEvent(event);\r
- switch (DOM.eventGetType(event)) {\r
- case Event.ONMOUSEDOWN:\r
- case Event.ONMOUSEUP:\r
- case Event.ONMOUSEMOVE:\r
- case Event.ONMOUSEOVER:\r
- case Event.ONMOUSEOUT:\r
- if (mouseListeners != null) {\r
- mouseListeners.fireMouseEvent(this, event);\r
- }\r
- break;\r
- }\r
- }\r
- }\r
-\r
- private class DateClickListener implements TableListener {\r
-\r
- private ICalendarPanel cal;\r
-\r
- public DateClickListener(ICalendarPanel panel) {\r
- cal = panel;\r
- }\r
-\r
- public void onCellClicked(SourcesTableEvents sender, int row, int col) {\r
- if (sender != cal || row < 2 || row > 7 || !cal.datefield.isEnabled()\r
- || cal.datefield.isReadonly())\r
- return;\r
-\r
- String text = cal.getText(row, col);\r
- if (text.equals(" "))\r
- return;\r
-\r
- Integer day = new Integer(text);\r
-\r
- Date newDate = new Date(cal.datefield.getCurrentDate().getTime());\r
- newDate.setDate(day.intValue());\r
- if (!isEnabledDate(newDate)) {\r
- return;\r
- }\r
- cal.datefield.getCurrentDate().setTime(newDate.getTime());\r
- cal.datefield.getClient().updateVariable(cal.datefield.getId(), "day",\r
- cal.datefield.getCurrentDate().getDate(), cal.datefield.isImmediate());\r
-\r
- updateCalendar();\r
- }\r
-\r
- }\r
-\r
- public void setLimits(Date min, Date max) {\r
- if (min != null) {\r
- Date d = new Date(min.getTime());\r
- d.setHours(0);\r
- d.setMinutes(0);\r
- d.setSeconds(1);\r
- this.minDate = d;\r
- } else {\r
- this.minDate = null;\r
- }\r
- if (max != null) {\r
- Date d = new Date(max.getTime());\r
- d.setHours(24);\r
- d.setMinutes(59);\r
- d.setSeconds(59);\r
- this.maxDate = d;\r
- } else {\r
- this.maxDate = null;\r
- }\r
- }\r
-\r
- public void setCalendarEntrySource(CalendarEntrySource entrySource) {\r
- this.entrySource = entrySource;\r
- }\r
-\r
- public CalendarEntrySource getCalendarEntrySource() {\r
- return this.entrySource;\r
- }\r
-\r
- public interface CalendarEntrySource {\r
- public List getEntries(Date date, int resolution);\r
- }\r
-\r
-}\r
+++ /dev/null
-package com.itmill.toolkit.terminal.gwt.client.ui.datefield;\r
-\r
-import com.google.gwt.user.client.ui.ChangeListener;\r
-import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.google.gwt.user.client.ui.ListBox;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.IDateField;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.ILabel;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.ISelect;\r
-import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate;\r
-\r
-public class ITime extends FlowPanel implements ChangeListener {\r
- \r
- private IDateField datefield;\r
- \r
- private ListBox hours;\r
- \r
- private ListBox mins;\r
- \r
- private ListBox sec;\r
- \r
- private ListBox msec;\r
- \r
- private ListBox ampm;\r
- \r
- private int resolution = IDateField.RESOLUTION_HOUR;\r
- \r
- private boolean readonly;\r
- \r
- public ITime(IDateField parent) {\r
- super();\r
- datefield = parent;\r
- setStyleName(IDateField.CLASSNAME+"-time");\r
- }\r
- \r
- private void buildTime(boolean redraw) {\r
- boolean thc = datefield.getDateTimeService().isTwelveHourClock();\r
- if(redraw) {\r
- clear();\r
- int numHours = thc?12:24;\r
- hours = new ListBox();\r
- hours.setStyleName(ISelect.CLASSNAME);\r
- for(int i=0; i<numHours; i++)\r
- hours.addItem((i<10)?"0"+i:""+i);\r
- hours.addChangeListener(this);\r
- if(thc) {\r
- ampm = new ListBox();\r
- ampm.setStyleName(ISelect.CLASSNAME);\r
- String[] ampmText = datefield.getDateTimeService().getAmPmStrings();\r
- ampm.addItem(ampmText[0]);\r
- ampm.addItem(ampmText[1]);\r
- ampm.addChangeListener(this);\r
- }\r
- \r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
- mins = new ListBox();\r
- mins.setStyleName(ISelect.CLASSNAME);\r
- for(int i=0; i<60; i++)\r
- mins.addItem((i<10)?"0"+i:""+i);\r
- mins.addChangeListener(this);\r
- }\r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
- sec = new ListBox();\r
- sec.setStyleName(ISelect.CLASSNAME);\r
- for(int i=0; i<60; i++)\r
- sec.addItem((i<10)?"0"+i:""+i);\r
- sec.addChangeListener(this);\r
- }\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
- msec = new ListBox();\r
- msec.setStyleName(ISelect.CLASSNAME);\r
- for(int i=0; i<1000; i++) {\r
- if(i<10)\r
- msec.addItem("00"+i);\r
- else if(i<100)\r
- msec.addItem("0"+i);\r
- else msec.addItem(""+i);\r
- }\r
- msec.addChangeListener(this);\r
- }\r
- \r
- String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
- boolean ro = datefield.isReadonly();\r
- \r
- if(ro) {\r
- int h = 0;\r
- if(datefield.getCurrentDate() != null)\r
- h = datefield.getCurrentDate().getHours();\r
- if(thc) h -= h<12? 0 : 12;\r
- add(new ILabel(h<10? "0"+h : ""+h));\r
- } else add(hours);\r
- \r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
- add(new ILabel(delimiter));\r
- if(ro) {\r
- int m = mins.getSelectedIndex();\r
- add(new ILabel(m<10? "0"+m : ""+m));\r
- }\r
- else add(mins);\r
- }\r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
- add(new ILabel(delimiter));\r
- if(ro) {\r
- int s = sec.getSelectedIndex();\r
- add(new ILabel(s<10? "0"+s : ""+s));\r
- }\r
- else add(sec);\r
- }\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
- add(new ILabel("."));\r
- if(ro) {\r
- int m = datefield.getMilliseconds();\r
- String ms = m<100? "0"+m : ""+m;\r
- add(new ILabel(m<10? "0"+ms : ms));\r
- }\r
- else add(msec);\r
- }\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
- add(new ILabel(delimiter+"00")); // o'clock\r
- }\r
- if(thc) {\r
- add(new ILabel(" "));\r
- if(ro) add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
- else add(ampm);\r
- }\r
- \r
- if(ro) return;\r
- }\r
- \r
- // Update times\r
- if(thc) {\r
- int h = datefield.getCurrentDate().getHours();\r
- ampm.setSelectedIndex(h<12? 0 : 1);\r
- h -= ampm.getSelectedIndex()*12;\r
- hours.setSelectedIndex(h);\r
- } else\r
- hours.setSelectedIndex(datefield.getCurrentDate().getHours());\r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN)\r
- mins.setSelectedIndex(datefield.getCurrentDate().getMinutes());\r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC)\r
- sec.setSelectedIndex(datefield.getCurrentDate().getSeconds());\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC)\r
- msec.setSelectedIndex(datefield.getMilliseconds());\r
- if(thc)\r
- ampm.setSelectedIndex(datefield.getCurrentDate().getHours()<12?0:1);\r
- \r
- if(datefield.isReadonly() && !redraw) {\r
- // Do complete redraw when in read-only status\r
- clear();\r
- String delimiter = datefield.getDateTimeService().getClockDelimeter();\r
- \r
- int h = datefield.getCurrentDate().getHours();\r
- if(thc) h -= h<12? 0 : 12;\r
- add(new ILabel(h<10? "0"+h : ""+h));\r
- \r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) {\r
- add(new ILabel(delimiter));\r
- int m = mins.getSelectedIndex();\r
- add(new ILabel(m<10? "0"+m : ""+m));\r
- }\r
- if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) {\r
- add(new ILabel(delimiter));\r
- int s = sec.getSelectedIndex();\r
- add(new ILabel(s<10? "0"+s : ""+s));\r
- }\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) {\r
- add(new ILabel("."));\r
- int m = datefield.getMilliseconds();\r
- String ms = m<100? "0"+m : ""+m;\r
- add(new ILabel(m<10? "0"+ms : ms));\r
- }\r
- if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) {\r
- add(new ILabel(delimiter+"00")); // o'clock\r
- }\r
- if(thc) {\r
- add(new ILabel(" "));\r
- add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1)));\r
- }\r
- }\r
- \r
- boolean enabled = datefield.isEnabled();\r
- hours.setEnabled(enabled);\r
- if(mins != null) mins.setEnabled(enabled);\r
- if(sec != null) sec.setEnabled(enabled);\r
- if(msec != null) msec.setEnabled(enabled);\r
- if(ampm != null) ampm.setEnabled(enabled);\r
- \r
- }\r
-\r
- public void updateTime(boolean redraw) {\r
- buildTime(redraw || resolution != datefield.getCurrentResolution() \r
- || readonly != datefield.isReadonly());\r
- if(datefield instanceof ITextualDate)\r
- ((ITextualDate) datefield).buildDate();\r
- resolution = datefield.getCurrentResolution();\r
- readonly = datefield.isReadonly();\r
- }\r
-\r
- public void onChange(Widget sender) {\r
- if(sender == hours) {\r
- int h = hours.getSelectedIndex();\r
- if(datefield.getDateTimeService().isTwelveHourClock())\r
- h = h + ampm.getSelectedIndex()*12;\r
- datefield.getCurrentDate().setHours(h);\r
- datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
- updateTime(false);\r
- }\r
- else if(sender == mins) {\r
- int m = mins.getSelectedIndex();\r
- datefield.getCurrentDate().setMinutes(m);\r
- datefield.getClient().updateVariable(datefield.getId(), "min", m, datefield.isImmediate());\r
- updateTime(false);\r
- }\r
- else if(sender == sec) {\r
- int s = sec.getSelectedIndex();\r
- datefield.getCurrentDate().setSeconds(s);\r
- datefield.getClient().updateVariable(datefield.getId(), "sec", s, datefield.isImmediate());\r
- updateTime(false);\r
- }\r
- else if(sender == msec) {\r
- int ms = msec.getSelectedIndex();\r
- datefield.setMilliseconds(ms);\r
- datefield.getClient().updateVariable(datefield.getId(), "msec", ms, datefield.isImmediate());\r
- updateTime(false);\r
- }\r
- else if(sender == ampm) {\r
- int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12;\r
- datefield.getCurrentDate().setHours(h);\r
- datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate());\r
- updateTime(false);\r
- }\r
- }\r
-\r
-}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.util;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+/**\r
+ * Date locale support for the {@link SimpleDateParser}. You are encouraged to\r
+ * extend this class and provide implementations for other locales. \r
+ * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>\r
+ *\r
+ */\r
+public class DateLocale {\r
+ public final static String TOKEN_DAY_OF_WEEK = "E";\r
+\r
+ public final static String TOKEN_DAY_OF_MONTH = "d";\r
+\r
+ public final static String TOKEN_MONTH = "M";\r
+\r
+ public final static String TOKEN_YEAR = "y";\r
+\r
+ public final static String TOKEN_HOUR_12 = "h";\r
+\r
+ public final static String TOKEN_HOUR_24 = "H";\r
+\r
+ public final static String TOKEN_MINUTE = "m";\r
+\r
+ public final static String TOKEN_SECOND = "s";\r
+ \r
+ public final static String TOKEN_MILLISECOND = "S";\r
+ \r
+ public final static String TOKEN_AM_PM = "a";\r
+\r
+ public final static String AM = "AM";\r
+\r
+ public final static String PM = "PM";\r
+\r
+ public static List SUPPORTED_DF_TOKENS = Arrays.asList(new String[] {\r
+ TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR,\r
+ TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND,\r
+ TOKEN_AM_PM });\r
+ \r
+ public static List TOKENS_RESOLUTION_ALL = Arrays.asList(new String[] {\r
+ TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR,\r
+ TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND,\r
+ TOKEN_AM_PM });\r
+ \r
+ public static List TOKENS_RESOLUTION_YEAR = Arrays.asList(new String[] {\r
+ TOKEN_YEAR});\r
+ \r
+ public static List TOKENS_RESOLUTION_MONTH = Arrays.asList(new String[] {\r
+ TOKEN_YEAR, TOKEN_MONTH});\r
+ \r
+ public static List TOKENS_RESOLUTION_DAY = Arrays.asList(new String[] {\r
+ TOKEN_YEAR, TOKEN_MONTH, TOKEN_DAY_OF_MONTH});\r
+\r
+ public String[] MONTH_LONG = { "January", "February", "March", "April",\r
+ "May", "June", "July", "August", "September", "October",\r
+ "November", "December" };\r
+\r
+ public String[] MONTH_SHORT = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
+ "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };\r
+\r
+ public String[] WEEKDAY_LONG = { "Sunday", "Monday", "Tuesday",\r
+ "Wednesday", "Thursday", "Friday", "Saturday" };\r
+\r
+ public String[] WEEKDAY_SHORT = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",\r
+ "Sat" };\r
+\r
+ public static String getAM() {\r
+ return AM;\r
+ }\r
+\r
+ public static String getPM() {\r
+ return PM;\r
+ }\r
+\r
+ public String[] getWEEKDAY_LONG() {\r
+ return WEEKDAY_LONG;\r
+ }\r
+\r
+ public String[] getWEEKDAY_SHORT() {\r
+ return WEEKDAY_SHORT;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.itmill.toolkit.terminal.gwt.client.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.google.gwt.core.client.JavaScriptObject;\r
+\r
+/**\r
+ * <p>\r
+ * Implementation of the {@link java.util.regex.Pattern} class with a\r
+ * wrapper aroung the Javascript <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Regular_Expressions">RegExp</a> object.\r
+ * As most of the methods delegate to the JavaScript RegExp object, certain differences in the \r
+ * declaration and behaviour of regular expressions must be expected.\r
+ * </p>\r
+ * <p>\r
+ * Please note that neither the {@link java.util.regex.Pattern#compile(String)} method nor\r
+ * {@link Matcher} instances are supported. For the later, consider using {@link Pattern#match(String)}.\r
+ * </p>\r
+ * \r
+ * @author George Georgovassilis\r
+ *\r
+ */\r
+public class Pattern {\r
+\r
+ /**\r
+ * Declares that regular expressions should be matched across line borders.\r
+ */\r
+ public final static int MULTILINE = 1;\r
+\r
+ /**\r
+ * Declares that characters are matched reglardless of case.\r
+ */\r
+ public final static int CASE_INSENSITIVE = 2;\r
+\r
+ private JavaScriptObject regExp;\r
+\r
+ private static JavaScriptObject createExpression(String pattern, int flags) {\r
+ String sFlags = "";\r
+ if ((flags & MULTILINE) != 0)\r
+ sFlags += "m";\r
+ if ((flags & CASE_INSENSITIVE) != 0)\r
+ sFlags += "i";\r
+ return _createExpression(pattern, sFlags);\r
+ }\r
+\r
+ private static native JavaScriptObject _createExpression(String pattern,\r
+ String flags)/*-{\r
+ return new RegExp(pattern, flags);\r
+ }-*/;\r
+\r
+ private native void _match(String text, List matches)/*-{\r
+ var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
+ var result = text.match(regExp);\r
+ if (result == null) return;\r
+ for (var i=0;i<result.length;i++)\r
+ matches.@java.util.ArrayList::add(Ljava/lang/Object;)(result[i]);\r
+ }-*/;\r
+\r
+ /**\r
+ * Determines wether the specified regular expression is validated by the \r
+ * provided input.\r
+ * @param regex Regular expression\r
+ * @param input String to validate\r
+ * @return <code>true</code> if matched.\r
+ */\r
+ public static boolean matches(String regex, String input) {\r
+ return new Pattern(regex).matches(input);\r
+ }\r
+\r
+ /**\r
+ * Escape a provided string so that it will be interpreted as a literal\r
+ * in regular expressions.\r
+ * The current implementation does escape each character even if not neccessary,\r
+ * generating verbose literals.\r
+ * @param input\r
+ * @return\r
+ */\r
+ public static String quote(String input) {\r
+ String output = "";\r
+ for (int i = 0; i < input.length(); i++) {\r
+ output += "\\" + input.charAt(i);\r
+ }\r
+ return output;\r
+ }\r
+\r
+ /**\r
+ * Class constructor\r
+ * @param pattern Regular expression\r
+ */\r
+ public Pattern(String pattern) {\r
+ this(pattern, 0);\r
+ }\r
+\r
+ /**\r
+ * Class constructor\r
+ * @param pattern Regular expression\r
+ * @param flags \r
+ */\r
+ public Pattern(String pattern, int flags) {\r
+ regExp = createExpression(pattern, flags);\r
+ }\r
+\r
+ /**\r
+ * This method is borrowed from the JavaScript RegExp object.\r
+ * It parses a string and returns as an array any assignments to parenthesis groups\r
+ * in the pattern's regular expression\r
+ * @param text\r
+ * @return Array of strings following java's Pattern convention for groups:\r
+ * Group 0 is the entire input string and the remaining groups are the matched parenthesis.\r
+ * In case nothing was matched an empty array is returned.\r
+ */\r
+ public String[] match(String text) {\r
+ List matches = new ArrayList();\r
+ _match(text, matches);\r
+ String arr[] = new String[matches.size()];\r
+ for (int i = 0; i < matches.size(); i++)\r
+ arr[i] = matches.get(i).toString();\r
+ return arr;\r
+ }\r
+\r
+ /**\r
+ * Determines wether a provided text matches the regular expression\r
+ * @param text\r
+ * @return\r
+ */\r
+ public native boolean matches(String text)/*-{\r
+ var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
+ return regExp.test(text);\r
+ }-*/;\r
+\r
+ /**\r
+ * Returns the regular expression for this pattern\r
+ * @return\r
+ */\r
+ public native String pattern()/*-{\r
+ var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
+ return regExp.source;\r
+ }-*/;\r
+\r
+ private native void _split(String input, List results)/*-{\r
+ var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
+ var parts = input.split(regExp);\r
+ for (var i=0;i<parts.length;i++)\r
+ results.@java.util.ArrayList::add(Ljava/lang/Object;)(parts[i] );\r
+ }-*/;\r
+ \r
+ /**\r
+ * Split an input string by the pattern's regular expression\r
+ * @param input\r
+ * @return Array of strings\r
+ */\r
+ public String[] split(String input){\r
+ List results = new ArrayList(); \r
+ _split(input, results);\r
+ String[] parts = new String[results.size()];\r
+ for (int i=0;i<results.size();i++)\r
+ parts[i] = (String)results.get(i);\r
+ return parts;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.itmill.toolkit.terminal.gwt.client.util;
+
+import java.util.Date;
+
+/**
+ * <dl>
+ * <dt><b>Title: </b>
+ * <dd>SimpleDateFormat</dd>
+ * <p>
+ * <dt><b>Description: </b>
+ * <dd>GWT does not implement any of the java.text package, so this class tries
+ * to fill the void of the missing java.text.SimpleDateFormat class. This
+ * version however only supports a subset of the date and time patterns
+ * supported by its java.text counterpart. The pattern symbols supported by this
+ * class are:
+ * <dl>
+ * <dt><b>E</b></dt>
+ * <dd>Day in a week</dd>
+ * <dt><b>d</b></dt>
+ * <dd>Day of the month</dd>
+ * <dt><b>y</b></dt>
+ * <dd>Year</dd>
+ * <dt><b>M</b></dt>
+ * <dd>Month January, Jan, 01, 1</dd>
+ * <dt><b>H</b></dt>
+ * <dd>Hour in 24 hour format (0-23)</dd>
+ * <dt><b>h</b></dt>
+ * <dd>Hour in 12 hour format (1-12)</dd>
+ * <dt><b>m</b></dt>
+ * <dd>Minute of the hour </dd>
+ * <dt><b>s</b></dt>
+ * <dd>Seconds of the minute</dd>
+ * <dt><b>a</b></dt>
+ * <dd>am/pm</dd>
+ * </dl>
+ * All characters that are not recognised as a date format character are
+ * translated literally into the output string. <br/> </dd>
+ * <p>
+ * </dl>
+ * <p>
+ * A simple date parsing facility has also been implemented resembling the java
+ * prototype. You can currently parse most numeric patterns but no temporal
+ * literals (such as day or month names).
+ * </p>
+ *
+ * @author <a href="mailto:jasone@greenrivercomputing.com">Jason Essington</a>
+ * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>
+ * @version $Revision: 0.0 $
+ */
+public class SimpleDateFormat {
+ private String format;
+ private DateLocale locale = new DateLocale();
+
+ /**
+ * Gets the support locale for formatting and parsing dates
+ * @return
+ */
+ public DateLocale getLocale() {
+ return locale;
+ }
+
+ public void setLocale(DateLocale locale) {
+ this.locale = locale;
+ }
+
+ public SimpleDateFormat(String pattern) {
+ format = pattern;
+ }
+
+ public String format(Date date) {
+ String f = "";
+ if (format != null && format.length() > 0) {
+ String lastTokenType = null;
+ String currentToken = "";
+ for (int i = 0; i < format.length(); i++) {
+ String thisChar = format.substring(i, i + 1);
+ String currentTokenType = DateLocale.SUPPORTED_DF_TOKENS
+ .contains(thisChar) ? thisChar : "";
+ if (currentTokenType.equals(lastTokenType) || i == 0) {
+ currentToken += thisChar;
+ lastTokenType = currentTokenType;
+ } else {
+ if ("".equals(lastTokenType))
+ f += currentToken;
+ else
+ f += handleToken(currentToken, date);
+ currentToken = thisChar;
+ lastTokenType = currentTokenType;
+ }
+ }
+ if ("".equals(lastTokenType))
+ f += currentToken;
+ else
+ f += handleToken(currentToken, date);
+ }
+ return f;
+ }
+
+ /**
+ * takes a date format string and returns the formatted portion of the date.
+ * For instance if the token is MMMM then the full month name is returned.
+ *
+ * @param token
+ * date format token
+ * @param date
+ * date to format
+ * @return formatted portion of the date
+ */
+ private String handleToken(String token, Date date) {
+ String response = token;
+ String tc = token.substring(0, 1);
+ if (DateLocale.TOKEN_DAY_OF_WEEK.equals(tc)) {
+ if (token.length() > 3)
+ response = locale.getWEEKDAY_LONG()[date.getDay()];
+ else
+ response = locale.getWEEKDAY_SHORT()[date.getDay()];
+ } else if (DateLocale.TOKEN_DAY_OF_MONTH.equals(tc)) {
+ if (token.length() == 1)
+ response = Integer.toString(date.getDate());
+ else
+ response = twoCharDateField(date.getDate());
+ } else if (DateLocale.TOKEN_MONTH.equals(tc)) {
+ switch (token.length()) {
+ case 1:
+ response = Integer.toString(date.getMonth() + 1);
+ break;
+ case 2:
+ response = twoCharDateField(date.getMonth() + 1);
+ break;
+ case 3:
+ response = locale.MONTH_SHORT[date.getMonth()];
+ break;
+ default:
+ response = locale.MONTH_LONG[date.getMonth()];
+ break;
+ }
+ } else if (DateLocale.TOKEN_YEAR.equals(tc)) {
+ if (token.length() >= 2)
+ response = Integer.toString(date.getYear() + 1900);
+ else
+ response = twoCharDateField(date.getYear());
+ } else if (DateLocale.TOKEN_HOUR_12.equals(tc)) {
+ int h = date.getHours();
+ if (h == 0)
+ h = 12;
+ else if (h > 12)
+ h -= 12;
+ //if (token.length() > 1)
+ response = twoCharDateField(h);
+ //else
+ //response = Integer.toString(h);
+ } else if (DateLocale.TOKEN_HOUR_24.equals(tc)) {
+ //if (token.length() > 1)
+ response = twoCharDateField(date.getHours());
+ //else
+ //response = Integer.toString(date.getHours());
+ } else if (DateLocale.TOKEN_MINUTE.equals(tc)) {
+ //if (token.length() > 1)
+ response = twoCharDateField(date.getMinutes());
+ //else
+ //response = Integer.toString(date.getMinutes());
+ } else if (DateLocale.TOKEN_SECOND.equals(tc)) {
+ //if (token.length() > 1)
+ response = twoCharDateField(date.getSeconds());
+ //else
+ //response = Integer.toString(date.getSeconds());
+ } else if (DateLocale.TOKEN_AM_PM.equals(tc)) {
+ int hour = date.getHours();
+ if (hour > 11)
+ response = DateLocale.getPM();
+ else
+ response = DateLocale.getAM();
+ }
+ return response;
+ }
+
+ /**
+ * This is basically just a sneaky way to guarantee that our 1 or 2 digit
+ * numbers come out as a 2 character string. we add an arbitrary number
+ * larger than 100, convert this new number to a string, then take the right
+ * most 2 characters.
+ *
+ * @param num
+ * @return
+ */
+ private String twoCharDateField(int num) {
+ String res = Integer.toString(num + 1900);
+ res = res.substring(res.length() - 2);
+ return res;
+ }
+
+ private static Date newDate(long time) {
+ return new Date(time);
+ }
+
+ /**
+ * Parses text and returns the corresponding date object.
+ *
+ * @param source
+ * @return java.util.Date
+ */
+ public Date parse(String source){
+ return SimpleDateParser.parse(source, format);
+ };
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.util;\r
+\r
+import java.util.Date;\r
+\r
+\r
+/**\r
+ * This is a simple regular expression based parser for date notations.\r
+ * While our aim is to fully support in the future the JDK date parser, currently\r
+ * only numeric notations and literals are supported such as <code>dd/MM/yyyy HH:mm:ss.SSSS</code>.\r
+ * Each entity is parsed with the same number of digits, i.e. for <code>dd</code> two digits will be\r
+ * parsed while for <code>d</code> only one will be parsed.\r
+ * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>\r
+ *\r
+ */\r
+\r
+public class SimpleDateParser {\r
+\r
+\r
+ private final static String DAY_IN_MONTH = "d";\r
+\r
+ private final static String MONTH = "M";\r
+\r
+ private final static String YEAR = "y";\r
+\r
+ private final static String LITERAL = "\\";\r
+\r
+ private final static int DATE_PATTERN = 0;\r
+\r
+ private final static int REGEX_PATTERN = 1;\r
+\r
+ private final static int COMPONENT = 2;\r
+\r
+ private final static int REGEX = 0;\r
+\r
+ private final static int INSTRUCTION = 1;\r
+\r
+ private final static String[] TOKENS[] = {\r
+ { "SSSS", "(\\d\\d\\d\\d)",DateLocale.TOKEN_MILLISECOND }, \r
+ { "SSS", "(\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND },\r
+ { "SS", "(\\d\\d)", DateLocale.TOKEN_MILLISECOND }, \r
+ { "S", "(\\d)", DateLocale.TOKEN_MILLISECOND },\r
+ { "ss", "(\\d\\d)", DateLocale.TOKEN_SECOND }, \r
+ { "s", "(\\d\\d)", DateLocale.TOKEN_SECOND },\r
+ { "mm", "(\\d\\d)", DateLocale.TOKEN_MINUTE }, \r
+ { "m", "(\\d\\d)", DateLocale.TOKEN_MINUTE},\r
+ { "HH", "(\\d\\d)", DateLocale.TOKEN_HOUR_24},\r
+ { "H", "(\\d{1,2})", DateLocale.TOKEN_HOUR_24 },\r
+ { "hh", "(\\d\\d)", DateLocale.TOKEN_HOUR_12},\r
+ { "h", "(\\d{1,2})", DateLocale.TOKEN_HOUR_12 },\r
+ { "dd", "(\\d\\d)", DateLocale.TOKEN_DAY_OF_MONTH }, \r
+ { "d", "(\\d{1,2})", DateLocale.TOKEN_DAY_OF_MONTH },\r
+ { "MM", "(\\d\\d)", DateLocale.TOKEN_MONTH }, \r
+ { "M", "(\\d{1,2})", DateLocale.TOKEN_MONTH },\r
+ { "yyyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, \r
+ { "yyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR },\r
+ { "yy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, \r
+ { "y", "(\\d{1,2})", DateLocale.TOKEN_YEAR },\r
+ { "a", "(\\S{1,4})", DateLocale.TOKEN_AM_PM }\r
+ };\r
+\r
+ private Pattern regularExpression;\r
+\r
+ private String instructions = "";\r
+\r
+ private static void _parse(String format, String[] args) {\r
+ if (format.length() == 0)\r
+ return;\r
+ if (format.startsWith("'")){\r
+ format = format.substring(1);\r
+ int end = format.indexOf("'");\r
+ if (end == -1)\r
+ throw new IllegalArgumentException("Unmatched single quotes.");\r
+ args[REGEX]+=Pattern.quote(format.substring(0,end));\r
+ format = format.substring(end+1);\r
+ }\r
+ for (int i = 0; i < TOKENS.length; i++) {\r
+ String[] row = TOKENS[i];\r
+ String datePattern = row[DATE_PATTERN];\r
+ if (!format.startsWith(datePattern))\r
+ continue;\r
+ format = format.substring(datePattern.length());\r
+ args[REGEX] += row[REGEX_PATTERN];\r
+ args[INSTRUCTION] += row[COMPONENT];\r
+ _parse(format, args);\r
+ return;\r
+ }\r
+ args[REGEX] += Pattern.quote(""+format.charAt(0));\r
+ format = format.substring(1);\r
+ _parse(format, args);\r
+ }\r
+\r
+ private static void load(Date date, String text, String component, String input, Pattern regex) {\r
+ if (component.equals(DateLocale.TOKEN_MILLISECOND)) {\r
+ date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text));\r
+ }\r
+\r
+ if (component.equals(DateLocale.TOKEN_SECOND)) {\r
+ date.setSeconds(Integer.parseInt(text));\r
+ }\r
+\r
+ if (component.equals(DateLocale.TOKEN_MINUTE)) {\r
+ date.setMinutes(Integer.parseInt(text));\r
+ }\r
+\r
+ if (component.equals(DateLocale.TOKEN_HOUR_24)) {\r
+ date.setHours(Integer.parseInt(text));\r
+ }\r
+ \r
+ if (component.equals(DateLocale.TOKEN_HOUR_12)) {\r
+ int h = Integer.parseInt(text);\r
+ String token = com.itmill.toolkit.terminal.gwt.client.DateLocale.getPM();\r
+ String which = input.substring(input.length() - token.length()); // Assumes both AM and PM tokens have same length\r
+ if(which.equalsIgnoreCase(token))\r
+ h += 12;\r
+ date.setHours(h);\r
+ }\r
+\r
+ if (component.equals(DateLocale.TOKEN_DAY_OF_MONTH)) {\r
+ date.setDate(Integer.parseInt(text));\r
+ }\r
+ if (component.equals(DateLocale.TOKEN_MONTH)) {\r
+ date.setMonth(Integer.parseInt(text)-1);\r
+ }\r
+ if (component.equals(DateLocale.TOKEN_YEAR)) {\r
+ //TODO: fix for short patterns\r
+ date.setYear(Integer.parseInt(text)-1900);\r
+ }\r
+\r
+ }\r
+\r
+ public SimpleDateParser(String format) {\r
+ String[] args = new String[] { "", "" };\r
+ _parse(format, args);\r
+ regularExpression = new Pattern(args[REGEX]);\r
+ instructions = args[INSTRUCTION];\r
+ }\r
+\r
+ public Date parse(String input) {\r
+ Date date = new Date(0, 0, 0, 0, 0, 0);\r
+ String matches[] = regularExpression.match(input);\r
+ if (matches == null)\r
+ throw new IllegalArgumentException(input+" does not match "+regularExpression.pattern());\r
+ if (matches.length-1!=instructions.length())\r
+ throw new IllegalArgumentException("Different group count - "+input+" does not match "+regularExpression.pattern());\r
+ for (int group = 0; group < instructions.length(); group++) {\r
+ String match = matches[group + 1];\r
+ load(date, match, ""+instructions.charAt(group), input, regularExpression);\r
+ }\r
+ return date;\r
+ }\r
+ \r
+ public static Date parse(String input, String pattern){\r
+ return new SimpleDateParser(pattern).parse(input);\r
+ }\r
+}\r
+++ /dev/null
-package com.itmill.toolkit.terminal.gwt.gwtwidgets.util;\r
-\r
-import java.util.Arrays;\r
-import java.util.List;\r
-\r
-/**\r
- * Date locale support for the {@link SimpleDateParser}. You are encouraged to\r
- * extend this class and provide implementations for other locales. \r
- * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>\r
- *\r
- */\r
-public class DateLocale {\r
- public final static String TOKEN_DAY_OF_WEEK = "E";\r
-\r
- public final static String TOKEN_DAY_OF_MONTH = "d";\r
-\r
- public final static String TOKEN_MONTH = "M";\r
-\r
- public final static String TOKEN_YEAR = "y";\r
-\r
- public final static String TOKEN_HOUR_12 = "h";\r
-\r
- public final static String TOKEN_HOUR_24 = "H";\r
-\r
- public final static String TOKEN_MINUTE = "m";\r
-\r
- public final static String TOKEN_SECOND = "s";\r
- \r
- public final static String TOKEN_MILLISECOND = "S";\r
- \r
- public final static String TOKEN_AM_PM = "a";\r
-\r
- public final static String AM = "AM";\r
-\r
- public final static String PM = "PM";\r
-\r
- public static List SUPPORTED_DF_TOKENS = Arrays.asList(new String[] {\r
- TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR,\r
- TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND,\r
- TOKEN_AM_PM });\r
- \r
- public static List TOKENS_RESOLUTION_ALL = Arrays.asList(new String[] {\r
- TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR,\r
- TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND,\r
- TOKEN_AM_PM });\r
- \r
- public static List TOKENS_RESOLUTION_YEAR = Arrays.asList(new String[] {\r
- TOKEN_YEAR});\r
- \r
- public static List TOKENS_RESOLUTION_MONTH = Arrays.asList(new String[] {\r
- TOKEN_YEAR, TOKEN_MONTH});\r
- \r
- public static List TOKENS_RESOLUTION_DAY = Arrays.asList(new String[] {\r
- TOKEN_YEAR, TOKEN_MONTH, TOKEN_DAY_OF_MONTH});\r
-\r
- public String[] MONTH_LONG = { "January", "February", "March", "April",\r
- "May", "June", "July", "August", "September", "October",\r
- "November", "December" };\r
-\r
- public String[] MONTH_SHORT = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
- "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };\r
-\r
- public String[] WEEKDAY_LONG = { "Sunday", "Monday", "Tuesday",\r
- "Wednesday", "Thursday", "Friday", "Saturday" };\r
-\r
- public String[] WEEKDAY_SHORT = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",\r
- "Sat" };\r
-\r
- public static String getAM() {\r
- return AM;\r
- }\r
-\r
- public static String getPM() {\r
- return PM;\r
- }\r
-\r
- public String[] getWEEKDAY_LONG() {\r
- return WEEKDAY_LONG;\r
- }\r
-\r
- public String[] getWEEKDAY_SHORT() {\r
- return WEEKDAY_SHORT;\r
- }\r
-\r
-}\r
+++ /dev/null
-/*
- * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.itmill.toolkit.terminal.gwt.gwtwidgets.util;
-
-import java.util.Date;
-
-/**
- * <dl>
- * <dt><b>Title: </b>
- * <dd>SimpleDateFormat</dd>
- * <p>
- * <dt><b>Description: </b>
- * <dd>GWT does not implement any of the java.text package, so this class tries
- * to fill the void of the missing java.text.SimpleDateFormat class. This
- * version however only supports a subset of the date and time patterns
- * supported by its java.text counterpart. The pattern symbols supported by this
- * class are:
- * <dl>
- * <dt><b>E</b></dt>
- * <dd>Day in a week</dd>
- * <dt><b>d</b></dt>
- * <dd>Day of the month</dd>
- * <dt><b>y</b></dt>
- * <dd>Year</dd>
- * <dt><b>M</b></dt>
- * <dd>Month January, Jan, 01, 1</dd>
- * <dt><b>H</b></dt>
- * <dd>Hour in 24 hour format (0-23)</dd>
- * <dt><b>h</b></dt>
- * <dd>Hour in 12 hour format (1-12)</dd>
- * <dt><b>m</b></dt>
- * <dd>Minute of the hour </dd>
- * <dt><b>s</b></dt>
- * <dd>Seconds of the minute</dd>
- * <dt><b>a</b></dt>
- * <dd>am/pm</dd>
- * </dl>
- * All characters that are not recognised as a date format character are
- * translated literally into the output string. <br/> </dd>
- * <p>
- * </dl>
- * <p>
- * A simple date parsing facility has also been implemented resembling the java
- * prototype. You can currently parse most numeric patterns but no temporal
- * literals (such as day or month names).
- * </p>
- *
- * @author <a href="mailto:jasone@greenrivercomputing.com">Jason Essington</a>
- * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>
- * @version $Revision: 0.0 $
- */
-public class SimpleDateFormat {
- private String format;
- private DateLocale locale = new DateLocale();
-
- /**
- * Gets the support locale for formatting and parsing dates
- * @return
- */
- public DateLocale getLocale() {
- return locale;
- }
-
- public void setLocale(DateLocale locale) {
- this.locale = locale;
- }
-
- public SimpleDateFormat(String pattern) {
- format = pattern;
- }
-
- public String format(Date date) {
- String f = "";
- if (format != null && format.length() > 0) {
- String lastTokenType = null;
- String currentToken = "";
- for (int i = 0; i < format.length(); i++) {
- String thisChar = format.substring(i, i + 1);
- String currentTokenType = DateLocale.SUPPORTED_DF_TOKENS
- .contains(thisChar) ? thisChar : "";
- if (currentTokenType.equals(lastTokenType) || i == 0) {
- currentToken += thisChar;
- lastTokenType = currentTokenType;
- } else {
- if ("".equals(lastTokenType))
- f += currentToken;
- else
- f += handleToken(currentToken, date);
- currentToken = thisChar;
- lastTokenType = currentTokenType;
- }
- }
- if ("".equals(lastTokenType))
- f += currentToken;
- else
- f += handleToken(currentToken, date);
- }
- return f;
- }
-
- /**
- * takes a date format string and returns the formatted portion of the date.
- * For instance if the token is MMMM then the full month name is returned.
- *
- * @param token
- * date format token
- * @param date
- * date to format
- * @return formatted portion of the date
- */
- private String handleToken(String token, Date date) {
- String response = token;
- String tc = token.substring(0, 1);
- if (DateLocale.TOKEN_DAY_OF_WEEK.equals(tc)) {
- if (token.length() > 3)
- response = locale.getWEEKDAY_LONG()[date.getDay()];
- else
- response = locale.getWEEKDAY_SHORT()[date.getDay()];
- } else if (DateLocale.TOKEN_DAY_OF_MONTH.equals(tc)) {
- if (token.length() == 1)
- response = Integer.toString(date.getDate());
- else
- response = twoCharDateField(date.getDate());
- } else if (DateLocale.TOKEN_MONTH.equals(tc)) {
- switch (token.length()) {
- case 1:
- response = Integer.toString(date.getMonth() + 1);
- break;
- case 2:
- response = twoCharDateField(date.getMonth() + 1);
- break;
- case 3:
- response = locale.MONTH_SHORT[date.getMonth()];
- break;
- default:
- response = locale.MONTH_LONG[date.getMonth()];
- break;
- }
- } else if (DateLocale.TOKEN_YEAR.equals(tc)) {
- if (token.length() >= 2)
- response = Integer.toString(date.getYear() + 1900);
- else
- response = twoCharDateField(date.getYear());
- } else if (DateLocale.TOKEN_HOUR_12.equals(tc)) {
- int h = date.getHours();
- if (h == 0)
- h = 12;
- else if (h > 12)
- h -= 12;
- //if (token.length() > 1)
- response = twoCharDateField(h);
- //else
- //response = Integer.toString(h);
- } else if (DateLocale.TOKEN_HOUR_24.equals(tc)) {
- //if (token.length() > 1)
- response = twoCharDateField(date.getHours());
- //else
- //response = Integer.toString(date.getHours());
- } else if (DateLocale.TOKEN_MINUTE.equals(tc)) {
- //if (token.length() > 1)
- response = twoCharDateField(date.getMinutes());
- //else
- //response = Integer.toString(date.getMinutes());
- } else if (DateLocale.TOKEN_SECOND.equals(tc)) {
- //if (token.length() > 1)
- response = twoCharDateField(date.getSeconds());
- //else
- //response = Integer.toString(date.getSeconds());
- } else if (DateLocale.TOKEN_AM_PM.equals(tc)) {
- int hour = date.getHours();
- if (hour > 11)
- response = DateLocale.getPM();
- else
- response = DateLocale.getAM();
- }
- return response;
- }
-
- /**
- * This is basically just a sneaky way to guarantee that our 1 or 2 digit
- * numbers come out as a 2 character string. we add an arbitrary number
- * larger than 100, convert this new number to a string, then take the right
- * most 2 characters.
- *
- * @param num
- * @return
- */
- private String twoCharDateField(int num) {
- String res = Integer.toString(num + 1900);
- res = res.substring(res.length() - 2);
- return res;
- }
-
- private static Date newDate(long time) {
- return new Date(time);
- }
-
- /**
- * Parses text and returns the corresponding date object.
- *
- * @param source
- * @return java.util.Date
- */
- public Date parse(String source){
- return SimpleDateParser.parse(source, format);
- };
-
-}
+++ /dev/null
-package com.itmill.toolkit.terminal.gwt.gwtwidgets.util;\r
-\r
-import java.util.Date;\r
-\r
-import com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern;\r
-\r
-/**\r
- * This is a simple regular expression based parser for date notations.\r
- * While our aim is to fully support in the future the JDK date parser, currently\r
- * only numeric notations and literals are supported such as <code>dd/MM/yyyy HH:mm:ss.SSSS</code>.\r
- * Each entity is parsed with the same number of digits, i.e. for <code>dd</code> two digits will be\r
- * parsed while for <code>d</code> only one will be parsed.\r
- * @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>\r
- *\r
- */\r
-\r
-public class SimpleDateParser {\r
-\r
-\r
- private final static String DAY_IN_MONTH = "d";\r
-\r
- private final static String MONTH = "M";\r
-\r
- private final static String YEAR = "y";\r
-\r
- private final static String LITERAL = "\\";\r
-\r
- private final static int DATE_PATTERN = 0;\r
-\r
- private final static int REGEX_PATTERN = 1;\r
-\r
- private final static int COMPONENT = 2;\r
-\r
- private final static int REGEX = 0;\r
-\r
- private final static int INSTRUCTION = 1;\r
-\r
- private final static String[] TOKENS[] = {\r
- { "SSSS", "(\\d\\d\\d\\d)",DateLocale.TOKEN_MILLISECOND }, \r
- { "SSS", "(\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND },\r
- { "SS", "(\\d\\d)", DateLocale.TOKEN_MILLISECOND }, \r
- { "S", "(\\d)", DateLocale.TOKEN_MILLISECOND },\r
- { "ss", "(\\d\\d)", DateLocale.TOKEN_SECOND }, \r
- { "s", "(\\d\\d)", DateLocale.TOKEN_SECOND },\r
- { "mm", "(\\d\\d)", DateLocale.TOKEN_MINUTE }, \r
- { "m", "(\\d\\d)", DateLocale.TOKEN_MINUTE},\r
- { "HH", "(\\d\\d)", DateLocale.TOKEN_HOUR_24},\r
- { "H", "(\\d{1,2})", DateLocale.TOKEN_HOUR_24 },\r
- { "hh", "(\\d\\d)", DateLocale.TOKEN_HOUR_12},\r
- { "h", "(\\d{1,2})", DateLocale.TOKEN_HOUR_12 },\r
- { "dd", "(\\d\\d)", DateLocale.TOKEN_DAY_OF_MONTH }, \r
- { "d", "(\\d{1,2})", DateLocale.TOKEN_DAY_OF_MONTH },\r
- { "MM", "(\\d\\d)", DateLocale.TOKEN_MONTH }, \r
- { "M", "(\\d{1,2})", DateLocale.TOKEN_MONTH },\r
- { "yyyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, \r
- { "yyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR },\r
- { "yy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, \r
- { "y", "(\\d{1,2})", DateLocale.TOKEN_YEAR },\r
- { "a", "(\\S{1,4})", DateLocale.TOKEN_AM_PM }\r
- };\r
-\r
- private Pattern regularExpression;\r
-\r
- private String instructions = "";\r
-\r
- private static void _parse(String format, String[] args) {\r
- if (format.length() == 0)\r
- return;\r
- if (format.startsWith("'")){\r
- format = format.substring(1);\r
- int end = format.indexOf("'");\r
- if (end == -1)\r
- throw new IllegalArgumentException("Unmatched single quotes.");\r
- args[REGEX]+=Pattern.quote(format.substring(0,end));\r
- format = format.substring(end+1);\r
- }\r
- for (int i = 0; i < TOKENS.length; i++) {\r
- String[] row = TOKENS[i];\r
- String datePattern = row[DATE_PATTERN];\r
- if (!format.startsWith(datePattern))\r
- continue;\r
- format = format.substring(datePattern.length());\r
- args[REGEX] += row[REGEX_PATTERN];\r
- args[INSTRUCTION] += row[COMPONENT];\r
- _parse(format, args);\r
- return;\r
- }\r
- args[REGEX] += Pattern.quote(""+format.charAt(0));\r
- format = format.substring(1);\r
- _parse(format, args);\r
- }\r
-\r
- private static void load(Date date, String text, String component, String input, Pattern regex) {\r
- if (component.equals(DateLocale.TOKEN_MILLISECOND)) {\r
- date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text));\r
- }\r
-\r
- if (component.equals(DateLocale.TOKEN_SECOND)) {\r
- date.setSeconds(Integer.parseInt(text));\r
- }\r
-\r
- if (component.equals(DateLocale.TOKEN_MINUTE)) {\r
- date.setMinutes(Integer.parseInt(text));\r
- }\r
-\r
- if (component.equals(DateLocale.TOKEN_HOUR_24)) {\r
- date.setHours(Integer.parseInt(text));\r
- }\r
- \r
- if (component.equals(DateLocale.TOKEN_HOUR_12)) {\r
- int h = Integer.parseInt(text);\r
- String token = com.itmill.toolkit.terminal.gwt.client.DateLocale.getPM();\r
- String which = input.substring(input.length() - token.length()); // Assumes both AM and PM tokens have same length\r
- if(which.equalsIgnoreCase(token))\r
- h += 12;\r
- date.setHours(h);\r
- }\r
-\r
- if (component.equals(DateLocale.TOKEN_DAY_OF_MONTH)) {\r
- date.setDate(Integer.parseInt(text));\r
- }\r
- if (component.equals(DateLocale.TOKEN_MONTH)) {\r
- date.setMonth(Integer.parseInt(text)-1);\r
- }\r
- if (component.equals(DateLocale.TOKEN_YEAR)) {\r
- //TODO: fix for short patterns\r
- date.setYear(Integer.parseInt(text)-1900);\r
- }\r
-\r
- }\r
-\r
- public SimpleDateParser(String format) {\r
- String[] args = new String[] { "", "" };\r
- _parse(format, args);\r
- regularExpression = new Pattern(args[REGEX]);\r
- instructions = args[INSTRUCTION];\r
- }\r
-\r
- public Date parse(String input) {\r
- Date date = new Date(0, 0, 0, 0, 0, 0);\r
- String matches[] = regularExpression.match(input);\r
- if (matches == null)\r
- throw new IllegalArgumentException(input+" does not match "+regularExpression.pattern());\r
- if (matches.length-1!=instructions.length())\r
- throw new IllegalArgumentException("Different group count - "+input+" does not match "+regularExpression.pattern());\r
- for (int group = 0; group < instructions.length(); group++) {\r
- String match = matches[group + 1];\r
- load(date, match, ""+instructions.charAt(group), input, regularExpression);\r
- }\r
- return date;\r
- }\r
- \r
- public static Date parse(String input, String pattern){\r
- return new SimpleDateParser(pattern).parse(input);\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- * \r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import com.google.gwt.core.client.JavaScriptObject;\r
-\r
-/**\r
- * <p>\r
- * Implementation of the {@link java.util.regex.Pattern} class with a\r
- * wrapper aroung the Javascript <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Regular_Expressions">RegExp</a> object.\r
- * As most of the methods delegate to the JavaScript RegExp object, certain differences in the \r
- * declaration and behaviour of regular expressions must be expected.\r
- * </p>\r
- * <p>\r
- * Please note that neither the {@link java.util.regex.Pattern#compile(String)} method nor\r
- * {@link Matcher} instances are supported. For the later, consider using {@link Pattern#match(String)}.\r
- * </p>\r
- * \r
- * @author George Georgovassilis\r
- *\r
- */\r
-public class Pattern {\r
-\r
- /**\r
- * Declares that regular expressions should be matched across line borders.\r
- */\r
- public final static int MULTILINE = 1;\r
-\r
- /**\r
- * Declares that characters are matched reglardless of case.\r
- */\r
- public final static int CASE_INSENSITIVE = 2;\r
-\r
- private JavaScriptObject regExp;\r
-\r
- private static JavaScriptObject createExpression(String pattern, int flags) {\r
- String sFlags = "";\r
- if ((flags & MULTILINE) != 0)\r
- sFlags += "m";\r
- if ((flags & CASE_INSENSITIVE) != 0)\r
- sFlags += "i";\r
- return _createExpression(pattern, sFlags);\r
- }\r
-\r
- private static native JavaScriptObject _createExpression(String pattern,\r
- String flags)/*-{\r
- return new RegExp(pattern, flags);\r
- }-*/;\r
-\r
- private native void _match(String text, List matches)/*-{\r
- var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
- var result = text.match(regExp);\r
- if (result == null) return;\r
- for (var i=0;i<result.length;i++)\r
- matches.@java.util.ArrayList::add(Ljava/lang/Object;)(result[i]);\r
- }-*/;\r
-\r
- /**\r
- * Determines wether the specified regular expression is validated by the \r
- * provided input.\r
- * @param regex Regular expression\r
- * @param input String to validate\r
- * @return <code>true</code> if matched.\r
- */\r
- public static boolean matches(String regex, String input) {\r
- return new Pattern(regex).matches(input);\r
- }\r
-\r
- /**\r
- * Escape a provided string so that it will be interpreted as a literal\r
- * in regular expressions.\r
- * The current implementation does escape each character even if not neccessary,\r
- * generating verbose literals.\r
- * @param input\r
- * @return\r
- */\r
- public static String quote(String input) {\r
- String output = "";\r
- for (int i = 0; i < input.length(); i++) {\r
- output += "\\" + input.charAt(i);\r
- }\r
- return output;\r
- }\r
-\r
- /**\r
- * Class constructor\r
- * @param pattern Regular expression\r
- */\r
- public Pattern(String pattern) {\r
- this(pattern, 0);\r
- }\r
-\r
- /**\r
- * Class constructor\r
- * @param pattern Regular expression\r
- * @param flags \r
- */\r
- public Pattern(String pattern, int flags) {\r
- regExp = createExpression(pattern, flags);\r
- }\r
-\r
- /**\r
- * This method is borrowed from the JavaScript RegExp object.\r
- * It parses a string and returns as an array any assignments to parenthesis groups\r
- * in the pattern's regular expression\r
- * @param text\r
- * @return Array of strings following java's Pattern convention for groups:\r
- * Group 0 is the entire input string and the remaining groups are the matched parenthesis.\r
- * In case nothing was matched an empty array is returned.\r
- */\r
- public String[] match(String text) {\r
- List matches = new ArrayList();\r
- _match(text, matches);\r
- String arr[] = new String[matches.size()];\r
- for (int i = 0; i < matches.size(); i++)\r
- arr[i] = matches.get(i).toString();\r
- return arr;\r
- }\r
-\r
- /**\r
- * Determines wether a provided text matches the regular expression\r
- * @param text\r
- * @return\r
- */\r
- public native boolean matches(String text)/*-{\r
- var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
- return regExp.test(text);\r
- }-*/;\r
-\r
- /**\r
- * Returns the regular expression for this pattern\r
- * @return\r
- */\r
- public native String pattern()/*-{\r
- var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
- return regExp.source;\r
- }-*/;\r
-\r
- private native void _split(String input, List results)/*-{\r
- var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp;\r
- var parts = input.split(regExp);\r
- for (var i=0;i<parts.length;i++)\r
- results.@java.util.ArrayList::add(Ljava/lang/Object;)(parts[i] );\r
- }-*/;\r
- \r
- /**\r
- * Split an input string by the pattern's regular expression\r
- * @param input\r
- * @return Array of strings\r
- */\r
- public String[] split(String input){\r
- List results = new ArrayList(); \r
- _split(input, results);\r
- String[] parts = new String[results.size()];\r
- for (int i=0;i<results.size();i++)\r
- parts[i] = (String)results.get(i);\r
- return parts;\r
- }\r
-\r
-}\r