1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: generic/calctrl.cpp
3 // Purpose: implementation fo the generic wxCalendarCtrl
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "calctrl.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
32 #include "wx/dcclient.h"
33 #include "wx/settings.h"
35 #include "wx/combobox.h"
36 #include "wx/stattext.h"
37 #include "wx/textctrl.h"
40 #if wxUSE_CALENDARCTRL
42 #include "wx/spinctrl.h"
44 #include "wx/calctrl.h"
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 class wxMonthComboBox
: public wxComboBox
55 wxMonthComboBox(wxCalendarCtrl
*cal
);
57 void OnMonthChange(wxCommandEvent
& event
) { m_cal
->OnMonthChange(event
); }
60 wxCalendarCtrl
*m_cal
;
63 DECLARE_NO_COPY_CLASS(wxMonthComboBox
)
66 class wxYearSpinCtrl
: public wxSpinCtrl
69 wxYearSpinCtrl(wxCalendarCtrl
*cal
);
71 void OnYearTextChange(wxCommandEvent
& event
)
73 m_cal
->SetUserChangedYear();
74 m_cal
->OnYearChange(event
);
76 void OnYearChange(wxSpinEvent
& event
) { m_cal
->OnYearChange(event
); }
79 wxCalendarCtrl
*m_cal
;
82 DECLARE_NO_COPY_CLASS(wxYearSpinCtrl
)
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 BEGIN_EVENT_TABLE(wxCalendarCtrl
, wxControl
)
90 EVT_PAINT(wxCalendarCtrl::OnPaint
)
92 EVT_CHAR(wxCalendarCtrl::OnChar
)
94 EVT_LEFT_DOWN(wxCalendarCtrl::OnClick
)
95 EVT_LEFT_DCLICK(wxCalendarCtrl::OnDClick
)
98 BEGIN_EVENT_TABLE(wxMonthComboBox
, wxComboBox
)
99 EVT_COMBOBOX(-1, wxMonthComboBox::OnMonthChange
)
102 BEGIN_EVENT_TABLE(wxYearSpinCtrl
, wxSpinCtrl
)
103 EVT_TEXT(-1, wxYearSpinCtrl::OnYearTextChange
)
104 EVT_SPINCTRL(-1, wxYearSpinCtrl::OnYearChange
)
107 #if wxUSE_EXTENDED_RTTI
108 IMPLEMENT_DYNAMIC_CLASS_XTI(wxCalendarCtrl
, wxControl
,"wx/calctrl.h")
110 WX_BEGIN_PROPERTIES_TABLE(wxCalendarCtrl
)
111 WX_PROPERTY( Date
,wxDateTime
, SetDate
, GetDate
, )
112 WX_END_PROPERTIES_TABLE()
114 WX_BEGIN_HANDLERS_TABLE(wxCalendarCtrl
)
115 WX_END_HANDLERS_TABLE()
117 WX_CONSTRUCTOR_6( wxCalendarCtrl
, wxWindow
* , Parent
, wxWindowID
, Id
, wxDateTime
, Date
, wxPoint
, Position
, wxSize
, Size
, long , WindowStyle
)
119 IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl
, wxControl
)
121 IMPLEMENT_DYNAMIC_CLASS(wxCalendarEvent
, wxCommandEvent
)
123 // ----------------------------------------------------------------------------
125 // ----------------------------------------------------------------------------
127 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_SEL_CHANGED
)
128 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_DAY_CHANGED
)
129 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_MONTH_CHANGED
)
130 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_YEAR_CHANGED
)
131 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_DOUBLECLICKED
)
132 DEFINE_EVENT_TYPE(wxEVT_CALENDAR_WEEKDAY_CLICKED
)
134 // ============================================================================
136 // ============================================================================
138 // ----------------------------------------------------------------------------
139 // wxMonthComboBox and wxYearSpinCtrl
140 // ----------------------------------------------------------------------------
142 wxMonthComboBox::wxMonthComboBox(wxCalendarCtrl
*cal
)
143 : wxComboBox(cal
->GetParent(), -1,
148 wxCB_READONLY
| wxCLIP_SIBLINGS
)
153 for ( m
= wxDateTime::Jan
; m
< wxDateTime::Inv_Month
; wxNextMonth(m
) )
155 Append(wxDateTime::GetMonthName(m
));
158 SetSelection(m_cal
->GetDate().GetMonth());
159 SetSize(-1, -1, -1, -1, wxSIZE_AUTO_WIDTH
|wxSIZE_AUTO_HEIGHT
);
162 wxYearSpinCtrl::wxYearSpinCtrl(wxCalendarCtrl
*cal
)
163 : wxSpinCtrl(cal
->GetParent(), -1,
164 cal
->GetDate().Format(_T("%Y")),
167 wxSP_ARROW_KEYS
| wxCLIP_SIBLINGS
,
168 -4300, 10000, cal
->GetDate().GetYear())
174 // ----------------------------------------------------------------------------
176 // ----------------------------------------------------------------------------
178 wxCalendarCtrl::wxCalendarCtrl(wxWindow
*parent
,
180 const wxDateTime
& date
,
184 const wxString
& name
)
188 (void)Create(parent
, id
, date
, pos
, size
, style
, name
);
191 void wxCalendarCtrl::Init()
196 m_staticMonth
= NULL
;
198 m_userChangedYear
= FALSE
;
203 wxDateTime::WeekDay wd
;
204 for ( wd
= wxDateTime::Sun
; wd
< wxDateTime::Inv_WeekDay
; wxNextWDay(wd
) )
206 m_weekdays
[wd
] = wxDateTime::GetWeekDayName(wd
, wxDateTime::Name_Abbr
);
209 for ( size_t n
= 0; n
< WXSIZEOF(m_attrs
); n
++ )
214 m_colHighlightFg
= wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
);
215 m_colHighlightBg
= wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
);
217 m_colHolidayFg
= *wxRED
;
218 // don't set m_colHolidayBg - by default, same as our bg colour
220 m_colHeaderFg
= *wxBLUE
;
221 m_colHeaderBg
= *wxLIGHT_GREY
;
224 bool wxCalendarCtrl::Create(wxWindow
*parent
,
226 const wxDateTime
& date
,
230 const wxString
& name
)
232 if ( !wxControl::Create(parent
, id
, pos
, size
,
233 style
| wxCLIP_CHILDREN
| wxWANTS_CHARS
,
234 wxDefaultValidator
, name
) )
239 // needed to get the arrow keys normally used for the dialog navigation
240 SetWindowStyle(style
| wxWANTS_CHARS
);
242 m_date
= date
.IsValid() ? date
: wxDateTime::Today();
244 m_lowdate
= wxDefaultDateTime
;
245 m_highdate
= wxDefaultDateTime
;
247 if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
249 m_spinYear
= new wxYearSpinCtrl(this);
250 m_staticYear
= new wxStaticText(GetParent(), -1, m_date
.Format(_T("%Y")),
251 wxDefaultPosition
, wxDefaultSize
,
254 m_comboMonth
= new wxMonthComboBox(this);
255 m_staticMonth
= new wxStaticText(GetParent(), -1, m_date
.Format(_T("%B")),
256 wxDefaultPosition
, wxDefaultSize
,
260 ShowCurrentControls();
263 if ( size
.x
== -1 || size
.y
== -1 )
265 sizeReal
= DoGetBestSize();
276 // we need to set the position as well because the main control position
277 // is not the same as the one specified in pos if we have the controls
279 SetSize(pos
.x
, pos
.y
, sizeReal
.x
, sizeReal
.y
);
281 SetBackgroundColour(*wxWHITE
);
282 SetFont(*wxSWISS_FONT
);
289 wxCalendarCtrl::~wxCalendarCtrl()
291 for ( size_t n
= 0; n
< WXSIZEOF(m_attrs
); n
++ )
297 // ----------------------------------------------------------------------------
298 // forward wxWin functions to subcontrols
299 // ----------------------------------------------------------------------------
301 bool wxCalendarCtrl::Destroy()
304 m_staticYear
->Destroy();
306 m_spinYear
->Destroy();
308 m_comboMonth
->Destroy();
310 m_staticMonth
->Destroy();
315 m_staticMonth
= NULL
;
317 return wxControl::Destroy();
320 bool wxCalendarCtrl::Show(bool show
)
322 if ( !wxControl::Show(show
) )
327 if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
329 if ( GetMonthControl() )
331 GetMonthControl()->Show(show
);
332 GetYearControl()->Show(show
);
339 bool wxCalendarCtrl::Enable(bool enable
)
341 if ( !wxControl::Enable(enable
) )
346 if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
348 GetMonthControl()->Enable(enable
);
349 GetYearControl()->Enable(enable
);
355 // ----------------------------------------------------------------------------
356 // enable/disable month/year controls
357 // ----------------------------------------------------------------------------
359 void wxCalendarCtrl::ShowCurrentControls()
361 if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
363 if ( AllowMonthChange() )
365 m_comboMonth
->Show();
366 m_staticMonth
->Hide();
368 if ( AllowYearChange() )
371 m_staticYear
->Hide();
379 m_comboMonth
->Hide();
380 m_staticMonth
->Show();
383 // year change not allowed here
385 m_staticYear
->Show();
389 wxControl
*wxCalendarCtrl::GetMonthControl() const
391 return AllowMonthChange() ? (wxControl
*)m_comboMonth
: (wxControl
*)m_staticMonth
;
394 wxControl
*wxCalendarCtrl::GetYearControl() const
396 return AllowYearChange() ? (wxControl
*)m_spinYear
: (wxControl
*)m_staticYear
;
399 void wxCalendarCtrl::EnableYearChange(bool enable
)
401 if ( enable
!= AllowYearChange() )
403 long style
= GetWindowStyle();
405 style
&= ~wxCAL_NO_YEAR_CHANGE
;
407 style
|= wxCAL_NO_YEAR_CHANGE
;
408 SetWindowStyle(style
);
410 ShowCurrentControls();
411 if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
)
418 void wxCalendarCtrl::EnableMonthChange(bool enable
)
420 if ( enable
!= AllowMonthChange() )
422 long style
= GetWindowStyle();
424 style
&= ~wxCAL_NO_MONTH_CHANGE
;
426 style
|= wxCAL_NO_MONTH_CHANGE
;
427 SetWindowStyle(style
);
429 ShowCurrentControls();
430 if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
)
437 // ----------------------------------------------------------------------------
439 // ----------------------------------------------------------------------------
441 bool wxCalendarCtrl::SetDate(const wxDateTime
& date
)
445 bool sameMonth
= m_date
.GetMonth() == date
.GetMonth(),
446 sameYear
= m_date
.GetYear() == date
.GetYear();
448 if ( IsDateInRange(date
) )
450 if ( sameMonth
&& sameYear
)
452 // just change the day
457 if ( AllowMonthChange() && (AllowYearChange() || sameYear
) )
462 if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
464 // update the controls
465 m_comboMonth
->SetSelection(m_date
.GetMonth());
467 if ( AllowYearChange() )
469 if ( !m_userChangedYear
)
470 m_spinYear
->SetValue(m_date
.Format(_T("%Y")));
474 // as the month changed, holidays did too
477 // update the calendar
488 m_userChangedYear
= FALSE
;
493 void wxCalendarCtrl::ChangeDay(const wxDateTime
& date
)
495 if ( m_date
!= date
)
497 // we need to refresh the row containing the old date and the one
498 // containing the new one
499 wxDateTime dateOld
= m_date
;
502 RefreshDate(dateOld
);
504 // if the date is in the same row, it was already drawn correctly
505 if ( GetWeek(m_date
) != GetWeek(dateOld
) )
512 void wxCalendarCtrl::SetDateAndNotify(const wxDateTime
& date
)
514 wxDateTime::Tm tm1
= m_date
.GetTm(),
518 if ( tm1
.year
!= tm2
.year
)
519 type
= wxEVT_CALENDAR_YEAR_CHANGED
;
520 else if ( tm1
.mon
!= tm2
.mon
)
521 type
= wxEVT_CALENDAR_MONTH_CHANGED
;
522 else if ( tm1
.mday
!= tm2
.mday
)
523 type
= wxEVT_CALENDAR_DAY_CHANGED
;
529 GenerateEvents(type
, wxEVT_CALENDAR_SEL_CHANGED
);
533 // ----------------------------------------------------------------------------
535 // ----------------------------------------------------------------------------
537 bool wxCalendarCtrl::SetLowerDateLimit(const wxDateTime
& date
/* = wxDefaultDateTime */)
541 if ( !(date
.IsValid()) || ( ( m_highdate
.IsValid() ) ? ( date
<= m_highdate
) : TRUE
) )
553 bool wxCalendarCtrl::SetUpperDateLimit(const wxDateTime
& date
/* = wxDefaultDateTime */)
557 if ( !(date
.IsValid()) || ( ( m_lowdate
.IsValid() ) ? ( date
>= m_lowdate
) : TRUE
) )
569 bool wxCalendarCtrl::SetDateRange(const wxDateTime
& lowerdate
/* = wxDefaultDateTime */, const wxDateTime
& upperdate
/* = wxDefaultDateTime */)
574 ( !( lowerdate
.IsValid() ) || ( ( upperdate
.IsValid() ) ? ( lowerdate
<= upperdate
) : TRUE
) ) &&
575 ( !( upperdate
.IsValid() ) || ( ( lowerdate
.IsValid() ) ? ( upperdate
>= lowerdate
) : TRUE
) ) )
577 m_lowdate
= lowerdate
;
578 m_highdate
= upperdate
;
588 // ----------------------------------------------------------------------------
590 // ----------------------------------------------------------------------------
592 wxDateTime
wxCalendarCtrl::GetStartDate() const
594 wxDateTime::Tm tm
= m_date
.GetTm();
596 wxDateTime date
= wxDateTime(1, tm
.mon
, tm
.year
);
599 date
.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST
600 ? wxDateTime::Mon
: wxDateTime::Sun
);
602 if ( GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS
)
604 // We want to offset the calendar if we start on the first..
605 if ( date
.GetDay() == 1 )
607 date
-= wxDateSpan::Week();
614 bool wxCalendarCtrl::IsDateShown(const wxDateTime
& date
) const
616 if ( !(GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS
) )
618 return date
.GetMonth() == m_date
.GetMonth();
626 bool wxCalendarCtrl::IsDateInRange(const wxDateTime
& date
) const
629 // Check if the given date is in the range specified
630 retval
= ( ( ( m_lowdate
.IsValid() ) ? ( date
>= m_lowdate
) : TRUE
)
631 && ( ( m_highdate
.IsValid() ) ? ( date
<= m_highdate
) : TRUE
) );
635 bool wxCalendarCtrl::ChangeYear(wxDateTime
* target
) const
639 if ( !(IsDateInRange(*target
)) )
641 if ( target
->GetYear() < m_date
.GetYear() )
643 if ( target
->GetYear() >= GetLowerDateLimit().GetYear() )
645 *target
= GetLowerDateLimit();
655 if ( target
->GetYear() <= GetUpperDateLimit().GetYear() )
657 *target
= GetUpperDateLimit();
674 bool wxCalendarCtrl::ChangeMonth(wxDateTime
* target
) const
678 if ( !(IsDateInRange(*target
)) )
682 if ( target
->GetMonth() < m_date
.GetMonth() )
684 *target
= GetLowerDateLimit();
688 *target
= GetUpperDateLimit();
695 size_t wxCalendarCtrl::GetWeek(const wxDateTime
& date
) const
697 size_t retval
= date
.GetWeekOfMonth(GetWindowStyle() & wxCAL_MONDAY_FIRST
698 ? wxDateTime::Monday_First
699 : wxDateTime::Sunday_First
);
701 if ( (GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS
) )
703 // we need to offset an extra week if we "start" on the 1st of the month
704 wxDateTime::Tm tm
= date
.GetTm();
706 wxDateTime datetest
= wxDateTime(1, tm
.mon
, tm
.year
);
709 datetest
.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST
710 ? wxDateTime::Mon
: wxDateTime::Sun
);
712 if ( datetest
.GetDay() == 1 )
721 // ----------------------------------------------------------------------------
723 // ----------------------------------------------------------------------------
725 // this is a composite control and it must arrange its parts each time its
726 // size or position changes: the combobox and spinctrl are along the top of
727 // the available area and the calendar takes up therest of the space
729 // the static controls are supposed to be always smaller than combo/spin so we
730 // always use the latter for size calculations and position the static to take
733 // the constants used for the layout
734 #define VERT_MARGIN 5 // distance between combo and calendar
736 #define HORZ_MARGIN 5 // spin
738 #define HORZ_MARGIN 15 // spin
740 wxSize
wxCalendarCtrl::DoGetBestSize() const
742 // calc the size of the calendar
743 ((wxCalendarCtrl
*)this)->RecalcGeometry(); // const_cast
745 wxCoord width
= 7*m_widthCol
,
746 height
= 7*m_heightRow
+ m_rowOffset
+ VERT_MARGIN
;
748 if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
750 // the combobox doesn't report its height correctly (it returns the
751 // height including the drop down list) so don't use it
752 height
+= m_spinYear
->GetBestSize().y
;
755 if ( !HasFlag(wxBORDER_NONE
) )
757 // the border would clip the last line otherwise
762 return wxSize(width
, height
);
765 void wxCalendarCtrl::DoSetSize(int x
, int y
,
766 int width
, int height
,
769 wxControl::DoSetSize(x
, y
, width
, height
, sizeFlags
);
772 void wxCalendarCtrl::DoMoveWindow(int x
, int y
, int width
, int height
)
776 if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
778 wxSize sizeCombo
= m_comboMonth
->GetSize();
779 wxSize sizeStatic
= m_staticMonth
->GetSize();
780 wxSize sizeSpin
= m_spinYear
->GetSize();
781 int dy
= (sizeCombo
.y
- sizeStatic
.y
) / 2;
783 In the calender the size of the combobox for the year
784 is just defined by a margin from the month combobox to
785 the left border. While in wxUniv the year control can't
786 show all 4 digits, in wxMsw it show almost twice as
787 much. Instead the year should use it's best size and be
788 left aligned to the calendar. Just in case the month in
789 any language is longer than it has space in the
790 calendar it is shortend.This way the year always can
793 This patch relies on the fact that a combobox has a
794 good best size implementation. This is not the case
795 with wxMSW but I don't know why.
800 #ifdef __WXUNIVERSAL__
801 if (sizeCombo
.x
+ HORZ_MARGIN
- sizeSpin
.x
> width
)
803 m_comboMonth
->SetSize(x
, y
, width
- HORZ_MARGIN
- sizeSpin
.x
, sizeCombo
.y
);
807 m_comboMonth
->Move(x
, y
);
809 m_staticMonth
->Move(x
, y
+ dy
);
810 m_spinYear
->Move(x
+ width
- sizeSpin
.x
, y
);
811 m_staticYear
->Move(x
+ width
- sizeSpin
.x
, y
+ dy
);
813 m_comboMonth
->Move(x
, y
);
814 m_staticMonth
->SetSize(x
, y
+ dy
, sizeCombo
.x
, sizeStatic
.y
);
816 int xDiff
= sizeCombo
.x
+ HORZ_MARGIN
;
818 m_spinYear
->SetSize(x
+ xDiff
, y
, width
- xDiff
, sizeCombo
.y
);
819 m_staticYear
->SetSize(x
+ xDiff
, y
+ dy
, width
- xDiff
, sizeStatic
.y
);
821 yDiff
= wxMax(sizeSpin
.y
, sizeCombo
.y
) + VERT_MARGIN
;
823 else // no controls on the top
828 wxControl::DoMoveWindow(x
, y
+ yDiff
, width
, height
- yDiff
);
831 void wxCalendarCtrl::DoGetPosition(int *x
, int *y
) const
833 wxControl::DoGetPosition(x
, y
);
835 if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
837 // our real top corner is not in this position
840 *y
-= GetMonthControl()->GetSize().y
+ VERT_MARGIN
;
845 void wxCalendarCtrl::DoGetSize(int *width
, int *height
) const
847 wxControl::DoGetSize(width
, height
);
849 if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
851 // our real height is bigger
852 if ( height
&& GetMonthControl())
854 *height
+= GetMonthControl()->GetSize().y
+ VERT_MARGIN
;
859 void wxCalendarCtrl::RecalcGeometry()
861 if ( m_widthCol
!= 0 )
868 // determine the column width (we assume that the weekday names are always
869 // wider (in any language) than the numbers)
871 wxDateTime::WeekDay wd
;
872 for ( wd
= wxDateTime::Sun
; wd
< wxDateTime::Inv_WeekDay
; wxNextWDay(wd
) )
875 dc
.GetTextExtent(m_weekdays
[wd
], &width
, &m_heightRow
);
876 if ( width
> m_widthCol
)
882 // leave some margins
886 m_rowOffset
= (GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) ? m_heightRow
: 0; // conditional in relation to style
889 // ----------------------------------------------------------------------------
891 // ----------------------------------------------------------------------------
893 void wxCalendarCtrl::OnPaint(wxPaintEvent
& WXUNUSED(event
))
902 wxLogDebug("--- starting to paint, selection: %s, week %u\n",
903 m_date
.Format("%a %d-%m-%Y %H:%M:%S").c_str(),
909 if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
911 // draw the sequential month-selector
913 dc
.SetBackgroundMode(wxTRANSPARENT
);
914 dc
.SetTextForeground(*wxBLACK
);
915 dc
.SetBrush(wxBrush(m_colHeaderBg
, wxSOLID
));
916 dc
.SetPen(wxPen(m_colHeaderBg
, 1, wxSOLID
));
917 dc
.DrawRectangle(0, y
, GetClientSize().x
, m_heightRow
);
919 // Get extent of month-name + year
920 wxCoord monthw
, monthh
;
921 wxString headertext
= m_date
.Format(wxT("%B %Y"));
922 dc
.GetTextExtent(headertext
, &monthw
, &monthh
);
924 // draw month-name centered above weekdays
925 wxCoord monthx
= ((m_widthCol
* 7) - monthw
) / 2;
926 wxCoord monthy
= ((m_heightRow
- monthh
) / 2) + y
;
927 dc
.DrawText(headertext
, monthx
, monthy
);
929 // calculate the "month-arrows"
930 wxPoint leftarrow
[3];
931 wxPoint rightarrow
[3];
933 int arrowheight
= monthh
/ 2;
935 leftarrow
[0] = wxPoint(0, arrowheight
/ 2);
936 leftarrow
[1] = wxPoint(arrowheight
/ 2, 0);
937 leftarrow
[2] = wxPoint(arrowheight
/ 2, arrowheight
- 1);
939 rightarrow
[0] = wxPoint(0, 0);
940 rightarrow
[1] = wxPoint(arrowheight
/ 2, arrowheight
/ 2);
941 rightarrow
[2] = wxPoint(0, arrowheight
- 1);
943 // draw the "month-arrows"
945 wxCoord arrowy
= (m_heightRow
- arrowheight
) / 2;
946 wxCoord larrowx
= (m_widthCol
- (arrowheight
/ 2)) / 2;
947 wxCoord rarrowx
= ((m_widthCol
- (arrowheight
/ 2)) / 2) + m_widthCol
*6;
948 m_leftArrowRect
= wxRect(0, 0, 0, 0);
949 m_rightArrowRect
= wxRect(0, 0, 0, 0);
951 if ( AllowMonthChange() )
953 wxDateTime ldpm
= wxDateTime(1,m_date
.GetMonth(), m_date
.GetYear()) - wxDateSpan::Day(); // last day prev month
954 // Check if range permits change
955 if ( IsDateInRange(ldpm
) && ( ( ldpm
.GetYear() == m_date
.GetYear() ) ? TRUE
: AllowYearChange() ) )
957 m_leftArrowRect
= wxRect(larrowx
- 3, arrowy
- 3, (arrowheight
/ 2) + 8, (arrowheight
+ 6));
958 dc
.SetBrush(wxBrush(*wxBLACK
, wxSOLID
));
959 dc
.SetPen(wxPen(*wxBLACK
, 1, wxSOLID
));
960 dc
.DrawPolygon(3, leftarrow
, larrowx
, arrowy
, wxWINDING_RULE
);
961 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
962 dc
.DrawRectangle(m_leftArrowRect
);
964 wxDateTime fdnm
= wxDateTime(1,m_date
.GetMonth(), m_date
.GetYear()) + wxDateSpan::Month(); // first day next month
965 if ( IsDateInRange(fdnm
) && ( ( fdnm
.GetYear() == m_date
.GetYear() ) ? TRUE
: AllowYearChange() ) )
967 m_rightArrowRect
= wxRect(rarrowx
- 4, arrowy
- 3, (arrowheight
/ 2) + 8, (arrowheight
+ 6));
968 dc
.SetBrush(wxBrush(*wxBLACK
, wxSOLID
));
969 dc
.SetPen(wxPen(*wxBLACK
, 1, wxSOLID
));
970 dc
.DrawPolygon(3, rightarrow
, rarrowx
, arrowy
, wxWINDING_RULE
);
971 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
972 dc
.DrawRectangle(m_rightArrowRect
);
979 // first draw the week days
980 if ( IsExposed(0, y
, 7*m_widthCol
, m_heightRow
) )
983 wxLogDebug("painting the header");
986 dc
.SetBackgroundMode(wxTRANSPARENT
);
987 dc
.SetTextForeground(m_colHeaderFg
);
988 dc
.SetBrush(wxBrush(m_colHeaderBg
, wxSOLID
));
989 dc
.SetPen(wxPen(m_colHeaderBg
, 1, wxSOLID
));
990 dc
.DrawRectangle(0, y
, GetClientSize().x
, m_heightRow
);
992 bool startOnMonday
= (GetWindowStyle() & wxCAL_MONDAY_FIRST
) != 0;
993 for ( size_t wd
= 0; wd
< 7; wd
++ )
997 n
= wd
== 6 ? 0 : wd
+ 1;
1001 dc
.GetTextExtent(m_weekdays
[n
], &dayw
, &dayh
);
1002 dc
.DrawText(m_weekdays
[n
], (wd
*m_widthCol
) + ((m_widthCol
- dayw
) / 2), y
); // center the day-name
1006 // then the calendar itself
1007 dc
.SetTextForeground(*wxBLACK
);
1008 //dc.SetFont(*wxNORMAL_FONT);
1011 wxDateTime date
= GetStartDate();
1014 wxLogDebug("starting calendar from %s\n",
1015 date
.Format("%a %d-%m-%Y %H:%M:%S").c_str());
1018 dc
.SetBackgroundMode(wxSOLID
);
1019 for ( size_t nWeek
= 1; nWeek
<= 6; nWeek
++, y
+= m_heightRow
)
1021 // if the update region doesn't intersect this row, don't paint it
1022 if ( !IsExposed(0, y
, 7*m_widthCol
, m_heightRow
- 1) )
1024 date
+= wxDateSpan::Week();
1030 wxLogDebug("painting week %d at y = %d\n", nWeek
, y
);
1033 for ( size_t wd
= 0; wd
< 7; wd
++ )
1035 if ( IsDateShown(date
) )
1037 // don't use wxDate::Format() which prepends 0s
1038 unsigned int day
= date
.GetDay();
1039 wxString dayStr
= wxString::Format(_T("%u"), day
);
1041 dc
.GetTextExtent(dayStr
, &width
, (wxCoord
*)NULL
);
1043 bool changedColours
= FALSE
,
1044 changedFont
= FALSE
;
1047 wxCalendarDateAttr
*attr
= NULL
;
1049 if ( date
.GetMonth() != m_date
.GetMonth() || !IsDateInRange(date
) )
1051 // surrounding week or out-of-range
1053 dc
.SetTextForeground(*wxLIGHT_GREY
);
1054 changedColours
= TRUE
;
1058 isSel
= date
.IsSameDate(m_date
);
1059 attr
= m_attrs
[day
- 1];
1063 dc
.SetTextForeground(m_colHighlightFg
);
1064 dc
.SetTextBackground(m_colHighlightBg
);
1066 changedColours
= TRUE
;
1070 wxColour colFg
, colBg
;
1072 if ( attr
->IsHoliday() )
1074 colFg
= m_colHolidayFg
;
1075 colBg
= m_colHolidayBg
;
1079 colFg
= attr
->GetTextColour();
1080 colBg
= attr
->GetBackgroundColour();
1085 dc
.SetTextForeground(colFg
);
1086 changedColours
= TRUE
;
1091 dc
.SetTextBackground(colBg
);
1092 changedColours
= TRUE
;
1095 if ( attr
->HasFont() )
1097 dc
.SetFont(attr
->GetFont());
1103 wxCoord x
= wd
*m_widthCol
+ (m_widthCol
- width
) / 2;
1104 dc
.DrawText(dayStr
, x
, y
+ 1);
1106 if ( !isSel
&& attr
&& attr
->HasBorder() )
1109 if ( attr
->HasBorderColour() )
1111 colBorder
= attr
->GetBorderColour();
1115 colBorder
= m_foregroundColour
;
1118 wxPen
pen(colBorder
, 1, wxSOLID
);
1120 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1122 switch ( attr
->GetBorder() )
1124 case wxCAL_BORDER_SQUARE
:
1125 dc
.DrawRectangle(x
- 2, y
,
1126 width
+ 4, m_heightRow
);
1129 case wxCAL_BORDER_ROUND
:
1130 dc
.DrawEllipse(x
- 2, y
,
1131 width
+ 4, m_heightRow
);
1135 wxFAIL_MSG(_T("unknown border type"));
1139 if ( changedColours
)
1141 dc
.SetTextForeground(m_foregroundColour
);
1142 dc
.SetTextBackground(m_backgroundColour
);
1150 //else: just don't draw it
1152 date
+= wxDateSpan::Day();
1156 // Greying out out-of-range background
1157 bool showSurrounding
= (GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS
) != 0;
1159 date
= ( showSurrounding
) ? GetStartDate() : wxDateTime(1, m_date
.GetMonth(), m_date
.GetYear());
1160 if ( !IsDateInRange(date
) )
1162 wxDateTime firstOOR
= GetLowerDateLimit() - wxDateSpan::Day(); // first out-of-range
1164 wxBrush oorbrush
= *wxLIGHT_GREY_BRUSH
;
1165 oorbrush
.SetStyle(wxFDIAGONAL_HATCH
);
1167 HighlightRange(&dc
, date
, firstOOR
, wxTRANSPARENT_PEN
, &oorbrush
);
1170 date
= ( showSurrounding
) ? GetStartDate() + wxDateSpan::Weeks(6) - wxDateSpan::Day() : wxDateTime().SetToLastMonthDay(m_date
.GetMonth(), m_date
.GetYear());
1171 if ( !IsDateInRange(date
) )
1173 wxDateTime firstOOR
= GetUpperDateLimit() + wxDateSpan::Day(); // first out-of-range
1175 wxBrush oorbrush
= *wxLIGHT_GREY_BRUSH
;
1176 oorbrush
.SetStyle(wxFDIAGONAL_HATCH
);
1178 HighlightRange(&dc
, firstOOR
, date
, wxTRANSPARENT_PEN
, &oorbrush
);
1182 wxLogDebug("+++ finished painting");
1186 void wxCalendarCtrl::RefreshDate(const wxDateTime
& date
)
1192 // always refresh the whole row at once because our OnPaint() will draw
1193 // the whole row anyhow - and this allows the small optimisation in
1194 // OnClick() below to work
1197 rect
.y
= (m_heightRow
* GetWeek(date
)) + m_rowOffset
;
1199 rect
.width
= 7*m_widthCol
;
1200 rect
.height
= m_heightRow
;
1203 // VZ: for some reason, the selected date seems to occupy more space under
1204 // MSW - this is probably some bug in the font size calculations, but I
1205 // don't know where exactly. This fix is ugly and leads to more
1206 // refreshes than really needed, but without it the selected days
1207 // leaves even more ugly underscores on screen.
1212 wxLogDebug("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
1215 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1218 Refresh(TRUE
, &rect
);
1221 void wxCalendarCtrl::HighlightRange(wxPaintDC
* pDC
, const wxDateTime
& fromdate
, const wxDateTime
& todate
, wxPen
* pPen
, wxBrush
* pBrush
)
1223 // Highlights the given range using pen and brush
1224 // Does nothing if todate < fromdate
1228 wxLogDebug("+++ HighlightRange: (%s) - (%s) +++", fromdate
.Format("%d %m %Y"), todate
.Format("%d %m %Y"));
1231 if ( todate
>= fromdate
)
1238 // implicit: both dates must be currently shown - checked by GetDateCoord
1239 if ( GetDateCoord(fromdate
, &fd
, &fw
) && GetDateCoord(todate
, &td
, &tw
) )
1242 wxLogDebug("Highlight range: (%i, %i) - (%i, %i)", fd
, fw
, td
, tw
);
1244 if ( ( (tw
- fw
) == 1 ) && ( td
< fd
) )
1246 // special case: interval 7 days or less not in same week
1247 // split in two seperate intervals
1248 wxDateTime tfd
= fromdate
+ wxDateSpan::Days(7-fd
);
1249 wxDateTime ftd
= tfd
+ wxDateSpan::Day();
1251 wxLogDebug("Highlight: Seperate segments");
1254 HighlightRange(pDC
, fromdate
, tfd
, pPen
, pBrush
);
1255 HighlightRange(pDC
, ftd
, todate
, pPen
, pBrush
);
1260 wxPoint corners
[8]; // potentially 8 corners in polygon
1264 // simple case: same week
1266 corners
[0] = wxPoint((fd
- 1) * m_widthCol
, (fw
* m_heightRow
) + m_rowOffset
);
1267 corners
[1] = wxPoint((fd
- 1) * m_widthCol
, ((fw
+ 1 ) * m_heightRow
) + m_rowOffset
);
1268 corners
[2] = wxPoint(td
* m_widthCol
, ((tw
+ 1) * m_heightRow
) + m_rowOffset
);
1269 corners
[3] = wxPoint(td
* m_widthCol
, (tw
* m_heightRow
) + m_rowOffset
);
1274 // "complex" polygon
1275 corners
[cidx
] = wxPoint((fd
- 1) * m_widthCol
, (fw
* m_heightRow
) + m_rowOffset
); cidx
++;
1279 corners
[cidx
] = wxPoint((fd
- 1) * m_widthCol
, ((fw
+ 1) * m_heightRow
) + m_rowOffset
); cidx
++;
1280 corners
[cidx
] = wxPoint(0, ((fw
+ 1) * m_heightRow
) + m_rowOffset
); cidx
++;
1283 corners
[cidx
] = wxPoint(0, ((tw
+ 1) * m_heightRow
) + m_rowOffset
); cidx
++;
1284 corners
[cidx
] = wxPoint(td
* m_widthCol
, ((tw
+ 1) * m_heightRow
) + m_rowOffset
); cidx
++;
1288 corners
[cidx
] = wxPoint(td
* m_widthCol
, (tw
* m_heightRow
) + m_rowOffset
); cidx
++;
1289 corners
[cidx
] = wxPoint(7 * m_widthCol
, (tw
* m_heightRow
) + m_rowOffset
); cidx
++;
1292 corners
[cidx
] = wxPoint(7 * m_widthCol
, (fw
* m_heightRow
) + m_rowOffset
); cidx
++;
1298 pDC
->SetBrush(*pBrush
);
1300 pDC
->DrawPolygon(numpoints
, corners
);
1306 wxLogDebug("--- HighlightRange ---");
1310 bool wxCalendarCtrl::GetDateCoord(const wxDateTime
& date
, int *day
, int *week
) const
1315 wxLogDebug("+++ GetDateCoord: (%s) +++", date
.Format("%d %m %Y"));
1318 if ( IsDateShown(date
) )
1320 bool startOnMonday
= ( GetWindowStyle() & wxCAL_MONDAY_FIRST
) != 0;
1323 *day
= date
.GetWeekDay();
1325 if ( *day
== 0 ) // sunday
1327 *day
= ( startOnMonday
) ? 7 : 1;
1331 day
+= ( startOnMonday
) ? 0 : 1;
1334 int targetmonth
= date
.GetMonth() + (12 * date
.GetYear());
1335 int thismonth
= m_date
.GetMonth() + (12 * m_date
.GetYear());
1338 if ( targetmonth
== thismonth
)
1340 *week
= GetWeek(date
);
1344 if ( targetmonth
< thismonth
)
1346 *week
= 1; // trivial
1348 else // targetmonth > thismonth
1354 // get the datecoord of the last day in the month currently shown
1356 wxLogDebug(" +++ LDOM +++");
1358 GetDateCoord(ldcm
.SetToLastMonthDay(m_date
.GetMonth(), m_date
.GetYear()), &lastday
, &lastweek
);
1360 wxLogDebug(" --- LDOM ---");
1363 wxTimeSpan span
= date
- ldcm
;
1365 int daysfromlast
= span
.GetDays();
1367 wxLogDebug("daysfromlast: %i", daysfromlast
);
1369 if ( daysfromlast
+ lastday
> 7 ) // past week boundary
1371 int wholeweeks
= (daysfromlast
/ 7);
1372 *week
= wholeweeks
+ lastweek
;
1373 if ( (daysfromlast
- (7 * wholeweeks
) + lastday
) > 7 )
1393 wxLogDebug("--- GetDateCoord: (%s) = (%i, %i) ---", date
.Format("%d %m %Y"), *day
, *week
);
1399 // ----------------------------------------------------------------------------
1401 // ----------------------------------------------------------------------------
1403 void wxCalendarCtrl::OnDClick(wxMouseEvent
& event
)
1405 if ( HitTest(event
.GetPosition()) != wxCAL_HITTEST_DAY
)
1411 GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED
);
1415 void wxCalendarCtrl::OnClick(wxMouseEvent
& event
)
1418 wxDateTime::WeekDay wday
;
1419 switch ( HitTest(event
.GetPosition(), &date
, &wday
) )
1421 case wxCAL_HITTEST_DAY
:
1422 if ( IsDateInRange(date
) )
1426 GenerateEvents(wxEVT_CALENDAR_DAY_CHANGED
,
1427 wxEVT_CALENDAR_SEL_CHANGED
);
1431 case wxCAL_HITTEST_HEADER
:
1433 wxCalendarEvent
event(this, wxEVT_CALENDAR_WEEKDAY_CLICKED
);
1434 event
.m_wday
= wday
;
1435 (void)GetEventHandler()->ProcessEvent(event
);
1439 case wxCAL_HITTEST_DECMONTH
:
1440 case wxCAL_HITTEST_INCMONTH
:
1441 case wxCAL_HITTEST_SURROUNDING_WEEK
:
1442 SetDateAndNotify(date
); // we probably only want to refresh the control. No notification.. (maybe as an option?)
1446 wxFAIL_MSG(_T("unknown hittest code"));
1449 case wxCAL_HITTEST_NOWHERE
:
1455 wxCalendarHitTestResult
wxCalendarCtrl::HitTest(const wxPoint
& pos
,
1457 wxDateTime::WeekDay
*wd
)
1463 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1464 if ( (GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION
) )
1468 // we need to find out if the hit is on left arrow, on month or on right arrow
1470 if ( wxRegion(m_leftArrowRect
).Contains(pos
) == wxInRegion
)
1474 if ( IsDateInRange(m_date
- wxDateSpan::Month()) )
1476 *date
= m_date
- wxDateSpan::Month();
1480 *date
= GetLowerDateLimit();
1484 return wxCAL_HITTEST_DECMONTH
;
1487 if ( wxRegion(m_rightArrowRect
).Contains(pos
) == wxInRegion
)
1491 if ( IsDateInRange(m_date
+ wxDateSpan::Month()) )
1493 *date
= m_date
+ wxDateSpan::Month();
1497 *date
= GetUpperDateLimit();
1501 return wxCAL_HITTEST_INCMONTH
;
1506 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1508 int wday
= pos
.x
/ m_widthCol
;
1509 // if ( y < m_heightRow )
1510 if ( y
< (m_heightRow
+ m_rowOffset
) )
1512 if ( y
> m_rowOffset
)
1516 if ( GetWindowStyle() & wxCAL_MONDAY_FIRST
)
1518 wday
= wday
== 6 ? 0 : wday
+ 1;
1521 *wd
= (wxDateTime::WeekDay
)wday
;
1524 return wxCAL_HITTEST_HEADER
;
1528 return wxCAL_HITTEST_NOWHERE
;
1532 // int week = (y - m_heightRow) / m_heightRow;
1533 int week
= (y
- (m_heightRow
+ m_rowOffset
)) / m_heightRow
;
1534 if ( week
>= 6 || wday
>= 7 )
1536 return wxCAL_HITTEST_NOWHERE
;
1539 wxDateTime dt
= GetStartDate() + wxDateSpan::Days(7*week
+ wday
);
1541 if ( IsDateShown(dt
) )
1546 if ( dt
.GetMonth() == m_date
.GetMonth() )
1549 return wxCAL_HITTEST_DAY
;
1553 return wxCAL_HITTEST_SURROUNDING_WEEK
;
1558 return wxCAL_HITTEST_NOWHERE
;
1562 // ----------------------------------------------------------------------------
1563 // subcontrols events handling
1564 // ----------------------------------------------------------------------------
1566 void wxCalendarCtrl::OnMonthChange(wxCommandEvent
& event
)
1568 wxDateTime::Tm tm
= m_date
.GetTm();
1570 wxDateTime::Month mon
= (wxDateTime::Month
)event
.GetInt();
1571 if ( tm
.mday
> wxDateTime::GetNumberOfDays(mon
, tm
.year
) )
1573 tm
.mday
= wxDateTime::GetNumberOfDays(mon
, tm
.year
);
1576 wxDateTime target
= wxDateTime(tm
.mday
, mon
, tm
.year
);
1578 ChangeMonth(&target
);
1579 SetDateAndNotify(target
);
1582 void wxCalendarCtrl::OnYearChange(wxCommandEvent
& event
)
1584 int year
= (int)event
.GetInt();
1585 if ( year
== INT_MIN
)
1587 // invalid year in the spin control, ignore it
1591 wxDateTime::Tm tm
= m_date
.GetTm();
1593 if ( tm
.mday
> wxDateTime::GetNumberOfDays(tm
.mon
, year
) )
1595 tm
.mday
= wxDateTime::GetNumberOfDays(tm
.mon
, year
);
1598 wxDateTime target
= wxDateTime(tm
.mday
, tm
.mon
, year
);
1600 if ( ChangeYear(&target
) )
1602 SetDateAndNotify(target
);
1606 // In this case we don't want to change the date. That would put us
1607 // inside the same year but a strange number of months forward/back..
1608 m_spinYear
->SetValue(target
.GetYear());
1612 // ----------------------------------------------------------------------------
1613 // keyboard interface
1614 // ----------------------------------------------------------------------------
1616 void wxCalendarCtrl::OnChar(wxKeyEvent
& event
)
1619 switch ( event
.GetKeyCode() )
1623 target
= m_date
+ wxDateSpan::Year();
1624 if ( ChangeYear(&target
) )
1626 SetDateAndNotify(target
);
1632 target
= m_date
- wxDateSpan::Year();
1633 if ( ChangeYear(&target
) )
1635 SetDateAndNotify(target
);
1640 target
= m_date
- wxDateSpan::Month();
1641 ChangeMonth(&target
);
1642 SetDateAndNotify(target
); // always
1646 target
= m_date
+ wxDateSpan::Month();
1647 ChangeMonth(&target
);
1648 SetDateAndNotify(target
); // always
1652 if ( event
.ControlDown() )
1654 target
= wxDateTime(m_date
).SetToNextWeekDay(
1655 GetWindowStyle() & wxCAL_MONDAY_FIRST
1656 ? wxDateTime::Sun
: wxDateTime::Sat
);
1657 if ( !IsDateInRange(target
) )
1659 target
= GetUpperDateLimit();
1661 SetDateAndNotify(target
);
1664 SetDateAndNotify(m_date
+ wxDateSpan::Day());
1668 if ( event
.ControlDown() )
1670 target
= wxDateTime(m_date
).SetToPrevWeekDay(
1671 GetWindowStyle() & wxCAL_MONDAY_FIRST
1672 ? wxDateTime::Mon
: wxDateTime::Sun
);
1673 if ( !IsDateInRange(target
) )
1675 target
= GetLowerDateLimit();
1677 SetDateAndNotify(target
);
1680 SetDateAndNotify(m_date
- wxDateSpan::Day());
1684 SetDateAndNotify(m_date
- wxDateSpan::Week());
1688 SetDateAndNotify(m_date
+ wxDateSpan::Week());
1692 if ( event
.ControlDown() )
1693 SetDateAndNotify(wxDateTime::Today());
1695 SetDateAndNotify(wxDateTime(1, m_date
.GetMonth(), m_date
.GetYear()));
1699 SetDateAndNotify(wxDateTime(m_date
).SetToLastMonthDay());
1703 GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED
);
1711 // ----------------------------------------------------------------------------
1712 // holidays handling
1713 // ----------------------------------------------------------------------------
1715 void wxCalendarCtrl::EnableHolidayDisplay(bool display
)
1717 long style
= GetWindowStyle();
1719 style
|= wxCAL_SHOW_HOLIDAYS
;
1721 style
&= ~wxCAL_SHOW_HOLIDAYS
;
1723 SetWindowStyle(style
);
1728 ResetHolidayAttrs();
1733 void wxCalendarCtrl::SetHolidayAttrs()
1735 if ( GetWindowStyle() & wxCAL_SHOW_HOLIDAYS
)
1737 ResetHolidayAttrs();
1739 wxDateTime::Tm tm
= m_date
.GetTm();
1740 wxDateTime
dtStart(1, tm
.mon
, tm
.year
),
1741 dtEnd
= dtStart
.GetLastMonthDay();
1743 wxDateTimeArray hol
;
1744 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart
, dtEnd
, hol
);
1746 size_t count
= hol
.GetCount();
1747 for ( size_t n
= 0; n
< count
; n
++ )
1749 SetHoliday(hol
[n
].GetDay());
1754 void wxCalendarCtrl::SetHoliday(size_t day
)
1756 wxCHECK_RET( day
> 0 && day
< 32, _T("invalid day in SetHoliday") );
1758 wxCalendarDateAttr
*attr
= GetAttr(day
);
1761 attr
= new wxCalendarDateAttr
;
1764 attr
->SetHoliday(TRUE
);
1766 // can't use SetAttr() because it would delete this pointer
1767 m_attrs
[day
- 1] = attr
;
1770 void wxCalendarCtrl::ResetHolidayAttrs()
1772 for ( size_t day
= 0; day
< 31; day
++ )
1776 m_attrs
[day
]->SetHoliday(FALSE
);
1781 // ----------------------------------------------------------------------------
1783 // ----------------------------------------------------------------------------
1785 void wxCalendarEvent::Init()
1787 m_wday
= wxDateTime::Inv_WeekDay
;
1790 wxCalendarEvent::wxCalendarEvent(wxCalendarCtrl
*cal
, wxEventType type
)
1791 : wxCommandEvent(type
, cal
->GetId())
1793 m_date
= cal
->GetDate();
1794 SetEventObject(cal
);
1797 #endif // wxUSE_CALENDARCTRL