Add wxDateTimePickerCtrl::SetNullText()
This allows to customize the string shown when there is no valid date under MSW (only, for now) and can be notably used to suppress the unused date completely, which can be useful to lighten up the display when there are many controls. Add UI elements to the widgets sample allowing to test the new function.
This commit is contained in:
@@ -32,6 +32,13 @@ public:
|
||||
// Set/get the date or time (in the latter case, time part is ignored).
|
||||
virtual void SetValue(const wxDateTime& dt) = 0;
|
||||
virtual wxDateTime GetValue() const = 0;
|
||||
|
||||
// For the controls with wxDP_ALLOWNONE style, set the string displayed
|
||||
// when the control doesn't have any valid value. Currently this is only
|
||||
// actually used under MSW, where it can be used to override the previous
|
||||
// value which is still displayed by the control in this case, and ignored
|
||||
// elsewhere.
|
||||
virtual void SetNullText(const wxString& WXUNUSED(text)) { }
|
||||
};
|
||||
|
||||
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
||||
|
@@ -26,6 +26,8 @@ public:
|
||||
virtual void SetValue(const wxDateTime& dt) wxOVERRIDE;
|
||||
virtual wxDateTime GetValue() const wxOVERRIDE;
|
||||
|
||||
virtual void SetNullText(const wxString& text) wxOVERRIDE;
|
||||
|
||||
// returns true if the platform should explicitly apply a theme border
|
||||
virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; }
|
||||
|
||||
@@ -61,6 +63,19 @@ protected:
|
||||
|
||||
// the date currently shown by the control, may be invalid
|
||||
wxDateTime m_date;
|
||||
|
||||
private:
|
||||
// Helper setting the appropriate format depending on the passed in state.
|
||||
void MSWUpdateFormat(bool valid);
|
||||
|
||||
// Same thing, but only doing if the validity differs from the date
|
||||
// validity, i.e. avoiding useless work if nothing needs to be done.
|
||||
void MSWUpdateFormatIfNeeded(bool valid);
|
||||
|
||||
|
||||
// shown when there is no valid value (so only used with wxDP_ALLOWNONE),
|
||||
// always non-empty if SetNullText() was called, see the comments there
|
||||
wxString m_nullText;
|
||||
};
|
||||
|
||||
#endif // _WX_MSW_DATETIMECTRL_H_
|
||||
|
@@ -168,6 +168,22 @@ public:
|
||||
*/
|
||||
virtual wxDateTime GetValue() const;
|
||||
|
||||
/**
|
||||
Set the text to show when there is no valid value.
|
||||
|
||||
For the controls with @c wxDP_ALLOWNONE style, set the string displayed
|
||||
when the control doesn't have any valid value. Currently this is only
|
||||
actually used under MSW, where it can be used to override the previous
|
||||
value which is still displayed by the control in this case, and ignored
|
||||
elsewhere.
|
||||
|
||||
Notably, @a text can be empty to completely hide the date if no valid
|
||||
date is specified.
|
||||
|
||||
@since 3.1.5
|
||||
*/
|
||||
void SetNullText(const wxString& text);
|
||||
|
||||
/**
|
||||
Sets the valid range for the date selection. If @a dt1 is valid, it
|
||||
becomes the earliest date (inclusive) accepted by the control. If
|
||||
|
@@ -54,6 +54,7 @@ enum
|
||||
DatePickerPage_Reset = wxID_HIGHEST,
|
||||
DatePickerPage_Set,
|
||||
DatePickerPage_SetRange,
|
||||
DatePickerPage_SetNullText,
|
||||
DatePickerPage_Picker
|
||||
};
|
||||
|
||||
@@ -78,6 +79,7 @@ protected:
|
||||
|
||||
void OnButtonSet(wxCommandEvent& event);
|
||||
void OnButtonSetRange(wxCommandEvent& event);
|
||||
void OnButtonSetNullText(wxCommandEvent& event);
|
||||
void OnButtonReset(wxCommandEvent& event);
|
||||
|
||||
// reset the date picker parameters
|
||||
@@ -96,6 +98,7 @@ protected:
|
||||
wxTextCtrl *m_textCur;
|
||||
wxTextCtrl *m_textMin;
|
||||
wxTextCtrl *m_textMax;
|
||||
wxTextCtrl *m_textNull;
|
||||
|
||||
wxRadioBox* m_radioKind;
|
||||
wxCheckBox* m_chkStyleCentury;
|
||||
@@ -117,6 +120,7 @@ wxBEGIN_EVENT_TABLE(DatePickerWidgetsPage, WidgetsPage)
|
||||
EVT_BUTTON(DatePickerPage_Reset, DatePickerWidgetsPage::OnButtonReset)
|
||||
EVT_BUTTON(DatePickerPage_Set, DatePickerWidgetsPage::OnButtonSet)
|
||||
EVT_BUTTON(DatePickerPage_SetRange, DatePickerWidgetsPage::OnButtonSetRange)
|
||||
EVT_BUTTON(DatePickerPage_SetNullText, DatePickerWidgetsPage::OnButtonSetNullText)
|
||||
|
||||
EVT_DATE_CHANGED(wxID_ANY, DatePickerWidgetsPage::OnDateChanged)
|
||||
wxEND_EVENT_TABLE()
|
||||
@@ -197,6 +201,20 @@ void DatePickerWidgetsPage::CreateContent()
|
||||
sizerMiddle->Add(new wxButton(this, DatePickerPage_SetRange, "Set &range"),
|
||||
wxSizerFlags().Centre().Border());
|
||||
|
||||
sizerMiddle->AddSpacer(10);
|
||||
|
||||
sizerMiddle->Add(CreateSizerWithTextAndLabel
|
||||
(
|
||||
"&Null text",
|
||||
wxID_ANY,
|
||||
&m_textNull
|
||||
),
|
||||
wxSizerFlags().Expand().Border());
|
||||
|
||||
sizerMiddle->Add(new wxButton(this, DatePickerPage_SetNullText,
|
||||
"Set &null text"),
|
||||
wxSizerFlags().Centre().Border());
|
||||
|
||||
|
||||
// right pane: control itself
|
||||
wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -327,6 +345,11 @@ void DatePickerWidgetsPage::OnButtonSetRange(wxCommandEvent& WXUNUSED(event))
|
||||
}
|
||||
}
|
||||
|
||||
void DatePickerWidgetsPage::OnButtonSetNullText(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
m_datePicker->SetNullText(m_textNull->GetValue());
|
||||
}
|
||||
|
||||
// Helper function which has to be used here because the controls with
|
||||
// wxDP_ALLOWNONE style can have invalid date, both in the control itself and
|
||||
// in the event it generates.
|
||||
|
@@ -99,6 +99,8 @@ void wxDateTimePickerCtrl::SetValue(const wxDateTime& dt)
|
||||
return;
|
||||
}
|
||||
|
||||
MSWUpdateFormatIfNeeded(dt.IsValid());
|
||||
|
||||
m_date = dt;
|
||||
}
|
||||
|
||||
@@ -107,6 +109,57 @@ wxDateTime wxDateTimePickerCtrl::GetValue() const
|
||||
return m_date;
|
||||
}
|
||||
|
||||
void wxDateTimePickerCtrl::MSWUpdateFormatIfNeeded(bool valid)
|
||||
{
|
||||
if ( MSWAllowsNone() && !m_nullText.empty() && valid != m_date.IsValid() )
|
||||
MSWUpdateFormat(valid);
|
||||
}
|
||||
|
||||
void wxDateTimePickerCtrl::MSWUpdateFormat(bool valid)
|
||||
{
|
||||
// We just use NULL to reset to the default format when the date is valid,
|
||||
// as the control seems to remember whichever format was used when it was
|
||||
// created, i.e. this works both with and without wxDP_SHOWCENTURY.
|
||||
|
||||
// Note: due to a bug in MinGW headers, with missing parentheses around the
|
||||
// macro argument (corrected in or before 8.2, but still existing in 5.3),
|
||||
// we have to use a temporary variable here.
|
||||
const TCHAR* const format = valid ? NULL : m_nullText.t_str();
|
||||
DateTime_SetFormat(GetHwnd(), format);
|
||||
}
|
||||
|
||||
void wxDateTimePickerCtrl::SetNullText(const wxString& text)
|
||||
{
|
||||
m_nullText = text;
|
||||
if ( m_nullText.empty() )
|
||||
{
|
||||
// Using empty format doesn't work with the native control, it just
|
||||
// uses the default short date format in this case, so set the format
|
||||
// to the single space which is more or less guaranteed to work as it's
|
||||
// the semi-official way to clear the control contents when it doesn't
|
||||
// have any valid value, according to Microsoft's old KB document
|
||||
// Q238077, which can still be found online by searching for its
|
||||
// number, even if it's not available on Microsoft web site any more.
|
||||
//
|
||||
// Coincidentally, it's also convenient for us, as we can just check if
|
||||
// null text is empty to see if we need to use it elsewhere in the code.
|
||||
m_nullText = wxS(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to quote the text, as otherwise format specifiers (e.g.
|
||||
// "d", "m" etc) would be interpreted specially by the control. To make
|
||||
// things simple, we just quote it entirely and always.
|
||||
m_nullText.Replace("'", "''");
|
||||
m_nullText.insert(0, "'");
|
||||
m_nullText.append("'");
|
||||
}
|
||||
|
||||
// Apply it immediately if we don't have any value right now.
|
||||
if ( !m_date.IsValid() )
|
||||
MSWUpdateFormat(false);
|
||||
}
|
||||
|
||||
wxSize wxDateTimePickerCtrl::DoGetBestSize() const
|
||||
{
|
||||
wxClientDC dc(const_cast<wxDateTimePickerCtrl *>(this));
|
||||
@@ -168,7 +221,12 @@ wxDateTimePickerCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
switch ( hdr->code )
|
||||
{
|
||||
case DTN_DATETIMECHANGE:
|
||||
if ( MSWOnDateTimeChange(*(NMDATETIMECHANGE*)(hdr)) )
|
||||
const NMDATETIMECHANGE& dtch = *(NMDATETIMECHANGE*)(hdr);
|
||||
|
||||
// Update the format before showing the new date if necessary.
|
||||
MSWUpdateFormatIfNeeded(dtch.dwFlags == GDT_VALID);
|
||||
|
||||
if ( MSWOnDateTimeChange(dtch) )
|
||||
{
|
||||
*result = 0;
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user