2 * This file is a part of hildon
4 * Copyright (C) 2005, 2008 Nokia Corporation.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * SECTION:hildon-time-selector
23 * @short_description: A widget to select the current time.
25 * HildonTimeSelector is a time widget, equivalent to hildon-calendar, but with a multi-column
31 #include "hildon-time-selector.h"
33 #define _GNU_SOURCE /* needed for GNU nl_langinfo_l */
34 #define __USE_GNU /* needed for locale */
36 #ifdef HAVE_SYS_TIME_H
47 #include <gconf/gconf-client.h>
49 #define HILDON_TIME_SELECTOR_GET_PRIVATE(obj) \
50 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TIME_SELECTOR, HildonTimeSelectorPrivate))
52 G_DEFINE_TYPE (HildonTimeSelector, hildon_time_selector, HILDON_TYPE_TOUCH_PICKER)
55 #define LAST_YEAR 50 /* since current year */
57 #define _(String) dgettext("hildon-libs", String)
59 /* #define _(String) "%I:%M %p" debug purposes */
62 /* FIXME: we should get this two props from the clock ui headers */
63 #define CLOCK_GCONF_PATH "/apps/clock"
64 #define CLOCK_GCONF_IS_24H_FORMAT CLOCK_GCONF_PATH "/time-format"
79 struct _HildonTimeSelectorPrivate
81 GtkTreeModel *hours_model;
82 GtkTreeModel *minutes_model;
83 GtkTreeModel *ampm_model;
85 gboolean ampm_format; /* if using am/pm format or 24 h one */
87 gboolean pm; /* if we are on pm (only useful if ampm_format == TRUE) */
90 gint creation_minutes;
93 static void hildon_time_selector_finalize (GObject * object);
95 /* private functions */
96 static GtkTreeModel *_create_hours_model (HildonTimeSelector * selector);
97 static GtkTreeModel *_create_minutes_model (HildonTimeSelector * selector);
98 static GtkTreeModel *_create_ampm_model (HildonTimeSelector * selector);
100 static void _get_real_time (gint * hours, gint * minutes);
101 static void _manage_ampm_selection_cb (HildonTouchPicker * selector,
102 gint num_column, gpointer data);
103 static void _check_ampm_format (HildonTimeSelector * selector);
104 static void _set_pm (HildonTimeSelector * selector, gboolean pm);
106 static gchar *_custom_print_func (HildonTouchPicker * selector);
109 hildon_time_selector_class_init (HildonTimeSelectorClass * class)
111 GObjectClass *gobject_class;
112 GtkObjectClass *object_class;
113 GtkWidgetClass *widget_class;
114 GtkContainerClass *container_class;
116 gobject_class = (GObjectClass *) class;
117 object_class = (GtkObjectClass *) class;
118 widget_class = (GtkWidgetClass *) class;
119 container_class = (GtkContainerClass *) class;
122 gobject_class->finalize = hildon_time_selector_finalize;
130 g_type_class_add_private (object_class, sizeof (HildonTimeSelectorPrivate));
135 hildon_time_selector_init (HildonTimeSelector * selector)
137 selector->priv = HILDON_TIME_SELECTOR_GET_PRIVATE (selector);
139 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
140 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
142 hildon_touch_picker_set_print_func (HILDON_TOUCH_PICKER (selector),
145 _get_real_time (&selector->priv->creation_hours,
146 &selector->priv->creation_minutes);
148 _check_ampm_format (selector);
150 selector->priv->hours_model = _create_hours_model (selector);
151 selector->priv->minutes_model = _create_minutes_model (selector);
153 hildon_touch_picker_append_text_column (HILDON_TOUCH_PICKER (selector),
154 selector->priv->hours_model);
156 hildon_touch_picker_append_text_column (HILDON_TOUCH_PICKER (selector),
157 selector->priv->minutes_model);
159 if (selector->priv->ampm_format) {
160 selector->priv->ampm_model = _create_ampm_model (selector);
162 hildon_touch_picker_append_text_column (HILDON_TOUCH_PICKER (selector),
163 selector->priv->ampm_model);
165 g_signal_connect (G_OBJECT (selector),
166 "changed", G_CALLBACK (_manage_ampm_selection_cb),
170 /* By default we should select the current day */
171 hildon_time_selector_set_time (selector,
172 selector->priv->creation_hours,
173 selector->priv->creation_minutes);
178 hildon_time_selector_finalize (GObject * object)
180 HildonTimeSelector *selector = NULL;
182 selector = HILDON_TIME_SELECTOR (object);
184 /* FIXME: FILL ME !! */
186 (*G_OBJECT_CLASS (hildon_time_selector_parent_class)->finalize) (object);
189 /* ------------------------------ PRIVATE METHODS ---------------------------- */
192 _custom_print_func (HildonTouchPicker * touch_picker)
194 gchar *result = NULL;
195 struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
196 HildonTimeSelector *selector = NULL;
197 static gchar string[255];
201 selector = HILDON_TIME_SELECTOR (touch_picker);
203 hildon_time_selector_get_time (selector, &hours, &minutes);
208 if (selector->priv->ampm_format) {
209 strftime (string, 255, _("wdgt_va_12h_hours"), &tm);
211 strftime (string, 255, _("wdgt_va_24h_hours"), &tm);
215 result = g_strdup (string);
220 static GtkTreeModel *
221 _create_minutes_model (HildonTimeSelector * selector)
223 GtkListStore *store_minutes = NULL;
228 store_minutes = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
229 for (i = 0; i <= 59; i++) {
230 label = g_strdup_printf ("%02d", i);
232 gtk_list_store_append (store_minutes, &iter);
233 gtk_list_store_set (store_minutes, &iter,
234 COLUMN_STRING, label, COLUMN_INT, i, -1);
238 return GTK_TREE_MODEL (store_minutes);
241 static GtkTreeModel *
242 _create_hours_model (HildonTimeSelector * selector)
244 GtkListStore *store_hours = NULL;
251 if (selector->priv->ampm_format) {
259 store_hours = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
260 for (i = 0; i < last_hour; i++) {
261 label = g_strdup_printf ("%02d", i + addition);
263 gtk_list_store_append (store_hours, &iter);
264 gtk_list_store_set (store_hours, &iter,
265 COLUMN_STRING, label, COLUMN_INT, i, -1);
269 return GTK_TREE_MODEL (store_hours);
272 static GtkTreeModel *
273 _create_ampm_model (HildonTimeSelector * selector)
275 GtkListStore *store_ampm = NULL;
278 store_ampm = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
280 gtk_list_store_append (store_ampm, &iter);
281 gtk_list_store_set (store_ampm, &iter, COLUMN_STRING, "am", /* FIXME: use nl_langinfo am/pm strings */
284 gtk_list_store_append (store_ampm, &iter);
285 gtk_list_store_set (store_ampm, &iter,
286 COLUMN_STRING, "pm", COLUMN_INT, 1, -1);
288 return GTK_TREE_MODEL (store_ampm);
292 _get_real_time (gint * hours, gint * minutes)
295 struct tm *tm = NULL;
298 tm = localtime (&secs);
301 *hours = tm->tm_hour;
304 if (minutes != NULL) {
305 *minutes = tm->tm_min;
310 _manage_ampm_selection_cb (HildonTouchPicker * touch_picker,
311 gint num_column, gpointer data)
313 HildonTimeSelector *selector = NULL;
317 g_return_if_fail (HILDON_IS_TIME_SELECTOR (touch_picker));
318 selector = HILDON_TIME_SELECTOR (touch_picker);
320 if (num_column == COLUMN_AMPM) {
321 hildon_touch_picker_get_active_iter (HILDON_TOUCH_PICKER (selector),
323 gtk_tree_model_get (selector->priv->ampm_model, &iter, COLUMN_INT, &pm, -1);
325 selector->priv->pm = pm;
330 _check_ampm_format (HildonTimeSelector * selector)
332 GConfClient *client = NULL;
333 gboolean value = FALSE;
334 GError *error = NULL;
336 client = gconf_client_get_default ();
337 value = gconf_client_get_bool (client, CLOCK_GCONF_IS_24H_FORMAT, &error);
340 ("Error trying to get gconf variable %s, using 24h format by default",
341 CLOCK_GCONF_IS_24H_FORMAT);
342 g_error_free (error);
345 selector->priv->ampm_format = value;
346 selector->priv->pm = TRUE;
350 _set_pm (HildonTimeSelector * selector, gboolean pm)
354 selector->priv->pm = pm;
356 gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
358 hildon_touch_picker_set_active_iter (HILDON_TOUCH_PICKER (selector),
359 COLUMN_AMPM, &iter, FALSE);
362 /* ------------------------------ PUBLIC METHODS ---------------------------- */
365 * hildon_time_selector_new:
368 * Creates a new #HildonTimeSelector
370 * Returns: a new #HildonTimeSelector
373 hildon_time_selector_new ()
375 return g_object_new (HILDON_TYPE_TIME_SELECTOR, NULL);
383 hildon_time_selector_set_time (HildonTimeSelector * selector,
384 guint hours, guint minutes)
389 g_return_val_if_fail (hours >= 0 && hours <= 23, FALSE);
390 g_return_val_if_fail (minutes >= 0 && minutes <= 59, FALSE);
392 if (selector->priv->ampm_format) {
394 hours_item = hours - 13;
396 hours_item = hours - 1;
399 _set_pm (selector, hours >= 12);
404 gtk_tree_model_iter_nth_child (selector->priv->hours_model, &iter, NULL,
406 hildon_touch_picker_set_active_iter (HILDON_TOUCH_PICKER (selector),
407 COLUMN_HOURS, &iter, FALSE);
409 gtk_tree_model_iter_nth_child (selector->priv->minutes_model, &iter, NULL,
411 hildon_touch_picker_set_active_iter (HILDON_TOUCH_PICKER (selector),
412 COLUMN_MINUTES, &iter, FALSE);
418 hildon_time_selector_get_time (HildonTimeSelector * selector,
419 guint * hours, guint * minutes)
424 hildon_touch_picker_get_active_iter (HILDON_TOUCH_PICKER (selector),
425 COLUMN_HOURS, &iter);
426 gtk_tree_model_get (selector->priv->hours_model,
427 &iter, COLUMN_INT, hours, -1);
428 if (selector->priv->ampm_format) {
429 *hours += selector->priv->pm * 12;
433 if (minutes != NULL) {
434 hildon_touch_picker_get_active_iter (HILDON_TOUCH_PICKER (selector),
435 COLUMN_MINUTES, &iter);
436 gtk_tree_model_get (selector->priv->minutes_model,
437 &iter, COLUMN_INT, minutes, -1);