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
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);

View File

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

View File

@ -121,16 +121,41 @@ public:
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)
{
wxASSERT(pDt);
if ( !s.empty() )
{
pDt->ParseFormat(s, m_format);
if ( !pDt->IsValid() )
return false;
}
pDt->ParseFormat(s, m_format);
if ( !pDt->IsValid() )
return false;
return true;
}
@ -147,8 +172,6 @@ public:
datePicker->GetEventHandler()->ProcessEvent(event);
}
private:
void OnCalKey(wxKeyEvent & ev)
{
if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers())
@ -183,17 +206,33 @@ private:
dt = dtOld;
}
m_combo->SetText(GetStringValueFor(dt));
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()) )
if ( dt.IsValid() )
{
// Set it at wxCalendarCtrl level.
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
{
wxDateTime dt;
if ( !s.empty() && ParseDateTime(s, &dt) )
if ( ParseDateTime(s, &dt) )
SetDate(dt);
//else: keep the old value
}
@ -475,13 +514,8 @@ void wxDatePickerCtrlGeneric::OnText(wxCommandEvent &ev)
ev.SetId(GetId());
GetParent()->GetEventHandler()->ProcessEvent(ev);
// We'll create an additional event if the date is valid.
// If the date isn't valid, the user's probably in the middle of typing
wxDateTime dt;
if ( !m_popup || !m_popup->ParseDateTime(m_combo->GetValue(), &dt) )
return;
m_popup->SendDateEvent(dt);
if ( m_popup )
m_popup->ChangeDateAndNotifyIfValid();
}
#endif // wxUSE_DATEPICKCTRL

View File

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