// 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),
// 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() { }
};
// ----------------------------------------------------------------------------
// 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
// -------------
// 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
{
wxControl *GetYearControl() const;
private:
+ virtual void ResetHolidayAttrs();
+ virtual void RefreshHolidays() { Refresh(); }
+
// OnPaint helper-methods
// Highlight the [fromdate : todate] range using pen and brush
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,
void MSWOnDoubleClick(wxMouseEvent& event);
private:
- void Init() { m_marks = 0; }
+ void Init();
// bring the control in sync with m_marks
void UpdateMarks();
// 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
// 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)
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()
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);
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
// 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") );
// wxCalendarCtrl creation
// ----------------------------------------------------------------------------
+void wxCalendarCtrl::Init()
+{
+ m_marks =
+ m_holidays = 0;
+}
+
bool
wxCalendarCtrl::Create(wxWindow *parent,
wxWindowID id,
SetDate(dt.IsValid() ? dt : wxDateTime::Today());
- UpdateMarks();
+ if ( SetHolidayAttrs() )
+ UpdateMarks();
Connect(wxEVT_LEFT_DOWN,
wxMouseEventHandler(wxCalendarCtrl::MSWOnClick));
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
// 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) )
{
// 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;
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;