+void wxCalendarCtrl::OnYearChange(wxSpinEvent& event)
+{
+ wxDateTime::Tm tm = m_date.GetTm();
+
+ int year = (int)event.GetInt();
+ if ( tm.mday > wxDateTime::GetNumberOfDays(tm.mon, year) )
+ {
+ tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year);
+ }
+
+ SetDate(wxDateTime(tm.mday, tm.mon, year));
+
+ GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
+}
+
+// ----------------------------------------------------------------------------
+// keyboard interface
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::OnChar(wxKeyEvent& event)
+{
+ switch ( event.KeyCode() )
+ {
+ case _T('+'):
+ case WXK_ADD:
+ SetDateAndNotify(m_date + wxDateSpan::Year());
+ break;
+
+ case _T('-'):
+ case WXK_SUBTRACT:
+ SetDateAndNotify(m_date - wxDateSpan::Year());
+ break;
+
+ case WXK_PRIOR:
+ SetDateAndNotify(m_date - wxDateSpan::Month());
+ break;
+
+ case WXK_NEXT:
+ SetDateAndNotify(m_date + wxDateSpan::Month());
+ break;
+
+ case WXK_RIGHT:
+ if ( event.ControlDown() )
+ SetDateAndNotify(wxDateTime(m_date).SetToNextWeekDay(
+ GetWindowStyle() & wxCAL_MONDAY_FIRST
+ ? wxDateTime::Sun : wxDateTime::Sat));
+ else
+ SetDateAndNotify(m_date + wxDateSpan::Day());
+ break;
+
+ case WXK_LEFT:
+ if ( event.ControlDown() )
+ SetDateAndNotify(wxDateTime(m_date).SetToPrevWeekDay(
+ GetWindowStyle() & wxCAL_MONDAY_FIRST
+ ? wxDateTime::Mon : wxDateTime::Sun));
+ else
+ SetDateAndNotify(m_date - wxDateSpan::Day());
+ break;
+
+ case WXK_UP:
+ SetDateAndNotify(m_date - wxDateSpan::Week());
+ break;
+
+ case WXK_DOWN:
+ SetDateAndNotify(m_date + wxDateSpan::Week());
+ break;
+
+ case WXK_HOME:
+ if ( event.ControlDown() )
+ SetDateAndNotify(wxDateTime::Today());
+ else
+ SetDateAndNotify(wxDateTime(1, m_date.GetMonth(), m_date.GetYear()));
+ break;
+
+ case WXK_END:
+ SetDateAndNotify(wxDateTime(m_date).SetToLastMonthDay());
+ break;
+
+ default:
+ event.Skip();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxCalendarEvent
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::GenerateEvent(wxEventType type, bool selChanged)
+{
+ // we're called for a change in some particular date field but we always
+ // also generate a generic "changed" event
+ wxCalendarEvent event(this, type);
+ (void)GetEventHandler()->ProcessEvent(event);
+
+ if ( selChanged )
+ {
+ wxCalendarEvent event2(this, wxEVT_CALENDAR_SEL_CHANGED);