]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/calctrl.cpp
adapting to init pattern
[wxWidgets.git] / src / gtk / calctrl.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/calctrl.cpp
3 // Purpose: implementation of the wxGtkCalendarCtrl
4 // Author: Marcin Wojdyr
5 // RCS-ID: $Id$
6 // Copyright: (c) 2008 Marcin Wojdyr
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 #ifndef WX_PRECOMP
17 #endif //WX_PRECOMP
18
19 #if wxUSE_CALENDARCTRL
20
21 #include "wx/gtk/private.h"
22 #include "wx/calctrl.h"
23 #include "wx/gtk/calctrl.h"
24
25
26 extern "C" {
27
28 static void gtk_day_selected_callback(GtkWidget *WXUNUSED(widget),
29 wxGtkCalendarCtrl *cal)
30 {
31 wxDateTime date = cal->GetDate();
32 if (cal->m_selectedDate == date)
33 return;
34
35 cal->m_selectedDate = date;
36
37 cal->GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
38 // send deprecated event
39 cal->GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
40 }
41
42 static void gtk_day_selected_double_click_callback(GtkWidget *WXUNUSED(widget),
43 wxGtkCalendarCtrl *cal)
44 {
45 cal->GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
46 }
47
48 static void gtk_month_changed_callback(GtkWidget *WXUNUSED(widget),
49 wxGtkCalendarCtrl *cal)
50 {
51 cal->GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
52 }
53
54 // callbacks that send deprecated events
55
56 static void gtk_prev_month_callback(GtkWidget *WXUNUSED(widget),
57 wxGtkCalendarCtrl *cal)
58 {
59 cal->GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
60 }
61
62 static void gtk_prev_year_callback(GtkWidget *WXUNUSED(widget),
63 wxGtkCalendarCtrl *cal)
64 {
65 cal->GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
66 }
67
68 }
69
70 // ----------------------------------------------------------------------------
71 // wxGtkCalendarCtrl
72 // ----------------------------------------------------------------------------
73
74
75 bool wxGtkCalendarCtrl::Create(wxWindow *parent,
76 wxWindowID id,
77 const wxDateTime& date,
78 const wxPoint& pos,
79 const wxSize& size,
80 long style,
81 const wxString& name)
82 {
83 if (!PreCreation(parent, pos, size) ||
84 !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name))
85 {
86 wxFAIL_MSG(wxT("wxGtkCalendarCtrl creation failed"));
87 return false;
88 }
89
90 m_widget = gtk_calendar_new();
91 g_object_ref(m_widget);
92 SetDate(date.IsValid() ? date : wxDateTime::Today());
93
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);
98
99 g_signal_connect_after(m_widget, "day-selected",
100 G_CALLBACK (gtk_day_selected_callback),
101 this);
102 g_signal_connect_after(m_widget, "day-selected-double-click",
103 G_CALLBACK (gtk_day_selected_double_click_callback),
104 this);
105 g_signal_connect_after(m_widget, "month-changed",
106 G_CALLBACK (gtk_month_changed_callback),
107 this);
108
109 // connect callbacks that send deprecated events
110 g_signal_connect_after(m_widget, "prev-month",
111 G_CALLBACK (gtk_prev_month_callback),
112 this);
113 g_signal_connect_after(m_widget, "next-month",
114 G_CALLBACK (gtk_prev_month_callback),
115 this);
116 g_signal_connect_after(m_widget, "prev-year",
117 G_CALLBACK (gtk_prev_year_callback),
118 this);
119 g_signal_connect_after(m_widget, "next-year",
120 G_CALLBACK (gtk_prev_year_callback),
121 this);
122
123 m_parent->DoAddChild(this);
124
125 PostCreation(size);
126
127 return true;
128 }
129
130 bool wxGtkCalendarCtrl::EnableMonthChange(bool enable)
131 {
132 if ( !wxCalendarCtrlBase::EnableMonthChange(enable) )
133 return false;
134
135 g_object_set (G_OBJECT (m_widget), "no-month-change", !enable, NULL);
136
137 return true;
138 }
139
140
141 bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date)
142 {
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);
147
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);
154
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);
159
160 return true;
161 }
162
163 wxDateTime wxGtkCalendarCtrl::GetDate() const
164 {
165 guint year, monthGTK, day;
166 gtk_calendar_get_date(GTK_CALENDAR(m_widget), &year, &monthGTK, &day);
167
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);
177 if ( day > dayMax )
178 day = dayMax;
179
180 return wxDateTime(day, month, year);
181 }
182
183 void wxGtkCalendarCtrl::Mark(size_t day, bool mark)
184 {
185 if (mark)
186 gtk_calendar_mark_day(GTK_CALENDAR(m_widget), day);
187 else
188 gtk_calendar_unmark_day(GTK_CALENDAR(m_widget), day);
189 }
190
191 #endif // wxUSE_CALENDARCTRL