* src/hildon-touch-selector.c, (_hildon_touch_selector_set_model): Cleaning the code...
[hildon] / src / hildon-touch-selector.c
index 844df85..fbff98b 100644 (file)
 
 /**
  * SECTION:hildon-touch-selector
- * @short_description: A selector widget with several columns
+ * @short_description: A selector widget with several columns.
  *
- * HildonTouchSelector is a selector widget, very similar to the #GtkComboBox, but with
- * several individual pannable columns
+ * #HildonTouchSelector is a selector widget, that allows users to
+ * select items from one to many predefined lists. It is very similar
+ * to #GtkComboBox, but with several individual pannable columns.
  *
+ * Normally, you would use #HildonTouchSelector together with a
+ * #HildonPickerDialog activated from a button. For the most common
+ * cases, you should use #HildonPickerButton.
+ *
+ * The composition of each column in the selector is represented by a
+ * #GtkTreeModel. To add a new column to a #HildonTouchSelector, use
+ * hildon_touch_selector_append_column(). If you want to add a
+ * text-only column, without special attributes, use
+ * hildon_touch_selector_append_text_column().
+ *
+ * It is highly recommended that you use only one column
+ * #HildonTouchSelector<!-- -->s.
+ * If you only need a text only, one column selector, you can create it with
+ * hildon_touch_selector_new_text() and populate with
+ * hildon_touch_selector_append_text(), hildon_touch_selector_prepend_text(),
+ * and hildon_touch_selector_insert_text().
+ *
+ * If you need a selector widget that also accepts user inputs, you
+ * can use #HildonTouchSelectorEntry.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -33,6 +53,9 @@
 
 #include <string.h>
 #include <stdlib.h>
+
+#include "hildon-gtk.h"
+
 #include "hildon-pannable-area.h"
 #include "hildon-touch-selector.h"
 
@@ -43,7 +66,7 @@ G_DEFINE_TYPE (HildonTouchSelector, hildon_touch_selector, GTK_TYPE_VBOX)
 
 #define CENTER_ON_SELECTED_ITEM_DELAY 50
 
-/**
+/*
  * Struct to maintain the data of each column. The columns are the elements
  * of the widget that belongs properly to the selection behaviour. As
  * the selector contents are arranged in a #GtkHBox, you can add more widgets, like buttons etc.
@@ -70,12 +93,21 @@ struct _HildonTouchSelectorPrivate
 
 enum
 {
+  PROP_HAS_MULTIPLE_SELECTION = 1
+};
+
+enum
+{
   CHANGED,
   LAST_SIGNAL
 };
 
 static gint hildon_touch_selector_signals[LAST_SIGNAL] = { 0 };
 
+static void hildon_touch_selector_get_property (GObject * object,
+                                                guint prop_id,
+                                                GValue * value, GParamSpec * pspec);
+
 /* gtkwidget */
 static void hildon_touch_selector_map (GtkWidget * widget);
 
@@ -94,6 +126,12 @@ static SelectorColumn *_create_new_column (HildonTouchSelector * selector,
 static gboolean _hildon_touch_selector_center_on_selected_items (gpointer data);
 
 static void
+_hildon_touch_selector_set_model (HildonTouchSelector * selector,
+                                  gint num_column, GtkTreeModel * model);
+static gboolean
+_hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector);
+
+static void
 hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
 {
   GObjectClass *gobject_class;
@@ -108,12 +146,18 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
 
   /* GObject */
 
+  gobject_class->get_property = hildon_touch_selector_get_property;
+
   /* GtkWidget */
   widget_class->map = hildon_touch_selector_map;
 
   /* GtkContainer */
   container_class->remove = hildon_touch_selector_remove;
 
+  /* HildonTouchSelector */
+  class->set_model = _hildon_touch_selector_set_model;
+
+  class->has_multiple_selection = _hildon_touch_selector_has_multiple_selection;
 
   /* signals */
   /**
@@ -121,10 +165,10 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
    * @widget: the object which received the signal
    *
    * The changed signal is emitted when the active
-   * item is changed. The can be due to the user selecting
+   * item is changed. This can be due to the user selecting
    * a different item from the list, or due to a
-   * call to hildon_touch_selector_set_active_iter() on
-   * one of the columns
+   * call to hildon_touch_selector_select_iter() on
+   * one of the columns.
    *
    */
   hildon_touch_selector_signals[CHANGED] =
@@ -136,10 +180,37 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
                   gtk_marshal_NONE__INT, G_TYPE_NONE, 1, G_TYPE_INT);
   /* properties */
 
+  g_object_class_install_property (gobject_class, PROP_HAS_MULTIPLE_SELECTION,
+                                   g_param_spec_boolean ("has-multiple-selection",
+                                                         "has multiple selection",
+                                                         "Whether the widget has multiple "
+                                                         "selection (like multiple columns, "
+                                                         "multiselection mode, or multiple "
+                                                         "internal widgets) and therefore "
+                                                         "it may need a confirmation button, "
+                                                         "for instance.",
+                                                         FALSE,
+                                                         G_PARAM_READABLE));
+
   /* style properties */
   g_type_class_add_private (object_class, sizeof (HildonTouchSelectorPrivate));
 }
 
+static void
+hildon_touch_selector_get_property (GObject * object,
+                                    guint prop_id,
+                                    GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+  case PROP_HAS_MULTIPLE_SELECTION:
+    g_value_set_boolean (value,
+                         hildon_touch_selector_has_multiple_selection (HILDON_TOUCH_SELECTOR (object)));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
 
 static void
 hildon_touch_selector_init (HildonTouchSelector * selector)
@@ -224,7 +295,7 @@ hildon_touch_selector_remove (GtkContainer * container, GtkWidget * widget)
  *
  * Default print function
  *
- * Returns: a new string that represent the selected items
+ * Returns: a new string that represents the selected items
  **/
 static gchar *
 _default_print_func (HildonTouchSelector * selector)
@@ -285,7 +356,7 @@ _default_print_func (HildonTouchSelector * selector)
 
   for (i = initial_value; i < num_columns; i++) {
     model = hildon_touch_selector_get_model (selector, i);
-    if (hildon_touch_selector_get_active_iter (selector, i, &iter)) {
+    if (hildon_touch_selector_get_selected (selector, i, &iter)) {
 
       gtk_tree_model_get (model, &iter, 0, &current_string, -1);
       if (i != 0) {
@@ -326,7 +397,6 @@ _create_new_column (HildonTouchSelector * selector,
 {
   SelectorColumn *new_column = NULL;
   GtkTreeViewColumn *tree_column = NULL;
-  GValue val = { 0, };
   GtkTreeView *tv = NULL;
   GtkWidget *panarea = NULL;
   GtkTreeSelection *selection = NULL;
@@ -345,9 +415,9 @@ _create_new_column (HildonTouchSelector * selector,
     attribute = va_arg (args, gchar *);
   }
 
-  tv = g_object_new (GTK_TYPE_TREE_VIEW, "model", model, "name", "fremantle-widget",    /* FIXME: is this always this name? */
-                     "hildon-ui-mode", HILDON_UI_MODE_EDIT,
-                     "rules-hint", TRUE, NULL);
+  tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (HILDON_UI_MODE_EDIT));
+  gtk_tree_view_set_model (tv, model);
+  gtk_tree_view_set_rules_hint (tv, TRUE);
 
   gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tree_column);
 
@@ -356,14 +426,8 @@ _create_new_column (HildonTouchSelector * selector,
 
   panarea = hildon_pannable_area_new ();
 
-  g_value_init (&val, G_TYPE_INT);
-  g_value_set_int (&val, HILDON_PANNABLE_AREA_INDICATOR_MODE_HIDE);
-  g_object_set_property (G_OBJECT (panarea), "vindicator-mode", &val);
-
-  g_value_unset (&val);
-  g_value_init (&val, G_TYPE_BOOLEAN);
-  g_value_set_boolean (&val, FALSE);
-  g_object_set_property (G_OBJECT (panarea), "initial-hint", &val);
+  g_object_set (G_OBJECT (panarea), "vscrollbar-policy", GTK_POLICY_NEVER, 
+                "initial-hint", FALSE, NULL);
 
   gtk_container_add (GTK_CONTAINER (panarea), GTK_WIDGET (tv));
 
@@ -392,21 +456,19 @@ _create_new_column (HildonTouchSelector * selector,
 
 /**
  * hildon_touch_selector_new:
- * @:
  *
- * Creates a new empty #HildonTouchSelector
+ * Creates a new empty #HildonTouchSelector.
  *
- * Returns: a new #HildonTouchSelector
+ * Returns: a new #HildonTouchSelector.
  **/
 GtkWidget *
-hildon_touch_selector_new ()
+hildon_touch_selector_new (void)
 {
   return g_object_new (HILDON_TYPE_TOUCH_SELECTOR, NULL);
 }
 
 /**
  * hildon_touch_selector_new_text:
- * @void: 
  *
  * Creates a #HildonTouchSelector with a single text column that
  * can be populated conveniently through hildon_touch_selector_append_text(),
@@ -424,7 +486,7 @@ hildon_touch_selector_new_text (void)
   store = gtk_list_store_new (1, G_TYPE_STRING);
 
   hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
-                                            GTK_TREE_MODEL (store));
+                                            GTK_TREE_MODEL (store), TRUE);
 
   return selector;
 }
@@ -487,7 +549,7 @@ hildon_touch_selector_prepend_text (HildonTouchSelector * selector,
  * @position: the position to insert @text.
  * @text: A non %NULL text string.
  *
- * Inserts a new entry in particular positio of a #HildoTouchSelector created
+ * Inserts a new entry in particular position of a #HildoTouchSelector created
  * with hildon_touch_selector_new_text().
  *
  **/
@@ -511,22 +573,30 @@ hildon_touch_selector_insert_text (HildonTouchSelector * selector,
 }
 
 /**
- * hildon_touch_selector_append_text_column
- * @selector: the #HildonTouchSelector widget
+ * hildon_touch_selector_append_column
+ * @selector: a #HildonTouchSelector
  * @model: the #GtkTreeModel with the data of the column
+ * @cell_renderer: The #GtkCellRenderer where to draw each row contents.
+ * @Varargs: a %NULL-terminated pair of attributes and column numbers.
  *
- * This functions adds a new column to the widget, with the data on
- * the model. Only the widgets added in this way should used on
- * the selection logic, ie: the print function, the "changed" signal etc.
+ * This functions adds a new column to the widget, whose data will
+ * be obtained from the model. Only widgets added this way should used on
+ * the selection logic, i.e., the print function, the #HildonTouchPicker::changed
+ * signal, etc.
  *
- * There are a prerequisite on this model: this append
- * consideres that the text data is in the first column of the model
+ * Contents will be represented in @cell_renderer. You can pass a %NULL-terminated
+ * list of pairs property/value, in the same way you would use
+ * gtk_tree_view_column_set_attributes().
  *
- * Basically it adds a tree view to the widget, using the model and
+ * There is a prerequisite to be considered on models used: text data must
+ * be in the first column.
+ *
+ * This method basically adds a #GtkTreeView to the widget, using the model and
  * the data received.
  *
- * Returns: TRUE if a new column were added, FALSE otherside
+ * Returns: %TRUE if a new column was added, %FALSE otherwise
  **/
+
 gboolean
 hildon_touch_selector_append_column (HildonTouchSelector * selector,
                                      GtkTreeModel * model,
@@ -558,18 +628,19 @@ hildon_touch_selector_append_column (HildonTouchSelector * selector,
 
 /**
  * hildon_touch_selector_append_text_column
- * @selector: the #HildonTouchSelector widget
- * @model: the #GtkTreeModel with the data of the column
+ * @selector: a #HildonTouchSelector
+ * @model: a #GtkTreeModel with data for the column
+ * @center: whether to center the text on the column
  *
- * Equivalent to hildon_touch_selector_append_column, but using a
- * default text cell renderer. This is the most common use of the
+ * Equivalent to hildon_touch_selector_append_column(), but using a
+ * default text cell renderer. This is the most common use case of the
  * widget.
  *
- * Returns: TRUE if a new column were added, FALSE otherside
+ * Returns: %TRUE if a new column was added, %FALSE otherwise.
  **/
 gboolean
 hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
-                                          GtkTreeModel * model)
+                                          GtkTreeModel * model, gboolean center)
 {
   GtkCellRenderer *renderer = NULL;
   GValue val = { 0, };
@@ -580,10 +651,12 @@ hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
   if (model != NULL) {
     renderer = gtk_cell_renderer_text_new ();
 
-    g_value_init (&val, G_TYPE_FLOAT);
-    g_value_set_float (&val, 0.5);
-    /* FIXME: center the text, this should be configurable */
-    g_object_set_property (G_OBJECT (renderer), "xalign", &val);
+    if (center) {
+      g_value_init (&val, G_TYPE_FLOAT);
+      g_value_set_float (&val, 0.5);
+      /* FIXME: center the text, this should be configurable */
+      g_object_set_property (G_OBJECT (renderer), "xalign", &val);
+    }
 
     return hildon_touch_selector_append_column (selector, model, renderer,
                                                 "text", 0, NULL);
@@ -593,29 +666,46 @@ hildon_touch_selector_append_text_column (HildonTouchSelector * selector,
 }
 
 /**
- * hildon_touch_selector_remove_column
+ * hildon_touch_selector_remove_column:
  * @selector: a #HildonTouchSelector
- * @position: the column position to remove, counting from 0 to (total column number - 1)
+ * @column: the position of the column to be removed
  *
+ * Removes a column from @selector.
  *
- * Returns: TRUE is the column was removed, FALSE otherwise
+ * Returns: %TRUE if the column was removed, %FALSE otherwise
  **/
 gboolean
-hildon_touch_selector_remove_column (HildonTouchSelector * selector, gint position)
+hildon_touch_selector_remove_column (HildonTouchSelector * selector, gint column)
 {
   SelectorColumn *current_column = NULL;
+  HildonTouchSelectorPrivate *priv;
 
   g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
-  g_return_val_if_fail (position <
+  g_return_val_if_fail (column <
                         hildon_touch_selector_get_num_columns (selector), FALSE);
 
-  current_column = g_slist_nth_data (selector->priv->columns, position);
+  priv = HILDON_TOUCH_SELECTOR_GET_PRIVATE (selector);
+  current_column = g_slist_nth_data (priv->columns, column);
 
-  gtk_container_remove (GTK_CONTAINER (selector), current_column->panarea);
+  gtk_container_remove (GTK_CONTAINER (priv->hbox), current_column->panarea);
+  priv->columns = g_slist_remove (priv->columns, current_column);
+  g_free (current_column);
 
   return TRUE;
 }
 
+/**
+ * hildon_touch_selector_set_column_attributes:
+ * @selector: a #HildonTouchSelector
+ * @num_column: the number of the column whose attributes we're setting
+ * @cell_renderer: the #GtkCellRendere we're setting the attributes of
+ * @Varargs: A %NULL-terminated list of attributes.
+ *
+ * Sets the attributes for the given column. The attributes must be given
+ * in attribute/column pairs, just like in gtk_tree_view_column_set_attributes().
+ * All existing attributes are removed and replaced with the new ones.
+ *
+ **/
 void
 hildon_touch_selector_set_column_attributes (HildonTouchSelector * selector,
                                              gint num_column,
@@ -657,20 +747,30 @@ hildon_touch_selector_set_column_attributes (HildonTouchSelector * selector,
   gtk_tree_view_append_column (current_column->tree_view, tree_column);
 }
 
-gboolean
-hildon_touch_selector_insert_column (HildonTouchSelector * selector, gint position)
-{
-  g_warning ("Un-implemented!");
-
-  return TRUE;
-}
-
+/**
+ * hildon_touch_selector_get_num_columns:
+ * @selector: a #HildonTouchSelector
+ *
+ * Gets the number of columns in the #HildonTouchSelector.
+ *
+ * Returns: the number of columns in @selector.
+ **/
 gint
 hildon_touch_selector_get_num_columns (HildonTouchSelector * selector)
 {
+  g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), -1);
+
   return g_slist_length (selector->priv->columns);
 }
 
+/**
+ * hildon_touch_selector_get_column_selection_mode:
+ * @selector: a #HildonTouchSelector
+ *
+ * Gets the selection mode of @selector.
+ *
+ * Returns: one of #HildonTouchSelectorSelectionMode
+ **/
 HildonTouchSelectorSelectionMode
 hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
 {
@@ -699,15 +799,21 @@ hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
   return result;
 }
 
+/**
+ * hildon_touch_selector_set_column_selection_mode:
+ * @selector: a #HildonTouchSelector
+ * @mode: the #HildonTouchSelectorMode for @selector
+ *
+ * Sets the selection mode for @selector. See #HildonTouchSelectorSelectionMode.
+ **/
 void
 hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
-                                                 HildonTouchSelectorSelectionMode
-                                                 mode)
+                                                 HildonTouchSelectorSelectionMode mode)
 {
   GtkTreeView *tv = NULL;
   SelectorColumn *column = NULL;
   GtkTreeSelection *selection = NULL;
-  GtkSelectionMode treeview_mode;
+  GtkSelectionMode treeview_mode = GTK_SELECTION_MULTIPLE;
   GtkTreeIter iter;
 
   g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
@@ -737,6 +843,18 @@ hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
 
 }
 
+/**
+ * hildon_touch_selector_set_print_func:
+ * @selector: a #HildonTouchSelector
+ * @func: a #HildonTouchSelectorPrintFunc function
+ *
+ * Sets the function to be used by hildon_touch_selector_get_current_text()
+ * to produce a text representation of the currently selected items in @selector.
+ * The default function will return a concatenation of comma separated items
+ * selected in each column in @selector. Use this to override this method if you
+ * need a particular representation for your application.
+ *
+ **/
 void
 hildon_touch_selector_set_print_func (HildonTouchSelector * selector,
                                       HildonTouchSelectorPrintFunc func)
@@ -746,6 +864,16 @@ hildon_touch_selector_set_print_func (HildonTouchSelector * selector,
   selector->priv->print_func = func;
 }
 
+/**
+ * hildon_touch_selector_get_print_func:
+ * @selector: a #HildonTouchSelector
+ *
+ * Gets the #HildonTouchSelectorPrintFunc currently used. See
+ * hildon_touch_selector_set_print_func().
+ *
+ * Returns: a #HildonTouchSelectorPrintFunc or %NULL if the default
+ * one is currently used.
+ **/
 HildonTouchSelectorPrintFunc
 hildon_touch_selector_get_print_func (HildonTouchSelector * selector)
 {
@@ -755,33 +883,39 @@ hildon_touch_selector_get_print_func (HildonTouchSelector * selector)
 }
 
 /**
- * hildon_touch_selector_get_active_iter:
+ * hildon_touch_selector_get_selected:
  * @selector: a #HildonTouchSelector
  * @column: the column number we want to get the element
  * @iter: #GtkTreeIter currently selected
  *
- * Sets iter to the currently selected node on the nth-column, if selection is set to
- * HILDON_TOUCH_SELECTOR_SINGLE. iter may be NULL if you just want to test if selection
- * has any selected nodes.
+ * Sets @iter to the currently selected node on the nth-column, if selection is
+ * set to %HILDON_TOUCH_SELECTOR_SINGLE or %HILDON_TOUCH_SELECTOR_MULTIPLE with
+ * a column different that the first one. @iter may be %NULL if you just want to
+ * test if selection has any selected items.
  *
- * This function will not work if you use selection is HILDON_TOUCH_SELECTOR_MULTIPLE.
+ * This function will not work if selection is in
+ * %HILDON_TOUCH_SELECTOR_MULTIPLE mode and the column is the first one.
  *
- * See gtk_tree_selection_get_selected for more information
+ * See gtk_tree_selection_get_selected() for more information.
  *
- * Returns: TRUE if was posible to get the iter, FALSE otherwise
+ * Returns: %TRUE if @iter was correctly set, %FALSE otherwise
  **/
 gboolean
-hildon_touch_selector_get_active_iter (HildonTouchSelector * selector,
-                                       gint column, GtkTreeIter * iter)
+hildon_touch_selector_get_selected (HildonTouchSelector * selector,
+                                    gint column, GtkTreeIter * iter)
 {
   GtkTreeSelection *selection = NULL;
   SelectorColumn *current_column = NULL;
+  HildonTouchSelectorSelectionMode mode;
 
   g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
-  g_return_val_if_fail (hildon_touch_selector_get_column_selection_mode (selector)
-                        == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE, FALSE);
   g_return_val_if_fail (column < hildon_touch_selector_get_num_columns (selector),
                         FALSE);
+  mode = hildon_touch_selector_get_column_selection_mode (selector);
+  g_return_val_if_fail
+    ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE) ||
+     ((mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)&&(column>0)),
+     FALSE);
 
   current_column = g_slist_nth_data (selector->priv->columns, column);
 
@@ -792,18 +926,20 @@ hildon_touch_selector_get_active_iter (HildonTouchSelector * selector,
 }
 
 /**
- * hildon_touch_selector_set_active_iter
+ * hildon_touch_selector_select_iter
  * @selector: a #HildonTouchSelector
  * @column:   the column to selects
  * @iter:     the #GtkTreeIter to be selected
+ * @scroll_to: whether to smoothly scroll to the item
  *
- * Sets the current iter
+ * Sets the currently selected item in the column @column to the one pointed by @iter,
+ * optionally smoothly scrolling to it.
  *
  **/
 void
-hildon_touch_selector_set_active_iter (HildonTouchSelector * selector,
-                                       gint column, GtkTreeIter * iter,
-                                       gboolean scroll_to)
+hildon_touch_selector_select_iter (HildonTouchSelector * selector,
+                                   gint column, GtkTreeIter * iter,
+                                   gboolean scroll_to)
 {
   GtkTreePath *path;
   GtkTreeModel *model;
@@ -818,35 +954,60 @@ hildon_touch_selector_set_active_iter (HildonTouchSelector * selector,
   current_column = g_slist_nth_data (selector->priv->columns, column);
 
   selection = gtk_tree_view_get_selection (current_column->tree_view);
+  model = gtk_tree_view_get_model (current_column->tree_view);
+  path = gtk_tree_model_get_path (model, iter);
 
   gtk_tree_selection_select_iter (selection, iter);
 
   if (scroll_to) {
-    model = gtk_tree_view_get_model (current_column->tree_view);
-    path = gtk_tree_model_get_path (model, iter);
     gtk_tree_view_get_background_area (current_column->tree_view,
                                        path, NULL, &rect);
     gtk_tree_view_convert_bin_window_to_tree_coords (current_column->tree_view,
                                                      0, rect.y, NULL, &y);
     hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (current_column->panarea),
                                     -1, y);
-    gtk_tree_path_free (path);
   }
+  gtk_tree_path_free (path);
+}
+
+/**
+ * hildon_touch_selector_unselect_iter
+ * @selector: a #HildonTouchSelector
+ * @column:   the column to unselects from
+ * @iter:     the #GtkTreeIter to be unselected
+ *
+ * Unselect the item pointed by @iter in the column @column
+ *
+ **/
+
+void hildon_touch_selector_unselect_iter (HildonTouchSelector * selector,
+                                          gint column,
+                                          GtkTreeIter * iter)
+{
+  SelectorColumn *current_column = NULL;
+  GtkTreeSelection *selection = NULL;
+
+  g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
+  g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
+
+  current_column = g_slist_nth_data (selector->priv->columns, column);
+  selection = gtk_tree_view_get_selection (current_column->tree_view);
+  gtk_tree_selection_unselect_iter (selection, iter);
 }
 
 /**
  * hildon_touch_selector_get_selected_rows:
  * @selector: a #HildonTouchSelector
- * @column:
+ * @column: the position of the column to get the selected rows from
  *
- * Creates a list of path of all selected rows at a concrete column. Additionally,
- * if you are planning on modifying the model after calling this function, you may
+ * Creates a list of #GtkTreePath<!-- -->s of all selected rows in a column. Additionally,
+ * if you to plan to modify the model after calling this function, you may
  * want to convert the returned list into a list of GtkTreeRowReferences. To do this,
  * you can use gtk_tree_row_reference_new().
  *
- * See #GtkTreeSelection:gtk_tree_selection_get_selected_rows for more information
+ * See gtk_tree_selection_get_selected_rows() for more information.
  *
- * Returns: A new GList containing a GtkTreePath for each selected row in the concrete column
+ * Returns: A new #GList containing a #GtkTreePath for each selected row in the column @column.
  *
  **/
 GList *
@@ -870,6 +1031,15 @@ hildon_touch_selector_get_selected_rows (HildonTouchSelector * selector,
   return result;
 }
 
+/**
+ * hildon_touch_selector_get_model:
+ * @selector: a #HildonTouchSelector
+ * @column: the position of the column in @selector
+ *
+ * Gets the model of a column of @selector.
+ *
+ * Returns: the #GtkTreeModel for the column @column of @selector.
+ **/
 GtkTreeModel *
 hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
 {
@@ -884,31 +1054,45 @@ hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
   return current_column->model;
 }
 
+static void
+_hildon_touch_selector_set_model (HildonTouchSelector * selector,
+                                 gint column, GtkTreeModel * model)
+{
+  SelectorColumn *current_column = NULL;
+
+  current_column =
+    (SelectorColumn *) g_slist_nth_data (selector->priv->columns, column);
+
+  current_column->model = model;
+  gtk_tree_view_set_model (current_column->tree_view, current_column->model);
+}
+
+/**
+ * hildon_touch_selector_set_model:
+ * @selector: a #HildonTouchSelector
+ * @column: the position of the column to set the model to
+ * @model: a #GtkTreeModel
+ *
+ * Sets the #GtkTreeModel for a particular column in @model.
+ **/
 void
 hildon_touch_selector_set_model (HildonTouchSelector * selector,
-                                 gint num_column, GtkTreeModel * model)
+                                 gint column, GtkTreeModel * model)
 {
-  SelectorColumn *column = NULL;
-
   g_return_if_fail (HILDON_TOUCH_SELECTOR (selector));
-  g_return_if_fail (num_column <
-                    hildon_touch_selector_get_num_columns (selector));
-
-  column =
-    (SelectorColumn *) g_slist_nth_data (selector->priv->columns, num_column);
+  g_return_if_fail (column < hildon_touch_selector_get_num_columns (selector));
 
-  column->model = model;
-  gtk_tree_view_set_model (column->tree_view, column->model);
+  HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->set_model (selector, column, model);
 }
 
 /**
- * hildon_touch_selector_get_active_text
- * @selector: the #HildonTouchSelector
+ * hildon_touch_selector_get_current_text:
+ * @selector: a #HildonTouchSelector
  *
- * It return a new gchar that represents the current element(s) selected,
- * using the current print_func.
+ * Returns a string representing the currently selected items for
+ * each column of @selector. See hildon_touch_selector_set_print_func().
  *
- * Returns: a new allocated gchar*
+ * Returns: a newly allocated string.
  **/
 gchar *
 hildon_touch_selector_get_current_text (HildonTouchSelector * selector)
@@ -952,7 +1136,7 @@ _hildon_touch_selector_center_on_selected_items (gpointer data)
         && (selection_mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)) {
       break;
     }
-    if (hildon_touch_selector_get_active_iter (selector, i, &iter)) {
+    if (hildon_touch_selector_get_selected (selector, i, &iter)) {
       path = gtk_tree_model_get_path (column->model, &iter);
       gtk_tree_view_get_background_area (GTK_TREE_VIEW
                                          (column->tree_view), path, NULL,
@@ -973,3 +1157,38 @@ _hildon_touch_selector_center_on_selected_items (gpointer data)
 
   return FALSE;
 }
+
+static gboolean
+_hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
+{
+  HildonTouchSelectorSelectionMode mode = HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE;
+  gint n_columns = 0;
+
+  n_columns = hildon_touch_selector_get_num_columns (selector);
+  mode = hildon_touch_selector_get_column_selection_mode (selector);
+
+  return ((n_columns > 1) || (mode == HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE));
+}
+
+/**
+ * hildon_touch_selector_has_multiple_selection:
+ * @selector: A #HildonTouchSelector
+ *
+ * Determines whether @selector is complex enough to actually require an
+ * extra selection step than only picking an item. This is normally %TRUE
+ * if @selector has multiple columns, multiple selection, or when it is a
+ * more complex widget, like %HildonTouchSelectorEntry.
+ *
+ * This information is useful for widgets containing a %HildonTouchSelector,
+ * like #HildonPickerDialog, that could need a "Done" button, in case that
+ * its internal #HildonTouchSelector has multiple columns, for instance.
+ *
+ * Returns: %TRUE if @selector requires multiple selection steps.
+ **/
+gboolean
+hildon_touch_selector_has_multiple_selection (HildonTouchSelector * selector)
+{
+  g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
+
+  return HILDON_TOUCH_SELECTOR_GET_CLASS (selector)->has_multiple_selection (selector);
+}