X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a4fcd589a85e735e6c17f1470e739d9fcc946e9e..07aaf32633ecf18ec3edfbb41793a112914792d0:/src/generic/calctrlg.cpp diff --git a/src/generic/calctrlg.cpp b/src/generic/calctrlg.cpp index c52a74808a..f8a14221c6 100644 --- a/src/generic/calctrlg.cpp +++ b/src/generic/calctrlg.cpp @@ -47,6 +47,12 @@ // wxWin macros // ---------------------------------------------------------------------------- +#ifdef wxHAS_NATIVE_CALENDARCTRL + +wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h") + +#endif + BEGIN_EVENT_TABLE(wxGenericCalendarCtrl, wxControl) EVT_PAINT(wxGenericCalendarCtrl::OnPaint) @@ -58,64 +64,6 @@ BEGIN_EVENT_TABLE(wxGenericCalendarCtrl, wxControl) EVT_SYS_COLOUR_CHANGED(wxGenericCalendarCtrl::OnSysColourChanged) END_EVENT_TABLE() -#if wxUSE_EXTENDED_RTTI -WX_DEFINE_FLAGS( wxCalendarCtrlStyle ) - -wxBEGIN_FLAGS( wxCalendarCtrlStyle ) - // new style border flags, we put them first to - // use them for streaming out - wxFLAGS_MEMBER(wxBORDER_SIMPLE) - wxFLAGS_MEMBER(wxBORDER_SUNKEN) - wxFLAGS_MEMBER(wxBORDER_DOUBLE) - wxFLAGS_MEMBER(wxBORDER_RAISED) - wxFLAGS_MEMBER(wxBORDER_STATIC) - wxFLAGS_MEMBER(wxBORDER_NONE) - - // old style border flags - wxFLAGS_MEMBER(wxSIMPLE_BORDER) - wxFLAGS_MEMBER(wxSUNKEN_BORDER) - wxFLAGS_MEMBER(wxDOUBLE_BORDER) - wxFLAGS_MEMBER(wxRAISED_BORDER) - wxFLAGS_MEMBER(wxSTATIC_BORDER) - wxFLAGS_MEMBER(wxBORDER) - - // standard window styles - wxFLAGS_MEMBER(wxTAB_TRAVERSAL) - wxFLAGS_MEMBER(wxCLIP_CHILDREN) - wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW) - wxFLAGS_MEMBER(wxWANTS_CHARS) - wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE) - wxFLAGS_MEMBER(wxALWAYS_SHOW_SB ) - wxFLAGS_MEMBER(wxVSCROLL) - wxFLAGS_MEMBER(wxHSCROLL) - - wxFLAGS_MEMBER(wxCAL_SUNDAY_FIRST) - wxFLAGS_MEMBER(wxCAL_MONDAY_FIRST) - wxFLAGS_MEMBER(wxCAL_SHOW_HOLIDAYS) - wxFLAGS_MEMBER(wxCAL_NO_YEAR_CHANGE) - wxFLAGS_MEMBER(wxCAL_NO_MONTH_CHANGE) - wxFLAGS_MEMBER(wxCAL_SEQUENTIAL_MONTH_SELECTION) - wxFLAGS_MEMBER(wxCAL_SHOW_SURROUNDING_WEEKS) - -wxEND_FLAGS( wxCalendarCtrlStyle ) - -IMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h") - -wxBEGIN_PROPERTIES_TABLE(wxGenericCalendarCtrl) - wxEVENT_RANGE_PROPERTY( Updated , wxEVT_CALENDAR_SEL_CHANGED , wxEVT_CALENDAR_WEEKDAY_CLICKED , wxCalendarEvent ) - wxHIDE_PROPERTY( Children ) - wxPROPERTY( Date,wxDateTime, SetDate , GetDate, , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) - wxPROPERTY_FLAGS( WindowStyle , wxCalendarCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style -wxEND_PROPERTIES_TABLE() - -wxBEGIN_HANDLERS_TABLE(wxGenericCalendarCtrl) -wxEND_HANDLERS_TABLE() - -wxCONSTRUCTOR_6( wxGenericCalendarCtrl , wxWindow* , Parent , wxWindowID , Id , wxDateTime , Date , wxPoint , Position , wxSize , Size , long , WindowStyle ) -#else -IMPLEMENT_DYNAMIC_CLASS(wxGenericCalendarCtrl, wxControl) -#endif - // ============================================================================ // implementation // ============================================================================ @@ -190,7 +138,8 @@ void wxGenericCalendarCtrl::Init() m_userChangedYear = false; m_widthCol = - m_heightRow = 0; + m_heightRow = + m_calendarWeekWidth = 0; wxDateTime::WeekDay wd; for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) ) @@ -211,7 +160,7 @@ void wxGenericCalendarCtrl::InitColours() m_colHighlightFg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); m_colHighlightBg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); m_colBackground = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_colSorrounding = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); + m_colSurrounding = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); m_colHolidayFg = *wxRED; // don't set m_colHolidayBg - by default, same as our bg colour @@ -246,12 +195,11 @@ bool wxGenericCalendarCtrl::Create(wxWindow *parent, if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { CreateYearSpinCtrl(); - m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%Y")), + m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%Y")), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - CreateMonthComboBox(); - m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(_T("%B")), + m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%B")), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); } @@ -295,7 +243,7 @@ void wxGenericCalendarCtrl::SetWindowStyleFlag(long style) // created/shown/hidden accordingly wxASSERT_MSG( (style & wxCAL_SEQUENTIAL_MONTH_SELECTION) == (m_windowStyle & wxCAL_SEQUENTIAL_MONTH_SELECTION), - _T("wxCAL_SEQUENTIAL_MONTH_SELECTION can't be changed after creation") ); + wxT("wxCAL_SEQUENTIAL_MONTH_SELECTION can't be changed after creation") ); wxControl::SetWindowStyleFlag(style); } @@ -334,7 +282,7 @@ void wxGenericCalendarCtrl::CreateMonthComboBox() void wxGenericCalendarCtrl::CreateYearSpinCtrl() { m_spinYear = new wxSpinCtrl(GetParent(), wxID_ANY, - GetDate().Format(_T("%Y")), + GetDate().Format(wxT("%Y")), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS | wxCLIP_SIBLINGS, @@ -345,7 +293,7 @@ void wxGenericCalendarCtrl::CreateYearSpinCtrl() NULL, this); m_spinYear->Connect(m_spinYear->GetId(), wxEVT_COMMAND_SPINCTRL_UPDATED, - wxCommandEventHandler(wxGenericCalendarCtrl::OnYearChange), + wxSpinEventHandler(wxGenericCalendarCtrl::OnYearChange), NULL, this); } @@ -516,7 +464,7 @@ bool wxGenericCalendarCtrl::SetDate(const wxDateTime& date) if ( AllowYearChange() ) { if ( !m_userChangedYear ) - m_spinYear->SetValue(m_date.Format(_T("%Y"))); + m_spinYear->SetValue(m_date.Format(wxT("%Y"))); } } @@ -644,8 +592,7 @@ wxDateTime wxGenericCalendarCtrl::GetStartDate() const wxDateTime date = wxDateTime(1, tm.mon, tm.year); // rewind back - date.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST - ? wxDateTime::Mon : wxDateTime::Sun); + date.SetToPrevWeekDay(GetWeekStart()); if ( GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS ) { @@ -678,69 +625,26 @@ bool wxGenericCalendarCtrl::IsDateInRange(const wxDateTime& date) const && ( ( m_highdate.IsValid() ) ? ( date <= m_highdate ) : true ) ); } -bool wxGenericCalendarCtrl::ChangeYear(wxDateTime* target) const +bool wxGenericCalendarCtrl::AdjustDateToRange(wxDateTime *date) const { - bool retval = false; - - if ( !(IsDateInRange(*target)) ) - { - if ( target->GetYear() < m_date.GetYear() ) - { - if ( target->GetYear() >= GetLowerDateLimit().GetYear() ) - { - *target = GetLowerDateLimit(); - retval = true; - } - else - { - *target = m_date; - } - } - else - { - if ( target->GetYear() <= GetUpperDateLimit().GetYear() ) - { - *target = GetUpperDateLimit(); - retval = true; - } - else - { - *target = m_date; - } - } - } - else + if ( m_lowdate.IsValid() && *date < m_lowdate ) { - retval = true; + *date = m_lowdate; + return true; } - return retval; -} - -bool wxGenericCalendarCtrl::ChangeMonth(wxDateTime* target) const -{ - bool retval = true; - - if ( !(IsDateInRange(*target)) ) + if ( m_highdate.IsValid() && *date > m_highdate ) { - retval = false; - - if ( target->GetMonth() < m_date.GetMonth() ) - { - *target = GetLowerDateLimit(); - } - else - { - *target = GetUpperDateLimit(); - } + *date = m_highdate; + return true; } - return retval; + return false; } size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const { - size_t retval = date.GetWeekOfMonth(GetWindowStyle() & wxCAL_MONDAY_FIRST + size_t retval = date.GetWeekOfMonth(HasFlag(wxCAL_MONDAY_FIRST) ? wxDateTime::Monday_First : wxDateTime::Sunday_First); @@ -752,8 +656,7 @@ size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const wxDateTime datetest = wxDateTime(1, tm.mon, tm.year); // rewind back - datetest.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST - ? wxDateTime::Mon : wxDateTime::Sun); + datetest.SetToPrevWeekDay(GetWeekStart()); if ( datetest.GetDay() == 1 ) { @@ -770,56 +673,45 @@ size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const // this is a composite control and it must arrange its parts each time its // size or position changes: the combobox and spinctrl are along the top of -// the available area and the calendar takes up therest of the space +// the available area and the calendar takes up the rest of the space // the static controls are supposed to be always smaller than combo/spin so we // always use the latter for size calculations and position the static to take // the same space // the constants used for the layout -#define VERT_MARGIN 5 // distance between combo and calendar -#ifdef __WXMAC__ +#define VERT_MARGIN 5 // distance between combo and calendar #define HORZ_MARGIN 5 // spin -#else -#define HORZ_MARGIN 15 // spin -#endif + wxSize wxGenericCalendarCtrl::DoGetBestSize() const { // calc the size of the calendar - wx_const_cast(wxGenericCalendarCtrl *, this)->RecalcGeometry(); + const_cast(this)->RecalcGeometry(); - wxCoord width = 7*m_widthCol, + wxCoord width = 7*m_widthCol + m_calendarWeekWidth, height = 7*m_heightRow + m_rowOffset + VERT_MARGIN; if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { - // the combobox doesn't report its height correctly (it returns the - // height including the drop down list) so don't use it - height += m_spinYear->GetBestSize().y; + const wxSize bestSizeCombo = m_comboMonth->GetBestSize(); + height += wxMax(bestSizeCombo.y, m_spinYear->GetBestSize().y) + + VERT_MARGIN; - wxCoord w2 = m_comboMonth->GetBestSize().x + HORZ_MARGIN + GetCharWidth()*6; - if (width < w2) + wxCoord w2 = bestSizeCombo.x + HORZ_MARGIN + GetCharWidth()*8; + if ( width < w2 ) width = w2; } + wxSize best(width, height); if ( !HasFlag(wxBORDER_NONE) ) { - // the border would clip the last line otherwise - height += 6; - width += 4; + best += GetWindowBorderSize(); } - wxSize best(width, height); CacheBestSize(best); - return best; -} -void wxGenericCalendarCtrl::DoSetSize(int x, int y, - int width, int height, - int sizeFlags) -{ - wxControl::DoSetSize(x, y, width, height, sizeFlags); + return best; } void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) @@ -832,26 +724,17 @@ void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) wxSize sizeStatic = m_staticMonth->GetSize(); wxSize sizeSpin = m_spinYear->GetSize(); - // wxMSW sometimes reports the wrong combo height, - // so on this platform we'll use the spin control - // height instead. -#ifdef __WXMSW__ - int maxHeight = sizeSpin.y; - int requiredSpinHeight = -1; -#else - int maxHeight = sizeCombo.y; - int requiredSpinHeight = sizeCombo.y; -#endif + int maxHeight = wxMax(sizeSpin.y, sizeCombo.y); int dy = (maxHeight - sizeStatic.y) / 2; - m_comboMonth->Move(x, y); - m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1, sizeStatic.y); + m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2); + m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1); int xDiff = sizeCombo.x + HORZ_MARGIN; - m_spinYear->SetSize(x + xDiff, y, width - xDiff, requiredSpinHeight); + m_spinYear->SetSize(x + xDiff, y + (maxHeight - sizeSpin.y)/2, width - xDiff, maxHeight); m_staticYear->SetSize(x + xDiff, y + dy, width - xDiff, sizeStatic.y); - yDiff = wxMax(sizeSpin.y, maxHeight) + VERT_MARGIN; + yDiff = maxHeight + VERT_MARGIN; } else // no controls on the top { @@ -861,34 +744,9 @@ void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height) wxControl::DoMoveWindow(x, y + yDiff, width, height - yDiff); } -void wxGenericCalendarCtrl::DoGetPosition(int *x, int *y) const -{ - wxControl::DoGetPosition(x, y); -#ifndef __WXPM__ - if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) && GetMonthControl() ) - { - // our real top corner is not in this position - if ( y ) - { - *y -= GetMonthControl()->GetSize().y + VERT_MARGIN; - } - } -#endif -} - void wxGenericCalendarCtrl::DoGetSize(int *width, int *height) const { - wxControl::DoGetSize(width, height); -#ifndef __WXPM__ - if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) - { - // our real height is bigger - if ( height && GetMonthControl()) - { - *height += GetMonthControl()->GetSize().y + VERT_MARGIN; - } - } -#endif + wxControl::DoGetSize( width, height ); } void wxGenericCalendarCtrl::RecalcGeometry() @@ -922,6 +780,9 @@ void wxGenericCalendarCtrl::RecalcGeometry() } } + m_calendarWeekWidth = HasFlag( wxCAL_SHOW_WEEK_NUMBERS ) + ? dc.GetTextExtent( wxString::Format( wxT( "%d" ), 42 )).GetWidth() + 4 : 0; + // leave some margins m_widthCol += 2; m_heightRow += 2; @@ -948,7 +809,7 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) #endif wxCoord y = 0; - wxCoord x0 = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + wxCoord x0 = m_calendarWeekWidth; if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { @@ -1032,7 +893,7 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) dc.SetPen(wxPen(m_colHeaderBg, 1, wxPENSTYLE_SOLID)); dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow); - bool startOnMonday = (GetWindowStyle() & wxCAL_MONDAY_FIRST) != 0; + bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST); for ( int wd = 0; wd < 7; wd++ ) { size_t n; @@ -1051,6 +912,24 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) //dc.SetFont(*wxNORMAL_FONT); y += m_heightRow; + + // draw column with calendar week nr + if ( HasFlag( wxCAL_SHOW_WEEK_NUMBERS ) && IsExposed( 0, y, m_calendarWeekWidth, m_heightRow * 6 )) + { + dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID)); + dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID)); + dc.DrawRectangle( 0, y, m_calendarWeekWidth, m_heightRow * 6 ); + wxDateTime date = GetStartDate(); + for ( size_t i = 0; i < 6; ++i ) + { + const int weekNr = date.GetWeekOfYear(); + wxString text = wxString::Format( wxT( "%d" ), weekNr ); + dc.DrawText( text, m_calendarWeekWidth - dc.GetTextExtent( text ).GetWidth() - 2, y + m_heightRow * i ); + date += wxDateSpan::Week(); + } + } + wxDateTime date = GetStartDate(); #if DEBUG_PAINT @@ -1080,9 +959,9 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { // don't use wxDate::Format() which prepends 0s unsigned int day = date.GetDay(); - wxString dayStr = wxString::Format(_T("%u"), day); + wxString dayStr = wxString::Format(wxT("%u"), day); wxCoord width; - dc.GetTextExtent(dayStr, &width, (wxCoord *)NULL); + dc.GetTextExtent(dayStr, &width, NULL); bool changedColours = false, changedFont = false; @@ -1092,9 +971,8 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) if ( date.GetMonth() != m_date.GetMonth() || !IsDateInRange(date) ) { - // surrounding week or out-of-range - // draw "disabled" - dc.SetTextForeground(m_colSorrounding); + // draw the days of adjacent months in different colour + dc.SetTextForeground(m_colSurrounding); changedColours = true; } else @@ -1124,13 +1002,13 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) colBg = attr->GetBackgroundColour(); } - if ( colFg.Ok() ) + if ( colFg.IsOk() ) { dc.SetTextForeground(colFg); changedColours = true; } - if ( colBg.Ok() ) + if ( colBg.IsOk() ) { dc.SetTextBackground(colBg); changedColours = true; @@ -1176,7 +1054,7 @@ void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) break; default: - wxFAIL_MSG(_T("unknown border type")); + wxFAIL_MSG(wxT("unknown border type")); } } @@ -1234,9 +1112,9 @@ void wxGenericCalendarCtrl::RefreshDate(const wxDateTime& date) wxRect rect; // always refresh the whole row at once because our OnPaint() will draw - // the whole row anyhow - and this allows the small optimisation in + // the whole row anyhow - and this allows the small optimization in // OnClick() below to work - rect.x = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + rect.x = m_calendarWeekWidth; rect.y = (m_heightRow * GetWeek(date)) + m_rowOffset; @@ -1302,7 +1180,7 @@ void wxGenericCalendarCtrl::HighlightRange(wxPaintDC* pDC, const wxDateTime& fro { int numpoints; wxPoint corners[8]; // potentially 8 corners in polygon - wxCoord x0 = wxMax( (GetSize().x - m_widthCol*7) /2 , 0 ); + wxCoord x0 = m_calendarWeekWidth; if ( fw == tw ) { @@ -1362,7 +1240,7 @@ bool wxGenericCalendarCtrl::GetDateCoord(const wxDateTime& date, int *day, int * if ( IsDateShown(date) ) { - bool startOnMonday = ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) != 0; + bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST); // Find day *day = date.GetWeekDay(); @@ -1475,7 +1353,14 @@ void wxGenericCalendarCtrl::OnClick(wxMouseEvent& event) // GenerateAllChangeEvents() here, we know which event to send GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED); } - break; + break; + + case wxCAL_HITTEST_WEEK: + { + wxCalendarEvent send( this, date, wxEVT_CALENDAR_WEEK_CLICKED ); + HandleWindowEvent( send ); + } + break; case wxCAL_HITTEST_HEADER: { @@ -1493,13 +1378,17 @@ void wxGenericCalendarCtrl::OnClick(wxMouseEvent& event) break; default: - wxFAIL_MSG(_T("unknown hittest code")); + wxFAIL_MSG(wxT("unknown hittest code")); // fall through case wxCAL_HITTEST_NOWHERE: event.Skip(); break; } + + // as we don't (always) skip the message, we're not going to receive the + // focus on click by default if we don't do it ourselves + SetFocus(); } wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos, @@ -1509,7 +1398,7 @@ wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos, RecalcGeometry(); // the position where the calendar really begins - wxCoord x0 = wxMax((GetSize().x - m_widthCol*7)/2, 0); + wxCoord x0 = m_calendarWeekWidth; if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ) { @@ -1550,18 +1439,36 @@ wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos, return wxCAL_HITTEST_INCMONTH; } + } + if ( pos.x - x0 < 0 ) + { + if ( pos.x >= 0 && pos.y > m_rowOffset + m_heightRow && pos.y <= m_rowOffset + m_heightRow * 7 ) + { + if ( date ) + { + *date = GetStartDate(); + *date += wxDateSpan::Week() * (( pos.y - m_rowOffset ) / m_heightRow - 1 ); + } + if ( wd ) + *wd = GetWeekStart(); + return wxCAL_HITTEST_WEEK; + } + else // early exit -> the rest of the function checks for clicks on days + return wxCAL_HITTEST_NOWHERE; } // header: week days int wday = (pos.x - x0) / m_widthCol; - if ( pos.y < (m_heightRow + m_rowOffset) ) + if ( wday > 6 ) + return wxCAL_HITTEST_NOWHERE; + if ( pos.y < (m_heightRow + m_rowOffset)) { if ( pos.y > m_rowOffset ) { if ( wd ) { - if ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) + if ( HasFlag(wxCAL_MONDAY_FIRST) ) { wday = wday == 6 ? 0 : wday + 1; } @@ -1620,13 +1527,18 @@ void wxGenericCalendarCtrl::OnMonthChange(wxCommandEvent& event) tm.mday = wxDateTime::GetNumberOfDays(mon, tm.year); } - wxDateTime target = wxDateTime(tm.mday, mon, tm.year); + wxDateTime dt(tm.mday, mon, tm.year); + if ( AdjustDateToRange(&dt) ) + { + // The date must have been changed to ensure it's in valid range, + // reflect this in the month choice control. + m_comboMonth->SetSelection(dt.GetMonth()); + } - ChangeMonth(&target); - SetDateAndNotify(target); + SetDateAndNotify(dt); } -void wxGenericCalendarCtrl::OnYearChange(wxCommandEvent& event) +void wxGenericCalendarCtrl::HandleYearChange(wxCommandEvent& event) { int year = (int)event.GetInt(); if ( year == INT_MIN ) @@ -1642,24 +1554,26 @@ void wxGenericCalendarCtrl::OnYearChange(wxCommandEvent& event) tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year); } - wxDateTime target = wxDateTime(tm.mday, tm.mon, year); - - if ( ChangeYear(&target) ) + wxDateTime dt(tm.mday, tm.mon, year); + if ( AdjustDateToRange(&dt) ) { - SetDateAndNotify(target); - } - else - { - // In this case we don't want to change the date. That would put us - // inside the same year but a strange number of months forward/back.. - m_spinYear->SetValue(target.GetYear()); + // As above, if the date was changed to keep it in valid range, its + // possibly changed year must be shown in the GUI. + m_spinYear->SetValue(dt.GetYear()); } + + SetDateAndNotify(dt); +} + +void wxGenericCalendarCtrl::OnYearChange(wxSpinEvent& event) +{ + HandleYearChange( event ); } void wxGenericCalendarCtrl::OnYearTextChange(wxCommandEvent& event) { SetUserChangedYear(); - OnYearChange(event); + HandleYearChange(event); } // Responds to colour changes, and passes event on to children. @@ -1682,49 +1596,31 @@ void wxGenericCalendarCtrl::OnSysColourChanged(wxSysColourChangedEvent& event) void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) { - wxDateTime target; switch ( event.GetKeyCode() ) { - case _T('+'): + case wxT('+'): case WXK_ADD: - target = m_date + wxDateSpan::Year(); - if ( ChangeYear(&target) ) - { - SetDateAndNotify(target); - } + SetDateAndNotify(m_date + wxDateSpan::Year()); break; - case _T('-'): + case wxT('-'): case WXK_SUBTRACT: - target = m_date - wxDateSpan::Year(); - if ( ChangeYear(&target) ) - { - SetDateAndNotify(target); - } + SetDateAndNotify(m_date - wxDateSpan::Year()); break; case WXK_PAGEUP: - target = m_date - wxDateSpan::Month(); - ChangeMonth(&target); - SetDateAndNotify(target); // always + SetDateAndNotify(m_date - wxDateSpan::Month()); break; case WXK_PAGEDOWN: - target = m_date + wxDateSpan::Month(); - ChangeMonth(&target); - SetDateAndNotify(target); // always + SetDateAndNotify(m_date + wxDateSpan::Month()); break; case WXK_RIGHT: if ( event.ControlDown() ) { - target = wxDateTime(m_date).SetToNextWeekDay( - GetWindowStyle() & wxCAL_MONDAY_FIRST - ? wxDateTime::Sun : wxDateTime::Sat); - if ( !IsDateInRange(target) ) - { - target = GetUpperDateLimit(); - } + wxDateTime target = m_date.SetToNextWeekDay(GetWeekEnd()); + AdjustDateToRange(&target); SetDateAndNotify(target); } else @@ -1734,13 +1630,8 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event) case WXK_LEFT: if ( event.ControlDown() ) { - target = wxDateTime(m_date).SetToPrevWeekDay( - GetWindowStyle() & wxCAL_MONDAY_FIRST - ? wxDateTime::Mon : wxDateTime::Sun); - if ( !IsDateInRange(target) ) - { - target = GetLowerDateLimit(); - } + wxDateTime target = m_date.SetToPrevWeekDay(GetWeekStart()); + AdjustDateToRange(&target); SetDateAndNotify(target); } else @@ -1779,48 +1670,9 @@ 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") ); + wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in SetHoliday") ); wxCalendarDateAttr *attr = GetAttr(day); if ( !attr ) @@ -1847,7 +1699,7 @@ void wxGenericCalendarCtrl::ResetHolidayAttrs() void wxGenericCalendarCtrl::Mark(size_t day, bool mark) { - wxCHECK_RET( day > 0 && day < 32, _T("invalid day in Mark") ); + wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in Mark") ); const wxCalendarDateAttr& m = wxCalendarDateAttr::GetMark(); if (mark) {