2009-04-01 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-picker-dialog.c
index a881ca1..3fa11b3 100644 (file)
  * SECTION:hildon-picker-dialog
  * @short_description: A utility widget that shows a #HildonTouchSelector widget
  *
- * HildonPickerDialog is a utility widget that shows a #HildonTouchSelector widget in
- * a new dialog (see #GtkDialog for more information about this issue)
+ * #HildonPickerDialog is a dialog that is used to show a
+ * #HildonTouchSelector widget and a 'Done' button to allow users to
+ * finish their selections.
  *
+ * The #HildonPickerDialog will show a 'Done' button in case the
+ * #HildonTouchSelector allows multiple selection. The label of the
+ * button can be set using hildon_picker_dialog_set_done_label() and
+ * retrieved using hildon_picker_dialog_get_done_label()
+ *
+ * Note that in most cases developers don't need to deal directly with
+ * this widget. #HildonPickerButton is designed to pop up a
+ * #HildonPickerDialog and manage the interaction with it.
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include <string.h>
 #include <stdlib.h>
-
 #include <libintl.h>
-#include <gtk/gtkmarshal.h>
 
 #include "hildon-touch-selector.h"
+#include "hildon-touch-selector-entry.h"
 #include "hildon-picker-dialog.h"
 
 #define _(String)  dgettext("hildon-libs", String)
 
 #define HILDON_PICKER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_PICKER_DIALOG, HildonPickerDialogPrivate))
 
-G_DEFINE_TYPE (HildonPickerDialog, hildon_picker_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE (HildonPickerDialog, hildon_picker_dialog, HILDON_TYPE_DIALOG)
+
+#define HILDON_TOUCH_SELECTOR_HEIGHT            320
 
 struct _HildonPickerDialogPrivate
 {
   GtkWidget *selector;
-  GtkWidget *separator;
   GtkWidget *button;
 
-  GtkWidget *title_label;
+  gulong signal_changed_id;
+  gulong signal_columns_changed_id;
 
-  gulong signal_id;
+  gboolean center_on_show;
+  GSList *current_selection;
+  gchar *current_text;
 };
 
 /* properties */
@@ -62,6 +74,7 @@ enum
 {
   PROP_0,
   PROP_DONE_BUTTON_TEXT,
+  PROP_CENTER_ON_SHOW,
   PROP_LAST
 };
 
@@ -71,35 +84,63 @@ enum
   LAST_SIGNAL
 };
 
-#define DEFAULT_DONE_BUTTON_TEXT        "Done"
+#define DEFAULT_DONE_BUTTON_TEXT        _("wdgt_bd_done")
 
 static void
-hildon_picker_dialog_set_property (GObject * object,
-                                   guint prop_id,
-                                   const GValue * value,
-                                   GParamSpec * pspec);
+hildon_picker_dialog_set_property               (GObject * object,
+                                                 guint prop_id,
+                                                 const GValue * value,
+                                                 GParamSpec * pspec);
 
 static void
-hildon_picker_dialog_get_property (GObject * object,
-                                   guint prop_id,
-                                   GValue * value, GParamSpec * pspec);
+hildon_picker_dialog_get_property               (GObject * object,
+                                                 guint prop_id,
+                                                 GValue * value, GParamSpec * pspec);
+
+static void
+hildon_picker_dialog_finalize                   (GObject *object);
+
 /* gtkwidget */
-static void hildon_picker_dialog_realize (GtkWidget * widget);
+static void
+hildon_picker_dialog_show                       (GtkWidget *widget);
+
+static void
+hildon_picker_dialog_realize                    (GtkWidget *widget);
 
 /* private functions */
-static gboolean requires_done_button (HildonPickerDialog * dialog);
+static gboolean
+requires_done_button                            (HildonPickerDialog * dialog);
+
+static void
+prepare_action_area                             (HildonPickerDialog *dialog);
+
+static void
+setup_interaction_mode                          (HildonPickerDialog * dialog);
 
 static void
-_select_on_selector_changed_cb (HildonTouchSelector * dialog,
-                                gint column, gpointer data);
+_select_on_selector_changed_cb                  (HildonTouchSelector * dialog,
+                                                 gint column,
+                                                 gpointer data);
 
 static gboolean
-_hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
-                                    HildonTouchSelector * selector);
+_hildon_picker_dialog_set_selector              (HildonPickerDialog * dialog,
+                                                 HildonTouchSelector * selector);
 
 static void
-_update_title_on_selector_changed_cb (HildonTouchSelector * selector,
-                                      gint column, gpointer data);
+_on_dialog_response                             (GtkDialog *dialog,
+                                                 gint response_id,
+                                                 gpointer data);
+
+static void
+_save_current_selection                         (HildonPickerDialog *dialog);
+
+static void
+_restore_current_selection                      (HildonPickerDialog *dialog);
+
+static void
+_clean_current_selection                        (HildonPickerDialog *dialog);
+
+/**********************************************************************************/
 
 static void
 hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
@@ -117,8 +158,10 @@ hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
   /* GObject */
   gobject_class->set_property = hildon_picker_dialog_set_property;
   gobject_class->get_property = hildon_picker_dialog_get_property;
+  gobject_class->finalize = hildon_picker_dialog_finalize;
 
   /* GtkWidget */
+  widget_class->show = hildon_picker_dialog_show;
   widget_class->realize = hildon_picker_dialog_realize;
 
   /* HildonPickerDialog */
@@ -131,6 +174,8 @@ hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
    * HildonPickerDialog
    *
    * Button label
+   *
+   * Since: 2.2
    */
   g_object_class_install_property (gobject_class,
                                    PROP_DONE_BUTTON_TEXT,
@@ -142,6 +187,17 @@ hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
                                                         G_PARAM_WRITABLE |
                                                         G_PARAM_CONSTRUCT));
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_CENTER_ON_SHOW,
+                                   g_param_spec_boolean ("center-on-show",
+                                                         "Center on show",
+                                                         "If the dialog should center"
+                                                         " on the current selection"
+                                                         " when it is showed",
+                                                         TRUE,
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+
   g_type_class_add_private (object_class, sizeof (HildonPickerDialogPrivate));
 }
 
@@ -149,8 +205,6 @@ hildon_picker_dialog_class_init (HildonPickerDialogClass * class)
 static void
 hildon_picker_dialog_init (HildonPickerDialog * dialog)
 {
-  GtkWidget *separator = NULL;
-
   dialog->priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
 
   dialog->priv->selector = NULL;
@@ -158,17 +212,15 @@ hildon_picker_dialog_init (HildonPickerDialog * dialog)
     gtk_dialog_add_button (GTK_DIALOG (dialog), "", GTK_RESPONSE_OK);
   gtk_widget_grab_default (dialog->priv->button);
 
-  dialog->priv->title_label = gtk_label_new ("default value");
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-                      dialog->priv->title_label, FALSE, FALSE, 0);
-  separator = gtk_hseparator_new ();
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-                      separator, FALSE, FALSE, 0);
+  dialog->priv->signal_changed_id = 0;
+  dialog->priv->signal_columns_changed_id = 0;
+  dialog->priv->center_on_show = TRUE;
+  dialog->priv->current_selection = NULL;
+  dialog->priv->current_text = NULL;
 
-  dialog->priv->signal_id = 0;
-
-/*   gtk_widget_show (dialog->priv->title_label); */
-/*   gtk_widget_show (separator); */
+  g_signal_connect (G_OBJECT (dialog),
+                    "response", G_CALLBACK (_on_dialog_response),
+                    NULL);
 }
 
 
@@ -177,14 +229,18 @@ hildon_picker_dialog_set_property (GObject * object,
                                    guint param_id,
                                    const GValue * value, GParamSpec * pspec)
 {
-  HildonPickerDialogPrivate *priv = HILDON_PICKER_DIALOG_GET_PRIVATE (object);
-  g_assert (priv);
+  HildonPickerDialog *dialog;
+
+  dialog = HILDON_PICKER_DIALOG (object);
 
   switch (param_id) {
   case PROP_DONE_BUTTON_TEXT:
     hildon_picker_dialog_set_done_label (HILDON_PICKER_DIALOG (object),
                                          g_value_get_string (value));
     break;
+  case PROP_CENTER_ON_SHOW:
+    dialog->priv->center_on_show = g_value_get_boolean (value);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
     break;
@@ -197,66 +253,126 @@ hildon_picker_dialog_get_property (GObject * object,
                                    GValue * value, GParamSpec * pspec)
 {
   HildonPickerDialog *dialog;
-  HildonPickerDialogPrivate *priv;
 
   dialog = HILDON_PICKER_DIALOG (object);
-  priv = HILDON_PICKER_DIALOG_GET_PRIVATE (object);
 
   switch (param_id) {
   case PROP_DONE_BUTTON_TEXT:
     g_value_set_string (value, hildon_picker_dialog_get_done_label (dialog));
     break;
+  case PROP_CENTER_ON_SHOW:
+    g_value_set_boolean (value, dialog->priv->center_on_show);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
     break;
   }
 }
 
-
 static void
-hildon_picker_dialog_realize (GtkWidget * widget)
+hildon_picker_dialog_finalize (GObject *object)
 {
-  GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->realize (widget);
+  _clean_current_selection (HILDON_PICKER_DIALOG (object));
 
-/*   gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER); */
+  G_OBJECT_CLASS (hildon_picker_dialog_parent_class)->finalize (object);
 }
 
-/* ------------------------------ PRIVATE METHODS ---------------------------- */
 static void
-_select_on_selector_changed_cb (HildonTouchSelector * selector,
-                                gint column, gpointer data)
+hildon_picker_dialog_show                       (GtkWidget *widget)
 {
-  HildonPickerDialog *dialog = NULL;
+  HildonPickerDialog *dialog = HILDON_PICKER_DIALOG (widget);
+  HildonTouchSelector *selector;
 
-  g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
+  if (dialog->priv->center_on_show) {
+    selector = hildon_picker_dialog_get_selector (dialog);
+    hildon_touch_selector_center_on_selected (selector);
+  }
 
-  dialog = HILDON_PICKER_DIALOG (data);
+  _save_current_selection (dialog);
+  prepare_action_area (dialog);
 
-  gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+  GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->show (widget);
 }
 
 static void
-_update_title_on_selector_changed_cb (HildonTouchSelector * selector,
-                                      gint column, gpointer data)
+hildon_picker_dialog_realize (GtkWidget *widget)
 {
-  HildonPickerDialog *dialog = NULL;
-  gchar *new_title = NULL;
+  setup_interaction_mode (HILDON_PICKER_DIALOG (widget));
+
+  GTK_WIDGET_CLASS (hildon_picker_dialog_parent_class)->realize (widget);
+}
+
+/* ------------------------------ PRIVATE METHODS ---------------------------- */
 
+static void
+_select_on_selector_changed_cb (HildonTouchSelector * selector,
+                                gint column, gpointer data)
+{
   g_return_if_fail (HILDON_IS_PICKER_DIALOG (data));
 
-  dialog = HILDON_PICKER_DIALOG (data);
+  gtk_dialog_response (GTK_DIALOG (data), GTK_RESPONSE_OK);
+}
+
+static gboolean
+selection_completed (HildonPickerDialog *dialog)
+{
+  HildonPickerDialogPrivate *priv;
+  GList *list;
+  gint i, n_cols;
+  gboolean all_selected = TRUE;
 
-  new_title = hildon_touch_selector_get_current_text (selector);
+  priv = HILDON_PICKER_DIALOG_GET_PRIVATE (dialog);
 
-  if (dialog->priv->title_label != NULL) {
-/*       gtk_label_set_text (GTK_LABEL(selector->priv->title_label), new_title); */
+  n_cols = hildon_touch_selector_get_num_columns (HILDON_TOUCH_SELECTOR (priv->selector));
+  for (i = 0; i < n_cols; i++) {
+    list = hildon_touch_selector_get_selected_rows (HILDON_TOUCH_SELECTOR (priv->selector), i);
+    if (list == NULL) {
+      all_selected = FALSE;
+      break;
+    }
+    g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
+    g_list_free (list);
   }
-  gtk_window_set_title (GTK_WINDOW (dialog), new_title);
 
-  g_free (new_title);
+  return all_selected;
 }
 
+static void
+_on_dialog_response                             (GtkDialog *dialog,
+                                                 gint response_id,
+                                                 gpointer data)
+{
+  if (response_id == GTK_RESPONSE_OK) {
+    if (selection_completed (HILDON_PICKER_DIALOG (dialog)) == FALSE) {
+      g_signal_stop_emission_by_name (dialog, "response");
+    }
+  } else if (response_id == GTK_RESPONSE_DELETE_EVENT) {
+    _restore_current_selection (HILDON_PICKER_DIALOG (dialog));
+  }
+}
+
+static void
+on_selector_columns_changed (HildonTouchSelector * selector, gpointer userdata)
+{
+  HildonPickerDialog * dialog;
+
+  dialog = HILDON_PICKER_DIALOG (userdata);
 
+  prepare_action_area (dialog);
+  if (GTK_WIDGET_REALIZED (dialog)) {
+    setup_interaction_mode (dialog);
+  }
+}
+
+/**
+ * hildon_picker_dialog_set_done_label:
+ * @dialog: a #HildonPickerDialog
+ * @label: a string
+ *
+ * Sets a custom string to be used as the 'Done' button label in @dialog.
+ *
+ * Since: 2.2
+ **/
 void
 hildon_picker_dialog_set_done_label (HildonPickerDialog * dialog,
                                      const gchar * label)
@@ -271,6 +387,16 @@ hildon_picker_dialog_set_done_label (HildonPickerDialog * dialog,
   gtk_button_set_label (GTK_BUTTON (priv->button), label);
 }
 
+/**
+ * hildon_picker_dialog_get_done_label:
+ * @dialog: a #HildonPickerDialog
+ *
+ * Retrieves current 'Done' button label.
+ *
+ * Returns: the custom string to be used.
+ *
+ * Since: 2.2
+ **/
 const gchar *
 hildon_picker_dialog_get_done_label (HildonPickerDialog * dialog)
 {
@@ -283,6 +409,97 @@ hildon_picker_dialog_get_done_label (HildonPickerDialog * dialog)
   return gtk_button_get_label (GTK_BUTTON (priv->button));
 }
 
+static void
+free_path_list (GList *list)
+{
+  g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+  g_list_free (list);
+}
+
+static void
+_clean_current_selection (HildonPickerDialog *dialog)
+{
+  if (dialog->priv->current_selection) {
+    g_slist_foreach (dialog->priv->current_selection, (GFunc) free_path_list, NULL);
+    g_slist_free (dialog->priv->current_selection);
+    dialog->priv->current_selection = NULL;
+  }
+  if (dialog->priv->current_text) {
+    g_free (dialog->priv->current_text);
+    dialog->priv->current_text = NULL;
+  }
+}
+
+static void
+_save_current_selection (HildonPickerDialog *dialog)
+{
+  HildonTouchSelector *selector;
+  gint i, columns;
+
+  selector = HILDON_TOUCH_SELECTOR (dialog->priv->selector);
+
+  _clean_current_selection (dialog);
+
+  columns = hildon_touch_selector_get_num_columns (selector);
+  for (i = 0; i  < columns; i++) {
+    dialog->priv->current_selection
+      = g_slist_append (dialog->priv->current_selection,
+                        hildon_touch_selector_get_selected_rows (selector, i));
+  }
+  if (HILDON_IS_TOUCH_SELECTOR_ENTRY (selector)) {
+         HildonEntry *entry = hildon_touch_selector_entry_get_entry (HILDON_TOUCH_SELECTOR_ENTRY (selector));
+         dialog->priv->current_text = g_strdup (hildon_entry_get_text (entry));
+  }
+}
+
+static void
+_restore_current_selection (HildonPickerDialog *dialog)
+{
+  GSList *current_selection, *iter;
+  GList *selected, *selected_iter;
+  GtkTreePath *current_path;
+  HildonTouchSelector *selector;
+  GtkTreeModel *model;
+  GtkTreeIter tree_iter;
+  gint i;
+
+  if (dialog->priv->current_selection == NULL)
+    return;
+
+  current_selection = dialog->priv->current_selection;
+  selector = HILDON_TOUCH_SELECTOR (dialog->priv->selector);
+
+  if (hildon_touch_selector_get_num_columns (selector) !=
+      g_slist_length (current_selection)) {
+    /* We conclude that if the current selection has the same
+       numbers of columns that the selector, all this ok
+       Anyway this shouldn't happen. */
+    g_critical ("Trying to restore the selection on a selector after change"
+                " the number of columns. Are you removing columns while the"
+                " dialog is open?");
+    return;
+  }
+
+  if (dialog->priv->signal_changed_id)
+    g_signal_handler_block (selector, dialog->priv->signal_changed_id);
+  for (iter = current_selection, i = 0; iter; iter = g_slist_next (iter), i++) {
+    selected = (GList *) (iter->data);
+    model = hildon_touch_selector_get_model (selector, i);
+    hildon_touch_selector_unselect_all (selector, i);
+    for (selected_iter = selected; selected_iter; selected_iter = g_list_next (selected_iter)) {
+      current_path = (GtkTreePath *) selected_iter->data;
+      gtk_tree_model_get_iter (model, &tree_iter, current_path);
+      hildon_touch_selector_select_iter (selector, i, &tree_iter, FALSE);
+    }
+  }
+  if (HILDON_IS_TOUCH_SELECTOR_ENTRY (selector) && dialog->priv->current_text != NULL) {
+    HildonEntry *entry = hildon_touch_selector_entry_get_entry (HILDON_TOUCH_SELECTOR_ENTRY (selector));
+    hildon_entry_set_text (entry, dialog->priv->current_text);
+  }
+  if (dialog->priv->signal_changed_id)
+    g_signal_handler_unblock (selector, dialog->priv->signal_changed_id);
+}
+
 static gboolean
 requires_done_button (HildonPickerDialog * dialog)
 {
@@ -290,7 +507,34 @@ requires_done_button (HildonPickerDialog * dialog)
     (HILDON_TOUCH_SELECTOR (dialog->priv->selector));
 }
 
-/* ------------------------------ PUBLIC METHODS ---------------------------- */
+static void
+prepare_action_area (HildonPickerDialog *dialog)
+{
+  if (requires_done_button (dialog)) {
+    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), TRUE);
+    gtk_widget_show (GTK_DIALOG (dialog)->action_area);
+  } else {
+    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+    gtk_widget_hide (GTK_DIALOG (dialog)->action_area);
+  }
+}
+
+static void
+setup_interaction_mode (HildonPickerDialog * dialog)
+{
+  if (dialog->priv->signal_changed_id) {
+    g_signal_handler_disconnect (dialog->priv->selector,
+                                 dialog->priv->signal_changed_id);
+  }
+
+  if (requires_done_button (dialog) == FALSE) {
+    dialog->priv->signal_changed_id =
+      g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
+                        G_CALLBACK (_select_on_selector_changed_cb), dialog);
+  }
+}
+
+/*------------------------- PUBLIC METHODS ---------------------------- */
 
 /**
  * hildon_picker_dialog_new:
@@ -299,6 +543,8 @@ requires_done_button (HildonPickerDialog * dialog)
  * Creates a new #HildonPickerDialog
  *
  * Returns: a new #HildonPickerDialog
+ *
+ * Since: 2.2
  **/
 GtkWidget *
 hildon_picker_dialog_new (GtkWindow * parent)
@@ -319,46 +565,54 @@ static gboolean
 _hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
                                     HildonTouchSelector * selector)
 {
+  g_object_ref (selector);
+
+  /* Remove the old selector, if any */
   if (dialog->priv->selector != NULL) {
     gtk_container_remove (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
                           dialog->priv->selector);
-    g_object_unref (dialog->priv->selector);
-    dialog->priv->selector = NULL;
+    if (dialog->priv->signal_columns_changed_id) {
+            g_signal_handler_disconnect (dialog->priv->selector,
+                                         dialog->priv->signal_columns_changed_id);
+    }
   }
 
   dialog->priv->selector = GTK_WIDGET (selector);
 
-  if (dialog->priv->selector != NULL) {
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-                        dialog->priv->selector, TRUE, TRUE, 0);
-    gtk_widget_show (dialog->priv->selector);
-    g_object_ref (dialog->priv->selector);
-  }
+  /* Pack the new selector */
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                      dialog->priv->selector, TRUE, TRUE, 0);
 
-  if (dialog->priv->signal_id) {
-    g_signal_handler_disconnect (dialog->priv->selector,
-                                 dialog->priv->signal_id);
-  }
+  g_object_unref (selector);
 
-  if (requires_done_button (dialog)) {
-    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), TRUE);
-    gtk_widget_show (GTK_DIALOG (dialog)->action_area);
-    /* update the title */
-    dialog->priv->signal_id =
-      g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
-                        G_CALLBACK (_update_title_on_selector_changed_cb),
-                        dialog);
-  } else {
-    gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-    gtk_widget_hide (GTK_DIALOG (dialog)->action_area);
-    dialog->priv->signal_id =
-      g_signal_connect (G_OBJECT (dialog->priv->selector), "changed",
-                        G_CALLBACK (_select_on_selector_changed_cb), dialog);
+  /* Ensure that the dialog's height is correct */
+  gtk_widget_set_size_request (GTK_WIDGET (dialog->priv->selector), -1,
+                               HILDON_TOUCH_SELECTOR_HEIGHT);
+
+  gtk_widget_show (dialog->priv->selector);
+
+  prepare_action_area (dialog);
+  if (GTK_WIDGET_REALIZED (dialog)) {
+    setup_interaction_mode (dialog);
   }
 
+  dialog->priv->signal_columns_changed_id = g_signal_connect (G_OBJECT (dialog->priv->selector),
+                                                              "columns-changed",
+                                                              G_CALLBACK (on_selector_columns_changed), dialog);
   return TRUE;
 }
 
+/**
+ * hildon_picker_dialog_set_selector:
+ * @dialog: a #HildonPickerDialog
+ * @selector: a #HildonTouchSelector
+ *
+ * Sets @selector as the #HildonTouchSelector to be shown in @dialog
+ *
+ * Returns: %TRUE if @selector was set, %FALSE otherwise
+ *
+ * Since: 2.2
+ **/
 gboolean
 hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
                                    HildonTouchSelector * selector)
@@ -369,6 +623,16 @@ hildon_picker_dialog_set_selector (HildonPickerDialog * dialog,
   return HILDON_PICKER_DIALOG_GET_CLASS (dialog)->set_selector (dialog, selector);
 }
 
+/**
+ * hildon_picker_dialog_get_selector:
+ * @dialog: a #HildonPickerDialog
+ *
+ * Retrieves the #HildonTouchSelector associated to @dialog.
+ *
+ * Returns: a #HildonTouchSelector
+ *
+ * Since: 2.2
+ **/
 HildonTouchSelector *
 hildon_picker_dialog_get_selector (HildonPickerDialog * dialog)
 {