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);
};
/**
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);
/**
@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
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
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);
}
}
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) )
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,