2009-01-12 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-date-selector.c
index f0acfb9..1bbd993 100644 (file)
  * SECTION:hildon-date-selector
  * @short_description: A widget to select the current date.
  *
- * HildonDateSelector is a date widget, equivalent to hildon-calendar, but with a multi-column
- * approach
+ * #HildonDateSelector is a date widget with multiple columns. Users
+ * can choose a date by selecting values in the day, month and year
+ * columns.
  *
+ * The currently selected month and year can be altered with
+ * hildon_date_selector_select_month(). The day can be selected from
+ * the active month using hildon_date_selector_select_day().
  */
 
 #define _GNU_SOURCE     /* needed for GNU nl_langinfo_l */
@@ -88,7 +92,7 @@ struct _HildonDateSelectorPrivate
   gint creation_month;
   gint creation_year;           /* date at creation time */
 
-  gchar *monthname[12];
+  gint current_num_days;
 };
 
 static void hildon_date_selector_finalize (GObject * object);
@@ -216,6 +220,7 @@ hildon_date_selector_init (HildonDateSelector * selector)
 {
   GSList *iter = NULL;
   gint current_item = 0;
+  HildonTouchSelectorColumn *column = NULL;
 
   selector->priv = HILDON_DATE_SELECTOR_GET_PRIVATE (selector);
 
@@ -235,24 +240,28 @@ hildon_date_selector_init (HildonDateSelector * selector)
   selector->priv->year_model = _create_year_model (selector);
   selector->priv->month_model = _create_month_model (selector);
   selector->priv->day_model = _create_day_model (selector);
+  selector->priv->current_num_days = 31;
 
-  /* We add the columns: FIXME: check the locale order */
+  /* We add the columns, checking the locale order */
   iter = selector->priv->column_order;
   for (iter = selector->priv->column_order; iter; iter = g_slist_next (iter)) {
     current_item = GPOINTER_TO_INT (iter->data);
 
     switch (current_item) {
     case DAY:
-      hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
-                                                selector->priv->day_model, TRUE);
+      column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
+                                                         selector->priv->day_model, TRUE);
+      g_object_set (G_OBJECT (column), "text-column", 0, NULL);
       break;
     case MONTH:
-      hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
-                                                selector->priv->month_model, TRUE);
+      column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
+                                                         selector->priv->month_model, TRUE);
+      g_object_set (G_OBJECT (column), "text-column", 0, NULL);
       break;
     case YEAR:
-      hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
-                                                selector->priv->year_model, TRUE);
+      column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
+                                                         selector->priv->year_model, TRUE);
+      g_object_set (G_OBJECT (column), "text-column", 0, NULL);
       break;
     default:
       g_error ("Current column order incorrect");
@@ -273,17 +282,11 @@ static void
 hildon_date_selector_finalize (GObject * object)
 {
   HildonDateSelector *selector = NULL;
-  gint i = 0;
 
   selector = HILDON_DATE_SELECTOR (object);
 
-  for (i = 0; i < 12; i++) {
-    g_free (selector->priv->monthname[i]);
-  }
-
   g_slist_free (selector->priv->column_order);
-
-  g_free (selector->priv);
+  g_free (selector->priv->format);
 
   (*G_OBJECT_CLASS (hildon_date_selector_parent_class)->finalize) (object);
 }
@@ -329,31 +332,6 @@ _locales_init (HildonDateSelectorPrivate * priv)
 
   l = newlocale (LC_TIME_MASK, setlocale (LC_MESSAGES, NULL), NULL);
 
-  priv->monthname[0] = g_locale_to_utf8 (nl_langinfo_l (MON_1, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[1] = g_locale_to_utf8 (nl_langinfo_l (MON_2, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[2] = g_locale_to_utf8 (nl_langinfo_l (MON_3, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[3] = g_locale_to_utf8 (nl_langinfo_l (MON_4, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[4] = g_locale_to_utf8 (nl_langinfo_l (MON_5, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[5] = g_locale_to_utf8 (nl_langinfo_l (MON_6, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[6] = g_locale_to_utf8 (nl_langinfo_l (MON_7, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[7] = g_locale_to_utf8 (nl_langinfo_l (MON_8, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[8] = g_locale_to_utf8 (nl_langinfo_l (MON_9, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[9] = g_locale_to_utf8 (nl_langinfo_l (MON_10, l),
-                                         -1, NULL, NULL, NULL);
-  priv->monthname[10] = g_locale_to_utf8 (nl_langinfo_l (MON_11, l),
-                                          -1, NULL, NULL, NULL);
-  priv->monthname[11] = g_locale_to_utf8 (nl_langinfo_l (MON_12, l),
-                                          -1, NULL, NULL, NULL);
-
   priv->format = g_locale_to_utf8 (nl_langinfo_l (D_FMT, l),
                                    -1, NULL, NULL, NULL);
 
@@ -438,17 +416,18 @@ _create_day_model (HildonDateSelector * selector)
 {
   GtkListStore *store_days = NULL;
   gint i = 0;
-  gchar *label = NULL;
+  gchar label[255];
+  struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   GtkTreeIter iter;
 
   store_days = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
   for (i = 1; i < 32; i++) {
-    label = g_strdup_printf ("%d", i);
+    tm.tm_mday = i;
+    strftime (label, 255, _("wdgt_va_day_numeric"), &tm);
 
     gtk_list_store_append (store_days, &iter);
     gtk_list_store_set (store_days, &iter,
                         COLUMN_STRING, label, COLUMN_INT, i, -1);
-    g_free (label);
   }
 
   return GTK_TREE_MODEL (store_days);
@@ -460,19 +439,20 @@ _create_year_model (HildonDateSelector * selector)
   GtkListStore *store_years = NULL;
   gint real_year = 0;
   gint i = 0;
-  gchar *label = NULL;
+  static gchar label[255];
+  struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   GtkTreeIter iter;
 
   real_year = selector->priv->creation_year;
 
   store_years = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
   for (i = real_year - INIT_YEAR; i < real_year + LAST_YEAR; i++) {
-    label = g_strdup_printf ("%d", i);
+    tm.tm_year = i - 1900;
+    strftime (label, 255, _("wdgt_va_year"), &tm);
 
     gtk_list_store_append (store_years, &iter);
     gtk_list_store_set (store_years, &iter,
                         COLUMN_STRING, label, COLUMN_INT, i, -1);
-    g_free (label);
   }
 
   return GTK_TREE_MODEL (store_years);
@@ -484,17 +464,18 @@ _create_month_model (HildonDateSelector * selector)
   GtkTreeIter iter;
   gint i = 0;
   GtkListStore *store_months = NULL;
-  gchar *label = NULL;
+  static gchar label[255];
+  struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
   store_months = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
   for (i = 0; i < 12; i++) {
-    label = g_strdup_printf ("%s", selector->priv->monthname[i]);
+    tm.tm_mon = i;
+    strftime (label, 255, _("wdgt_va_month"), &tm);
 
     gtk_list_store_append (store_months, &iter);
-    gtk_list_store_set (store_months, &iter, COLUMN_STRING, label,      /* the label with the month */
-                        COLUMN_INT, i,  /* the month number */
+    gtk_list_store_set (store_months, &iter, COLUMN_STRING, label,
+                        COLUMN_INT, i,
                         -1);
-    g_free (label);
   }
 
   return GTK_TREE_MODEL (store_months);
@@ -504,40 +485,48 @@ static GtkTreeModel *
 _update_day_model (HildonDateSelector * selector)
 {
   GtkListStore *store_days = NULL;
+  GtkTreePath *path = NULL;
   gint i = 0;
   GtkTreeIter iter;
-  gchar *label = NULL;
+  static gchar label[255];
+  struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   guint current_day = 0;
   guint current_year = 0;
   guint current_month = 0;
   guint num_days = 31;
 
-  hildon_date_selector_get_date (selector, NULL, NULL, &current_day);
-
-  hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
-                                      selector->priv->month_column, &iter);
-  gtk_tree_model_get (selector->priv->month_model,
-                      &iter, COLUMN_INT, &current_month, -1);
-
-  hildon_touch_selector_get_selected (HILDON_TOUCH_SELECTOR (selector),
-                                      selector->priv->year_column, &iter);
-  gtk_tree_model_get (selector->priv->year_model,
-                      &iter, COLUMN_INT, &current_year, -1);
+  hildon_date_selector_get_date (selector, &current_year, &current_month,
+                                 &current_day);
 
   num_days = _month_days (current_month, current_year);
-
   store_days = GTK_LIST_STORE (selector->priv->day_model);
-  gtk_list_store_clear (store_days);
 
-  for (i = 1; i <= num_days; i++) {
-    label = g_strdup_printf ("%d", i);
+  if (num_days == selector->priv->current_num_days) {
+    return GTK_TREE_MODEL (store_days);
+  }
 
-    gtk_list_store_append (store_days, &iter);
-    gtk_list_store_set (store_days, &iter,
-                        COLUMN_STRING, label, COLUMN_INT, i, -1);
-    g_free (label);
+  if (num_days > selector->priv->current_num_days) {
+    for (i = selector->priv->current_num_days + 1; i <= num_days; i++) {
+      tm.tm_mday = i;
+      strftime (label, 255, _("wdgt_va_day_numeric"), &tm);
+
+      gtk_list_store_append (store_days, &iter);
+      gtk_list_store_set (store_days, &iter,
+                          COLUMN_STRING, label, COLUMN_INT, i, -1);
+    }
+  } else {
+    path = gtk_tree_path_new_from_indices (num_days,
+                                           -1);
+    gtk_tree_model_get_iter (GTK_TREE_MODEL (store_days), &iter, path);
+    do {
+    }while (gtk_list_store_remove (store_days, &iter));
+
+    gtk_tree_path_free (path);
   }
 
+
+  selector->priv->current_num_days = num_days;
+
   /* now we select a day */
   if (current_day >= num_days) {
     current_day = num_days;
@@ -584,6 +573,8 @@ _manage_selector_change_cb (HildonTouchSelector * touch_selector,
   if ((num_column == selector->priv->month_column) ||
       (num_column == selector->priv->year_column)) /* it is required to check that with
                                                     * the years too,remember: leap years
+                                                    * update_day_model will check if
+                                                    * the number of days is different
                                                     */
   {
     _update_day_model (selector);
@@ -612,6 +603,8 @@ _month_days (gint month, gint year)
  * Creates a new #HildonDateSelector
  *
  * Returns: a new #HildonDateSelector
+ *
+ * Since: 2.2
  **/
 GtkWidget *
 hildon_date_selector_new ()
@@ -621,7 +614,7 @@ hildon_date_selector_new ()
 
 
 /**
- * hildon_date_selector_select_date:
+ * hildon_date_selector_select_current_date:
  * @selector: the #HildonDateSelector
  * @year:  the current year
  * @month: the current month (0-11)
@@ -629,6 +622,9 @@ hildon_date_selector_new ()
  *
  * Sets the current active date on the #HildonDateSelector widget
  *
+ * Since: 2.2
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
  **/
 gboolean
 hildon_date_selector_select_current_date (HildonDateSelector * selector,
@@ -681,7 +677,7 @@ hildon_date_selector_select_current_date (HildonDateSelector * selector,
  *
  * Gets the current active date on the #HildonDateSelector widget
  *
- *
+ * Since: 2.2
  **/
 void
 hildon_date_selector_get_date (HildonDateSelector * selector,
@@ -725,10 +721,12 @@ hildon_date_selector_get_date (HildonDateSelector * selector,
  *
  * Modify the current month and year on the current active date
  *
- * Utility function, too keep this API more similar to the previously existing
- * hildon-calendar widget.
+ * Utility function to keep this API similar to the previously
+ * existing #HildonCalendar widget.
  *
+ * Since: 2.2
  *
+ * Returns: %TRUE on success, %FALSE otherwise
  **/
 gboolean hildon_date_selector_select_month (HildonDateSelector *selector,
                                             guint month, guint year)
@@ -747,10 +745,10 @@ gboolean hildon_date_selector_select_month (HildonDateSelector *selector,
  *
  * Modify the current day on the current active date
  *
- * Utility function, too keep this API more similar to the previously existing
- * hildon-calendar widget.
- *
+ * Utility function to keep this API similar to the previously
+ * existing #HildonCalendar widget.
  *
+ * Since: 2.2
  **/
 void
 hildon_date_selector_select_day (HildonDateSelector *selector, guint day)