+ if ( IsDateShown(dt) )
+ {
+ if ( date )
+ *date = dt;
+
+ return wxCAL_HITTEST_DAY;
+ }
+ else
+ {
+ return wxCAL_HITTEST_NOWHERE;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// subcontrols events handling
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::OnMonthChange(wxCommandEvent& event)
+{
+ wxDateTime::Tm tm = m_date.GetTm();
+
+ wxDateTime::Month mon = (wxDateTime::Month)event.GetInt();
+ if ( tm.mday > wxDateTime::GetNumberOfDays(mon, tm.year) )
+ {
+ tm.mday = wxDateTime::GetNumberOfDays(mon, tm.year);
+ }
+
+ SetDateAndNotify(wxDateTime(tm.mday, mon, tm.year));
+}
+
+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);
+ }
+
+ SetDateAndNotify(wxDateTime(tm.mday, tm.mon, year));
+}
+
+// ----------------------------------------------------------------------------
+// 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;
+
+ case WXK_RETURN:
+ GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
+ break;
+
+ default:
+ event.Skip();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// holidays handling
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::EnableHolidayDisplay(bool display)
+{
+ long style = GetWindowStyle();
+ if ( display )
+ style |= wxCAL_SHOW_HOLIDAYS;
+ else
+ style &= ~wxCAL_SHOW_HOLIDAYS;
+
+ SetWindowStyle(style);
+
+ if ( display )
+ SetHolidayAttrs();
+ else
+ ResetHolidayAttrs();
+
+ Refresh();
+}
+
+void wxCalendarCtrl::SetHolidayAttrs()
+{
+ if ( GetWindowStyle() & wxCAL_SHOW_HOLIDAYS )
+ {
+ ResetHolidayAttrs();
+
+ wxDateTime::Tm tm = m_date.GetTm();
+ wxDateTime dtStart(1, tm.mon, tm.year),
+ dtEnd = dtStart.GetLastMonthDay();
+
+ wxDateTimeArray hol;
+ wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
+
+ size_t count = hol.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ SetHoliday(hol[n].GetDay());
+ }
+ }
+}
+
+void wxCalendarCtrl::SetHoliday(size_t day)
+{
+ wxCHECK_RET( day > 0 && day < 32, _T("invalid day in SetHoliday") );
+
+ wxCalendarDateAttr *attr = GetAttr(day);
+ if ( !attr )
+ {
+ attr = new wxCalendarDateAttr;
+ }
+
+ attr->SetHoliday(TRUE);
+
+ // can't use SetAttr() because it would delete this pointer
+ m_attrs[day - 1] = attr;
+}
+
+void wxCalendarCtrl::ResetHolidayAttrs()
+{
+ for ( size_t day = 0; day < 31; day++ )
+ {
+ if ( m_attrs[day] )
+ {
+ m_attrs[day]->SetHoliday(FALSE);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxCalendarEvent
+// ----------------------------------------------------------------------------
+
+void wxCalendarEvent::Init()
+{
+ m_wday = wxDateTime::Inv_WeekDay;
+}
+
+wxCalendarEvent::wxCalendarEvent(wxCalendarCtrl *cal, wxEventType type)
+ : wxCommandEvent(type, cal->GetId())
+{
+ m_date = cal->GetDate();