From: Jani Laakso Date: Thu, 20 Sep 2007 07:18:16 +0000 (+0000) Subject: Current convention for client-side components is X-Git-Tag: 6.7.0.beta1~5976 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4266bccf0426f38ace66797cd4f7c774112d359d;p=vaadin-framework.git Current convention for client-side components is * 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 --- diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarEntry.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarEntry.java new file mode 100644 index 0000000000..19bb70707f --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarEntry.java @@ -0,0 +1,112 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import java.util.Date; + +import com.itmill.toolkit.terminal.gwt.client.DateTimeService; + +public class CalendarEntry { + private Date start; + private Date end; + private String title; + private String description; + private boolean notime; + + public CalendarEntry(Date start, Date end, String title, String description, boolean notime) { + if (notime) { + Date d = new Date(start.getTime()); + d.setSeconds(0); + d.setMinutes(0); + this.start = d; + if (end != null) { + d = new Date(end.getTime()); + d.setSeconds(0); + d.setMinutes(0); + this.end = d; + } else { + end = start; + } + } else { + this.start = start; + this.end = end; + } + this.title = title; + this.description = description; + this.notime = notime; + } + + public CalendarEntry(Date start, Date end, String title, String description) { + this(start, end, title, description, false); + } + + public Date getStart() { + return start; + } + + public void setStart(Date start) { + this.start = start; + } + + public Date getEnd() { + return end; + } + + public void setEnd(Date end) { + this.end = end; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isNotime() { + return notime; + } + + public void setNotime(boolean notime) { + this.notime = notime; + } + + public String getStringForDate(Date d) { + // TODO format from DateTimeService + String s = ""; + if (!notime) { + if (!DateTimeService.isSameDay(d, start)) { + s += (start.getYear() + 1900) + "." + (start.getMonth() + 1) + + "." + start.getDate() + " "; + } + int i = start.getHours(); + s += (i < 10 ? "0" : "") + i; + s += ":"; + i = start.getMinutes(); + s += (i < 10 ? "0" : "") + i; + if (!start.equals(end)) { + s += " - "; + if (!DateTimeService.isSameDay(start, end)) { + s += (end.getYear() + 1900) + "." + (end.getMonth() + 1) + "." + + end.getDate() + " "; + } + i = end.getHours(); + s += (i < 10 ? "0" : "") + i; + s += ":"; + i = end.getMinutes(); + s += (i < 10 ? "0" : "") + i; + } + s += " "; + } + s += title; + return s; + } + +} \ No newline at end of file diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarPanel.java new file mode 100644 index 0000000000..d770444102 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/CalendarPanel.java @@ -0,0 +1,408 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +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 CalendarPanel extends FlexTable implements MouseListener, + ClickListener { + + private IDateField datefield; + + private IEventButton prevYear; + private IEventButton nextYear; + private IEventButton prevMonth; + private IEventButton nextMonth; + + private Time time; + + private Date minDate = null; + private Date maxDate = null; + + private CalendarEntrySource entrySource; + + /* Needed to identify resolution changes */ + private int resolution = IDateField.RESOLUTION_YEAR; + + /* Needed to identify locale changes */ + private String locale = LocaleService.getDefaultLocale(); + + public CalendarPanel(IDateField parent) { + datefield = parent; + setStyleName(datefield.CLASSNAME + "-calendarpanel"); + // buildCalendar(true); + addTableListener(new DateClickListener(this)); + } + + public CalendarPanel(IDateField parent, Date min, Date max) { + datefield = parent; + setStyleName(datefield.CLASSNAME + "-calendarpanel"); + // buildCalendar(true); + addTableListener(new DateClickListener(this)); + } + + private void buildCalendar(boolean forceRedraw) { + boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR; + boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY; + boolean needsTime = datefield.getCurrentResolution() >= 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(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, boolean needsMonth) { + // Can't draw a calendar without a date :) + if (datefield.getCurrentDate() == null) + datefield.setCurrentDate(new Date()); + + if (forceRedraw) { + 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.getDateTimeService().getFirstDayOfWeek(); + for (int i = 0; i < 7; i++) { + int day = i + firstDay; + if (day > 6) + day = 0; + if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH) + setHTML(1, i, "" + + datefield.getDateTimeService().getShortDay(day) + + ""); + else + setHTML(1, i, ""); + } + } + + String monthName = needsMonth ? datefield.getDateTimeService() + .getMonth(datefield.getCurrentDate().getMonth()) : ""; + int year = datefield.getCurrentDate().getYear() + 1900; + setHTML(0, 2, "" + monthName + " " + year + + ""); + } + + private void buildCalendarBody() { + Date date = datefield.getCurrentDate(); + if (date == null) + date = new Date(); + int startWeekDay = datefield.getDateTimeService().getStartWeekDay(date); + int numDays = DateTimeService.getNumberOfDaysInMonth(date); + int dayCount = 0; + Date today = new Date(); + Date curr = new Date(date.getTime()); + for (int row = 2; row < 8; row++) { + for (int col = 0; col < 7; col++) { + if (!(row == 2 && col < startWeekDay)) { + if (dayCount < numDays) { + int selectedDate = ++dayCount; + String title = ""; + if (this.entrySource != null) { + curr.setDate(dayCount); + List entries = this.entrySource.getEntries(curr, + IDateField.RESOLUTION_DAY); + if (entries != null) { + for (Iterator it = entries.iterator(); it + .hasNext();) { + CalendarEntry entry = (CalendarEntry) it + .next(); + title += (title.length() > 0 ? ", " : "") + + entry.getStringForDate(curr); + } + } + } + String baseclass = datefield.CLASSNAME + + "-calendarpanel-day"; + String cssClass = baseclass; + if (!isEnabledDate(curr)) { + cssClass += " " + baseclass + "-disabled"; + } + if (date.getDate() == dayCount) { + cssClass += " " + baseclass + "-selected"; + } + if (today.getDate() == dayCount + && today.getMonth() == date.getMonth() + && today.getYear() == date.getYear()) { + cssClass += " " + baseclass + "-today"; + } + if (title.length() > 0) + cssClass += " " + baseclass + "-entry"; + setHTML(row, col, "" + + selectedDate + ""); + } else { + break; + } + + } + } + } + } + + private void buildTime(boolean forceRedraw) { + if (time == null) { + time = new Time(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() { + // Locale and resolution changes force a complete redraw + buildCalendar(locale != datefield.getCurrentLocale() + || resolution != datefield.getCurrentResolution()); + if (datefield instanceof ITextualDate) + ((ITextualDate) datefield).buildDate(); + locale = datefield.getCurrentLocale(); + resolution = datefield.getCurrentResolution(); + } + + public void onClick(Widget sender) { + processClickEvent(sender); + } + + private boolean isEnabledDate(Date date) { + if ((this.minDate != null && date.before(this.minDate)) + || (this.maxDate != null && date.after(this.maxDate))) { + return false; + } + return true; + } + + private void processClickEvent(Widget sender) { + if (!datefield.isEnabled() || datefield.isReadonly()) + return; + + if (sender == prevYear) { + datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() - 1); + datefield.getClient().updateVariable(datefield.getId(), "year", + datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate()); + updateCalendar(); + } else if (sender == nextYear) { + datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() + 1); + datefield.getClient().updateVariable(datefield.getId(), "year", + datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate()); + updateCalendar(); + } else if (sender == prevMonth) { + datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() - 1); + datefield.getClient().updateVariable(datefield.getId(), "month", + datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate()); + updateCalendar(); + } else if (sender == nextMonth) { + datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() + 1); + datefield.getClient().updateVariable(datefield.getId(), "month", + datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate()); + 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 CalendarPanel cal; + + public DateClickListener(CalendarPanel panel) { + cal = panel; + } + + public void onCellClicked(SourcesTableEvents sender, int row, int col) { + if (sender != cal || row < 2 || row > 7 || !cal.datefield.isEnabled() + || cal.datefield.isReadonly()) + return; + + String text = cal.getText(row, col); + if (text.equals(" ")) + return; + + Integer day = new Integer(text); + + Date newDate = new Date(cal.datefield.getCurrentDate().getTime()); + newDate.setDate(day.intValue()); + if (!isEnabledDate(newDate)) { + return; + } + cal.datefield.getCurrentDate().setTime(newDate.getTime()); + cal.datefield.getClient().updateVariable(cal.datefield.getId(), "day", + cal.datefield.getCurrentDate().getDate(), cal.datefield.isImmediate()); + + updateCalendar(); + } + + } + + public void setLimits(Date min, Date max) { + if (min != null) { + Date d = new Date(min.getTime()); + d.setHours(0); + d.setMinutes(0); + d.setSeconds(1); + this.minDate = d; + } else { + this.minDate = null; + } + if (max != null) { + Date d = new Date(max.getTime()); + d.setHours(24); + d.setMinutes(59); + d.setSeconds(59); + this.maxDate = d; + } else { + this.maxDate = null; + } + } + + public void setCalendarEntrySource(CalendarEntrySource entrySource) { + this.entrySource = entrySource; + } + + public CalendarEntrySource getCalendarEntrySource() { + return this.entrySource; + } + + public interface CalendarEntrySource { + public List getEntries(Date date, int resolution); + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java index 9a49ac7978..15eca990a0 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICalendar.java @@ -14,12 +14,10 @@ import com.google.gwt.user.client.ui.TableListener; import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.DateTimeService; import com.itmill.toolkit.terminal.gwt.client.UIDL; -import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry; -import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel; public class ICalendar extends IDateField { - private ICalendarPanel calPanel; + private CalendarPanel calPanel; private HTMLTable hourTable; @@ -35,7 +33,7 @@ public class ICalendar extends IDateField { public ICalendar() { super(); setStyleName(CLASSNAME); - calPanel = new ICalendarPanel(this); + calPanel = new CalendarPanel(this); add(calPanel); this.entrySource = new EntrySource(); calPanel.setCalendarEntrySource(this.entrySource); @@ -114,7 +112,7 @@ public class ICalendar extends IDateField { String text = ""; if (entries != null) { for (Iterator it = entries.iterator(); it.hasNext();) { - ICalendarEntry entry = (ICalendarEntry) it.next(); + CalendarEntry entry = (CalendarEntry) it.next(); String title = entry.getTitle(); String desc = entry.getDescription(); text += (text == "" ? "" : ", "); @@ -145,7 +143,7 @@ public class ICalendar extends IDateField { } - private class EntrySource implements ICalendarPanel.CalendarEntrySource { + private class EntrySource implements CalendarPanel.CalendarEntrySource { private HashMap items = new HashMap(); @@ -162,14 +160,14 @@ public class ICalendar extends IDateField { if (items.containsKey(id)) { items.remove(id); } - items.put(id, new ICalendarEntry(startDate, endDate, title, desc, + items.put(id, new CalendarEntry(startDate, endDate, title, desc, notime)); } public List getEntries(Date date, int resolution) { ArrayList res = new ArrayList(); for (Iterator it = this.items.values().iterator(); it.hasNext();) { - ICalendarEntry item = (ICalendarEntry) it.next(); + CalendarEntry item = (CalendarEntry) it.next(); if (DateTimeService.isInRange(date, item.getStart(), item .getEnd(), resolution)) { res.add(item); diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java index 949ab1d967..e48f35cd12 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IDateFieldCalendar.java @@ -2,16 +2,15 @@ package com.itmill.toolkit.terminal.gwt.client.ui; import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.UIDL; -import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel; public class IDateFieldCalendar extends IDateField { - private ICalendarPanel date; + private CalendarPanel date; public IDateFieldCalendar() { super(); setStyleName(CLASSNAME+"-calendar"); - date = new ICalendarPanel(this); + date = new CalendarPanel(this); add(date); } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java index acf4ea0827..07b87a80e9 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupCalendar.java @@ -7,13 +7,12 @@ import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -import com.itmill.toolkit.terminal.gwt.client.ui.datefield.ICalendarPanel; public class IPopupCalendar extends ITextualDate implements Paintable, ClickListener, PopupListener { private IButton calendarToggle; - private ICalendarPanel calendar; + private CalendarPanel calendar; private PopupPanel popup; @@ -25,7 +24,7 @@ public class IPopupCalendar extends ITextualDate implements Paintable, ClickList calendarToggle.addClickListener(this); add(calendarToggle); - calendar = new ICalendarPanel(this); + calendar = new CalendarPanel(this); popup = new PopupPanel(true); popup.setStyleName(IDateField.CLASSNAME+"-calendar"); popup.setWidget(calendar); diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java index bd6c605603..8eb768b980 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java @@ -8,7 +8,7 @@ import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; import com.itmill.toolkit.terminal.gwt.client.DateLocale; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -import com.itmill.toolkit.terminal.gwt.gwtwidgets.util.SimpleDateFormat; +import com.itmill.toolkit.terminal.gwt.client.util.SimpleDateFormat; public class ITextualDate extends IDateField implements Paintable, ChangeListener { diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/Time.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/Time.java new file mode 100644 index 0000000000..fae1143600 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/Time.java @@ -0,0 +1,230 @@ +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 Time 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 Time(IDateField parent) { + super(); + datefield = parent; + setStyleName(IDateField.CLASSNAME+"-time"); + } + + private void buildTime(boolean redraw) { + boolean thc = datefield.getDateTimeService().isTwelveHourClock(); + if(redraw) { + clear(); + int numHours = thc?12:24; + hours = new ListBox(); + hours.setStyleName(ISelect.CLASSNAME); + for(int i=0; i= 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.getCurrentResolution() >= 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.getCurrentResolution() == 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); + } + + String delimiter = datefield.getDateTimeService().getClockDelimeter(); + boolean ro = datefield.isReadonly(); + + if(ro) { + int h = 0; + if(datefield.getCurrentDate() != null) + h = datefield.getCurrentDate().getHours(); + if(thc) h -= h<12? 0 : 12; + add(new ILabel(h<10? "0"+h : ""+h)); + } else add(hours); + + if(datefield.getCurrentResolution() >= 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.getCurrentResolution() >= 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.getCurrentResolution() == 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.getCurrentResolution() == IDateField.RESOLUTION_HOUR) { + add(new ILabel(delimiter+"00")); // o'clock + } + if(thc) { + add(new ILabel(" ")); + if(ro) add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1))); + else add(ampm); + } + + if(ro) return; + } + + // Update times + if(thc) { + int h = datefield.getCurrentDate().getHours(); + ampm.setSelectedIndex(h<12? 0 : 1); + h -= ampm.getSelectedIndex()*12; + hours.setSelectedIndex(h); + } else + hours.setSelectedIndex(datefield.getCurrentDate().getHours()); + if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) + mins.setSelectedIndex(datefield.getCurrentDate().getMinutes()); + if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) + sec.setSelectedIndex(datefield.getCurrentDate().getSeconds()); + if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) + msec.setSelectedIndex(datefield.getMilliseconds()); + if(thc) + ampm.setSelectedIndex(datefield.getCurrentDate().getHours()<12?0:1); + + if(datefield.isReadonly() && !redraw) { + // Do complete redraw when in read-only status + clear(); + String delimiter = datefield.getDateTimeService().getClockDelimeter(); + + int h = datefield.getCurrentDate().getHours(); + if(thc) h -= h<12? 0 : 12; + add(new ILabel(h<10? "0"+h : ""+h)); + + if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) { + add(new ILabel(delimiter)); + int m = mins.getSelectedIndex(); + add(new ILabel(m<10? "0"+m : ""+m)); + } + if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) { + add(new ILabel(delimiter)); + int s = sec.getSelectedIndex(); + add(new ILabel(s<10? "0"+s : ""+s)); + } + if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) { + add(new ILabel(".")); + int m = datefield.getMilliseconds(); + String ms = m<100? "0"+m : ""+m; + add(new ILabel(m<10? "0"+ms : ms)); + } + if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) { + add(new ILabel(delimiter+"00")); // o'clock + } + if(thc) { + add(new ILabel(" ")); + add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1))); + } + } + + boolean enabled = datefield.isEnabled(); + 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.getCurrentResolution() + || readonly != datefield.isReadonly()); + if(datefield instanceof ITextualDate) + ((ITextualDate) datefield).buildDate(); + resolution = datefield.getCurrentResolution(); + readonly = datefield.isReadonly(); + } + + public void onChange(Widget sender) { + if(sender == hours) { + int h = hours.getSelectedIndex(); + if(datefield.getDateTimeService().isTwelveHourClock()) + h = h + ampm.getSelectedIndex()*12; + datefield.getCurrentDate().setHours(h); + datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate()); + updateTime(false); + } + else if(sender == mins) { + int m = mins.getSelectedIndex(); + datefield.getCurrentDate().setMinutes(m); + datefield.getClient().updateVariable(datefield.getId(), "min", m, datefield.isImmediate()); + updateTime(false); + } + else if(sender == sec) { + int s = sec.getSelectedIndex(); + datefield.getCurrentDate().setSeconds(s); + datefield.getClient().updateVariable(datefield.getId(), "sec", s, datefield.isImmediate()); + updateTime(false); + } + else if(sender == msec) { + int ms = msec.getSelectedIndex(); + datefield.setMilliseconds(ms); + datefield.getClient().updateVariable(datefield.getId(), "msec", ms, datefield.isImmediate()); + updateTime(false); + } + else if(sender == ampm) { + int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12; + datefield.getCurrentDate().setHours(h); + datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate()); + updateTime(false); + } + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java deleted file mode 100644 index 1ffbc0d016..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/calendar/ICalendarEntry.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.itmill.toolkit.terminal.gwt.client.ui.calendar; - -import java.util.Date; - -import com.itmill.toolkit.terminal.gwt.client.DateTimeService; - -public class ICalendarEntry { - private Date start; - private Date end; - private String title; - private String description; - private boolean notime; - - public ICalendarEntry(Date start, Date end, String title, String description, boolean notime) { - if (notime) { - Date d = new Date(start.getTime()); - d.setSeconds(0); - d.setMinutes(0); - this.start = d; - if (end != null) { - d = new Date(end.getTime()); - d.setSeconds(0); - d.setMinutes(0); - this.end = d; - } else { - end = start; - } - } else { - this.start = start; - this.end = end; - } - this.title = title; - this.description = description; - this.notime = notime; - } - - public ICalendarEntry(Date start, Date end, String title, String description) { - this(start, end, title, description, false); - } - - public Date getStart() { - return start; - } - - public void setStart(Date start) { - this.start = start; - } - - public Date getEnd() { - return end; - } - - public void setEnd(Date end) { - this.end = end; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public boolean isNotime() { - return notime; - } - - public void setNotime(boolean notime) { - this.notime = notime; - } - - public String getStringForDate(Date d) { - // TODO format from DateTimeService - String s = ""; - if (!notime) { - if (!DateTimeService.isSameDay(d, start)) { - s += (start.getYear() + 1900) + "." + (start.getMonth() + 1) - + "." + start.getDate() + " "; - } - int i = start.getHours(); - s += (i < 10 ? "0" : "") + i; - s += ":"; - i = start.getMinutes(); - s += (i < 10 ? "0" : "") + i; - if (!start.equals(end)) { - s += " - "; - if (!DateTimeService.isSameDay(start, end)) { - s += (end.getYear() + 1900) + "." + (end.getMonth() + 1) + "." - + end.getDate() + " "; - } - i = end.getHours(); - s += (i < 10 ? "0" : "") + i; - s += ":"; - i = end.getMinutes(); - s += (i < 10 ? "0" : "") + i; - } - s += " "; - } - s += title; - return s; - } - -} \ No newline at end of file diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java deleted file mode 100644 index 6633f3e18a..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ICalendarPanel.java +++ /dev/null @@ -1,412 +0,0 @@ -package com.itmill.toolkit.terminal.gwt.client.ui.datefield; - -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -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; -import com.itmill.toolkit.terminal.gwt.client.ui.IButton; -import com.itmill.toolkit.terminal.gwt.client.ui.IDateField; -import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate; -import com.itmill.toolkit.terminal.gwt.client.ui.calendar.ICalendarEntry; - -public class ICalendarPanel extends FlexTable implements MouseListener, - ClickListener { - - private IDateField datefield; - - private IEventButton prevYear; - private IEventButton nextYear; - private IEventButton prevMonth; - private IEventButton nextMonth; - - private ITime time; - - private Date minDate = null; - private Date maxDate = null; - - private CalendarEntrySource entrySource; - - /* 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; - setStyleName(datefield.CLASSNAME + "-calendarpanel"); - // buildCalendar(true); - addTableListener(new DateClickListener(this)); - } - - public ICalendarPanel(IDateField parent, Date min, Date max) { - datefield = parent; - setStyleName(datefield.CLASSNAME + "-calendarpanel"); - // buildCalendar(true); - addTableListener(new DateClickListener(this)); - } - - private void buildCalendar(boolean forceRedraw) { - boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR; - boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY; - boolean needsTime = datefield.getCurrentResolution() >= 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(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, boolean needsMonth) { - // Can't draw a calendar without a date :) - if (datefield.getCurrentDate() == null) - datefield.setCurrentDate(new Date()); - - if (forceRedraw) { - 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.getDateTimeService().getFirstDayOfWeek(); - for (int i = 0; i < 7; i++) { - int day = i + firstDay; - if (day > 6) - day = 0; - if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH) - setHTML(1, i, "" - + datefield.getDateTimeService().getShortDay(day) - + ""); - else - setHTML(1, i, ""); - } - } - - String monthName = needsMonth ? datefield.getDateTimeService() - .getMonth(datefield.getCurrentDate().getMonth()) : ""; - int year = datefield.getCurrentDate().getYear() + 1900; - setHTML(0, 2, "" + monthName + " " + year - + ""); - } - - private void buildCalendarBody() { - Date date = datefield.getCurrentDate(); - if (date == null) - date = new Date(); - int startWeekDay = datefield.getDateTimeService().getStartWeekDay(date); - int numDays = DateTimeService.getNumberOfDaysInMonth(date); - int dayCount = 0; - Date today = new Date(); - Date curr = new Date(date.getTime()); - for (int row = 2; row < 8; row++) { - for (int col = 0; col < 7; col++) { - if (!(row == 2 && col < startWeekDay)) { - if (dayCount < numDays) { - int selectedDate = ++dayCount; - String title = ""; - if (this.entrySource != null) { - curr.setDate(dayCount); - List entries = this.entrySource.getEntries(curr, - IDateField.RESOLUTION_DAY); - if (entries != null) { - for (Iterator it = entries.iterator(); it - .hasNext();) { - ICalendarEntry entry = (ICalendarEntry) it - .next(); - title += (title.length() > 0 ? ", " : "") - + entry.getStringForDate(curr); - } - } - } - String baseclass = datefield.CLASSNAME - + "-calendarpanel-day"; - String cssClass = baseclass; - if (!isEnabledDate(curr)) { - cssClass += " " + baseclass + "-disabled"; - } - if (date.getDate() == dayCount) { - cssClass += " " + baseclass + "-selected"; - } - if (today.getDate() == dayCount - && today.getMonth() == date.getMonth() - && today.getYear() == date.getYear()) { - cssClass += " " + baseclass + "-today"; - } - if (title.length() > 0) - cssClass += " " + baseclass + "-entry"; - setHTML(row, col, "" - + selectedDate + ""); - } else { - 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() { - // Locale and resolution changes force a complete redraw - buildCalendar(locale != datefield.getCurrentLocale() - || resolution != datefield.getCurrentResolution()); - if (datefield instanceof ITextualDate) - ((ITextualDate) datefield).buildDate(); - locale = datefield.getCurrentLocale(); - resolution = datefield.getCurrentResolution(); - } - - public void onClick(Widget sender) { - processClickEvent(sender); - } - - private boolean isEnabledDate(Date date) { - if ((this.minDate != null && date.before(this.minDate)) - || (this.maxDate != null && date.after(this.maxDate))) { - return false; - } - return true; - } - - private void processClickEvent(Widget sender) { - if (!datefield.isEnabled() || datefield.isReadonly()) - return; - - if (sender == prevYear) { - datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() - 1); - datefield.getClient().updateVariable(datefield.getId(), "year", - datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate()); - updateCalendar(); - } else if (sender == nextYear) { - datefield.getCurrentDate().setYear(datefield.getCurrentDate().getYear() + 1); - datefield.getClient().updateVariable(datefield.getId(), "year", - datefield.getCurrentDate().getYear() + 1900, datefield.isImmediate()); - updateCalendar(); - } else if (sender == prevMonth) { - datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() - 1); - datefield.getClient().updateVariable(datefield.getId(), "month", - datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate()); - updateCalendar(); - } else if (sender == nextMonth) { - datefield.getCurrentDate().setMonth(datefield.getCurrentDate().getMonth() + 1); - datefield.getClient().updateVariable(datefield.getId(), "month", - datefield.getCurrentDate().getMonth() + 1, datefield.isImmediate()); - 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.isEnabled() - || cal.datefield.isReadonly()) - return; - - String text = cal.getText(row, col); - if (text.equals(" ")) - return; - - Integer day = new Integer(text); - - Date newDate = new Date(cal.datefield.getCurrentDate().getTime()); - newDate.setDate(day.intValue()); - if (!isEnabledDate(newDate)) { - return; - } - cal.datefield.getCurrentDate().setTime(newDate.getTime()); - cal.datefield.getClient().updateVariable(cal.datefield.getId(), "day", - cal.datefield.getCurrentDate().getDate(), cal.datefield.isImmediate()); - - updateCalendar(); - } - - } - - public void setLimits(Date min, Date max) { - if (min != null) { - Date d = new Date(min.getTime()); - d.setHours(0); - d.setMinutes(0); - d.setSeconds(1); - this.minDate = d; - } else { - this.minDate = null; - } - if (max != null) { - Date d = new Date(max.getTime()); - d.setHours(24); - d.setMinutes(59); - d.setSeconds(59); - this.maxDate = d; - } else { - this.maxDate = null; - } - } - - public void setCalendarEntrySource(CalendarEntrySource entrySource) { - this.entrySource = entrySource; - } - - public CalendarEntrySource getCalendarEntrySource() { - return this.entrySource; - } - - public interface CalendarEntrySource { - public List getEntries(Date date, int resolution); - } - -} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java deleted file mode 100644 index 2b36966172..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/datefield/ITime.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.itmill.toolkit.terminal.gwt.client.ui.datefield; - -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; -import com.itmill.toolkit.terminal.gwt.client.ui.IDateField; -import com.itmill.toolkit.terminal.gwt.client.ui.ILabel; -import com.itmill.toolkit.terminal.gwt.client.ui.ISelect; -import com.itmill.toolkit.terminal.gwt.client.ui.ITextualDate; - -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.getDateTimeService().isTwelveHourClock(); - if(redraw) { - clear(); - int numHours = thc?12:24; - hours = new ListBox(); - hours.setStyleName(ISelect.CLASSNAME); - for(int i=0; i= 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.getCurrentResolution() >= 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.getCurrentResolution() == 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); - } - - String delimiter = datefield.getDateTimeService().getClockDelimeter(); - boolean ro = datefield.isReadonly(); - - if(ro) { - int h = 0; - if(datefield.getCurrentDate() != null) - h = datefield.getCurrentDate().getHours(); - if(thc) h -= h<12? 0 : 12; - add(new ILabel(h<10? "0"+h : ""+h)); - } else add(hours); - - if(datefield.getCurrentResolution() >= 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.getCurrentResolution() >= 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.getCurrentResolution() == 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.getCurrentResolution() == IDateField.RESOLUTION_HOUR) { - add(new ILabel(delimiter+"00")); // o'clock - } - if(thc) { - add(new ILabel(" ")); - if(ro) add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1))); - else add(ampm); - } - - if(ro) return; - } - - // Update times - if(thc) { - int h = datefield.getCurrentDate().getHours(); - ampm.setSelectedIndex(h<12? 0 : 1); - h -= ampm.getSelectedIndex()*12; - hours.setSelectedIndex(h); - } else - hours.setSelectedIndex(datefield.getCurrentDate().getHours()); - if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) - mins.setSelectedIndex(datefield.getCurrentDate().getMinutes()); - if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) - sec.setSelectedIndex(datefield.getCurrentDate().getSeconds()); - if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) - msec.setSelectedIndex(datefield.getMilliseconds()); - if(thc) - ampm.setSelectedIndex(datefield.getCurrentDate().getHours()<12?0:1); - - if(datefield.isReadonly() && !redraw) { - // Do complete redraw when in read-only status - clear(); - String delimiter = datefield.getDateTimeService().getClockDelimeter(); - - int h = datefield.getCurrentDate().getHours(); - if(thc) h -= h<12? 0 : 12; - add(new ILabel(h<10? "0"+h : ""+h)); - - if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_MIN) { - add(new ILabel(delimiter)); - int m = mins.getSelectedIndex(); - add(new ILabel(m<10? "0"+m : ""+m)); - } - if(datefield.getCurrentResolution() >= IDateField.RESOLUTION_SEC) { - add(new ILabel(delimiter)); - int s = sec.getSelectedIndex(); - add(new ILabel(s<10? "0"+s : ""+s)); - } - if(datefield.getCurrentResolution() == IDateField.RESOLUTION_MSEC) { - add(new ILabel(".")); - int m = datefield.getMilliseconds(); - String ms = m<100? "0"+m : ""+m; - add(new ILabel(m<10? "0"+ms : ms)); - } - if(datefield.getCurrentResolution() == IDateField.RESOLUTION_HOUR) { - add(new ILabel(delimiter+"00")); // o'clock - } - if(thc) { - add(new ILabel(" ")); - add(new ILabel(ampm.getItemText(datefield.getCurrentDate().getHours()<12? 0 : 1))); - } - } - - boolean enabled = datefield.isEnabled(); - 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.getCurrentResolution() - || readonly != datefield.isReadonly()); - if(datefield instanceof ITextualDate) - ((ITextualDate) datefield).buildDate(); - resolution = datefield.getCurrentResolution(); - readonly = datefield.isReadonly(); - } - - public void onChange(Widget sender) { - if(sender == hours) { - int h = hours.getSelectedIndex(); - if(datefield.getDateTimeService().isTwelveHourClock()) - h = h + ampm.getSelectedIndex()*12; - datefield.getCurrentDate().setHours(h); - datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate()); - updateTime(false); - } - else if(sender == mins) { - int m = mins.getSelectedIndex(); - datefield.getCurrentDate().setMinutes(m); - datefield.getClient().updateVariable(datefield.getId(), "min", m, datefield.isImmediate()); - updateTime(false); - } - else if(sender == sec) { - int s = sec.getSelectedIndex(); - datefield.getCurrentDate().setSeconds(s); - datefield.getClient().updateVariable(datefield.getId(), "sec", s, datefield.isImmediate()); - updateTime(false); - } - else if(sender == msec) { - int ms = msec.getSelectedIndex(); - datefield.setMilliseconds(ms); - datefield.getClient().updateVariable(datefield.getId(), "msec", ms, datefield.isImmediate()); - updateTime(false); - } - else if(sender == ampm) { - int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12; - datefield.getCurrentDate().setHours(h); - datefield.getClient().updateVariable(datefield.getId(), "hour", h, datefield.isImmediate()); - updateTime(false); - } - } - -} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/util/DateLocale.java b/src/com/itmill/toolkit/terminal/gwt/client/util/DateLocale.java new file mode 100644 index 0000000000..8c5b4c29b8 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/util/DateLocale.java @@ -0,0 +1,85 @@ +package com.itmill.toolkit.terminal.gwt.client.util; + +import java.util.Arrays; +import java.util.List; + +/** + * Date locale support for the {@link SimpleDateParser}. You are encouraged to + * extend this class and provide implementations for other locales. + * @author George Georgovassilis + * + */ +public class DateLocale { + public final static String TOKEN_DAY_OF_WEEK = "E"; + + public final static String TOKEN_DAY_OF_MONTH = "d"; + + public final static String TOKEN_MONTH = "M"; + + public final static String TOKEN_YEAR = "y"; + + public final static String TOKEN_HOUR_12 = "h"; + + public final static String TOKEN_HOUR_24 = "H"; + + public final static String TOKEN_MINUTE = "m"; + + public final static String TOKEN_SECOND = "s"; + + public final static String TOKEN_MILLISECOND = "S"; + + public final static String TOKEN_AM_PM = "a"; + + public final static String AM = "AM"; + + public final static String PM = "PM"; + + public static List SUPPORTED_DF_TOKENS = Arrays.asList(new String[] { + TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR, + TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND, + TOKEN_AM_PM }); + + public static List TOKENS_RESOLUTION_ALL = Arrays.asList(new String[] { + TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR, + TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND, + TOKEN_AM_PM }); + + public static List TOKENS_RESOLUTION_YEAR = Arrays.asList(new String[] { + TOKEN_YEAR}); + + public static List TOKENS_RESOLUTION_MONTH = Arrays.asList(new String[] { + TOKEN_YEAR, TOKEN_MONTH}); + + public static List TOKENS_RESOLUTION_DAY = Arrays.asList(new String[] { + TOKEN_YEAR, TOKEN_MONTH, TOKEN_DAY_OF_MONTH}); + + public String[] MONTH_LONG = { "January", "February", "March", "April", + "May", "June", "July", "August", "September", "October", + "November", "December" }; + + public String[] MONTH_SHORT = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" }; + + public String[] WEEKDAY_LONG = { "Sunday", "Monday", "Tuesday", + "Wednesday", "Thursday", "Friday", "Saturday" }; + + public String[] WEEKDAY_SHORT = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", + "Sat" }; + + public static String getAM() { + return AM; + } + + public static String getPM() { + return PM; + } + + public String[] getWEEKDAY_LONG() { + return WEEKDAY_LONG; + } + + public String[] getWEEKDAY_SHORT() { + return WEEKDAY_SHORT; + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/util/Pattern.java b/src/com/itmill/toolkit/terminal/gwt/client/util/Pattern.java new file mode 100644 index 0000000000..eead6832ac --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/util/Pattern.java @@ -0,0 +1,176 @@ +/* + * Copyright 2006 Robert Hanson + * + * 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.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.JavaScriptObject; + +/** + *

+ * Implementation of the {@link java.util.regex.Pattern} class with a + * wrapper aroung the Javascript RegExp object. + * As most of the methods delegate to the JavaScript RegExp object, certain differences in the + * declaration and behaviour of regular expressions must be expected. + *

+ *

+ * Please note that neither the {@link java.util.regex.Pattern#compile(String)} method nor + * {@link Matcher} instances are supported. For the later, consider using {@link Pattern#match(String)}. + *

+ * + * @author George Georgovassilis + * + */ +public class Pattern { + + /** + * Declares that regular expressions should be matched across line borders. + */ + public final static int MULTILINE = 1; + + /** + * Declares that characters are matched reglardless of case. + */ + public final static int CASE_INSENSITIVE = 2; + + private JavaScriptObject regExp; + + private static JavaScriptObject createExpression(String pattern, int flags) { + String sFlags = ""; + if ((flags & MULTILINE) != 0) + sFlags += "m"; + if ((flags & CASE_INSENSITIVE) != 0) + sFlags += "i"; + return _createExpression(pattern, sFlags); + } + + private static native JavaScriptObject _createExpression(String pattern, + String flags)/*-{ + return new RegExp(pattern, flags); + }-*/; + + private native void _match(String text, List matches)/*-{ + var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; + var result = text.match(regExp); + if (result == null) return; + for (var i=0;itrue if matched. + */ + public static boolean matches(String regex, String input) { + return new Pattern(regex).matches(input); + } + + /** + * Escape a provided string so that it will be interpreted as a literal + * in regular expressions. + * The current implementation does escape each character even if not neccessary, + * generating verbose literals. + * @param input + * @return + */ + public static String quote(String input) { + String output = ""; + for (int i = 0; i < input.length(); i++) { + output += "\\" + input.charAt(i); + } + return output; + } + + /** + * Class constructor + * @param pattern Regular expression + */ + public Pattern(String pattern) { + this(pattern, 0); + } + + /** + * Class constructor + * @param pattern Regular expression + * @param flags + */ + public Pattern(String pattern, int flags) { + regExp = createExpression(pattern, flags); + } + + /** + * This method is borrowed from the JavaScript RegExp object. + * It parses a string and returns as an array any assignments to parenthesis groups + * in the pattern's regular expression + * @param text + * @return Array of strings following java's Pattern convention for groups: + * Group 0 is the entire input string and the remaining groups are the matched parenthesis. + * In case nothing was matched an empty array is returned. + */ + public String[] match(String text) { + List matches = new ArrayList(); + _match(text, matches); + String arr[] = new String[matches.size()]; + for (int i = 0; i < matches.size(); i++) + arr[i] = matches.get(i).toString(); + return arr; + } + + /** + * Determines wether a provided text matches the regular expression + * @param text + * @return + */ + public native boolean matches(String text)/*-{ + var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; + return regExp.test(text); + }-*/; + + /** + * Returns the regular expression for this pattern + * @return + */ + public native String pattern()/*-{ + var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; + return regExp.source; + }-*/; + + private native void _split(String input, List results)/*-{ + var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; + var parts = input.split(regExp); + for (var i=0;i + * + * 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; + +/** + *
+ *
Title: + *
SimpleDateFormat
+ *

+ *

Description: + *
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: + *
+ *
E
+ *
Day in a week
+ *
d
+ *
Day of the month
+ *
y
+ *
Year
+ *
M
+ *
Month January, Jan, 01, 1
+ *
H
+ *
Hour in 24 hour format (0-23)
+ *
h
+ *
Hour in 12 hour format (1-12)
+ *
m
+ *
Minute of the hour
+ *
s
+ *
Seconds of the minute
+ *
a
+ *
am/pm
+ *
+ * All characters that are not recognised as a date format character are + * translated literally into the output string.
+ *

+ *

+ *

+ * 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). + *

+ * + * @author Jason Essington + * @author George Georgovassilis + * @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); + }; + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/util/SimpleDateParser.java b/src/com/itmill/toolkit/terminal/gwt/client/util/SimpleDateParser.java new file mode 100644 index 0000000000..a3c6b17237 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/util/SimpleDateParser.java @@ -0,0 +1,155 @@ +package com.itmill.toolkit.terminal.gwt.client.util; + +import java.util.Date; + + +/** + * This is a simple regular expression based parser for date notations. + * While our aim is to fully support in the future the JDK date parser, currently + * only numeric notations and literals are supported such as dd/MM/yyyy HH:mm:ss.SSSS. + * Each entity is parsed with the same number of digits, i.e. for dd two digits will be + * parsed while for d only one will be parsed. + * @author George Georgovassilis + * + */ + +public class SimpleDateParser { + + + private final static String DAY_IN_MONTH = "d"; + + private final static String MONTH = "M"; + + private final static String YEAR = "y"; + + private final static String LITERAL = "\\"; + + private final static int DATE_PATTERN = 0; + + private final static int REGEX_PATTERN = 1; + + private final static int COMPONENT = 2; + + private final static int REGEX = 0; + + private final static int INSTRUCTION = 1; + + private final static String[] TOKENS[] = { + { "SSSS", "(\\d\\d\\d\\d)",DateLocale.TOKEN_MILLISECOND }, + { "SSS", "(\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND }, + { "SS", "(\\d\\d)", DateLocale.TOKEN_MILLISECOND }, + { "S", "(\\d)", DateLocale.TOKEN_MILLISECOND }, + { "ss", "(\\d\\d)", DateLocale.TOKEN_SECOND }, + { "s", "(\\d\\d)", DateLocale.TOKEN_SECOND }, + { "mm", "(\\d\\d)", DateLocale.TOKEN_MINUTE }, + { "m", "(\\d\\d)", DateLocale.TOKEN_MINUTE}, + { "HH", "(\\d\\d)", DateLocale.TOKEN_HOUR_24}, + { "H", "(\\d{1,2})", DateLocale.TOKEN_HOUR_24 }, + { "hh", "(\\d\\d)", DateLocale.TOKEN_HOUR_12}, + { "h", "(\\d{1,2})", DateLocale.TOKEN_HOUR_12 }, + { "dd", "(\\d\\d)", DateLocale.TOKEN_DAY_OF_MONTH }, + { "d", "(\\d{1,2})", DateLocale.TOKEN_DAY_OF_MONTH }, + { "MM", "(\\d\\d)", DateLocale.TOKEN_MONTH }, + { "M", "(\\d{1,2})", DateLocale.TOKEN_MONTH }, + { "yyyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, + { "yyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, + { "yy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, + { "y", "(\\d{1,2})", DateLocale.TOKEN_YEAR }, + { "a", "(\\S{1,4})", DateLocale.TOKEN_AM_PM } + }; + + private Pattern regularExpression; + + private String instructions = ""; + + private static void _parse(String format, String[] args) { + if (format.length() == 0) + return; + if (format.startsWith("'")){ + format = format.substring(1); + int end = format.indexOf("'"); + if (end == -1) + throw new IllegalArgumentException("Unmatched single quotes."); + args[REGEX]+=Pattern.quote(format.substring(0,end)); + format = format.substring(end+1); + } + for (int i = 0; i < TOKENS.length; i++) { + String[] row = TOKENS[i]; + String datePattern = row[DATE_PATTERN]; + if (!format.startsWith(datePattern)) + continue; + format = format.substring(datePattern.length()); + args[REGEX] += row[REGEX_PATTERN]; + args[INSTRUCTION] += row[COMPONENT]; + _parse(format, args); + return; + } + args[REGEX] += Pattern.quote(""+format.charAt(0)); + format = format.substring(1); + _parse(format, args); + } + + private static void load(Date date, String text, String component, String input, Pattern regex) { + if (component.equals(DateLocale.TOKEN_MILLISECOND)) { + date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text)); + } + + if (component.equals(DateLocale.TOKEN_SECOND)) { + date.setSeconds(Integer.parseInt(text)); + } + + if (component.equals(DateLocale.TOKEN_MINUTE)) { + date.setMinutes(Integer.parseInt(text)); + } + + if (component.equals(DateLocale.TOKEN_HOUR_24)) { + date.setHours(Integer.parseInt(text)); + } + + if (component.equals(DateLocale.TOKEN_HOUR_12)) { + int h = Integer.parseInt(text); + String token = com.itmill.toolkit.terminal.gwt.client.DateLocale.getPM(); + String which = input.substring(input.length() - token.length()); // Assumes both AM and PM tokens have same length + if(which.equalsIgnoreCase(token)) + h += 12; + date.setHours(h); + } + + if (component.equals(DateLocale.TOKEN_DAY_OF_MONTH)) { + date.setDate(Integer.parseInt(text)); + } + if (component.equals(DateLocale.TOKEN_MONTH)) { + date.setMonth(Integer.parseInt(text)-1); + } + if (component.equals(DateLocale.TOKEN_YEAR)) { + //TODO: fix for short patterns + date.setYear(Integer.parseInt(text)-1900); + } + + } + + public SimpleDateParser(String format) { + String[] args = new String[] { "", "" }; + _parse(format, args); + regularExpression = new Pattern(args[REGEX]); + instructions = args[INSTRUCTION]; + } + + public Date parse(String input) { + Date date = new Date(0, 0, 0, 0, 0, 0); + String matches[] = regularExpression.match(input); + if (matches == null) + throw new IllegalArgumentException(input+" does not match "+regularExpression.pattern()); + if (matches.length-1!=instructions.length()) + throw new IllegalArgumentException("Different group count - "+input+" does not match "+regularExpression.pattern()); + for (int group = 0; group < instructions.length(); group++) { + String match = matches[group + 1]; + load(date, match, ""+instructions.charAt(group), input, regularExpression); + } + return date; + } + + public static Date parse(String input, String pattern){ + return new SimpleDateParser(pattern).parse(input); + } +} diff --git a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/DateLocale.java b/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/DateLocale.java deleted file mode 100644 index bb4cb01e9d..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/DateLocale.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.itmill.toolkit.terminal.gwt.gwtwidgets.util; - -import java.util.Arrays; -import java.util.List; - -/** - * Date locale support for the {@link SimpleDateParser}. You are encouraged to - * extend this class and provide implementations for other locales. - * @author George Georgovassilis - * - */ -public class DateLocale { - public final static String TOKEN_DAY_OF_WEEK = "E"; - - public final static String TOKEN_DAY_OF_MONTH = "d"; - - public final static String TOKEN_MONTH = "M"; - - public final static String TOKEN_YEAR = "y"; - - public final static String TOKEN_HOUR_12 = "h"; - - public final static String TOKEN_HOUR_24 = "H"; - - public final static String TOKEN_MINUTE = "m"; - - public final static String TOKEN_SECOND = "s"; - - public final static String TOKEN_MILLISECOND = "S"; - - public final static String TOKEN_AM_PM = "a"; - - public final static String AM = "AM"; - - public final static String PM = "PM"; - - public static List SUPPORTED_DF_TOKENS = Arrays.asList(new String[] { - TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR, - TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND, - TOKEN_AM_PM }); - - public static List TOKENS_RESOLUTION_ALL = Arrays.asList(new String[] { - TOKEN_DAY_OF_WEEK, TOKEN_DAY_OF_MONTH, TOKEN_MONTH, TOKEN_YEAR, - TOKEN_HOUR_12, TOKEN_HOUR_24, TOKEN_MINUTE, TOKEN_SECOND, - TOKEN_AM_PM }); - - public static List TOKENS_RESOLUTION_YEAR = Arrays.asList(new String[] { - TOKEN_YEAR}); - - public static List TOKENS_RESOLUTION_MONTH = Arrays.asList(new String[] { - TOKEN_YEAR, TOKEN_MONTH}); - - public static List TOKENS_RESOLUTION_DAY = Arrays.asList(new String[] { - TOKEN_YEAR, TOKEN_MONTH, TOKEN_DAY_OF_MONTH}); - - public String[] MONTH_LONG = { "January", "February", "March", "April", - "May", "June", "July", "August", "September", "October", - "November", "December" }; - - public String[] MONTH_SHORT = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" }; - - public String[] WEEKDAY_LONG = { "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday" }; - - public String[] WEEKDAY_SHORT = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", - "Sat" }; - - public static String getAM() { - return AM; - } - - public static String getPM() { - return PM; - } - - public String[] getWEEKDAY_LONG() { - return WEEKDAY_LONG; - } - - public String[] getWEEKDAY_SHORT() { - return WEEKDAY_SHORT; - } - -} diff --git a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateFormat.java b/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateFormat.java deleted file mode 100644 index 79ce6518fc..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateFormat.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2006 Robert Hanson - * - * 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; - -/** - *
- *
Title: - *
SimpleDateFormat
- *

- *

Description: - *
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: - *
- *
E
- *
Day in a week
- *
d
- *
Day of the month
- *
y
- *
Year
- *
M
- *
Month January, Jan, 01, 1
- *
H
- *
Hour in 24 hour format (0-23)
- *
h
- *
Hour in 12 hour format (1-12)
- *
m
- *
Minute of the hour
- *
s
- *
Seconds of the minute
- *
a
- *
am/pm
- *
- * All characters that are not recognised as a date format character are - * translated literally into the output string.
- *

- *

- *

- * 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). - *

- * - * @author Jason Essington - * @author George Georgovassilis - * @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); - }; - -} diff --git a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateParser.java b/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateParser.java deleted file mode 100644 index 862356b20d..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/SimpleDateParser.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.itmill.toolkit.terminal.gwt.gwtwidgets.util; - -import java.util.Date; - -import com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern; - -/** - * This is a simple regular expression based parser for date notations. - * While our aim is to fully support in the future the JDK date parser, currently - * only numeric notations and literals are supported such as dd/MM/yyyy HH:mm:ss.SSSS. - * Each entity is parsed with the same number of digits, i.e. for dd two digits will be - * parsed while for d only one will be parsed. - * @author George Georgovassilis - * - */ - -public class SimpleDateParser { - - - private final static String DAY_IN_MONTH = "d"; - - private final static String MONTH = "M"; - - private final static String YEAR = "y"; - - private final static String LITERAL = "\\"; - - private final static int DATE_PATTERN = 0; - - private final static int REGEX_PATTERN = 1; - - private final static int COMPONENT = 2; - - private final static int REGEX = 0; - - private final static int INSTRUCTION = 1; - - private final static String[] TOKENS[] = { - { "SSSS", "(\\d\\d\\d\\d)",DateLocale.TOKEN_MILLISECOND }, - { "SSS", "(\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND }, - { "SS", "(\\d\\d)", DateLocale.TOKEN_MILLISECOND }, - { "S", "(\\d)", DateLocale.TOKEN_MILLISECOND }, - { "ss", "(\\d\\d)", DateLocale.TOKEN_SECOND }, - { "s", "(\\d\\d)", DateLocale.TOKEN_SECOND }, - { "mm", "(\\d\\d)", DateLocale.TOKEN_MINUTE }, - { "m", "(\\d\\d)", DateLocale.TOKEN_MINUTE}, - { "HH", "(\\d\\d)", DateLocale.TOKEN_HOUR_24}, - { "H", "(\\d{1,2})", DateLocale.TOKEN_HOUR_24 }, - { "hh", "(\\d\\d)", DateLocale.TOKEN_HOUR_12}, - { "h", "(\\d{1,2})", DateLocale.TOKEN_HOUR_12 }, - { "dd", "(\\d\\d)", DateLocale.TOKEN_DAY_OF_MONTH }, - { "d", "(\\d{1,2})", DateLocale.TOKEN_DAY_OF_MONTH }, - { "MM", "(\\d\\d)", DateLocale.TOKEN_MONTH }, - { "M", "(\\d{1,2})", DateLocale.TOKEN_MONTH }, - { "yyyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, - { "yyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, - { "yy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR }, - { "y", "(\\d{1,2})", DateLocale.TOKEN_YEAR }, - { "a", "(\\S{1,4})", DateLocale.TOKEN_AM_PM } - }; - - private Pattern regularExpression; - - private String instructions = ""; - - private static void _parse(String format, String[] args) { - if (format.length() == 0) - return; - if (format.startsWith("'")){ - format = format.substring(1); - int end = format.indexOf("'"); - if (end == -1) - throw new IllegalArgumentException("Unmatched single quotes."); - args[REGEX]+=Pattern.quote(format.substring(0,end)); - format = format.substring(end+1); - } - for (int i = 0; i < TOKENS.length; i++) { - String[] row = TOKENS[i]; - String datePattern = row[DATE_PATTERN]; - if (!format.startsWith(datePattern)) - continue; - format = format.substring(datePattern.length()); - args[REGEX] += row[REGEX_PATTERN]; - args[INSTRUCTION] += row[COMPONENT]; - _parse(format, args); - return; - } - args[REGEX] += Pattern.quote(""+format.charAt(0)); - format = format.substring(1); - _parse(format, args); - } - - private static void load(Date date, String text, String component, String input, Pattern regex) { - if (component.equals(DateLocale.TOKEN_MILLISECOND)) { - date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text)); - } - - if (component.equals(DateLocale.TOKEN_SECOND)) { - date.setSeconds(Integer.parseInt(text)); - } - - if (component.equals(DateLocale.TOKEN_MINUTE)) { - date.setMinutes(Integer.parseInt(text)); - } - - if (component.equals(DateLocale.TOKEN_HOUR_24)) { - date.setHours(Integer.parseInt(text)); - } - - if (component.equals(DateLocale.TOKEN_HOUR_12)) { - int h = Integer.parseInt(text); - String token = com.itmill.toolkit.terminal.gwt.client.DateLocale.getPM(); - String which = input.substring(input.length() - token.length()); // Assumes both AM and PM tokens have same length - if(which.equalsIgnoreCase(token)) - h += 12; - date.setHours(h); - } - - if (component.equals(DateLocale.TOKEN_DAY_OF_MONTH)) { - date.setDate(Integer.parseInt(text)); - } - if (component.equals(DateLocale.TOKEN_MONTH)) { - date.setMonth(Integer.parseInt(text)-1); - } - if (component.equals(DateLocale.TOKEN_YEAR)) { - //TODO: fix for short patterns - date.setYear(Integer.parseInt(text)-1900); - } - - } - - public SimpleDateParser(String format) { - String[] args = new String[] { "", "" }; - _parse(format, args); - regularExpression = new Pattern(args[REGEX]); - instructions = args[INSTRUCTION]; - } - - public Date parse(String input) { - Date date = new Date(0, 0, 0, 0, 0, 0); - String matches[] = regularExpression.match(input); - if (matches == null) - throw new IllegalArgumentException(input+" does not match "+regularExpression.pattern()); - if (matches.length-1!=instructions.length()) - throw new IllegalArgumentException("Different group count - "+input+" does not match "+regularExpression.pattern()); - for (int group = 0; group < instructions.length(); group++) { - String match = matches[group + 1]; - load(date, match, ""+instructions.charAt(group), input, regularExpression); - } - return date; - } - - public static Date parse(String input, String pattern){ - return new SimpleDateParser(pattern).parse(input); - } -} diff --git a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/regex/Pattern.java b/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/regex/Pattern.java deleted file mode 100644 index 3a6d0b4e18..0000000000 --- a/src/com/itmill/toolkit/terminal/gwt/gwtwidgets/util/regex/Pattern.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2006 Robert Hanson - * - * 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.regex; - -import java.util.ArrayList; -import java.util.List; - -import com.google.gwt.core.client.JavaScriptObject; - -/** - *

- * Implementation of the {@link java.util.regex.Pattern} class with a - * wrapper aroung the Javascript RegExp object. - * As most of the methods delegate to the JavaScript RegExp object, certain differences in the - * declaration and behaviour of regular expressions must be expected. - *

- *

- * Please note that neither the {@link java.util.regex.Pattern#compile(String)} method nor - * {@link Matcher} instances are supported. For the later, consider using {@link Pattern#match(String)}. - *

- * - * @author George Georgovassilis - * - */ -public class Pattern { - - /** - * Declares that regular expressions should be matched across line borders. - */ - public final static int MULTILINE = 1; - - /** - * Declares that characters are matched reglardless of case. - */ - public final static int CASE_INSENSITIVE = 2; - - private JavaScriptObject regExp; - - private static JavaScriptObject createExpression(String pattern, int flags) { - String sFlags = ""; - if ((flags & MULTILINE) != 0) - sFlags += "m"; - if ((flags & CASE_INSENSITIVE) != 0) - sFlags += "i"; - return _createExpression(pattern, sFlags); - } - - private static native JavaScriptObject _createExpression(String pattern, - String flags)/*-{ - return new RegExp(pattern, flags); - }-*/; - - private native void _match(String text, List matches)/*-{ - var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; - var result = text.match(regExp); - if (result == null) return; - for (var i=0;itrue if matched. - */ - public static boolean matches(String regex, String input) { - return new Pattern(regex).matches(input); - } - - /** - * Escape a provided string so that it will be interpreted as a literal - * in regular expressions. - * The current implementation does escape each character even if not neccessary, - * generating verbose literals. - * @param input - * @return - */ - public static String quote(String input) { - String output = ""; - for (int i = 0; i < input.length(); i++) { - output += "\\" + input.charAt(i); - } - return output; - } - - /** - * Class constructor - * @param pattern Regular expression - */ - public Pattern(String pattern) { - this(pattern, 0); - } - - /** - * Class constructor - * @param pattern Regular expression - * @param flags - */ - public Pattern(String pattern, int flags) { - regExp = createExpression(pattern, flags); - } - - /** - * This method is borrowed from the JavaScript RegExp object. - * It parses a string and returns as an array any assignments to parenthesis groups - * in the pattern's regular expression - * @param text - * @return Array of strings following java's Pattern convention for groups: - * Group 0 is the entire input string and the remaining groups are the matched parenthesis. - * In case nothing was matched an empty array is returned. - */ - public String[] match(String text) { - List matches = new ArrayList(); - _match(text, matches); - String arr[] = new String[matches.size()]; - for (int i = 0; i < matches.size(); i++) - arr[i] = matches.get(i).toString(); - return arr; - } - - /** - * Determines wether a provided text matches the regular expression - * @param text - * @return - */ - public native boolean matches(String text)/*-{ - var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; - return regExp.test(text); - }-*/; - - /** - * Returns the regular expression for this pattern - * @return - */ - public native String pattern()/*-{ - var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; - return regExp.source; - }-*/; - - private native void _split(String input, List results)/*-{ - var regExp = this.@com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern::regExp; - var parts = input.split(regExp); - for (var i=0;i