+wxCalendarCtrl::~wxCalendarCtrl()
+{
+ for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
+ {
+ delete m_attrs[n];
+ }
+}
+
+// ----------------------------------------------------------------------------
+// forward wxWin functions to subcontrols
+// ----------------------------------------------------------------------------
+
+bool wxCalendarCtrl::Show(bool show)
+{
+ if ( !wxControl::Show(show) )
+ {
+ return FALSE;
+ }
+
+ GetMonthControl()->Show(show);
+ GetYearControl()->Show(show);
+
+ return TRUE;
+}
+
+bool wxCalendarCtrl::Enable(bool enable)
+{
+ if ( !wxControl::Enable(enable) )
+ {
+ return FALSE;
+ }
+
+ GetMonthControl()->Enable(enable);
+ GetYearControl()->Enable(enable);
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// enable/disable month/year controls
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::ShowCurrentControls()
+{
+ if ( AllowMonthChange() )
+ {
+ m_comboMonth->Show();
+ m_staticMonth->Hide();
+
+ if ( AllowYearChange() )
+ {
+ m_spinYear->Show();
+ m_staticYear->Hide();
+
+ // skip the rest
+ return;
+ }
+ }
+ else
+ {
+ m_comboMonth->Hide();
+ m_staticMonth->Show();
+ }
+
+ // year change not allowed here
+ m_spinYear->Hide();
+ m_staticYear->Show();
+}
+
+wxControl *wxCalendarCtrl::GetMonthControl() const
+{
+ return AllowMonthChange() ? (wxControl *)m_comboMonth : (wxControl *)m_staticMonth;
+}
+
+wxControl *wxCalendarCtrl::GetYearControl() const
+{
+ return AllowYearChange() ? (wxControl *)m_spinYear : (wxControl *)m_staticYear;
+}
+
+void wxCalendarCtrl::EnableYearChange(bool enable)
+{
+ if ( enable != AllowYearChange() )
+ {
+ long style = GetWindowStyle();
+ if ( enable )
+ style &= ~wxCAL_NO_YEAR_CHANGE;
+ else
+ style |= wxCAL_NO_YEAR_CHANGE;
+ SetWindowStyle(style);
+
+ ShowCurrentControls();
+ }
+}
+
+void wxCalendarCtrl::EnableMonthChange(bool enable)
+{
+ if ( enable != AllowMonthChange() )
+ {
+ long style = GetWindowStyle();
+ if ( enable )
+ style &= ~wxCAL_NO_MONTH_CHANGE;
+ else
+ style |= wxCAL_NO_MONTH_CHANGE;
+ SetWindowStyle(style);
+
+ ShowCurrentControls();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// changing date
+// ----------------------------------------------------------------------------
+
+void wxCalendarCtrl::SetDate(const wxDateTime& date)
+{
+ bool sameMonth = m_date.GetMonth() == date.GetMonth(),
+ sameYear = m_date.GetYear() == date.GetYear();
+
+ if ( sameMonth && sameYear )
+ {
+ // just change the day
+ ChangeDay(date);
+ }
+ else
+ {
+ if ( !AllowMonthChange() || (!AllowYearChange() && !sameYear) )
+ {
+ // forbidden
+ return;
+ }
+
+ // change everything
+ m_date = date;
+
+ // update the controls
+ m_comboMonth->SetSelection(m_date.GetMonth());
+
+ if ( AllowYearChange() )
+ {
+ m_spinYear->SetValue(m_date.Format(_T("%Y")));
+ }
+
+ // as the month changed, holidays did too
+ SetHolidayAttrs();
+
+ // update the calendar
+ Refresh();
+ }
+}
+
+void wxCalendarCtrl::ChangeDay(const wxDateTime& date)
+{
+ if ( m_date != date )
+ {
+ // we need to refresh the row containing the old date and the one
+ // containing the new one
+ wxDateTime dateOld = m_date;
+ m_date = date;
+
+ RefreshDate(dateOld);
+
+ // if the date is in the same row, it was already drawn correctly
+ if ( GetWeek(m_date) != GetWeek(dateOld) )
+ {
+ RefreshDate(m_date);
+ }
+ }
+}
+
+void wxCalendarCtrl::SetDateAndNotify(const wxDateTime& date)
+{
+ wxDateTime::Tm tm1 = m_date.GetTm(),
+ tm2 = date.GetTm();
+
+ wxEventType type;
+ if ( tm1.year != tm2.year )
+ type = wxEVT_CALENDAR_YEAR_CHANGED;
+ else if ( tm1.mon != tm2.mon )
+ type = wxEVT_CALENDAR_MONTH_CHANGED;
+ else if ( tm1.mday != tm2.mday )
+ type = wxEVT_CALENDAR_DAY_CHANGED;
+ else
+ return;
+
+ SetDate(date);
+
+ GenerateEvents(type, wxEVT_CALENDAR_SEL_CHANGED);
+}
+