1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/calctrl.cpp
3 // Purpose: implementation of the wxGtkCalendarCtrl
4 // Author: Marcin Wojdyr
6 // Copyright: (c) 2008 Marcin Wojdyr
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 #include "wx/wxprec.h"
19 #if wxUSE_CALENDARCTRL
21 #include "wx/gtk/private.h"
22 #include "wx/calctrl.h"
23 #include "wx/gtk/calctrl.h"
28 static void gtk_day_selected_callback(GtkWidget
*WXUNUSED(widget
),
29 wxGtkCalendarCtrl
*cal
)
31 wxDateTime date
= cal
->GetDate();
32 if (cal
->m_selectedDate
== date
)
35 cal
->m_selectedDate
= date
;
37 cal
->GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED
);
38 // send deprecated event
39 cal
->GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED
);
42 static void gtk_day_selected_double_click_callback(GtkWidget
*WXUNUSED(widget
),
43 wxGtkCalendarCtrl
*cal
)
45 cal
->GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED
);
48 static void gtk_month_changed_callback(GtkWidget
*WXUNUSED(widget
),
49 wxGtkCalendarCtrl
*cal
)
51 cal
->GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED
);
54 // callbacks that send deprecated events
56 static void gtk_prev_month_callback(GtkWidget
*WXUNUSED(widget
),
57 wxGtkCalendarCtrl
*cal
)
59 cal
->GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED
);
62 static void gtk_prev_year_callback(GtkWidget
*WXUNUSED(widget
),
63 wxGtkCalendarCtrl
*cal
)
65 cal
->GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED
);
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
75 bool wxGtkCalendarCtrl::Create(wxWindow
*parent
,
77 const wxDateTime
& date
,
83 if (!PreCreation(parent
, pos
, size
) ||
84 !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
86 wxFAIL_MSG(wxT("wxGtkCalendarCtrl creation failed"));
90 m_widget
= gtk_calendar_new();
91 g_object_ref(m_widget
);
92 SetDate(date
.IsValid() ? date
: wxDateTime::Today());
94 if (style
& wxCAL_NO_MONTH_CHANGE
)
95 g_object_set (G_OBJECT (m_widget
), "no-month-change", true, NULL
);
96 if (style
& wxCAL_SHOW_WEEK_NUMBERS
)
97 g_object_set (G_OBJECT (m_widget
), "show-week-numbers", true, NULL
);
99 g_signal_connect_after(m_widget
, "day-selected",
100 G_CALLBACK (gtk_day_selected_callback
),
102 g_signal_connect_after(m_widget
, "day-selected-double-click",
103 G_CALLBACK (gtk_day_selected_double_click_callback
),
105 g_signal_connect_after(m_widget
, "month-changed",
106 G_CALLBACK (gtk_month_changed_callback
),
109 // connect callbacks that send deprecated events
110 g_signal_connect_after(m_widget
, "prev-month",
111 G_CALLBACK (gtk_prev_month_callback
),
113 g_signal_connect_after(m_widget
, "next-month",
114 G_CALLBACK (gtk_prev_month_callback
),
116 g_signal_connect_after(m_widget
, "prev-year",
117 G_CALLBACK (gtk_prev_year_callback
),
119 g_signal_connect_after(m_widget
, "next-year",
120 G_CALLBACK (gtk_prev_year_callback
),
123 m_parent
->DoAddChild(this);
130 bool wxGtkCalendarCtrl::EnableMonthChange(bool enable
)
132 if ( !wxCalendarCtrlBase::EnableMonthChange(enable
) )
135 g_object_set (G_OBJECT (m_widget
), "no-month-change", !enable
, NULL
);
141 bool wxGtkCalendarCtrl::SetDate(const wxDateTime
& date
)
143 g_signal_handlers_block_by_func(m_widget
,
144 (gpointer
) gtk_day_selected_callback
, this);
145 g_signal_handlers_block_by_func(m_widget
,
146 (gpointer
) gtk_month_changed_callback
, this);
148 m_selectedDate
= date
;
149 int year
= date
.GetYear();
150 int month
= date
.GetMonth();
151 int day
= date
.GetDay();
152 gtk_calendar_select_month(GTK_CALENDAR(m_widget
), month
, year
);
153 gtk_calendar_select_day(GTK_CALENDAR(m_widget
), day
);
155 g_signal_handlers_unblock_by_func( m_widget
,
156 (gpointer
) gtk_month_changed_callback
, this);
157 g_signal_handlers_unblock_by_func( m_widget
,
158 (gpointer
) gtk_day_selected_callback
, this);
163 wxDateTime
wxGtkCalendarCtrl::GetDate() const
165 guint year
, monthGTK
, day
;
166 gtk_calendar_get_date(GTK_CALENDAR(m_widget
), &year
, &monthGTK
, &day
);
168 // GTK may return an invalid date, this happens at least when switching the
169 // month (or the year in case of February in a leap year) and the new month
170 // has fewer days than the currently selected one making the currently
171 // selected day invalid, e.g. just choosing May 31 and going back a month
172 // results in the date being (non existent) April 31 when we're called from
173 // gtk_prev_month_callback(). We need to manually work around this to avoid
174 // asserts from wxDateTime ctor.
175 const wxDateTime::Month month
= static_cast<wxDateTime::Month
>(monthGTK
);
176 const guint dayMax
= wxDateTime::GetNumberOfDays(month
, year
);
180 return wxDateTime(day
, month
, year
);
183 void wxGtkCalendarCtrl::Mark(size_t day
, bool mark
)
186 gtk_calendar_mark_day(GTK_CALENDAR(m_widget
), day
);
188 gtk_calendar_unmark_day(GTK_CALENDAR(m_widget
), day
);
191 #endif // wxUSE_CALENDARCTRL