Keep displayed month and year in sync in wxGenericCalendarCtrl.

When the date was constrained to a range in wxGenericCalendarCtrl, the display
of the month in the month combobox could get out of sync with its real value.

Ensure that the correct month is always displayed and also simplify the code
by removing the apparently unnecessarily complex logic in ChangeYear() and
ChangeMonth() functions.

Closes #11060.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65901 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-10-24 22:40:41 +00:00
parent 69060f4f0c
commit 3c9863aca7
2 changed files with 36 additions and 88 deletions

View File

@@ -202,12 +202,12 @@ private:
// is this date shown?
bool IsDateShown(const wxDateTime& date) const;
// is this date in the given range?
// is this date in the currently allowed range?
bool IsDateInRange(const wxDateTime& date) const;
// range helpers
bool ChangeYear(wxDateTime* target) const;
bool ChangeMonth(wxDateTime* target) const;
// adjust the date to the currently allowed range, return true if it was
// changed
bool AdjustDateToRange(wxDateTime *date) const;
// redraw the given date
void RefreshDate(const wxDateTime& date);

View File

@@ -682,64 +682,21 @@ 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 ( m_lowdate.IsValid() && *date < m_lowdate )
{
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
{
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
@@ -1649,10 +1606,15 @@ 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::HandleYearChange(wxCommandEvent& event)
@@ -1671,18 +1633,15 @@ void wxGenericCalendarCtrl::HandleYearChange(wxCommandEvent& event)
tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year);
}
wxDateTime target = wxDateTime(tm.mday, tm.mon, year);
wxDateTime dt(tm.mday, tm.mon, year);
if ( AdjustDateToRange(&dt) )
{
// 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());
}
if ( ChangeYear(&target) )
{
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());
}
SetDateAndNotify(dt);
}
void wxGenericCalendarCtrl::OnYearChange(wxSpinEvent& event)
@@ -1716,43 +1675,31 @@ void wxGenericCalendarCtrl::OnSysColourChanged(wxSysColourChangedEvent& event)
void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event)
{
wxDateTime target;
switch ( event.GetKeyCode() )
{
case wxT('+'):
case WXK_ADD:
target = m_date + wxDateSpan::Year();
if ( ChangeYear(&target) )
{
SetDateAndNotify(target);
}
SetDateAndNotify(m_date + wxDateSpan::Year());
break;
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(
wxDateTime
target = m_date.SetToNextWeekDay(
GetWindowStyle() & wxCAL_MONDAY_FIRST
? wxDateTime::Sun : wxDateTime::Sat);
if ( !IsDateInRange(target) )
@@ -1768,7 +1715,8 @@ void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event)
case WXK_LEFT:
if ( event.ControlDown() )
{
target = wxDateTime(m_date).SetToPrevWeekDay(
wxDateTime
target = m_date.SetToPrevWeekDay(
GetWindowStyle() & wxCAL_MONDAY_FIRST
? wxDateTime::Mon : wxDateTime::Sun);
if ( !IsDateInRange(target) )