Merge branch 'gtk-datapick-events'

Make generic wxDatePickerCtrl more consistent with the native MSW.

See https://github.com/wxWidgets/wxWidgets/pull/868
This commit is contained in:
Vadim Zeitlin 2018-08-02 01:13:07 +02:00
commit 5ddeeee825
4 changed files with 66 additions and 27 deletions

View File

@ -469,7 +469,8 @@ public:
The @a date parameter must be valid and in the currently valid range as The @a date parameter must be valid and in the currently valid range as
set by SetDateRange(), otherwise the current date is not changed and set by SetDateRange(), otherwise the current date is not changed and
the function returns @false. the function returns @false and, additionally, triggers an assertion
failure if the date is invalid.
*/ */
virtual bool SetDate(const wxDateTime& date); virtual bool SetDate(const wxDateTime& date);

View File

@ -434,6 +434,8 @@ bool wxGenericCalendarCtrl::EnableMonthChange(bool enable)
bool wxGenericCalendarCtrl::SetDate(const wxDateTime& date) bool wxGenericCalendarCtrl::SetDate(const wxDateTime& date)
{ {
wxCHECK_MSG( date.IsValid(), false, "invalid date" );
bool retval = true; bool retval = true;
bool sameMonth = m_date.GetMonth() == date.GetMonth(), bool sameMonth = m_date.GetMonth() == date.GetMonth(),

View File

@ -121,16 +121,41 @@ public:
return m_combo->GetTextCtrl()->IsEmpty(); return m_combo->GetTextCtrl()->IsEmpty();
} }
// This is public because it is used by wxDatePickerCtrlGeneric itself to
// change the date when the text control field changes. The reason it's
// done there and not in this class itself is mostly historic.
void ChangeDateAndNotifyIfValid()
{
wxDateTime dt;
if ( !ParseDateTime(m_combo->GetValue(), &dt) )
{
// The user must be in the process of updating the date, don't do
// anything -- we'll take care of ensuring it's valid on focus loss
// later.
return;
}
if ( dt == GetDate() )
{
// No need to send event if the date hasn't changed.
return;
}
// We change the date immediately, as it's more consistent with the
// native MSW version and avoids another event on focus loss.
SetDate(dt);
SendDateEvent(dt);
}
private:
bool ParseDateTime(const wxString& s, wxDateTime* pDt) bool ParseDateTime(const wxString& s, wxDateTime* pDt)
{ {
wxASSERT(pDt); wxASSERT(pDt);
if ( !s.empty() ) pDt->ParseFormat(s, m_format);
{ if ( !pDt->IsValid() )
pDt->ParseFormat(s, m_format); return false;
if ( !pDt->IsValid() )
return false;
}
return true; return true;
} }
@ -147,8 +172,6 @@ public:
datePicker->GetEventHandler()->ProcessEvent(event); datePicker->GetEventHandler()->ProcessEvent(event);
} }
private:
void OnCalKey(wxKeyEvent & ev) void OnCalKey(wxKeyEvent & ev)
{ {
if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers()) if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers())
@ -183,17 +206,33 @@ private:
dt = dtOld; dt = dtOld;
} }
m_combo->SetText(GetStringValueFor(dt)); if ( dt.IsValid() )
if ( !dt.IsValid() && HasDPFlag(wxDP_ALLOWNONE) )
return;
// notify that we had to change the date after validation
if ( (dt.IsValid() && (!dtOld.IsValid() || dt != dtOld)) ||
(!dt.IsValid() && dtOld.IsValid()) )
{ {
// Set it at wxCalendarCtrl level.
SetDate(dt); SetDate(dt);
SendDateEvent(dt);
// And show it in the text field.
m_combo->SetText(GetStringValue());
// And if the date has really changed, send an event about it.
if ( dt != dtOld )
SendDateEvent(dt);
}
else // Invalid date currently entered.
{
if ( HasDPFlag(wxDP_ALLOWNONE) )
{
// Clear the text part to indicate that the date is invalid.
// Would it be better to indicate this in some more clear way,
// e.g. maybe by using "[none]" or something like this?
m_combo->SetText(wxString());
}
else
{
// Restore the original value, as we can't have invalid value
// in this control.
m_combo->SetText(GetStringValue());
}
} }
} }
@ -252,7 +291,7 @@ private:
virtual void SetStringValue(const wxString& s) wxOVERRIDE virtual void SetStringValue(const wxString& s) wxOVERRIDE
{ {
wxDateTime dt; wxDateTime dt;
if ( !s.empty() && ParseDateTime(s, &dt) ) if ( ParseDateTime(s, &dt) )
SetDate(dt); SetDate(dt);
//else: keep the old value //else: keep the old value
} }
@ -475,13 +514,8 @@ void wxDatePickerCtrlGeneric::OnText(wxCommandEvent &ev)
ev.SetId(GetId()); ev.SetId(GetId());
GetParent()->GetEventHandler()->ProcessEvent(ev); GetParent()->GetEventHandler()->ProcessEvent(ev);
// We'll create an additional event if the date is valid. if ( m_popup )
// If the date isn't valid, the user's probably in the middle of typing m_popup->ChangeDateAndNotifyIfValid();
wxDateTime dt;
if ( !m_popup || !m_popup->ParseDateTime(m_combo->GetValue(), &dt) )
return;
m_popup->SendDateEvent(dt);
} }
#endif // wxUSE_DATEPICKCTRL #endif // wxUSE_DATEPICKCTRL

View File

@ -198,7 +198,9 @@ bool wxGtkCalendarCtrl::EnableMonthChange(bool enable)
bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date) bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date)
{ {
if ( date.IsValid() && !IsInValidRange(date) ) wxCHECK_MSG( date.IsValid(), false, "invalid date" );
if ( !IsInValidRange(date) )
return false; return false;
g_signal_handlers_block_by_func(m_widget, g_signal_handlers_block_by_func(m_widget,