Remove unnecessary function call redundant checks in HildonTimeSelector
[hildon] / hildon / hildon-time-selector.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2008 Nokia Corporation.
5  *
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.
10  *
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.
15  *
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.
19  */
20
21 /**
22  * SECTION:hildon-time-selector
23  * @short_description: A widget to select the current time.
24  *
25  * #HildonTimeSelector allows users to choose a time by selecting hour
26  * and minute. It also allows choosing between AM or PM format.
27  *
28  * The currently selected time can be altered with
29  * hildon_time_selector_set_time(), and retrieved using
30  * hildon_time_selector_get_time().
31  *
32  * Use this widget instead of deprecated HildonTimeEditor widget.
33  */
34
35 #define _GNU_SOURCE     /* needed for GNU nl_langinfo_l */
36 #define __USE_GNU       /* needed for locale */
37
38 #ifdef HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41
42 #include <string.h>
43 #include <stdlib.h>
44 #include <libintl.h>
45 #include <time.h>
46 #include <langinfo.h>
47 #include <locale.h>
48 #include <gconf/gconf-client.h>
49
50 #include "hildon-enum-types.h"
51 #include "hildon-time-selector.h"
52 #include "hildon-touch-selector-private.h"
53
54 #define HILDON_TIME_SELECTOR_GET_PRIVATE(obj)                           \
55   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_TIME_SELECTOR, HildonTimeSelectorPrivate))
56
57 G_DEFINE_TYPE (HildonTimeSelector, hildon_time_selector, HILDON_TYPE_TOUCH_SELECTOR)
58
59 #define INIT_YEAR 100
60 #define LAST_YEAR 50    /* since current year */
61
62 #define _(String)  dgettext("hildon-libs", String)
63 #define N_(String) String
64
65
66 /* FIXME: we should get this two props from the clock ui headers */
67 #define CLOCK_GCONF_PATH "/apps/clock"
68 #define CLOCK_GCONF_IS_24H_FORMAT CLOCK_GCONF_PATH  "/time-format"
69
70 enum {
71   COLUMN_STRING,
72   COLUMN_INT,
73   TOTAL_MODEL_COLUMNS
74 };
75
76 enum {
77   COLUMN_HOURS = 0,
78   COLUMN_MINUTES,
79   COLUMN_AMPM,
80   TOTAL_TIME_COLUMNS
81 };
82
83 enum
84 {
85   PROP_0,
86   PROP_MINUTES_STEP,
87   PROP_TIME_FORMAT_POLICY
88 };
89
90 struct _HildonTimeSelectorPrivate
91 {
92   GtkTreeModel *hours_model;
93   GtkTreeModel *minutes_model;
94   GtkTreeModel *ampm_model;
95
96   guint minutes_step;
97   HildonTimeSelectorFormatPolicy format_policy;
98   gboolean ampm_format;         /* if using am/pm format or 24 h one */
99
100   gboolean pm;                  /* if we are on pm (only useful if ampm_format == TRUE) */
101
102   gint creation_hours;
103   gint creation_minutes;
104 };
105
106 static void hildon_time_selector_finalize (GObject * object);
107 static GObject* hildon_time_selector_constructor (GType type,
108                                                   guint n_construct_properties,
109                                                   GObjectConstructParam *construct_params);
110 static void hildon_time_selector_get_property (GObject *object,
111                                                guint param_id,
112                                                GValue *value,
113                                                GParamSpec *pspec);
114 static void hildon_time_selector_set_property (GObject *object,
115                                                guint param_id,
116                                                const GValue *value,
117                                                GParamSpec *pspec);
118
119 /* private functions */
120 static GtkTreeModel *_create_hours_model (HildonTimeSelector * selector);
121 static GtkTreeModel *_create_minutes_model (guint minutes_step);
122 static GtkTreeModel *_create_ampm_model (HildonTimeSelector * selector);
123
124 static void _get_real_time (gint * hours, gint * minutes);
125 static void _manage_ampm_selection_cb (HildonTouchSelector * selector,
126                                        gint num_column, gpointer data);
127 static void _set_pm (HildonTimeSelector * selector, gboolean pm);
128
129 static gchar *_custom_print_func (HildonTouchSelector * selector,
130                                   gpointer user_data);
131
132 static void
133 check_automatic_ampm_format                     (HildonTimeSelector * selector);
134
135 static void
136 update_format_policy                            (HildonTimeSelector *selector,
137                                                  HildonTimeSelectorFormatPolicy new_policy);
138 static void
139 update_format_dependant_columns                 (HildonTimeSelector *selector,
140                                                  guint hours,
141                                                  guint minutes);
142
143 static void
144 hildon_time_selector_class_init (HildonTimeSelectorClass * class)
145 {
146   GObjectClass *gobject_class;
147   GtkObjectClass *object_class;
148   GtkWidgetClass *widget_class;
149   GtkContainerClass *container_class;
150
151   gobject_class = (GObjectClass *) class;
152   object_class = (GtkObjectClass *) class;
153   widget_class = (GtkWidgetClass *) class;
154   container_class = (GtkContainerClass *) class;
155
156   /* GObject */
157   gobject_class->get_property = hildon_time_selector_get_property;
158   gobject_class->set_property = hildon_time_selector_set_property;
159   gobject_class->constructor = hildon_time_selector_constructor;
160   gobject_class->finalize = hildon_time_selector_finalize;
161
162   g_object_class_install_property (gobject_class,
163                                    PROP_MINUTES_STEP,
164                                    g_param_spec_uint ("minutes-step",
165                                                       "Step between minutes in the model",
166                                                       "Step between the minutes in the list of"
167                                                       " options of the widget ",
168                                                       1, 30, 1,
169                                                       G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
170
171   /**
172    * HildonTimeSelector:time-format-policy:
173    *
174    * The visual policy of the time format
175    *
176    * Since: 2.2
177    */
178   g_object_class_install_property (gobject_class,
179                                    PROP_TIME_FORMAT_POLICY,
180                                    g_param_spec_enum ("time_format_policy",
181                                                       "time format policy",
182                                                       "Visual policy of the time format",
183                                                       HILDON_TYPE_TIME_SELECTOR_FORMAT_POLICY,
184                                                       HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC,
185                                                       G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
186
187   /* GtkWidget */
188
189   /* GtkContainer */
190
191   /* signals */
192
193   g_type_class_add_private (object_class, sizeof (HildonTimeSelectorPrivate));
194 }
195
196 /* FIXME: the constructor was required because as we need the initial values
197    of the properties passed on g_object_new. But, probably use the method
198    constructed could be easier */
199 static GObject*
200 hildon_time_selector_constructor (GType type,
201                                   guint n_construct_properties,
202                                   GObjectConstructParam *construct_params)
203 {
204   GObject *object;
205   HildonTimeSelector *selector;
206   HildonTouchSelectorColumn *column;
207
208   object = (* G_OBJECT_CLASS (hildon_time_selector_parent_class)->constructor)
209     (type, n_construct_properties, construct_params);
210
211   selector = HILDON_TIME_SELECTOR (object);
212
213   selector->priv->hours_model = _create_hours_model (selector);
214
215   column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
216                                                      selector->priv->hours_model, TRUE);
217   hildon_touch_selector_column_set_text_column (column, 0);
218
219   /* we need initialization parameters in order to create minute models*/
220   selector->priv->minutes_step = selector->priv->minutes_step ? selector->priv->minutes_step : 1;
221
222   selector->priv->minutes_model = _create_minutes_model (selector->priv->minutes_step);
223
224   column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
225                                                      selector->priv->minutes_model, TRUE);
226   hildon_touch_selector_column_set_text_column (column, 0);
227
228   if (selector->priv->ampm_format) {
229     selector->priv->ampm_model = _create_ampm_model (selector);
230
231     hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
232                                               selector->priv->ampm_model, TRUE);
233
234     g_signal_connect (G_OBJECT (selector),
235                       "changed", G_CALLBACK (_manage_ampm_selection_cb),
236                       NULL);
237   }
238
239
240   /* By default we should select the current day */
241   hildon_time_selector_set_time (selector,
242                                  selector->priv->creation_hours,
243                                  selector->priv->creation_minutes);
244
245   return object;
246
247 }
248
249 static void
250 hildon_time_selector_init (HildonTimeSelector * selector)
251 {
252   selector->priv = HILDON_TIME_SELECTOR_GET_PRIVATE (selector);
253
254   GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
255   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
256
257   hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (selector),
258                                         _custom_print_func);
259
260   /* By default we use the automatic ampm format */
261   selector->priv->pm = TRUE;
262   check_automatic_ampm_format (selector);
263
264   _get_real_time (&selector->priv->creation_hours,
265                   &selector->priv->creation_minutes);
266 }
267
268 static void
269 hildon_time_selector_get_property (GObject *object,
270                                    guint param_id,
271                                    GValue *value,
272                                    GParamSpec *pspec)
273 {
274   HildonTimeSelectorPrivate *priv = HILDON_TIME_SELECTOR_GET_PRIVATE (object);
275
276   switch (param_id)
277     {
278     case PROP_MINUTES_STEP:
279       g_value_set_uint (value, priv->minutes_step);
280       break;
281     case PROP_TIME_FORMAT_POLICY:
282       g_value_set_enum (value, priv->format_policy);
283       break;
284     default:
285       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
286       break;
287     }
288 }
289
290 static void
291 hildon_time_selector_set_property (GObject *object,
292                                    guint param_id,
293                                    const GValue *value,
294                                    GParamSpec *pspec)
295 {
296   HildonTimeSelectorPrivate *priv = HILDON_TIME_SELECTOR_GET_PRIVATE (object);
297
298   switch (param_id)
299     {
300     case PROP_MINUTES_STEP:
301       priv->minutes_step = g_value_get_uint (value);
302       break;
303     case PROP_TIME_FORMAT_POLICY:
304       update_format_policy (HILDON_TIME_SELECTOR (object),
305                             g_value_get_enum (value));
306       break;
307     default:
308       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
309       break;
310     }
311 }
312
313 static void
314 hildon_time_selector_finalize (GObject * object)
315 {
316   /* Note: we don't require to free the models. We don't manage it using own
317      references, so will be freed on the hildon-touch-selector finalize code.
318      See the implementation notes related to that on the touch selector
319      code. */
320
321   (*G_OBJECT_CLASS (hildon_time_selector_parent_class)->finalize) (object);
322 }
323
324 /* ------------------------------ PRIVATE METHODS ---------------------------- */
325
326 static gchar *
327 _custom_print_func (HildonTouchSelector * touch_selector,
328                     gpointer user_data)
329 {
330   gchar *result = NULL;
331   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
332   HildonTimeSelector *selector = NULL;
333   static gchar string[255];
334   guint hours = 0;
335   guint minutes = 0;
336
337   selector = HILDON_TIME_SELECTOR (touch_selector);
338
339   hildon_time_selector_get_time (selector, &hours, &minutes);
340
341   tm.tm_min = minutes;
342   tm.tm_hour = hours;
343
344   if (selector->priv->ampm_format) {
345     if (selector->priv->pm) {
346       strftime (string, 255, _("wdgt_va_12h_time_pm"), &tm);
347     } else {
348       strftime (string, 255, _("wdgt_va_12h_time_am"), &tm);
349     }
350   } else {
351     strftime (string, 255, _("wdgt_va_24h_time"), &tm);
352   }
353
354
355   result = g_strdup (string);
356
357   return result;
358 }
359
360 static GtkTreeModel *
361 _create_minutes_model (guint minutes_step)
362 {
363   GtkListStore *store_minutes = NULL;
364   gint i = 0;
365   static gchar label[255];
366   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
367   GtkTreeIter iter;
368
369   store_minutes = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
370   for (i = 0; i <= 59; i=i+minutes_step) {
371     tm.tm_min = i;
372     strftime (label, 255, _("wdgt_va_minutes"), &tm);
373
374     gtk_list_store_append (store_minutes, &iter);
375     gtk_list_store_set (store_minutes, &iter,
376                         COLUMN_STRING, label, COLUMN_INT, i, -1);
377   }
378
379   return GTK_TREE_MODEL (store_minutes);
380 }
381
382 static GtkTreeModel *
383 _create_hours_model (HildonTimeSelector * selector)
384 {
385   GtkListStore *store_hours = NULL;
386   gint i = 0;
387   GtkTreeIter iter;
388   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
389   static gchar label[255];
390   static gint range_12h[12] = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11};
391   static gint range_24h[24] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
392                                12,13,14,15,16,17,18,19,20,21,22,23};
393   gint *range = NULL;
394   gint num_elements = 0;
395   gchar *format_string = NULL;
396
397   if (selector->priv->ampm_format) {
398     range = range_12h;
399     num_elements = 12;
400     format_string = N_("wdgt_va_12h_hours");
401   } else {
402     range = range_24h;
403     num_elements = 24;
404     format_string = N_("wdgt_va_24h_hours");
405   }
406
407   store_hours = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
408   for (i = 0; i < num_elements; i++) {
409     tm.tm_hour = range[i];
410     strftime (label, 255, _(format_string), &tm);
411
412     gtk_list_store_append (store_hours, &iter);
413     gtk_list_store_set (store_hours, &iter,
414                         COLUMN_STRING, label, COLUMN_INT, range[i], -1);
415   }
416
417   return GTK_TREE_MODEL (store_hours);
418 }
419
420 static GtkTreeModel *
421 _create_ampm_model (HildonTimeSelector * selector)
422 {
423   GtkListStore *store_ampm = NULL;
424   GtkTreeIter iter;
425   static gchar label[255];
426
427   store_ampm = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
428
429   snprintf (label, 255, _("wdgt_va_am"));
430   gtk_list_store_append (store_ampm, &iter);
431   gtk_list_store_set (store_ampm, &iter,
432                       COLUMN_STRING, label,
433                       COLUMN_INT, 0, -1);
434
435   snprintf (label, 255, _("wdgt_va_pm"));
436   gtk_list_store_append (store_ampm, &iter);
437   gtk_list_store_set (store_ampm, &iter,
438                       COLUMN_STRING, label,
439                       COLUMN_INT, 1, -1);
440
441   return GTK_TREE_MODEL (store_ampm);
442 }
443
444 static void
445 _get_real_time (gint * hours, gint * minutes)
446 {
447   time_t secs;
448   struct tm *tm = NULL;
449
450   secs = time (NULL);
451   tm = localtime (&secs);
452
453   if (hours != NULL) {
454     *hours = tm->tm_hour;
455   }
456
457   if (minutes != NULL) {
458     *minutes = tm->tm_min;
459   }
460 }
461
462 static void
463 _manage_ampm_selection_cb (HildonTouchSelector * touch_selector,
464                            gint num_column, gpointer data)
465 {
466   HildonTimeSelector *selector = NULL;
467   gint pm;
468   GtkTreeIter iter;
469
470   g_return_if_fail (HILDON_IS_TIME_SELECTOR (touch_selector));
471   selector = HILDON_TIME_SELECTOR (touch_selector);
472
473   if (num_column == COLUMN_AMPM &&
474       hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
475                                           COLUMN_AMPM, &iter)) {
476      gtk_tree_model_get (selector->priv->ampm_model, &iter, COLUMN_INT, &pm, -1);
477
478     selector->priv->pm = pm;
479   }
480 }
481
482 static void
483 check_automatic_ampm_format (HildonTimeSelector * selector)
484 {
485   GConfClient *client = NULL;
486   gboolean value = TRUE;
487   GError *error = NULL;
488
489   client = gconf_client_get_default ();
490   value = gconf_client_get_bool (client, CLOCK_GCONF_IS_24H_FORMAT, &error);
491   if (error != NULL) {
492     g_warning
493       ("Error trying to get gconf variable %s, using 24h format by default",
494        CLOCK_GCONF_IS_24H_FORMAT);
495     g_error_free (error);
496   }
497
498   selector->priv->ampm_format = !value;
499 }
500
501 static void
502 _set_pm (HildonTimeSelector * selector, gboolean pm)
503 {
504   GtkTreeIter iter;
505
506   selector->priv->pm = pm;
507
508   if (selector->priv->ampm_model != NULL) {
509     gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
510
511     hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
512                                        COLUMN_AMPM, &iter, FALSE);
513   }
514 }
515
516 static void
517 update_format_policy                            (HildonTimeSelector *selector,
518                                                  HildonTimeSelectorFormatPolicy new_policy)
519 {
520   gboolean prev_ampm_format = FALSE;
521   gint num_columns = -1;
522
523   num_columns = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (selector));
524   prev_ampm_format = selector->priv->ampm_format;
525
526   if (new_policy != selector->priv->format_policy) {
527     guint hours;
528     guint minutes;
529
530     selector->priv->format_policy = new_policy;
531
532     /* We get the hour previous all the changes, to avoid problems with the
533        changing widget structure */
534     if (num_columns >= 2) {/* we are on the object construction */
535       hildon_time_selector_get_time (selector, &hours, &minutes);
536     }
537
538     switch (new_policy)
539       {
540       case HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM:
541         selector->priv->ampm_format = TRUE;
542         break;
543       case HILDON_TIME_SELECTOR_FORMAT_POLICY_24H:
544         selector->priv->ampm_format = FALSE;
545         break;
546       case HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC:
547         check_automatic_ampm_format (selector);
548         break;
549       }
550
551     if (prev_ampm_format != selector->priv->ampm_format && num_columns >= 2) {
552       update_format_dependant_columns (selector, hours, minutes);
553     }
554   }
555 }
556
557 static void
558 update_format_dependant_columns                 (HildonTimeSelector *selector,
559                                                  guint hours,
560                                                  guint minutes)
561 {
562   /* To avoid an extra and wrong VALUE_CHANGED signal on the model update */
563   hildon_touch_selector_block_changed (HILDON_TOUCH_SELECTOR(selector));
564
565   selector->priv->hours_model = _create_hours_model (selector);
566   hildon_touch_selector_set_model (HILDON_TOUCH_SELECTOR (selector),
567                                    0,
568                                    selector->priv->hours_model);
569
570   /* We need to set NOW the correct hour on the hours column, because the number of
571      columns will be updated too, so a signal COLUMNS_CHANGED will be emitted. Some
572      other widget could have connected to this signal and ask for the hour, so this
573      emission could have a wrong hour. We could use a custom func to only modify the
574      hours selection, but hildon_time_selector_time manage yet all the ampm issues
575      to select the correct one */
576   hildon_time_selector_set_time (selector, hours, minutes);
577
578   /* if we are at this function, we are sure that a change on the number of columns
579      will happen, so check the column number is not required */
580   if (selector->priv->ampm_format) {
581     selector->priv->ampm_model = _create_ampm_model (selector);
582
583     hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
584                                               selector->priv->ampm_model, TRUE);
585
586     g_signal_connect (G_OBJECT (selector),
587                       "changed", G_CALLBACK (_manage_ampm_selection_cb),
588                       NULL);
589   } else {
590     selector->priv->ampm_model = NULL;
591     hildon_touch_selector_remove_column (HILDON_TOUCH_SELECTOR (selector), 2);
592   }
593
594   _set_pm (selector, hours >= 12);
595
596   hildon_touch_selector_unblock_changed (HILDON_TOUCH_SELECTOR (selector));
597 }
598 /* ------------------------------ PUBLIC METHODS ---------------------------- */
599
600 /**
601  * hildon_time_selector_new:
602  *
603  * Creates a new #HildonTimeSelector
604  *
605  * Returns: a new #HildonTimeSelector
606  *
607  * Since: 2.2
608  **/
609 GtkWidget *
610 hildon_time_selector_new ()
611 {
612   return g_object_new (HILDON_TYPE_TIME_SELECTOR, NULL);
613 }
614
615
616 /**
617  * hildon_time_selector_new_step:
618  * @minutes_step: step between the minutes in the selector.
619
620  * Creates a new #HildonTimeSelector, with @minutes_step steps between
621  * the minutes in the minutes column.
622  *
623  * Returns: a new #HildonTimeSelector
624  *
625  * Since: 2.2
626  **/
627 GtkWidget *
628 hildon_time_selector_new_step (guint minutes_step)
629 {
630   return g_object_new (HILDON_TYPE_TIME_SELECTOR, "minutes-step",
631                        minutes_step, NULL);
632 }
633
634 /**
635  * hildon_time_selector_set_time
636  * @selector: the #HildonTimeSelector
637  * @hours:  the current hour (0-23)
638  * @minutes: the current minute (0-59)
639  *
640  * Sets the current active hour on the #HildonTimeSelector widget
641  *
642  * The format of the hours accepted is always 24h format, with a range
643  * (0-23):(0-59).
644  *
645  * Since: 2.2
646  *
647  * Returns: %TRUE on success, %FALSE otherwise
648  **/
649 gboolean
650 hildon_time_selector_set_time (HildonTimeSelector * selector,
651                                guint hours, guint minutes)
652 {
653   GtkTreeIter iter;
654   gint hours_item = 0;
655
656   g_return_val_if_fail (HILDON_IS_TIME_SELECTOR (selector), FALSE);
657   g_return_val_if_fail (hours <= 23, FALSE);
658   g_return_val_if_fail (minutes <= 59, FALSE);
659
660   _set_pm (selector, hours >= 12);
661
662   if (selector->priv->ampm_format) {
663     hours_item = hours - selector->priv->pm * 12;
664   } else {
665     hours_item = hours;
666   }
667
668   gtk_tree_model_iter_nth_child (selector->priv->hours_model, &iter, NULL,
669                                  hours_item);
670   hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
671                                      COLUMN_HOURS, &iter, FALSE);
672
673   g_assert (selector->priv->minutes_step>0);
674   minutes = minutes/selector->priv->minutes_step;
675   gtk_tree_model_iter_nth_child (selector->priv->minutes_model, &iter, NULL,
676                                  minutes);
677   hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
678                                      COLUMN_MINUTES, &iter, FALSE);
679
680   return TRUE;
681 }
682
683 /**
684  * hildon_time_selector_get_time
685  * @selector: the #HildonTimeSelector
686  * @hours:  to set the current hour (0-23)
687  * @minutes: to set the current minute (0-59)
688  *
689  * Gets the current active hour on the #HildonTimeSelector widget. Both @year
690  * and @minutes can be NULL.
691  *
692  * This method returns the date always in 24h format, with a range (0-23):(0-59)
693  *
694  * Since: 2.2
695  **/
696 void
697 hildon_time_selector_get_time (HildonTimeSelector * selector,
698                                guint * hours, guint * minutes)
699 {
700   GtkTreeIter iter;
701
702   g_return_if_fail (HILDON_IS_TIME_SELECTOR (selector));
703
704   if (hours != NULL) {
705     if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
706                                             COLUMN_HOURS, &iter)) {
707
708       gtk_tree_model_get (selector->priv->hours_model,
709                           &iter, COLUMN_INT, hours, -1);
710     }
711     if (selector->priv->ampm_format) {
712       *hours %= 12;
713       *hours += selector->priv->pm * 12;
714     }
715   }
716
717   if (minutes != NULL) {
718     if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
719                                             COLUMN_MINUTES, &iter)) {
720       gtk_tree_model_get (selector->priv->minutes_model,
721                           &iter, COLUMN_INT, minutes, -1);
722     }
723   }
724 }