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
30 #define _GNU_SOURCE /* needed for GNU nl_langinfo_l */
31 #define __USE_GNU /* needed for locale */
33 #ifdef HAVE_SYS_TIME_H
43 #include <gconf/gconf-client.h>
45 #include "hildon-time-selector.h"
47 #define HILDON_TIME_SELECTOR_GET_PRIVATE(obj) \
48 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TIME_SELECTOR, HildonTimeSelectorPrivate))
50 G_DEFINE_TYPE (HildonTimeSelector, hildon_time_selector, HILDON_TYPE_TOUCH_SELECTOR)
53 #define LAST_YEAR 50 /* since current year */
55 #define _(String) dgettext("hildon-libs", String)
56 #define N_(String) String
59 /* FIXME: we should get this two props from the clock ui headers */
60 #define CLOCK_GCONF_PATH "/apps/clock"
61 #define CLOCK_GCONF_IS_24H_FORMAT CLOCK_GCONF_PATH "/time-format"
76 struct _HildonTimeSelectorPrivate
78 GtkTreeModel *hours_model;
79 GtkTreeModel *minutes_model;
80 GtkTreeModel *ampm_model;
82 gboolean ampm_format; /* if using am/pm format or 24 h one */
84 gboolean pm; /* if we are on pm (only useful if ampm_format == TRUE) */
87 gint creation_minutes;
90 static void hildon_time_selector_finalize (GObject * object);
92 /* private functions */
93 static GtkTreeModel *_create_hours_model (HildonTimeSelector * selector);
94 static GtkTreeModel *_create_minutes_model (HildonTimeSelector * selector);
95 static GtkTreeModel *_create_ampm_model (HildonTimeSelector * selector);
97 static void _get_real_time (gint * hours, gint * minutes);
98 static void _manage_ampm_selection_cb (HildonTouchSelector * selector,
99 gint num_column, gpointer data);
100 static void _check_ampm_format (HildonTimeSelector * selector);
101 static void _set_pm (HildonTimeSelector * selector, gboolean pm);
103 static gchar *_custom_print_func (HildonTouchSelector * selector);
106 hildon_time_selector_class_init (HildonTimeSelectorClass * class)
108 GObjectClass *gobject_class;
109 GtkObjectClass *object_class;
110 GtkWidgetClass *widget_class;
111 GtkContainerClass *container_class;
113 gobject_class = (GObjectClass *) class;
114 object_class = (GtkObjectClass *) class;
115 widget_class = (GtkWidgetClass *) class;
116 container_class = (GtkContainerClass *) class;
119 gobject_class->finalize = hildon_time_selector_finalize;
127 g_type_class_add_private (object_class, sizeof (HildonTimeSelectorPrivate));
132 hildon_time_selector_init (HildonTimeSelector * selector)
134 HildonTouchSelectorColumn *column = NULL;
136 selector->priv = HILDON_TIME_SELECTOR_GET_PRIVATE (selector);
138 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
139 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
141 hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (selector),
144 _get_real_time (&selector->priv->creation_hours,
145 &selector->priv->creation_minutes);
147 _check_ampm_format (selector);
149 selector->priv->hours_model = _create_hours_model (selector);
150 selector->priv->minutes_model = _create_minutes_model (selector);
152 column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
153 selector->priv->hours_model, TRUE);
154 g_object_set (column, "text-column", 0, NULL);
156 column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
157 selector->priv->minutes_model, TRUE);
158 g_object_set (column, "text-column", 0, NULL);
160 if (selector->priv->ampm_format) {
161 selector->priv->ampm_model = _create_ampm_model (selector);
163 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
164 selector->priv->ampm_model, TRUE);
166 g_signal_connect (G_OBJECT (selector),
167 "changed", G_CALLBACK (_manage_ampm_selection_cb),
171 /* By default we should select the current day */
172 hildon_time_selector_set_time (selector,
173 selector->priv->creation_hours,
174 selector->priv->creation_minutes);
179 hildon_time_selector_finalize (GObject * object)
181 HildonTimeSelector *selector = NULL;
183 selector = HILDON_TIME_SELECTOR (object);
185 /* FIXME: FILL ME !! */
187 (*G_OBJECT_CLASS (hildon_time_selector_parent_class)->finalize) (object);
190 /* ------------------------------ PRIVATE METHODS ---------------------------- */
193 _custom_print_func (HildonTouchSelector * touch_selector)
195 gchar *result = NULL;
196 struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
197 HildonTimeSelector *selector = NULL;
198 static gchar string[255];
202 selector = HILDON_TIME_SELECTOR (touch_selector);
204 hildon_time_selector_get_time (selector, &hours, &minutes);
209 if (selector->priv->ampm_format) {
210 strftime (string, 255, _("wdgt_va_12h_time"), &tm);
212 strftime (string, 255, _("wdgt_va_24h_time"), &tm);
216 result = g_strdup (string);
221 static GtkTreeModel *
222 _create_minutes_model (HildonTimeSelector * selector)
224 GtkListStore *store_minutes = NULL;
226 static gchar label[255];
227 struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
230 store_minutes = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
231 for (i = 0; i <= 59; i++) {
233 strftime (label, 255, _("wdgt_va_minutes"), &tm);
235 gtk_list_store_append (store_minutes, &iter);
236 gtk_list_store_set (store_minutes, &iter,
237 COLUMN_STRING, label, COLUMN_INT, i, -1);
240 return GTK_TREE_MODEL (store_minutes);
243 static GtkTreeModel *
244 _create_hours_model (HildonTimeSelector * selector)
246 GtkListStore *store_hours = NULL;
249 struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
250 static gchar label[255];
251 static gint range_12h[12] = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11};
252 static gint range_24h[24] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
253 12,13,14,15,16,17,18,19,20,21,22,23};
255 gint num_elements = 0;
256 gchar *format_string = NULL;
258 if (selector->priv->ampm_format) {
261 format_string = N_("wdgt_va_12h_hours");
265 format_string = N_("wdgt_va_24h_hours");
268 store_hours = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
269 for (i = 0; i < num_elements; i++) {
270 tm.tm_hour = range[i];
271 strftime (label, 255, _(format_string), &tm);
273 gtk_list_store_append (store_hours, &iter);
274 gtk_list_store_set (store_hours, &iter,
275 COLUMN_STRING, label, COLUMN_INT, range[i], -1);
278 return GTK_TREE_MODEL (store_hours);
281 static GtkTreeModel *
282 _create_ampm_model (HildonTimeSelector * selector)
284 GtkListStore *store_ampm = NULL;
286 static gchar label[255];
287 struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
289 store_ampm = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
292 strftime (label, 255, _("wdgt_va_am_pm"), &tm);
294 gtk_list_store_append (store_ampm, &iter);
295 gtk_list_store_set (store_ampm, &iter,
296 COLUMN_STRING, label,
300 strftime (label, 255, _("wdgt_va_am_pm"), &tm);
302 gtk_list_store_append (store_ampm, &iter);
303 gtk_list_store_set (store_ampm, &iter,
304 COLUMN_STRING, label,
307 return GTK_TREE_MODEL (store_ampm);
311 _get_real_time (gint * hours, gint * minutes)
314 struct tm *tm = NULL;
317 tm = localtime (&secs);
320 *hours = tm->tm_hour;
323 if (minutes != NULL) {
324 *minutes = tm->tm_min;
329 _manage_ampm_selection_cb (HildonTouchSelector * touch_selector,
330 gint num_column, gpointer data)
332 HildonTimeSelector *selector = NULL;
336 g_return_if_fail (HILDON_IS_TIME_SELECTOR (touch_selector));
337 selector = HILDON_TIME_SELECTOR (touch_selector);
339 if (num_column == COLUMN_AMPM) {
340 hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
342 gtk_tree_model_get (selector->priv->ampm_model, &iter, COLUMN_INT, &pm, -1);
344 selector->priv->pm = pm;
349 _check_ampm_format (HildonTimeSelector * selector)
351 GConfClient *client = NULL;
352 gboolean value = FALSE;
353 GError *error = NULL;
355 client = gconf_client_get_default ();
356 value = gconf_client_get_bool (client, CLOCK_GCONF_IS_24H_FORMAT, &error);
359 ("Error trying to get gconf variable %s, using 24h format by default",
360 CLOCK_GCONF_IS_24H_FORMAT);
361 g_error_free (error);
364 selector->priv->ampm_format = value;
365 selector->priv->pm = TRUE;
369 _set_pm (HildonTimeSelector * selector, gboolean pm)
373 selector->priv->pm = pm;
375 gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
377 hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
378 COLUMN_AMPM, &iter, FALSE);
381 /* ------------------------------ PUBLIC METHODS ---------------------------- */
384 * hildon_time_selector_new:
386 * Creates a new #HildonTimeSelector
388 * Returns: a new #HildonTimeSelector
391 hildon_time_selector_new ()
393 return g_object_new (HILDON_TYPE_TIME_SELECTOR, NULL);
397 * hildon_time_selector_set_time
398 * @selector: the #HildonTimeSelector
399 * @year: the current hour (0-23)
400 * @minutes: the current minute (0-59)
402 * Sets the current active hour on the #HildonTimeSelector widget
404 * The format of the hours acceptes is always 24h format, with a range
409 hildon_time_selector_set_time (HildonTimeSelector * selector,
410 guint hours, guint minutes)
415 g_return_val_if_fail (hours >= 0 && hours <= 23, FALSE);
416 g_return_val_if_fail (minutes >= 0 && minutes <= 59, FALSE);
418 if (selector->priv->ampm_format) {
419 _set_pm (selector, hours >= 12);
421 hours_item = hours - selector->priv->pm * 12;
426 gtk_tree_model_iter_nth_child (selector->priv->hours_model, &iter, NULL,
428 hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
429 COLUMN_HOURS, &iter, FALSE);
431 gtk_tree_model_iter_nth_child (selector->priv->minutes_model, &iter, NULL,
433 hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
434 COLUMN_MINUTES, &iter, FALSE);
440 * hildon_time_selector_get_time
441 * @selector: the #HildonTimeSelector
442 * @year: to set the current hour (0-23)
443 * @minutes: to set the current minute (0-59)
445 * Gets the current active hour on the #HildonTimeSelector widget. Both @year
446 * and @minutes can be NULL.
448 * This method returns the date always in 24h format, with a range (0-23):(0-59)
452 hildon_time_selector_get_time (HildonTimeSelector * selector,
453 guint * hours, guint * minutes)
458 hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
459 COLUMN_HOURS, &iter);
460 gtk_tree_model_get (selector->priv->hours_model,
461 &iter, COLUMN_INT, hours, -1);
462 if (selector->priv->ampm_format) {
464 *hours += selector->priv->pm * 12;
468 if (minutes != NULL) {
469 hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
470 COLUMN_MINUTES, &iter);
471 gtk_tree_model_get (selector->priv->minutes_model,
472 &iter, COLUMN_INT, minutes, -1);