mark holidays if wxCAL_SHOW_HOLIDAYS is on (replaces #9155)
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 5 Aug 2008 01:55:44 +0000 (01:55 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 5 Aug 2008 01:55:44 +0000 (01:55 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54971 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/calctrl.h
include/wx/generic/calctrlg.h
include/wx/msw/calctrl.h
samples/calendar/calendar.cpp
src/common/calctrlcmn.cpp
src/generic/calctrlg.cpp
src/msw/calctrl.cpp

index 4d800cd3a557fea69c736dd4ad51e852f40233d7..344768b838d889b09d085c9240f20bba1ce31181 100644 (file)
@@ -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() { }
 };
 
 // ----------------------------------------------------------------------------
index 9d9d296c92c00532f8659956a492539fd584e52c..7cdc50d2b406be9d1e7178ffef6ee1c55f34c463 100644 (file)
@@ -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
index 1b56830df805d3940ed6484f16dfc29b532d72da..d27875cf06b280d57ef4a9178bc48df9fd253267 100644 (file)
@@ -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)
index f81a70385b546dd0accfb4ce6ec981a36786fd70..ffa07b257c12f86cbae90f072082a8a248afae79 100644 (file)
@@ -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()
index 896ac3ba37087953398afd3a3cac5f74db320e4e..dc0c442680c2804e4b5ca8a34b2c68b8950bee1d 100644 (file)
@@ -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
index 2370792bd6742f0667ef8b15b1ae943a808440d2..d59309415be57bb5204dbcd0dc2c59168b8a11a4 100644 (file)
@@ -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") );
index cf1179b8aaef6338327e75a88b196dd70b733549..3b96095ac95ca874bfdf8893daaafd75d939dc0e 100644 (file)
@@ -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;