+
+ void OnKillTextFocus(wxFocusEvent &ev)
+ {
+ ev.Skip();
+
+ const wxDateTime& dtOld = GetDate();
+
+ wxDateTime dt;
+ wxString value = m_combo->GetValue();
+ if ( !ParseDateTime(value, &dt) )
+ {
+ if ( !HasDPFlag(wxDP_ALLOWNONE) )
+ 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()) )
+ {
+ SetDate(dt);
+ SendDateEvent(dt);
+ }
+ }
+
+ bool HasDPFlag(int flag) const
+ {
+ return m_combo->GetParent()->HasFlag(flag);
+ }
+
+ // it expands "%x" format and changes %y to %Y if wxDP_SHOWCENTURY flag
+ // is given. If the locale format can't be easily analyzed (e.g. when
+ // the month is given as a name, not number), "%x" is returned
+ wxString GetLocaleDateFormat() const
+ {
+ wxString x_format(wxT("%x"));
+ wxString fmt;
+ int year_cnt = 0, month_cnt = 0, day_cnt = 0;
+
+ wxDateTime dt;
+ dt.ParseFormat(wxT("2003-10-17"), wxT("%Y-%m-%d"));
+ wxString str(dt.Format(x_format));
+
+ const wxChar *p = str.c_str();
+ while ( *p )
+ {
+ if (wxIsdigit(*p))
+ {
+ int n=wxAtoi(p);
+ if (n == dt.GetDay())
+ {
+ fmt.Append(wxT("%d"));
+ day_cnt++;
+ p += 2;
+ }
+ else if (n == (int)dt.GetMonth()+1)
+ {
+ fmt.Append(wxT("%m"));
+ month_cnt++;
+ p += 2;
+ }
+ else if (n == dt.GetYear())
+ {
+ fmt.Append(wxT("%Y"));
+ year_cnt++;
+ p += 4;
+ }
+ else if (n == (dt.GetYear() % 100))
+ {
+ if ( HasDPFlag(wxDP_SHOWCENTURY) )
+ fmt.Append(wxT("%Y"));
+ else
+ fmt.Append(wxT("%y"));
+ year_cnt++;
+ p += 2;
+ }
+ else
+ // this shouldn't happen
+ return x_format;
+ }
+ else {
+ fmt.Append(*p);
+ p++;
+ }
+ }
+
+ if (year_cnt == 1 && month_cnt == 1 && day_cnt == 1)
+ return fmt;
+
+ return x_format;
+ }
+
+ bool SetFormat(const wxString& fmt)
+ {
+ m_format = fmt;
+
+ if ( m_combo )
+ {
+ wxArrayString allowedChars;
+ for ( wxChar c = wxT('0'); c <= wxT('9'); c++ )
+ allowedChars.Add(wxString(c, 1));
+
+ const wxChar *p2 = m_format.c_str();
+ while ( *p2 )
+ {
+ if ( *p2 == '%')
+ p2 += 2;
+ else
+ allowedChars.Add(wxString(*p2++, 1));
+ }
+
+ #if wxUSE_VALIDATORS
+ wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST);
+ tv.SetIncludes(allowedChars);
+ m_combo->SetValidator(tv);
+ #endif
+
+ if ( GetDate().IsValid() )
+ m_combo->SetText(GetDate().Format(m_format));
+ }
+
+ return true;
+ }
+
+ virtual void SetStringValue(const wxString& s)
+ {
+ wxDateTime dt;
+ if ( !s.empty() && ParseDateTime(s, &dt) )
+ SetDate(dt);
+ //else: keep the old value
+ }
+
+ virtual wxString GetStringValue() const
+ {
+ return GetStringValueFor(GetDate());
+ }
+
+private:
+ // returns either the given date representation using the current format or
+ // an empty string if it's invalid
+ wxString GetStringValueFor(const wxDateTime& dt) const
+ {
+ wxString val;
+ if ( dt.IsValid() )
+ val = dt.Format(m_format);
+
+ return val;
+ }
+
+ wxSize m_useSize;
+ wxString m_format;
+
+ DECLARE_EVENT_TABLE()