]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/datectlg.cpp
using new API (no visual difference)
[wxWidgets.git] / src / generic / datectlg.cpp
index d2feb04557020798e0e827ec2f905177621226fe..abcbacf408253df9f8b7a3f98c49b1700183ee3b 100644 (file)
@@ -29,7 +29,8 @@
 
 // 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"
@@ -88,6 +89,18 @@ enum
     #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
@@ -115,9 +128,8 @@ public:
                 long style = 0,
                 const wxValidator& validator = wxDefaultValidator);
 
-    virtual void DoMoveWindow(int x, int y, int w, int h);
-
 protected:
+    virtual void DoMoveWindow(int x, int y, int w, int h);
 
     void OnSize(wxSizeEvent& event);
     void OnMouseEnter(wxMouseEvent& event);
@@ -521,6 +533,13 @@ void wxDatePickerCtrlGeneric::Init()
     m_ignoreDrop = false;
 }
 
+wxDatePickerCtrlGeneric::~wxDatePickerCtrlGeneric()
+{
+    m_popup = NULL;
+    m_txt = NULL;
+    m_cal = NULL;
+    m_btn = NULL;
+}
 
 bool wxDatePickerCtrlGeneric::Destroy()
 {
@@ -613,14 +632,14 @@ wxDatePickerCtrlGeneric::SetDateRange(const wxDateTime& lowerdate,
 
 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())
@@ -650,19 +669,19 @@ bool wxDatePickerCtrlGeneric::SetFormat(const wxChar *fmt)
             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
@@ -687,20 +706,29 @@ wxDateTime wxDatePickerCtrlGeneric::GetValue() const
 
 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;
 }
 
 
@@ -820,6 +848,9 @@ void wxDatePickerCtrlGeneric::OnSetFocus(wxFocusEvent& WXUNUSED(ev))
 
 void wxDatePickerCtrlGeneric::OnKillFocus(wxFocusEvent &ev)
 {
+    if (!m_txt)
+        return;
+    
     ev.Skip();
 
     wxDateTime dt;
@@ -836,7 +867,7 @@ void wxDatePickerCtrlGeneric::OnKillFocus(wxFocusEvent &ev)
         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;
@@ -869,6 +900,12 @@ void wxDatePickerCtrlGeneric::OnSelChange(wxCalendarEvent &ev)
 
 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);