// use this version if we're explicitly requested to do it or if it's the only
// one we have
-#if wxUSE_DATEPICKCTRL_GENERIC || !defined(wxHAS_NATIVE_DATEPICKCTRL)
+#if !defined(wxHAS_NATIVE_DATEPICKCTRL) || \
+ (defined(wxUSE_DATEPICKCTRL_GENERIC) && wxUSE_DATEPICKCTRL_GENERIC)
#ifndef WX_PRECOMP
#include "wx/bmpbuttn.h"
#define TXTPOSY 0
#endif
+// ----------------------------------------------------------------------------
+// global variables
+// ----------------------------------------------------------------------------
+
+// this should have been a flag in wxDatePickerCtrlGeneric itself but adding it
+// there now would break backwards compatibility, so put it here as a global:
+// this shouldn't be a big problem as only one (GUI) thread normally can call
+// wxDatePickerCtrlGeneric::SetValue() and so it can be only ever used for one
+// control at a time
+//
+// if the value is not NULL, it points to the control which is inside SetValue()
+static wxDatePickerCtrlGeneric *gs_inSetValue = NULL;
// ----------------------------------------------------------------------------
// local classes
m_ignoreDrop = false;
}
+wxDatePickerCtrlGeneric::~wxDatePickerCtrlGeneric()
+{
+ m_popup = NULL;
+ m_txt = NULL;
+ m_cal = NULL;
+ m_btn = NULL;
+}
bool wxDatePickerCtrlGeneric::Destroy()
{
bool wxDatePickerCtrlGeneric::SetFormat(const wxChar *fmt)
{
+ m_format.clear();
+
wxDateTime dt;
dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
- wxString str=dt.Format(fmt);
- wxChar *p=(wxChar*)str.c_str();
-
- m_format=wxEmptyString;
+ wxString str(dt.Format(fmt));
- while (*p)
+ const wxChar *p = str.c_str();
+ while ( *p )
{
int n=wxAtoi(p);
if (n == dt.GetDay())
m_format.Append(*p++);
}
- if (m_txt)
+ if ( m_txt )
{
wxArrayString allowedChars;
for ( wxChar c = _T('0'); c <= _T('9'); c++ )
allowedChars.Add(wxString(c, 1));
- const wxChar *p = m_format.c_str();
- while (*p)
+ const wxChar *p2 = m_format.c_str();
+ while ( *p2 )
{
- if (*p == '%')
- p += 2;
+ if ( *p2 == '%')
+ p2 += 2;
else
- allowedChars.Add(wxString(*p++, 1));
+ allowedChars.Add(wxString(*p2++, 1));
}
#if wxUSE_VALIDATORS
void wxDatePickerCtrlGeneric::SetValue(const wxDateTime& date)
{
- if (m_cal)
- {
- if (date.IsValid())
- m_txt->SetValue(date.Format(m_format));
- else
- {
- wxASSERT_MSG( HasFlag(wxDP_ALLOWNONE),
- _T("this control must have a valid date") );
+ if ( !m_cal )
+ return;
- m_txt->SetValue(wxEmptyString);
- }
+ // we need to suppress the event sent from wxTextCtrl as calling our
+ // SetValue() should not result in an event being sent (wxTextCtrl is
+ // an exception to this rule)
+ gs_inSetValue = this;
- m_currentDate = date;
+ if ( date.IsValid() )
+ {
+ m_txt->SetValue(date.Format(m_format));
}
+ else // invalid date
+ {
+ wxASSERT_MSG( HasFlag(wxDP_ALLOWNONE),
+ _T("this control must have a valid date") );
+
+ m_txt->SetValue(wxEmptyString);
+ }
+
+ gs_inSetValue = NULL;
+
+ m_currentDate = date;
}
void wxDatePickerCtrlGeneric::OnKillFocus(wxFocusEvent &ev)
{
+ if (!m_txt)
+ return;
+
ev.Skip();
wxDateTime dt;
m_txt->SetValue(wxEmptyString);
// notify that we had to change the date after validation
- if ( (dt.IsValid() && m_currentDate != dt) ||
+ if ( (dt.IsValid() && (!m_currentDate.IsValid() || m_currentDate != dt)) ||
(!dt.IsValid() && m_currentDate.IsValid()) )
{
m_currentDate = dt;
void wxDatePickerCtrlGeneric::OnText(wxCommandEvent &ev)
{
+ if ( gs_inSetValue )
+ {
+ // artificial event resulting from our own SetValue() call, ignore it
+ return;
+ }
+
ev.SetEventObject(this);
ev.SetId(GetId());
GetParent()->ProcessEvent(ev);