]> git.saurik.com Git - wxWidgets.git/commitdiff
Implement wxCalendarCtrl::SetDateRange() in the native GTK version.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 19 Jun 2011 22:46:36 +0000 (22:46 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 19 Jun 2011 22:46:36 +0000 (22:46 +0000)
While GTK+ doesn't support imposing ranges for dates selection natively, we
can do it ourselves by preventing the user from selecting any date outside of
the currently valid range.

This allows to use ranges under all platforms and not only in wxCalendarCtrl
itself but in wxDatePickerCtrl as well.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67987 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/gtk/calctrl.h
interface/wx/calctrl.h
samples/calendar/calendar.cpp
src/gtk/calctrl.cpp

index a3fa1d5894d7a584ef7f67dd8a292ed2afe59a90..61dbacf73337e2dfa598704013a9829cbaa06659 100644 (file)
@@ -517,6 +517,7 @@ GTK:
 - wxTLW generates wxEVT_MAXIMIZE.
 - Fix copying clipboard data to primary selection (David Hart).
 - Implement wxGraphicsContext::GetSize() (Marcin Wojdyr).
+- Implement wxCalendarCtrl::SetDateRange() for the native control.
 
 MSW:
 
index e9afdfec1766d94998af1732d23970a9c269b634..fee84ec1a87aba3532574dacbd0f682a497c12a8 100644 (file)
@@ -38,15 +38,31 @@ public:
     virtual bool SetDate(const wxDateTime& date);
     virtual wxDateTime GetDate() const;
 
+    virtual bool SetDateRange(const wxDateTime& lowerdate = wxDefaultDateTime,
+                              const wxDateTime& upperdate = wxDefaultDateTime);
+    virtual bool GetDateRange(wxDateTime *lowerdate, wxDateTime *upperdate) const;
+
     virtual bool EnableMonthChange(bool enable = true);
 
     virtual void Mark(size_t day, bool mark);
 
     // implementation
     // --------------
-    wxDateTime m_selectedDate;
+
+    void GTKGenerateEvent(wxEventType type);
 
 private:
+    bool IsInValidRange(const wxDateTime& dt) const;
+
+    // Range of the dates that can be selected by user, either or both may be
+    // invalid to indicate that no corresponding restriction is set.
+    wxDateTime m_validStart,
+               m_validEnd;
+
+    // Last known selected date, may be different from the real selection in
+    // the control while a handler for day-selected is running.
+    wxDateTime m_selectedDate;
+
     DECLARE_DYNAMIC_CLASS(wxGtkCalendarCtrl)
     wxDECLARE_NO_COPY_CLASS(wxGtkCalendarCtrl);
 };
index 799465bc8934cbf89de5704e0dbe6484a9c18379..e4f2cd8702be53be8d5f2b889409fd2fdf474a9d 100644 (file)
@@ -424,7 +424,9 @@ public:
     /**
         Sets the current date.
 
-        The @a date parameter must be valid.
+        The @a date parameter must be valid and in the currently valid range as
+        set by SetDateRange(), otherwise the current date is not changed and
+        the function returns @false.
     */
     virtual bool SetDate(const wxDateTime& date);
 
@@ -476,14 +478,12 @@ public:
 
     /**
         @name Date Range Functions
-
-        The functions in this section are currently implemented in the generic
-        and MSW versions and do nothing in the native GTK implementation.
      */
     //@{
 
     /**
-        Restrict the dates shown by the control to the specified range.
+        Restrict the dates that can be selected in the control to the specified
+        range.
 
         If either date is set, the corresponding limit will be enforced and
         @true returned. If none are set, the existing restrictions are removed
index 74963223326f6e3fc7b4b0e08df983f3b2532160..73cf2adf1284c9e0059648cf51bf1f70af61dbb9 100644 (file)
@@ -280,7 +280,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 #ifdef __WXGTK20__
     EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly)
     EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly)
-    EVT_UPDATE_UI(Calendar_Cal_LimitDates, MyFrame::OnUpdateUIGenericOnly)
 #endif
     EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly)
     EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly)
index 09104839e041a05fb34564e5ba37a1ece55576cd..9d23433761a252a9c46674c1a9b485c75870bccf 100644 (file)
@@ -28,27 +28,19 @@ extern "C" {
 static void gtk_day_selected_callback(GtkWidget *WXUNUSED(widget),
                                       wxGtkCalendarCtrl *cal)
 {
-    wxDateTime date = cal->GetDate();
-    if (cal->m_selectedDate == date)
-        return;
-
-    cal->m_selectedDate = date;
-
-    cal->GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
-    // send deprecated event
-    cal->GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
+    cal->GTKGenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
 }
 
 static void gtk_day_selected_double_click_callback(GtkWidget *WXUNUSED(widget),
                                                    wxGtkCalendarCtrl *cal)
 {
-    cal->GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
+    cal->GTKGenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
 }
 
 static void gtk_month_changed_callback(GtkWidget *WXUNUSED(widget),
                                        wxGtkCalendarCtrl *cal)
 {
-    cal->GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
+    cal->GTKGenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
 }
 
 // callbacks that send deprecated events
@@ -56,13 +48,13 @@ static void gtk_month_changed_callback(GtkWidget *WXUNUSED(widget),
 static void gtk_prev_month_callback(GtkWidget *WXUNUSED(widget),
                                     wxGtkCalendarCtrl *cal)
 {
-    cal->GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
+    cal->GTKGenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
 }
 
 static void gtk_prev_year_callback(GtkWidget *WXUNUSED(widget),
                                     wxGtkCalendarCtrl *cal)
 {
-    cal->GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
+    cal->GTKGenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
 }
 
 }
@@ -127,6 +119,74 @@ bool wxGtkCalendarCtrl::Create(wxWindow *parent,
     return true;
 }
 
+void wxGtkCalendarCtrl::GTKGenerateEvent(wxEventType type)
+{
+    // First check if the new date is in the specified range.
+    wxDateTime dt = GetDate();
+    if ( !IsInValidRange(dt) )
+    {
+        if ( m_validStart.IsValid() && dt < m_validStart )
+            dt = m_validStart;
+        else
+            dt = m_validEnd;
+
+        SetDate(dt);
+
+        return;
+    }
+
+    if ( type == wxEVT_CALENDAR_SEL_CHANGED )
+    {
+        // Don't generate this event if the new date is the same as the old
+        // one.
+        if ( m_selectedDate == dt )
+            return;
+
+        m_selectedDate = dt;
+
+        GenerateEvent(type);
+
+        // Also send the deprecated event together with the new one.
+        GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
+    }
+    else
+    {
+        GenerateEvent(type);
+    }
+}
+
+bool wxGtkCalendarCtrl::IsInValidRange(const wxDateTime& dt) const
+{
+    return (!m_validStart.IsValid() || m_validStart <= dt) &&
+                (!m_validEnd.IsValid() || dt <= m_validEnd);
+}
+
+bool
+wxGtkCalendarCtrl::SetDateRange(const wxDateTime& lowerdate,
+                                const wxDateTime& upperdate)
+{
+    if ( lowerdate.IsValid() && upperdate.IsValid() && lowerdate >= upperdate )
+        return false;
+
+    m_validStart = lowerdate;
+    m_validEnd = upperdate;
+
+    return true;
+}
+
+bool
+wxGtkCalendarCtrl::GetDateRange(wxDateTime *lowerdate,
+                                wxDateTime *upperdate) const
+{
+    if ( lowerdate )
+        *lowerdate = m_validStart;
+    if ( upperdate )
+        *upperdate = m_validEnd;
+
+    return m_validStart.IsValid() || m_validEnd.IsValid();
+}
+
+
 bool wxGtkCalendarCtrl::EnableMonthChange(bool enable)
 {
     if ( !wxCalendarCtrlBase::EnableMonthChange(enable) )
@@ -140,6 +200,9 @@ bool wxGtkCalendarCtrl::EnableMonthChange(bool enable)
 
 bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date)
 {
+    if ( date.IsValid() && !IsInValidRange(date) )
+        return false;
+
     g_signal_handlers_block_by_func(m_widget,
         (gpointer) gtk_day_selected_callback, this);
     g_signal_handlers_block_by_func(m_widget,