Merge branch 'date-picker-blank'
Allow customizing text displayed in wxDatePickerCtrl without valid value, notably not displaying anything in it in this case. See https://github.com/wxWidgets/wxWidgets/pull/2109
This commit is contained in:
@@ -32,6 +32,13 @@ public:
|
|||||||
// Set/get the date or time (in the latter case, time part is ignored).
|
// Set/get the date or time (in the latter case, time part is ignored).
|
||||||
virtual void SetValue(const wxDateTime& dt) = 0;
|
virtual void SetValue(const wxDateTime& dt) = 0;
|
||||||
virtual wxDateTime GetValue() const = 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__)
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
||||||
|
@@ -13,11 +13,13 @@
|
|||||||
#include "wx/containr.h"
|
#include "wx/containr.h"
|
||||||
#include "wx/compositewin.h"
|
#include "wx/compositewin.h"
|
||||||
|
|
||||||
|
typedef wxTimePickerCtrlCommonBase<wxDateTimePickerCtrlBase> wxTimePickerCtrlGenericBase;
|
||||||
|
|
||||||
class WXDLLIMPEXP_ADV wxTimePickerCtrlGeneric
|
class WXDLLIMPEXP_ADV wxTimePickerCtrlGeneric
|
||||||
: public wxCompositeWindow< wxNavigationEnabled<wxTimePickerCtrlBase> >
|
: public wxCompositeWindow< wxNavigationEnabled<wxTimePickerCtrlGenericBase> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef wxCompositeWindow< wxNavigationEnabled<wxTimePickerCtrlBase> > Base;
|
typedef wxCompositeWindow< wxNavigationEnabled<wxTimePickerCtrlGenericBase> > Base;
|
||||||
|
|
||||||
// Creating the control.
|
// Creating the control.
|
||||||
wxTimePickerCtrlGeneric() { Init(); }
|
wxTimePickerCtrlGeneric() { Init(); }
|
||||||
|
@@ -26,6 +26,8 @@ public:
|
|||||||
virtual void SetValue(const wxDateTime& dt) wxOVERRIDE;
|
virtual void SetValue(const wxDateTime& dt) wxOVERRIDE;
|
||||||
virtual wxDateTime GetValue() const wxOVERRIDE;
|
virtual wxDateTime GetValue() const wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual void SetNullText(const wxString& text) wxOVERRIDE;
|
||||||
|
|
||||||
// returns true if the platform should explicitly apply a theme border
|
// returns true if the platform should explicitly apply a theme border
|
||||||
virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; }
|
virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; }
|
||||||
|
|
||||||
@@ -46,43 +48,34 @@ protected:
|
|||||||
const wxValidator& validator,
|
const wxValidator& validator,
|
||||||
const wxString& name);
|
const wxString& name);
|
||||||
|
|
||||||
// Notice that the methods below must be overridden in all native MSW
|
|
||||||
// classes inheriting from this one but they can't be pure virtual because
|
|
||||||
// the generic implementations, not needing nor able to implement them, is
|
|
||||||
// also derived from this class currently. The real problem is, of course,
|
|
||||||
// this wrong class structure because the generic classes also inherit the
|
|
||||||
// wrong implementations of Set/GetValue() and DoGetBestSize() but as they
|
|
||||||
// override these methods anyhow, it does work -- but is definitely ugly
|
|
||||||
// and need to be changed (but how?) in the future.
|
|
||||||
|
|
||||||
#if wxUSE_INTL
|
#if wxUSE_INTL
|
||||||
// Override to return the date/time format used by this control.
|
// Override to return the date/time format used by this control.
|
||||||
virtual wxLocaleInfo MSWGetFormat() const /* = 0 */
|
virtual wxLocaleInfo MSWGetFormat() const = 0;
|
||||||
{
|
|
||||||
wxFAIL_MSG( "Unreachable" );
|
|
||||||
return wxLOCALE_TIME_FMT;
|
|
||||||
}
|
|
||||||
#endif // wxUSE_INTL
|
#endif // wxUSE_INTL
|
||||||
|
|
||||||
// Override to indicate whether we can have no date at all.
|
// Override to indicate whether we can have no date at all.
|
||||||
virtual bool MSWAllowsNone() const /* = 0 */
|
virtual bool MSWAllowsNone() const = 0;
|
||||||
{
|
|
||||||
wxFAIL_MSG( "Unreachable" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override to update m_date and send the event when the control contents
|
// Override to update m_date and send the event when the control contents
|
||||||
// changes, return true if the event was handled.
|
// changes, return true if the event was handled.
|
||||||
virtual bool MSWOnDateTimeChange(const tagNMDATETIMECHANGE& dtch) /* = 0 */
|
virtual bool MSWOnDateTimeChange(const tagNMDATETIMECHANGE& dtch) = 0;
|
||||||
{
|
|
||||||
wxUnusedVar(dtch);
|
|
||||||
wxFAIL_MSG( "Unreachable" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// the date currently shown by the control, may be invalid
|
// the date currently shown by the control, may be invalid
|
||||||
wxDateTime m_date;
|
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_
|
#endif // _WX_MSW_DATETIMECTRL_H_
|
||||||
|
@@ -29,7 +29,10 @@ enum
|
|||||||
// wxTimePickerCtrl: Allow the user to enter the time.
|
// wxTimePickerCtrl: Allow the user to enter the time.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLIMPEXP_ADV wxTimePickerCtrlBase : public wxDateTimePickerCtrl
|
// The template argument must be a class deriving from wxDateTimePickerCtrlBase
|
||||||
|
// (i.e. in practice either this class itself or wxDateTimePickerCtrl).
|
||||||
|
template <typename Base>
|
||||||
|
class wxTimePickerCtrlCommonBase : public Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
@@ -67,7 +70,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetValue(dt);
|
this->SetValue(dt);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -78,7 +81,7 @@ public:
|
|||||||
wxCHECK_MSG( hour && min && sec, false,
|
wxCHECK_MSG( hour && min && sec, false,
|
||||||
wxS("Time component pointers must be non-NULL") );
|
wxS("Time component pointers must be non-NULL") );
|
||||||
|
|
||||||
const wxDateTime::Tm tm = GetValue().GetTm();
|
const wxDateTime::Tm tm = this->GetValue().GetTm();
|
||||||
*hour = tm.hour;
|
*hour = tm.hour;
|
||||||
*min = tm.min;
|
*min = tm.min;
|
||||||
*sec = tm.sec;
|
*sec = tm.sec;
|
||||||
@@ -87,6 +90,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class is defined mostly for compatibility and is used as the base class
|
||||||
|
// by native wxTimePickerCtrl implementations.
|
||||||
|
typedef wxTimePickerCtrlCommonBase<wxDateTimePickerCtrl> wxTimePickerCtrlBase;
|
||||||
|
|
||||||
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
||||||
#include "wx/msw/timectrl.h"
|
#include "wx/msw/timectrl.h"
|
||||||
|
|
||||||
|
@@ -168,6 +168,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual wxDateTime GetValue() const;
|
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
|
Sets the valid range for the date selection. If @a dt1 is valid, it
|
||||||
becomes the earliest date (inclusive) accepted by the control. If
|
becomes the earliest date (inclusive) accepted by the control. If
|
||||||
|
@@ -894,7 +894,8 @@ wxDatePickerCtrl =
|
|||||||
element object {
|
element object {
|
||||||
attribute class { "wxDatePickerCtrl" } &
|
attribute class { "wxDatePickerCtrl" } &
|
||||||
stdObjectNodeAttributes &
|
stdObjectNodeAttributes &
|
||||||
stdWindowProperties
|
stdWindowProperties &
|
||||||
|
[xrc:p="o"] element null-text {_, t_text }*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -218,12 +218,24 @@ class MyTimeDialog : public wxDialog
|
|||||||
public:
|
public:
|
||||||
MyTimeDialog(wxWindow* parent);
|
MyTimeDialog(wxWindow* parent);
|
||||||
|
|
||||||
wxDateTime GetTime() const { return m_timePicker->GetValue(); }
|
wxDateTime GetTime() const
|
||||||
|
{
|
||||||
|
#if wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
|
if ( m_timePickerGeneric )
|
||||||
|
return m_timePickerGeneric->GetValue();
|
||||||
|
#endif // wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
|
|
||||||
|
return m_timePicker->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnTimeChange(wxDateEvent& event);
|
void OnTimeChange(wxDateEvent& event);
|
||||||
|
|
||||||
wxTimePickerCtrlBase* m_timePicker;
|
wxTimePickerCtrl* m_timePicker;
|
||||||
|
#if wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
|
wxTimePickerCtrlGeneric* m_timePickerGeneric;
|
||||||
|
#endif // wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
|
|
||||||
wxStaticText* m_timeText;
|
wxStaticText* m_timeText;
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
@@ -987,20 +999,31 @@ wxEND_EVENT_TABLE()
|
|||||||
MyTimeDialog::MyTimeDialog(wxWindow *parent)
|
MyTimeDialog::MyTimeDialog(wxWindow *parent)
|
||||||
: wxDialog(parent, wxID_ANY, wxString("Calendar: Choose time"))
|
: wxDialog(parent, wxID_ANY, wxString("Calendar: Choose time"))
|
||||||
{
|
{
|
||||||
|
wxWindow* timePickerWindow = NULL;
|
||||||
|
|
||||||
#if wxUSE_TIMEPICKCTRL_GENERIC
|
#if wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
|
m_timePickerGeneric = NULL;
|
||||||
|
m_timePicker = NULL;
|
||||||
|
|
||||||
wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
|
wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
|
||||||
if ( frame && frame->GetMenuBar()->IsChecked(Calendar_TimePicker_Generic) )
|
if ( frame && frame->GetMenuBar()->IsChecked(Calendar_TimePicker_Generic) )
|
||||||
m_timePicker = new wxTimePickerCtrlGeneric(this, wxID_ANY);
|
{
|
||||||
|
m_timePickerGeneric = new wxTimePickerCtrlGeneric(this, wxID_ANY);
|
||||||
|
timePickerWindow = m_timePickerGeneric;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif // wxUSE_TIMEPICKCTRL_GENERIC
|
#endif // wxUSE_TIMEPICKCTRL_GENERIC
|
||||||
m_timePicker = new wxTimePickerCtrl(this, wxID_ANY);
|
m_timePicker = new wxTimePickerCtrl(this, wxID_ANY);
|
||||||
m_timeText = new wxStaticText(this, wxID_ANY,
|
|
||||||
m_timePicker->GetValue().FormatISOTime());
|
if ( !timePickerWindow )
|
||||||
|
timePickerWindow = m_timePicker;
|
||||||
|
|
||||||
|
m_timeText = new wxStaticText(this, wxID_ANY, GetTime().FormatISOTime());
|
||||||
|
|
||||||
const wxSizerFlags flags = wxSizerFlags().Centre().Border();
|
const wxSizerFlags flags = wxSizerFlags().Centre().Border();
|
||||||
wxFlexGridSizer* const sizerMain = new wxFlexGridSizer(2);
|
wxFlexGridSizer* const sizerMain = new wxFlexGridSizer(2);
|
||||||
sizerMain->Add(new wxStaticText(this, wxID_ANY, "Enter &time:"), flags);
|
sizerMain->Add(new wxStaticText(this, wxID_ANY, "Enter &time:"), flags);
|
||||||
sizerMain->Add(m_timePicker, flags);
|
sizerMain->Add(timePickerWindow, flags);
|
||||||
|
|
||||||
sizerMain->Add(new wxStaticText(this, wxID_ANY, "Time in ISO format:"),
|
sizerMain->Add(new wxStaticText(this, wxID_ANY, "Time in ISO format:"),
|
||||||
flags);
|
flags);
|
||||||
|
@@ -54,6 +54,7 @@ enum
|
|||||||
DatePickerPage_Reset = wxID_HIGHEST,
|
DatePickerPage_Reset = wxID_HIGHEST,
|
||||||
DatePickerPage_Set,
|
DatePickerPage_Set,
|
||||||
DatePickerPage_SetRange,
|
DatePickerPage_SetRange,
|
||||||
|
DatePickerPage_SetNullText,
|
||||||
DatePickerPage_Picker
|
DatePickerPage_Picker
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ protected:
|
|||||||
|
|
||||||
void OnButtonSet(wxCommandEvent& event);
|
void OnButtonSet(wxCommandEvent& event);
|
||||||
void OnButtonSetRange(wxCommandEvent& event);
|
void OnButtonSetRange(wxCommandEvent& event);
|
||||||
|
void OnButtonSetNullText(wxCommandEvent& event);
|
||||||
void OnButtonReset(wxCommandEvent& event);
|
void OnButtonReset(wxCommandEvent& event);
|
||||||
|
|
||||||
// reset the date picker parameters
|
// reset the date picker parameters
|
||||||
@@ -96,6 +98,7 @@ protected:
|
|||||||
wxTextCtrl *m_textCur;
|
wxTextCtrl *m_textCur;
|
||||||
wxTextCtrl *m_textMin;
|
wxTextCtrl *m_textMin;
|
||||||
wxTextCtrl *m_textMax;
|
wxTextCtrl *m_textMax;
|
||||||
|
wxTextCtrl *m_textNull;
|
||||||
|
|
||||||
wxRadioBox* m_radioKind;
|
wxRadioBox* m_radioKind;
|
||||||
wxCheckBox* m_chkStyleCentury;
|
wxCheckBox* m_chkStyleCentury;
|
||||||
@@ -117,6 +120,7 @@ wxBEGIN_EVENT_TABLE(DatePickerWidgetsPage, WidgetsPage)
|
|||||||
EVT_BUTTON(DatePickerPage_Reset, DatePickerWidgetsPage::OnButtonReset)
|
EVT_BUTTON(DatePickerPage_Reset, DatePickerWidgetsPage::OnButtonReset)
|
||||||
EVT_BUTTON(DatePickerPage_Set, DatePickerWidgetsPage::OnButtonSet)
|
EVT_BUTTON(DatePickerPage_Set, DatePickerWidgetsPage::OnButtonSet)
|
||||||
EVT_BUTTON(DatePickerPage_SetRange, DatePickerWidgetsPage::OnButtonSetRange)
|
EVT_BUTTON(DatePickerPage_SetRange, DatePickerWidgetsPage::OnButtonSetRange)
|
||||||
|
EVT_BUTTON(DatePickerPage_SetNullText, DatePickerWidgetsPage::OnButtonSetNullText)
|
||||||
|
|
||||||
EVT_DATE_CHANGED(wxID_ANY, DatePickerWidgetsPage::OnDateChanged)
|
EVT_DATE_CHANGED(wxID_ANY, DatePickerWidgetsPage::OnDateChanged)
|
||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
@@ -197,6 +201,20 @@ void DatePickerWidgetsPage::CreateContent()
|
|||||||
sizerMiddle->Add(new wxButton(this, DatePickerPage_SetRange, "Set &range"),
|
sizerMiddle->Add(new wxButton(this, DatePickerPage_SetRange, "Set &range"),
|
||||||
wxSizerFlags().Centre().Border());
|
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
|
// right pane: control itself
|
||||||
wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
|
wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
|
||||||
@@ -327,11 +345,24 @@ 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.
|
||||||
|
static wxString FormatPossiblyInvalidDate(const wxDateTime& dt)
|
||||||
|
{
|
||||||
|
return dt.IsValid() ? dt.FormatISOCombined() : wxString("[none]");
|
||||||
|
}
|
||||||
|
|
||||||
void DatePickerWidgetsPage::OnDateChanged(wxDateEvent& event)
|
void DatePickerWidgetsPage::OnDateChanged(wxDateEvent& event)
|
||||||
{
|
{
|
||||||
wxLogMessage("Date changed, now is %s (control value is %s).",
|
wxLogMessage("Date changed, now is %s (control value is %s).",
|
||||||
event.GetDate().FormatISOCombined(),
|
FormatPossiblyInvalidDate(event.GetDate()),
|
||||||
m_datePicker->GetValue().FormatISOCombined());
|
FormatPossiblyInvalidDate(m_datePicker->GetValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_DATEPICKCTRL
|
#endif // wxUSE_DATEPICKCTRL
|
||||||
|
@@ -99,6 +99,8 @@ void wxDateTimePickerCtrl::SetValue(const wxDateTime& dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSWUpdateFormatIfNeeded(dt.IsValid());
|
||||||
|
|
||||||
m_date = dt;
|
m_date = dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +109,57 @@ wxDateTime wxDateTimePickerCtrl::GetValue() const
|
|||||||
return m_date;
|
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
|
wxSize wxDateTimePickerCtrl::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
wxClientDC dc(const_cast<wxDateTimePickerCtrl *>(this));
|
wxClientDC dc(const_cast<wxDateTimePickerCtrl *>(this));
|
||||||
@@ -168,7 +221,12 @@ wxDateTimePickerCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
switch ( hdr->code )
|
switch ( hdr->code )
|
||||||
{
|
{
|
||||||
case DTN_DATETIMECHANGE:
|
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;
|
*result = 0;
|
||||||
return true;
|
return true;
|
||||||
|
@@ -42,6 +42,10 @@ wxObject *wxDateCtrlXmlHandler::DoCreateResource()
|
|||||||
|
|
||||||
SetupWindow(picker);
|
SetupWindow(picker);
|
||||||
|
|
||||||
|
// Note that we want to set this one even if it's empty.
|
||||||
|
if ( HasParam(wxS("null-text")) )
|
||||||
|
picker->SetNullText(GetText(wxS("null-text")));
|
||||||
|
|
||||||
return picker;
|
return picker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user