From 6d9b6716925a786d2455033ccb8775569001b631 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 5 Aug 2008 01:55:44 +0000 Subject: [PATCH] mark holidays if wxCAL_SHOW_HOLIDAYS is on (replaces #9155) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54971 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/calctrl.h | 24 +++++++++++++++---- include/wx/generic/calctrlg.h | 12 +++------- include/wx/msw/calctrl.h | 12 +++++++++- samples/calendar/calendar.cpp | 2 +- src/common/calctrlcmn.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++- src/generic/calctrlg.cpp | 39 ------------------------------- src/msw/calctrl.cpp | 29 +++++++++++++++++++---- 7 files changed, 113 insertions(+), 59 deletions(-) diff --git a/include/wx/calctrl.h b/include/wx/calctrl.h index 4d800cd..344768b 100644 --- a/include/wx/calctrl.h +++ b/include/wx/calctrl.h @@ -259,12 +259,13 @@ public: // holidays support // - // currently all functions in this section are implemented in the generic - // version of the control only and are simply ignored by native ones + // currently only the generic version implements all functions in this + // section; wxMSW implements simple support for holidays (they can be + // just enabled or disabled) and wxGTK doesn't support them at all // equivalent to changing wxCAL_SHOW_HOLIDAYS flag but should be called // instead of just changing it - virtual void EnableHolidayDisplay(bool WXUNUSED(display) = true) { } + virtual void EnableHolidayDisplay(bool display = true); // set/get the colours to use for holidays (if they're enabled) virtual void SetHolidayColours(const wxColour& WXUNUSED(colFg), @@ -313,7 +314,22 @@ protected: // generate all the events for the selection change from dateOld to current // date: SEL_CHANGED, PAGE_CHANGED if necessary and also one of (deprecated) // YEAR/MONTH/DAY_CHANGED ones - void GenerateAllChangeEvents(const wxDateTime& dateOld); + // + // returns true if page changed event was generated, false if the new date + // is still in the same month as before + bool GenerateAllChangeEvents(const wxDateTime& dateOld); + + // call SetHoliday() for all holidays in the current month + // + // should be called on month change, does nothing if wxCAL_SHOW_HOLIDAYS is + // not set and returns false in this case, true if we do show them + bool SetHolidayAttrs(); + + // called by SetHolidayAttrs() to forget the previously set holidays + virtual void ResetHolidayAttrs() { } + + // called by EnableHolidayDisplay() + virtual void RefreshHolidays() { } }; // ---------------------------------------------------------------------------- diff --git a/include/wx/generic/calctrlg.h b/include/wx/generic/calctrlg.h index 9d9d296..7cdc50d 100644 --- a/include/wx/generic/calctrlg.h +++ b/include/wx/generic/calctrlg.h @@ -84,9 +84,6 @@ public: // corresponds to wxCAL_NO_YEAR_CHANGE bit, deprecated, generic only void EnableYearChange(bool enable = true); - // corresponds to wxCAL_SHOW_HOLIDAYS bit, generic only - virtual void EnableHolidayDisplay(bool display = true); - // customization // ------------- @@ -215,12 +212,6 @@ private: // change the date inside the same month/year void ChangeDay(const wxDateTime& date); - // set the attributes for the holidays if needed - void SetHolidayAttrs(); - - // reset all holidays - void ResetHolidayAttrs(); - // deprecated bool AllowYearChange() const { @@ -240,6 +231,9 @@ public: wxControl *GetYearControl() const; private: + virtual void ResetHolidayAttrs(); + virtual void RefreshHolidays() { Refresh(); } + // OnPaint helper-methods // Highlight the [fromdate : todate] range using pen and brush diff --git a/include/wx/msw/calctrl.h b/include/wx/msw/calctrl.h index 1b56830..d27875c 100644 --- a/include/wx/msw/calctrl.h +++ b/include/wx/msw/calctrl.h @@ -45,6 +45,7 @@ public: virtual bool EnableMonthChange(bool enable = true); virtual void Mark(size_t day, bool mark); + virtual void SetHoliday(size_t day); virtual wxCalendarHitTestResult HitTest(const wxPoint& pos, wxDateTime *date = NULL, @@ -63,7 +64,7 @@ protected: void MSWOnDoubleClick(wxMouseEvent& event); private: - void Init() { m_marks = 0; } + void Init(); // bring the control in sync with m_marks void UpdateMarks(); @@ -72,6 +73,12 @@ private: // wxCAL_MONDAY_FIRST flag void UpdateFirstDayOfWeek(); + // reset holiday information + virtual void ResetHolidayAttrs() { m_holidays = 0; } + + // redisplay holidays + virtual void RefreshHolidays() { UpdateMarks(); } + // current date, we need to store it instead of simply retrieving it from // the control as needed in order to be able to generate the correct events @@ -81,6 +88,9 @@ private: // bit field containing the state (marked or not) of all days in the month wxUint32 m_marks; + // the same but indicating whether a day is a holiday or not + wxUint32 m_holidays; + DECLARE_DYNAMIC_CLASS(wxCalendarCtrl) DECLARE_NO_COPY_CLASS(wxCalendarCtrl) diff --git a/samples/calendar/calendar.cpp b/samples/calendar/calendar.cpp index f81a703..ffa07b2 100644 --- a/samples/calendar/calendar.cpp +++ b/samples/calendar/calendar.cpp @@ -274,8 +274,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_UPDATE_UI(Calendar_Cal_SeqMonth, MyFrame::OnUpdateUIGenericOnly) #ifdef __WXGTK20__ EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly) -#endif EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly) +#endif EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly) EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly) END_EVENT_TABLE() diff --git a/src/common/calctrlcmn.cpp b/src/common/calctrlcmn.cpp index 896ac3b..dc0c442 100644 --- a/src/common/calctrlcmn.cpp +++ b/src/common/calctrlcmn.cpp @@ -60,15 +60,21 @@ bool wxCalendarCtrlBase::EnableMonthChange(bool enable) return true; } -void wxCalendarCtrlBase::GenerateAllChangeEvents(const wxDateTime& dateOld) +bool wxCalendarCtrlBase::GenerateAllChangeEvents(const wxDateTime& dateOld) { const wxDateTime::Tm tm1 = dateOld.GetTm(), tm2 = GetDate().GetTm(); + bool pageChanged = false; + GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED); if ( tm1.year != tm2.year || tm1.mon != tm2.mon ) + { GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED); + pageChanged = true; + } + // send also one of the deprecated events if ( tm1.year != tm2.year ) GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED); @@ -76,6 +82,52 @@ void wxCalendarCtrlBase::GenerateAllChangeEvents(const wxDateTime& dateOld) GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED); else GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED); + + return pageChanged; +} + +void wxCalendarCtrlBase::EnableHolidayDisplay(bool display) +{ + long style = GetWindowStyle(); + if ( display ) + style |= wxCAL_SHOW_HOLIDAYS; + else + style &= ~wxCAL_SHOW_HOLIDAYS; + + if ( style == GetWindowStyle() ) + return; + + SetWindowStyle(style); + + if ( display ) + SetHolidayAttrs(); + else + ResetHolidayAttrs(); + + RefreshHolidays(); +} + +bool wxCalendarCtrlBase::SetHolidayAttrs() +{ + if ( !HasFlag(wxCAL_SHOW_HOLIDAYS) ) + return false; + + ResetHolidayAttrs(); + + wxDateTime::Tm tm = GetDate().GetTm(); + wxDateTime dtStart(1, tm.mon, tm.year), + dtEnd = dtStart.GetLastMonthDay(); + + wxDateTimeArray hol; + wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol); + + const size_t count = hol.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + SetHoliday(hol[n].GetDay()); + } + + return true; } #endif // wxUSE_CALENDARCTRL diff --git a/src/generic/calctrlg.cpp b/src/generic/calctrlg.cpp index 2370792..d593094 100644 --- a/src/generic/calctrlg.cpp +++ b/src/generic/calctrlg.cpp @@ -1760,45 +1760,6 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) // holidays handling // ---------------------------------------------------------------------------- -void wxGenericCalendarCtrl::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 wxGenericCalendarCtrl::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 wxGenericCalendarCtrl::SetHoliday(size_t day) { wxCHECK_RET( day > 0 && day < 32, _T("invalid day in SetHoliday") ); diff --git a/src/msw/calctrl.cpp b/src/msw/calctrl.cpp index cf1179b..3b96095 100644 --- a/src/msw/calctrl.cpp +++ b/src/msw/calctrl.cpp @@ -44,6 +44,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl) // wxCalendarCtrl creation // ---------------------------------------------------------------------------- +void wxCalendarCtrl::Init() +{ + m_marks = + m_holidays = 0; +} + bool wxCalendarCtrl::Create(wxWindow *parent, wxWindowID id, @@ -95,7 +101,8 @@ wxCalendarCtrl::Create(wxWindow *parent, SetDate(dt.IsValid() ? dt : wxDateTime::Today()); - UpdateMarks(); + if ( SetHolidayAttrs() ) + UpdateMarks(); Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxCalendarCtrl::MSWOnClick)); @@ -327,6 +334,13 @@ void wxCalendarCtrl::Mark(size_t day, bool mark) UpdateMarks(); } +void wxCalendarCtrl::SetHoliday(size_t day) +{ + wxCHECK_RET( day > 0 && day < 32, "invalid day" ); + + m_holidays |= 1 << (day - 1); +} + void wxCalendarCtrl::UpdateMarks() { // we show only one full month but there can be some days from the month @@ -342,7 +356,8 @@ void wxCalendarCtrl::UpdateMarks() // shows it on 6 lines and the number of visible months is still 3 wxCHECK_RET( nMonths == (int)WXSIZEOF(states), "unexpected months range" ); - states[1] = m_marks; // the fully visible month is the one in the middle + // the fully visible month is the one in the middle + states[1] = m_marks | m_holidays; if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) ) { @@ -377,7 +392,13 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // change anything -- filter it out if ( m_date != dateOld ) { - GenerateAllChangeEvents(dateOld); + if ( GenerateAllChangeEvents(dateOld) ) + { + // month changed, need to update the holidays if we use + // them + if ( SetHolidayAttrs() ) + UpdateMarks(); + } } } break; @@ -387,7 +408,7 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam; for ( int i = 0; i < ds->cDayState; i++ ) { - ds->prgDayState[i] = m_marks; + ds->prgDayState[i] = m_marks | m_holidays; } } break; -- 2.7.4