2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * @shortdesc: CalendarPopup allows choosing a date from a popup calendar.
27 * @longdesc: The Calendar popup is a dialog that contains a GtkCalendar
28 * widget. The pop-up is cancelled by
29 * either a mouse click outside of the dialog or pressing the ESC
33 * @seealso: #HildonDateEditor, #HildonTimeEditor
41 #include <gtk/gtkcalendar.h>
43 #include <gdk/gdkkeysyms.h>
47 #include <hildon-widgets/hildon-calendar-popup.h>
48 #include <hildon-widgets/gtk-infoprint.h>
50 #define _(String) dgettext(PACKAGE, String)
52 #define HILDON_CALENDAR_POPUP_GET_PRIVATE(obj) \
53 (G_TYPE_INSTANCE_GET_PRIVATE\
54 ((obj), HILDON_CALENDAR_POPUP_TYPE, HildonCalendarPopupPrivate));
56 static GtkDialog *parent_class;
58 typedef struct _HildonCalendarPopupPrivate HildonCalendarPopupPrivate;
60 static void init_dmy(guint year, guint month, guint day, guint * d,
61 guint * m, guint * y);
64 hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class);
66 static void hildon_calendar_popup_init(HildonCalendarPopup * cal);
68 static gboolean hildon_calendar_day_selected(GtkWidget * widget,
71 static void hildon_calendar_allow_exit(GtkWidget * self, gpointer data);
73 static gboolean hildon_calendar_deny_exit(GtkWidget * self);
75 static gboolean hildon_key_pressed(GtkWidget * widget, GdkEventKey * event,
78 struct _HildonCalendarPopupPrivate {
83 GType hildon_calendar_popup_get_type(void)
85 static GType popup_type = 0;
88 static const GTypeInfo popup_info = {
89 sizeof(HildonCalendarPopupClass),
91 NULL, /* base_finalize */
92 (GClassInitFunc) hildon_calendar_popup_class_init,
93 NULL, /* class_finalize */
94 NULL, /* class_data */
95 sizeof(HildonCalendarPopup),
97 (GInstanceInitFunc) hildon_calendar_popup_init,
99 popup_type = g_type_register_static(GTK_TYPE_DIALOG,
100 "HildonCalendarPopup",
108 * hildon_calendar_popup_new:
109 * @parent: parent window for dialog
110 * @year: initial year
111 * @month: initial month
114 * This function returns a new HildonCalendarPopup. The initially
115 * selected date is specified by the parameters (year, month, day).
116 * If the specified date is invalid, the current date is used.
118 * Return value: Pointer to a new @HildonCalendarPopup widget.
120 GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
121 guint month, guint day)
123 HildonCalendarPopup *cal = NULL;
124 HildonCalendarPopupPrivate *priv;
125 guint dtmp, mtmp, ytmp;
127 init_dmy(year, month, day, &dtmp, &mtmp, &ytmp);
129 cal = HILDON_CALENDAR_POPUP(g_object_new(HILDON_CALENDAR_POPUP_TYPE,
131 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
134 gtk_window_set_transient_for(GTK_WINDOW(cal), parent);
137 /* Select day, month, year */
138 gtk_calendar_select_month(GTK_CALENDAR(priv->cal), mtmp - 1, ytmp);
139 gtk_calendar_select_day(GTK_CALENDAR(priv->cal), dtmp);
141 return GTK_WIDGET(cal);
145 * hildon_calendar_popup_set_date:
146 * @cal: the @HildonCalendarPopup widget
151 * This function activates a new date on the calendar popup.
156 hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
157 guint year, guint month, guint day)
159 HildonCalendarPopupPrivate *priv;
161 g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
163 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
164 gtk_calendar_clear_marks(GTK_CALENDAR(priv->cal));
166 gtk_calendar_select_month(GTK_CALENDAR(priv->cal), month - 1, year);
167 gtk_calendar_select_day(GTK_CALENDAR(priv->cal), day);
171 * hildon_calendar_popup_get_date:
172 * @cal: the @HildonCalendarPopup widget
177 * This function is used to get the currently selected year, month,
182 hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
183 guint * year, guint * month, guint * day)
185 HildonCalendarPopupPrivate *priv;
187 g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
189 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
190 gtk_calendar_get_date(GTK_CALENDAR(priv->cal), year, month, day);
193 if (!g_date_valid_dmy(*day, *month, *year)) {
194 *day = g_date_get_days_in_month(*month, *year);
199 hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class)
201 parent_class = g_type_class_peek_parent(cal_class);
202 g_type_class_add_private(cal_class,
203 sizeof(HildonCalendarPopupPrivate));
206 static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
208 HildonCalendarPopupPrivate *priv;
209 static int set_domain = 1;
212 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
215 (void) bindtextdomain(PACKAGE, LOCALEDIR);
219 priv->can_exit = FALSE;
220 priv->cal = gtk_calendar_new();
222 /* first day of the week is obtained from the PO file */
223 week_start = _("week_start");
224 if (week_start[0] >= '0' && week_start[0] <= '6' && week_start[1] == 0)
225 g_object_set(G_OBJECT(priv->cal),
226 "week-start", week_start[0] - '0', NULL);
228 gtk_calendar_set_display_options(GTK_CALENDAR(priv->cal),
229 GTK_CALENDAR_SHOW_HEADING |
230 GTK_CALENDAR_SHOW_DAY_NAMES |
231 GTK_CALENDAR_SHOW_WEEK_NUMBERS);
233 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cal)->vbox), priv->cal,
235 gtk_dialog_set_has_separator(GTK_DIALOG(cal), FALSE);
236 gtk_dialog_add_button(GTK_DIALOG(cal), _("Ecdg_bd_calendar_popout_done"),
238 gtk_widget_show(priv->cal);
240 /* Connect signals */
241 g_signal_connect(G_OBJECT(priv->cal), "day-selected",
242 G_CALLBACK(hildon_calendar_day_selected), cal);
244 g_signal_connect(G_OBJECT(priv->cal), "key-press-event",
245 G_CALLBACK(hildon_key_pressed), cal);
246 g_signal_connect_swapped(G_OBJECT(priv->cal), "button-release-event",
247 G_CALLBACK(hildon_calendar_deny_exit), cal);
248 g_signal_connect_swapped(G_OBJECT(priv->cal), "month-changed",
249 G_CALLBACK(hildon_calendar_deny_exit), cal);
250 g_signal_connect_swapped(G_OBJECT(priv->cal), "button-press-event",
251 G_CALLBACK(hildon_calendar_deny_exit), cal);
253 g_signal_connect(G_OBJECT(priv->cal), "selected_date",
254 G_CALLBACK(hildon_calendar_allow_exit), cal);
256 gtk_widget_realize(GTK_WIDGET(cal));
257 gdk_window_set_decorations(GTK_WIDGET(cal)->window, GDK_DECOR_BORDER);
258 gtk_widget_grab_focus(priv->cal);
262 hildon_calendar_day_selected(GtkWidget * widget, gpointer data)
264 HildonCalendarPopup *cal;
265 HildonCalendarPopupPrivate *priv;
267 cal = HILDON_CALENDAR_POPUP(data);
268 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
270 if (priv->can_exit) {
271 gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
278 hildon_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer data)
280 HildonCalendarPopup *cal;
281 HildonCalendarPopupPrivate *priv;
283 g_return_val_if_fail(data, FALSE);
285 cal = HILDON_CALENDAR_POPUP(data);
286 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
288 if (event->keyval == GDK_Return) {
289 priv->can_exit = TRUE;
290 gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_OK);
294 if ((event->keyval == GDK_Escape) || (event->keyval == GDK_F1) ||
295 (event->keyval == GDK_F2) || (event->keyval == GDK_F3) ||
296 (event->keyval == GDK_F4) || (event->keyval == GDK_F5) ||
297 (event->keyval == GDK_F6) || (event->keyval == GDK_F7) ||
298 (event->keyval == GDK_F8)) {
299 gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_CANCEL);
307 init_dmy(guint year, guint month, guint day, guint * d, guint * m,
316 } else if (year < 1980) {
320 } else if (!g_date_valid_dmy(day, month, year)) {
321 g_date_clear(&date, 1);
322 g_date_set_time(&date, time(NULL));
324 *d = g_date_get_day(&date);
325 *m = g_date_get_month(&date);
326 *y = g_date_get_year(&date);
335 hildon_calendar_allow_exit(GtkWidget * self, gpointer data)
337 HildonCalendarPopup *cal;
338 HildonCalendarPopupPrivate *priv;
340 g_return_if_fail (GTK_IS_WIDGET (self));
341 g_return_if_fail (HILDON_IS_CALENDAR_POPUP (data));
343 cal = HILDON_CALENDAR_POPUP(data);
344 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
346 gtk_dialog_response(GTK_DIALOG(cal), GTK_RESPONSE_OK);
349 static gboolean hildon_calendar_deny_exit(GtkWidget * self)
351 HildonCalendarPopup *cal;
352 HildonCalendarPopupPrivate *priv;
354 cal = HILDON_CALENDAR_POPUP(self);
355 priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
357 priv->can_exit = FALSE;