X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/628e155d8c70da0f962289cf1e1dea3699255707..8a07956565ddccd1720abf4e510945593128d774:/src/gtk/calctrl.cpp diff --git a/src/gtk/calctrl.cpp b/src/gtk/calctrl.cpp index 9c5b2a1717..09104839e0 100644 --- a/src/gtk/calctrl.cpp +++ b/src/gtk/calctrl.cpp @@ -28,7 +28,14 @@ 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); } @@ -81,10 +88,13 @@ bool wxGtkCalendarCtrl::Create(wxWindow *parent, } m_widget = gtk_calendar_new(); + g_object_ref(m_widget); SetDate(date.IsValid() ? date : wxDateTime::Today()); if (style & wxCAL_NO_MONTH_CHANGE) g_object_set (G_OBJECT (m_widget), "no-month-change", true, NULL); + if (style & wxCAL_SHOW_WEEK_NUMBERS) + g_object_set (G_OBJECT (m_widget), "show-week-numbers", true, NULL); g_signal_connect_after(m_widget, "day-selected", G_CALLBACK (gtk_day_selected_callback), @@ -127,21 +137,47 @@ bool wxGtkCalendarCtrl::EnableMonthChange(bool enable) return true; } + bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date) { + g_signal_handlers_block_by_func(m_widget, + (gpointer) gtk_day_selected_callback, this); + g_signal_handlers_block_by_func(m_widget, + (gpointer) gtk_month_changed_callback, this); + + m_selectedDate = date; int year = date.GetYear(); int month = date.GetMonth(); int day = date.GetDay(); gtk_calendar_select_month(GTK_CALENDAR(m_widget), month, year); gtk_calendar_select_day(GTK_CALENDAR(m_widget), day); + + g_signal_handlers_unblock_by_func( m_widget, + (gpointer) gtk_month_changed_callback, this); + g_signal_handlers_unblock_by_func( m_widget, + (gpointer) gtk_day_selected_callback, this); + return true; } wxDateTime wxGtkCalendarCtrl::GetDate() const { - guint year, month, day; - gtk_calendar_get_date(GTK_CALENDAR(m_widget), &year, &month, &day); - return wxDateTime(day, (wxDateTime::Month) month, year); + guint year, monthGTK, day; + gtk_calendar_get_date(GTK_CALENDAR(m_widget), &year, &monthGTK, &day); + + // GTK may return an invalid date, this happens at least when switching the + // month (or the year in case of February in a leap year) and the new month + // has fewer days than the currently selected one making the currently + // selected day invalid, e.g. just choosing May 31 and going back a month + // results in the date being (non existent) April 31 when we're called from + // gtk_prev_month_callback(). We need to manually work around this to avoid + // asserts from wxDateTime ctor. + const wxDateTime::Month month = static_cast(monthGTK); + const guint dayMax = wxDateTime::GetNumberOfDays(month, year); + if ( day > dayMax ) + day = dayMax; + + return wxDateTime(day, month, year); } void wxGtkCalendarCtrl::Mark(size_t day, bool mark) @@ -152,7 +188,4 @@ void wxGtkCalendarCtrl::Mark(size_t day, bool mark) gtk_calendar_unmark_day(GTK_CALENDAR(m_widget), day); } -IMPLEMENT_DYNAMIC_CLASS(wxGtkCalendarCtrl, wxControl) - - #endif // wxUSE_CALENDARCTRL