Correct errors in hildon_format_file-size_for_display
[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   g_object_set (column, "text-column", 0, NULL);
218
219
220   /* we need initialization parameters in order to create minute models*/
221   selector->priv->minutes_step = selector->priv->minutes_step ? selector->priv->minutes_step : 1;
222
223   selector->priv->minutes_model = _create_minutes_model (selector->priv->minutes_step);
224
225   column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
226                                                      selector->priv->minutes_model, TRUE);
227   g_object_set (column, "text-column", 0, NULL);
228
229   if (selector->priv->ampm_format) {
230     selector->priv->ampm_model = _create_ampm_model (selector);
231
232     hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
233                                               selector->priv->ampm_model, TRUE);
234
235     g_signal_connect (G_OBJECT (selector),
236                       "changed", G_CALLBACK (_manage_ampm_selection_cb),
237                       NULL);
238   }
239
240
241   /* By default we should select the current day */
242   hildon_time_selector_set_time (selector,
243                                  selector->priv->creation_hours,
244                                  selector->priv->creation_minutes);
245
246   return object;
247
248 }
249
250 static void
251 hildon_time_selector_init (HildonTimeSelector * selector)
252 {
253   selector->priv = HILDON_TIME_SELECTOR_GET_PRIVATE (selector);
254
255   GTK_WIDGET_SET_FLAGS (GTK_WIDGET (selector), GTK_NO_WINDOW);
256   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (selector), FALSE);
257
258   hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (selector),
259                                         _custom_print_func);
260
261   /* By default we use the automatic ampm format */
262   selector->priv->pm = TRUE;
263   check_automatic_ampm_format (selector);
264
265   _get_real_time (&selector->priv->creation_hours,
266                   &selector->priv->creation_minutes);
267 }
268
269 static void
270 hildon_time_selector_get_property (GObject *object,
271                                    guint param_id,
272                                    GValue *value,
273                                    GParamSpec *pspec)
274 {
275   HildonTimeSelectorPrivate *priv = HILDON_TIME_SELECTOR_GET_PRIVATE (object);
276
277   switch (param_id)
278     {
279     case PROP_MINUTES_STEP:
280       g_value_set_uint (value, priv->minutes_step);
281       break;
282     case PROP_TIME_FORMAT_POLICY:
283       g_value_set_enum (value, priv->format_policy);
284       break;
285     default:
286       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
287       break;
288     }
289 }
290
291 static void
292 hildon_time_selector_set_property (GObject *object,
293                                    guint param_id,
294                                    const GValue *value,
295                                    GParamSpec *pspec)
296 {
297   HildonTimeSelectorPrivate *priv = HILDON_TIME_SELECTOR_GET_PRIVATE (object);
298
299   switch (param_id)
300     {
301     case PROP_MINUTES_STEP:
302       priv->minutes_step = g_value_get_uint (value);
303       break;
304     case PROP_TIME_FORMAT_POLICY:
305       update_format_policy (HILDON_TIME_SELECTOR (object),
306                             g_value_get_enum (value));
307       break;
308     default:
309       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
310       break;
311     }
312 }
313
314 static void
315 hildon_time_selector_finalize (GObject * object)
316 {
317   /* Note: we don't require to free the models. We don't manage it using own
318      references, so will be freed on the hildon-touch-selector finalize code.
319      See the implementation notes related to that on the touch selector
320      code. */
321
322   (*G_OBJECT_CLASS (hildon_time_selector_parent_class)->finalize) (object);
323 }
324
325 /* ------------------------------ PRIVATE METHODS ---------------------------- */
326
327 static gchar *
328 _custom_print_func (HildonTouchSelector * touch_selector,
329                     gpointer user_data)
330 {
331   gchar *result = NULL;
332   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
333   HildonTimeSelector *selector = NULL;
334   static gchar string[255];
335   guint hours = 0;
336   guint minutes = 0;
337
338   selector = HILDON_TIME_SELECTOR (touch_selector);
339
340   hildon_time_selector_get_time (selector, &hours, &minutes);
341
342   tm.tm_min = minutes;
343   tm.tm_hour = hours;
344
345   if (selector->priv->ampm_format) {
346     if (selector->priv->pm) {
347       strftime (string, 255, _("wdgt_va_12h_time_pm"), &tm);
348     } else {
349       strftime (string, 255, _("wdgt_va_12h_time_am"), &tm);
350     }
351   } else {
352     strftime (string, 255, _("wdgt_va_24h_time"), &tm);
353   }
354
355
356   result = g_strdup (string);
357
358   return result;
359 }
360
361 static GtkTreeModel *
362 _create_minutes_model (guint minutes_step)
363 {
364   GtkListStore *store_minutes = NULL;
365   gint i = 0;
366   static gchar label[255];
367   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
368   GtkTreeIter iter;
369
370   store_minutes = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
371   for (i = 0; i <= 59; i=i+minutes_step) {
372     tm.tm_min = i;
373     strftime (label, 255, _("wdgt_va_minutes"), &tm);
374
375     gtk_list_store_append (store_minutes, &iter);
376     gtk_list_store_set (store_minutes, &iter,
377                         COLUMN_STRING, label, COLUMN_INT, i, -1);
378   }
379
380   return GTK_TREE_MODEL (store_minutes);
381 }
382
383 static GtkTreeModel *
384 _create_hours_model (HildonTimeSelector * selector)
385 {
386   GtkListStore *store_hours = NULL;
387   gint i = 0;
388   GtkTreeIter iter;
389   struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
390   static gchar label[255];
391   static gint range_12h[12] = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11};
392   static gint range_24h[24] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
393                                12,13,14,15,16,17,18,19,20,21,22,23};
394   gint *range = NULL;
395   gint num_elements = 0;
396   gchar *format_string = NULL;
397
398   if (selector->priv->ampm_format) {
399     range = range_12h;
400     num_elements = 12;
401     format_string = N_("wdgt_va_12h_hours");
402   } else {
403     range = range_24h;
404     num_elements = 24;
405     format_string = N_("wdgt_va_24h_hours");
406   }
407
408   store_hours = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
409   for (i = 0; i < num_elements; i++) {
410     tm.tm_hour = range[i];
411     strftime (label, 255, _(format_string), &tm);
412
413     gtk_list_store_append (store_hours, &iter);
414     gtk_list_store_set (store_hours, &iter,
415                         COLUMN_STRING, label, COLUMN_INT, range[i], -1);
416   }
417
418   return GTK_TREE_MODEL (store_hours);
419 }
420
421 static GtkTreeModel *
422 _create_ampm_model (HildonTimeSelector * selector)
423 {
424   GtkListStore *store_ampm = NULL;
425   GtkTreeIter iter;
426   static gchar label[255];
427
428   store_ampm = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
429
430   snprintf (label, 255, _("wdgt_va_am"));
431   gtk_list_store_append (store_ampm, &iter);
432   gtk_list_store_set (store_ampm, &iter,
433                       COLUMN_STRING, label,
434                       COLUMN_INT, 0, -1);
435
436   snprintf (label, 255, _("wdgt_va_pm"));
437   gtk_list_store_append (store_ampm, &iter);
438   gtk_list_store_set (store_ampm, &iter,
439                       COLUMN_STRING, label,
440                       COLUMN_INT, 1, -1);
441
442   return GTK_TREE_MODEL (store_ampm);
443 }
444
445 static void
446 _get_real_time (gint * hours, gint * minutes)
447 {
448   time_t secs;
449   struct tm *tm = NULL;
450
451   secs = time (NULL);
452   tm = localtime (&secs);
453
454   if (hours != NULL) {
455     *hours = tm->tm_hour;
456   }
457
458   if (minutes != NULL) {
459     *minutes = tm->tm_min;
460   }
461 }
462
463 static void
464 _manage_ampm_selection_cb (HildonTouchSelector * touch_selector,
465                            gint num_column, gpointer data)
466 {
467   HildonTimeSelector *selector = NULL;
468   gint pm;
469   GtkTreeIter iter;
470
471   g_return_if_fail (HILDON_IS_TIME_SELECTOR (touch_selector));
472   selector = HILDON_TIME_SELECTOR (touch_selector);
473
474   if (num_column == COLUMN_AMPM &&
475       hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
476                                           COLUMN_AMPM, &iter)) {
477      gtk_tree_model_get (selector->priv->ampm_model, &iter, COLUMN_INT, &pm, -1);
478
479     selector->priv->pm = pm;
480   }
481 }
482
483 static void
484 check_automatic_ampm_format (HildonTimeSelector * selector)
485 {
486   GConfClient *client = NULL;
487   gboolean value = TRUE;
488   GError *error = NULL;
489
490   client = gconf_client_get_default ();
491   value = gconf_client_get_bool (client, CLOCK_GCONF_IS_24H_FORMAT, &error);
492   if (error != NULL) {
493     g_warning
494       ("Error trying to get gconf variable %s, using 24h format by default",
495        CLOCK_GCONF_IS_24H_FORMAT);
496     g_error_free (error);
497   }
498
499   selector->priv->ampm_format = !value;
500 }
501
502 static void
503 _set_pm (HildonTimeSelector * selector, gboolean pm)
504 {
505   GtkTreeIter iter;
506
507   selector->priv->pm = pm;
508
509   if (selector->priv->ampm_model != NULL) {
510     gtk_tree_model_iter_nth_child (selector->priv->ampm_model, &iter, NULL, pm);
511
512     hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
513                                        COLUMN_AMPM, &iter, FALSE);
514   }
515 }
516
517 static void
518 update_format_policy                            (HildonTimeSelector *selector,
519                                                  HildonTimeSelectorFormatPolicy new_policy)
520 {
521   gboolean prev_ampm_format = FALSE;
522   gint num_columns = -1;
523
524   num_columns = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (selector));
525   prev_ampm_format = selector->priv->ampm_format;
526
527   if (new_policy != selector->priv->format_policy) {
528     guint hours;
529     guint minutes;
530
531     selector->priv->format_policy = new_policy;
532
533     /* We get the hour previous all the changes, to avoid problems with the
534        changing widget structure */
535     if (num_columns >= 2) {/* we are on the object construction */
536       hildon_time_selector_get_time (selector, &hours, &minutes);
537     }
538
539     switch (new_policy)
540       {
541       case HILDON_TIME_SELECTOR_FORMAT_POLICY_AMPM:
542         selector->priv->ampm_format = TRUE;
543         break;
544       case HILDON_TIME_SELECTOR_FORMAT_POLICY_24H:
545         selector->priv->ampm_format = FALSE;
546         break;
547       case HILDON_TIME_SELECTOR_FORMAT_POLICY_AUTOMATIC:
548         check_automatic_ampm_format (selector);
549         break;
550       }
551
552     if (prev_ampm_format != selector->priv->ampm_format) {
553       update_format_dependant_columns (selector, hours, minutes);
554     }
555   }
556 }
557
558 static void
559 update_format_dependant_columns                 (HildonTimeSelector *selector,
560                                                  guint hours,
561                                                  guint minutes)
562 {
563   gint num_columns = -1;
564
565   num_columns = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (selector));
566   if (num_columns < 2) {/* we are on the object construction */
567     return;
568   }
569
570   /* To avoid an extra and wrong VALUE_CHANGED signal on the model update */
571   hildon_touch_selector_block_changed (HILDON_TOUCH_SELECTOR(selector));
572
573   selector->priv->hours_model = _create_hours_model (selector);
574   hildon_touch_selector_set_model (HILDON_TOUCH_SELECTOR (selector),
575                                    0,
576                                    selector->priv->hours_model);
577
578   /* We need to set NOW the correct hour on the hours column, because the number of
579      columns will be updated too, so a signal COLUMNS_CHANGED will be emitted. Some
580      other widget could have connected to this signal and ask for the hour, so this
581      emission could have a wrong hour. We could use a custom func to only modify the
582      hours selection, but hildon_time_selector_time manage yet all the ampm issues
583      to select the correct one */
584   hildon_time_selector_set_time (selector, hours, minutes);
585
586   /* if we are at this function, we are sure that a change on the number of columns
587      will happen, so check the column number is not required */
588   if (selector->priv->ampm_format) {
589     selector->priv->ampm_model = _create_ampm_model (selector);
590
591     hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
592                                               selector->priv->ampm_model, TRUE);
593
594     g_signal_connect (G_OBJECT (selector),
595                       "changed", G_CALLBACK (_manage_ampm_selection_cb),
596                       NULL);
597   } else {
598     selector->priv->ampm_model = NULL;
599     hildon_touch_selector_remove_column (HILDON_TOUCH_SELECTOR (selector), 2);
600   }
601
602   _set_pm (selector, hours >= 12);
603
604   hildon_touch_selector_unblock_changed (HILDON_TOUCH_SELECTOR (selector));
605 }
606 /* ------------------------------ PUBLIC METHODS ---------------------------- */
607
608 /**
609  * hildon_time_selector_new:
610  *
611  * Creates a new #HildonTimeSelector
612  *
613  * Returns: a new #HildonTimeSelector
614  *
615  * Since: 2.2
616  **/
617 GtkWidget *
618 hildon_time_selector_new ()
619 {
620   return g_object_new (HILDON_TYPE_TIME_SELECTOR, NULL);
621 }
622
623
624 /**
625  * hildon_time_selector_new_step:
626  *
627  * Creates a new #HildonTimeSelector
628  * @minutes_step: step between the minutes we are going to show in the
629  * selector
630  *
631  * Returns: a new #HildonTimeSelector
632  *
633  * Since: 2.2
634  **/
635 GtkWidget *
636 hildon_time_selector_new_step (guint minutes_step)
637 {
638   return g_object_new (HILDON_TYPE_TIME_SELECTOR, "minutes-step",
639                        minutes_step, NULL);
640 }
641
642 /**
643  * hildon_time_selector_set_time
644  * @selector: the #HildonTimeSelector
645  * @hours:  the current hour (0-23)
646  * @minutes: the current minute (0-59)
647  *
648  * Sets the current active hour on the #HildonTimeSelector widget
649  *
650  * The format of the hours accepted is always 24h format, with a range
651  * (0-23):(0-59).
652  *
653  * Since: 2.2
654  *
655  * Returns: %TRUE on success, %FALSE otherwise
656  **/
657 gboolean
658 hildon_time_selector_set_time (HildonTimeSelector * selector,
659                                guint hours, guint minutes)
660 {
661   GtkTreeIter iter;
662   gint hours_item = 0;
663
664   g_return_val_if_fail (HILDON_IS_TIME_SELECTOR (selector), FALSE);
665   g_return_val_if_fail (hours <= 23, FALSE);
666   g_return_val_if_fail (minutes <= 59, FALSE);
667
668   _set_pm (selector, hours >= 12);
669
670   if (selector->priv->ampm_format) {
671     hours_item = hours - selector->priv->pm * 12;
672   } else {
673     hours_item = hours;
674   }
675
676   gtk_tree_model_iter_nth_child (selector->priv->hours_model, &iter, NULL,
677                                  hours_item);
678   hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
679                                      COLUMN_HOURS, &iter, FALSE);
680
681   g_assert (selector->priv->minutes_step>0);
682   minutes = minutes/selector->priv->minutes_step;
683   gtk_tree_model_iter_nth_child (selector->priv->minutes_model, &iter, NULL,
684                                  minutes);
685   hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector),
686                                      COLUMN_MINUTES, &iter, FALSE);
687
688   return TRUE;
689 }
690
691 /**
692  * hildon_time_selector_get_time
693  * @selector: the #HildonTimeSelector
694  * @hours:  to set the current hour (0-23)
695  * @minutes: to set the current minute (0-59)
696  *
697  * Gets the current active hour on the #HildonTimeSelector widget. Both @year
698  * and @minutes can be NULL.
699  *
700  * This method returns the date always in 24h format, with a range (0-23):(0-59)
701  *
702  * Since: 2.2
703  **/
704 void
705 hildon_time_selector_get_time (HildonTimeSelector * selector,
706                                guint * hours, guint * minutes)
707 {
708   GtkTreeIter iter;
709
710   g_return_if_fail (HILDON_IS_TIME_SELECTOR (selector));
711
712   if (hours != NULL) {
713     if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
714                                             COLUMN_HOURS, &iter)) {
715
716       gtk_tree_model_get (selector->priv->hours_model,
717                           &iter, COLUMN_INT, hours, -1);
718     }
719     if (selector->priv->ampm_format) {
720       *hours %= 12;
721       *hours += selector->priv->pm * 12;
722     }
723   }
724
725   if (minutes != NULL) {
726     if (hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
727                                             COLUMN_MINUTES, &iter)) {
728       gtk_tree_model_get (selector->priv->minutes_model,
729                           &iter, COLUMN_INT, minutes, -1);
730     }
731   }
732 }