Added new method hildon_touch_selector_center_on_index
[hildon] / hildon / hildon-touch-selector.c
index 4ab005d..518924c 100644 (file)
@@ -30,7 +30,7 @@
  * #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
+ * The contents of each #HildonTouchSelector column are stored in 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
  *                                                 GTK_TREE_MODEL (store_icons),
  *                                                 renderer, "stock-id", 0, NULL);
  * <!-- -->
- *   g_object_set (G_OBJECT (column), "text-column", 0, NULL);
+ *   hildon_touch_selector_column_set_text_column (column, 0);
  * <!-- -->
  *   hildon_touch_selector_set_column_selection_mode (HILDON_TOUCH_SELECTOR (selector),
  *                                                    HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
 /**
  * SECTION:hildon-touch-selector-column
  * @short_description: A visible column in a #HildonTouchSelector
+ * @see_also: #HildonTouchSelector
  *
- * #HildonTouchSelectorColumn object represents a visible column in
- * #HildonTouchSelector. It allows to manage the cell renderers related to each
- * column.
+ * A #HildonTouchSelectorColumn is a column in a
+ * #HildonTouchSelector. This class implements the #GtkCellLayout interface, allowing
+ * a flexible management of the cellrenderers in each #HildonTouchSelector column.
  */
 
 #undef HILDON_DISABLE_DEPRECATED
@@ -197,6 +198,7 @@ struct _HildonTouchSelectorColumnPrivate
   GtkTreePath *initial_path;
 
   GtkWidget *panarea;           /* the pannable widget */
+  GtkTreeRowReference *last_activated;
 };
 
 struct _HildonTouchSelectorPrivate
@@ -210,12 +212,15 @@ struct _HildonTouchSelectorPrivate
   HildonTouchSelectorPrintFunc print_func;
   gpointer print_user_data;
   GDestroyNotify print_destroy_func;
+
+  HildonUIMode hildon_ui_mode;
 };
 
 enum
 {
   PROP_HAS_MULTIPLE_SELECTION = 1,
-  PROP_INITIAL_SCROLL
+  PROP_INITIAL_SCROLL,
+  PROP_HILDON_UI_MODE
 };
 
 enum
@@ -249,6 +254,12 @@ static void hildon_touch_selector_remove        (GtkContainer * container,
 static void _row_tapped_cb                      (GtkTreeView * tree_view,
                                                  GtkTreePath * path,
                                                  gpointer user_data);
+static void
+hildon_touch_selector_row_activated_cb          (GtkTreeView       *tree_view,
+                                                 GtkTreePath       *path,
+                                                 GtkTreeViewColumn *column,
+                                                 gpointer           user_data);
+
 static gchar *_default_print_func               (HildonTouchSelector * selector,
                                                  gpointer user_data);
 
@@ -261,6 +272,12 @@ static gboolean
 on_realize_cb                                  (GtkWidget *widget,
                                                 gpointer data);
 static void
+on_row_changed                                 (GtkTreeModel *model,
+                                                GtkTreePath *path,
+                                                GtkTreeIter *iter,
+                                                gpointer userdata);
+
+static void
 hildon_touch_selector_scroll_to (HildonTouchSelectorColumn *column,
                                  GtkTreeView *tv,
                                  GtkTreePath *path);
@@ -304,6 +321,8 @@ static void hildon_touch_selector_column_cell_layout_reorder       (GtkCellLayou
                                                                     gint                   position);
 static GList *hildon_touch_selector_column_cell_layout_get_cells   (GtkCellLayout         *cell_layout);
 
+static void
+hildon_touch_selector_check_ui_mode_coherence   (HildonTouchSelector *selector);
 
 static void
 hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
@@ -393,6 +412,31 @@ hildon_touch_selector_class_init (HildonTouchSelectorClass * class)
                                                          TRUE,
                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+    /**
+     * HildonTouchSelector:hildon-ui-mode:
+     *
+     * Specifies which UI mode to use in the internal treeviews.  A setting
+     * of %HILDON_UI_MODE_NORMAL will cause these tree view to disable selections
+     * and emit row-activated as soon as a row is pressed.  You can use the
+     * method hildon_touch_selector_get_last_activated_row() to get it. When
+     * %HILDON_UI_MODE_EDIT is set, selections can be made according to the
+     * setting of the mode on GtkTreeSelection.
+     *
+     * Toggling this property will cause the tree view to select an
+     * appropriate selection mode if not already done.
+     *
+     * Since: Hildon 2.2
+     */
+  g_object_class_install_property (gobject_class,
+                                   PROP_HILDON_UI_MODE,
+                                   g_param_spec_enum ("hildon-ui-mode",
+                                                      "Hildon UI Mode",
+                                                      "The Hildon UI mode according "
+                                                      "to which the touch selector "
+                                                      "should behave",
+                                                      HILDON_TYPE_UI_MODE,
+                                                      HILDON_UI_MODE_EDIT,
+                                                      G_PARAM_READWRITE));
   /* style properties */
   /* We need to ensure fremantle mode for the treeview in order to work
      properly. This is not about the appearance, this is about behaviour */
@@ -419,6 +463,9 @@ hildon_touch_selector_get_property (GObject * object,
   case PROP_INITIAL_SCROLL:
     g_value_set_boolean (value, priv->initial_scroll);
     break;
+  case PROP_HILDON_UI_MODE:
+    g_value_set_enum (value, priv->hildon_ui_mode);
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     break;
@@ -435,6 +482,10 @@ hildon_touch_selector_set_property (GObject *object, guint prop_id,
   case PROP_INITIAL_SCROLL:
     priv->initial_scroll = g_value_get_boolean (value);
     break;
+  case PROP_HILDON_UI_MODE:
+    hildon_touch_selector_set_hildon_ui_mode (HILDON_TOUCH_SELECTOR (object),
+                                              g_value_get_enum (value));
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     break;
@@ -460,6 +511,8 @@ hildon_touch_selector_init (HildonTouchSelector * selector)
 
   selector->priv->changed_blocked = FALSE;
 
+  selector->priv->hildon_ui_mode = HILDON_UI_MODE_EDIT;
+
   gtk_box_pack_end (GTK_BOX (selector), selector->priv->hbox,
                     TRUE, TRUE, 0);
   gtk_widget_show (selector->priv->hbox);
@@ -479,10 +532,24 @@ hildon_touch_selector_dispose (GObject * object)
     (* gobject_class->dispose) (object);
 }
 
+static void
+clean_column                                    (HildonTouchSelectorColumn *col,
+                                                 HildonTouchSelector *selector)
+{
+  g_signal_handlers_disconnect_by_func (col->priv->model,
+                                       on_row_changed, selector);
+
+  if (col->priv->last_activated != NULL) {
+    gtk_tree_row_reference_free (col->priv->last_activated);
+    col->priv->last_activated = NULL;
+  }
+}
+
 /*
  * IMPLEMENTATION NOTES:
- * Some people sent questions regarding a missing dispose/finalize function on
- * this widget that could lead to leak memory, so we will clarify this topic.
+ * Some people sent questions regarding the fact that the dispose/finalize functions
+ * doesn't clean the internal widgets that could lead to leak memory, so we will
+ * clarify this topic.
  *
  * This is not required as #HildonTouchSelector extends #GtkContainer. When the
  * widget is freed, the #GtkContainer freeing memory functions are called. This
@@ -510,6 +577,7 @@ hildon_touch_selector_remove (GtkContainer * container, GtkWidget * widget)
 
   /* Remove the extra data related to the columns, if required. */
   if (widget == selector->priv->hbox) {
+    g_slist_foreach (selector->priv->columns, (GFunc) clean_column, selector);
     g_slist_foreach (selector->priv->columns, (GFunc) g_object_unref, NULL);
 
     g_slist_free (selector->priv->columns);
@@ -540,11 +608,25 @@ static void
 hildon_touch_selector_emit_value_changed        (HildonTouchSelector *selector,
                                                  gint column)
 {
+  /* FIXME: it could be good to emit too the GtkTreePath of the element
+     selected, as now it is required to connect to the signal and then ask
+     for the element selected. We can't do this API change, in order to avoid
+     and ABI break */
   if (!selector->priv->changed_blocked) {
     g_signal_emit (selector, hildon_touch_selector_signals[CHANGED], 0, column);
   }
 }
 
+static void
+hildon_touch_selector_check_ui_mode_coherence   (HildonTouchSelector *selector)
+{
+  g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
+
+  if (hildon_touch_selector_get_num_columns (selector) > 1) {
+    hildon_touch_selector_set_hildon_ui_mode (selector, HILDON_UI_MODE_EDIT);
+  }
+}
+
 /**
  * default_print_func:
  * @selector: a #HildonTouchSelector
@@ -583,7 +665,7 @@ _default_print_func (HildonTouchSelector * selector, gpointer user_data)
     selected_rows = hildon_touch_selector_get_selected_rows (selector, 0);
     model = hildon_touch_selector_get_model (selector, 0);
     column = hildon_touch_selector_get_column (selector, 0);
-    g_object_get (G_OBJECT(column), "text-column", &text_column, NULL);
+    text_column = hildon_touch_selector_column_get_text_column (column);
 
     result = g_strdup_printf ("(");
     i = 0;
@@ -627,7 +709,7 @@ _default_print_func (HildonTouchSelector * selector, gpointer user_data)
   for (i = initial_value; i < num_columns; i++) {
     model = hildon_touch_selector_get_model (selector, i);
     column = hildon_touch_selector_get_column (selector, i);
-    g_object_get (G_OBJECT(column), "text-column", &text_column, NULL);
+    text_column = hildon_touch_selector_column_get_text_column (column);
 
     if (hildon_touch_selector_get_selected (selector, i, &iter)) {
       if (text_column == -1 ) {
@@ -654,6 +736,27 @@ _default_print_func (HildonTouchSelector * selector, gpointer user_data)
 }
 
 static void
+hildon_touch_selector_row_activated_cb          (GtkTreeView       *tree_view,
+                                                 GtkTreePath       *path,
+                                                 GtkTreeViewColumn *column,
+                                                 gpointer           user_data)
+{
+  HildonTouchSelectorColumn *selector_column = NULL;
+  GtkTreeModel *model = NULL;
+
+  g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (user_data));
+  selector_column = HILDON_TOUCH_SELECTOR_COLUMN (user_data);
+
+  model = selector_column->priv->model;
+
+  if (selector_column->priv->last_activated != NULL) {
+    gtk_tree_row_reference_free (selector_column->priv->last_activated);
+  }
+
+  selector_column->priv->last_activated = gtk_tree_row_reference_new (model, path);
+}
+
+static void
 _row_tapped_cb (GtkTreeView * tree_view, GtkTreePath * path, gpointer user_data)
 {
   HildonTouchSelector *selector = NULL;
@@ -701,7 +804,7 @@ _create_new_column (HildonTouchSelector * selector,
   }
 
 #ifdef MAEMO_GTK
-  tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (HILDON_UI_MODE_EDIT));
+  tv = GTK_TREE_VIEW (hildon_gtk_tree_view_new (selector->priv->hildon_ui_mode));
 #else
   tv = GTK_TREE_VIEW (gtk_tree_view_new ());
 #endif /* MAEMO_GTK */
@@ -710,6 +813,8 @@ _create_new_column (HildonTouchSelector * selector,
   GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (tv), GTK_CAN_FOCUS);
 
   gtk_tree_view_set_model (tv, model);
+  g_signal_connect (model, "row-changed",
+                    G_CALLBACK (on_row_changed), selector);
   gtk_tree_view_set_rules_hint (tv, TRUE);
 
   gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tree_column);
@@ -735,7 +840,8 @@ _create_new_column (HildonTouchSelector * selector,
 
   /* select the first item */
   *emit_changed = FALSE;
-  if (gtk_tree_model_get_iter_first (model, &iter)) {
+  if ((gtk_tree_model_get_iter_first (model, &iter))&&
+      (selector->priv->hildon_ui_mode == HILDON_UI_MODE_EDIT)) {
     gtk_tree_selection_select_iter (selection, &iter);
     *emit_changed = TRUE;
   }
@@ -746,6 +852,9 @@ _create_new_column (HildonTouchSelector * selector,
   g_signal_connect (G_OBJECT (tv), "hildon-row-tapped",
                     G_CALLBACK (_row_tapped_cb), new_column);
 
+  g_signal_connect (G_OBJECT (tv), "row-activated",
+                    G_CALLBACK (hildon_touch_selector_row_activated_cb), new_column);
+
   return new_column;
 }
 
@@ -771,12 +880,6 @@ static void
 hildon_touch_selector_column_set_property  (GObject *object, guint property_id,
                                             const GValue *value, GParamSpec *pspec);
 
-static void
-hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
-                                              gint text_column);
-static gint
-hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column);
-
 
 static void
 hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass)
@@ -791,6 +894,13 @@ hildon_touch_selector_column_class_init (HildonTouchSelectorColumnClass *klass)
   gobject_class->get_property = hildon_touch_selector_column_get_property;
   gobject_class->set_property = hildon_touch_selector_column_set_property;
 
+  /**
+   * HildonTouchSelectorColumn:text-column:
+   *
+   * A column in the data source model to get the strings from.
+   *
+   * Since: maemo 2.2
+   **/
   g_object_class_install_property (G_OBJECT_CLASS(klass),
                                    PROP_TEXT_COLUMN,
                                    g_param_spec_int ("text-column",
@@ -808,9 +918,22 @@ hildon_touch_selector_column_init (HildonTouchSelectorColumn *column)
   column->priv = G_TYPE_INSTANCE_GET_PRIVATE (column, HILDON_TYPE_TOUCH_SELECTOR_COLUMN,
                                               HildonTouchSelectorColumnPrivate);
   column->priv->text_column = -1;
+  column->priv->last_activated = NULL;
 }
 
-static void
+/**
+ * hildon_touch_selector_column_set_text_column:
+ * @column: A #HildonTouchSelectorColumn
+ * @text_column: the index of a model column in the model for @column.
+ *
+ * Sets the model column to be displayed in @column. @text_column must point to a
+ * column in the model used with type %G_TYPE_STRING. Initially, this property
+ * is unset. You should set it before using the #HildonTouchSelector that uses
+ * @column.
+ *
+ * Since: 2.2
+ **/
+void
 hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
                                               gint text_column)
 {
@@ -822,7 +945,17 @@ hildon_touch_selector_column_set_text_column (HildonTouchSelectorColumn *column,
   g_object_notify (G_OBJECT (column), "text-column");
 }
 
-static gint
+/**
+ * hildon_touch_selector_column_get_text_column:
+ * @column: a #HildonTouchSelectorColumn
+ *
+ * Gets the model column set as the text source for @column.
+ *
+ * Returns: the index of the text column for @column, or -1 if unset.
+ *
+ * Since: 2.2
+ **/
+gint
 hildon_touch_selector_column_get_text_column (HildonTouchSelectorColumn *column)
 {
   g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_COLUMN (column), -1);
@@ -1042,7 +1175,7 @@ hildon_touch_selector_new_text (void)
   column = hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
                                                      GTK_TREE_MODEL (store), TRUE);
 
-  g_object_set (G_OBJECT (column), "text-column", 0, NULL);
+  hildon_touch_selector_column_set_text_column (column, 0);
 
   return selector;
 }
@@ -1142,22 +1275,30 @@ hildon_touch_selector_insert_text (HildonTouchSelector * selector,
  *
  * 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.
+ * the selection logic, the print function, the #HildonTouchSelector::changed
+ * signal, etc. Internally, a #GtkTreeView will be added to the widget, using
+ * @model as the data source.
  *
  * You can optionally pass a #GtkCellRenderer in @cell_renderer,
  * together with a %NULL-terminated list of pairs property/value, in
  * the same way you would use gtk_tree_view_column_set_attributes().
- * This will pack @cell_renderer at the start of the column, expanded by default.
- * If you prefer not to add it this way, you can simply pass %NULL to @cell_renderer
- * and use the #GtkCellLayout interface on the returned #HildonTouchSelectorColumn
- * to set your renderers.
- *
- * 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.
+ * This will pack @cell_renderer at the start of the column, expanded
+ * by default.  If you prefer not to add it this way, you can simply
+ * pass %NULL to @cell_renderer and use the #GtkCellLayout interface
+ * on the returned #HildonTouchSelectorColumn to set your
+ * renderers. Please note that the returned #HildonTouchSelectorColumn
+ * is owned by @selector, you shouldn't unref it after setting it
+ * up.
+ *
+ * Initially, the returned #HildonTouchSelectorColumn will have its
+ * #HildonTouchSelectorColumn:text-column property unset. You should set
+ * it to a column in @model with type %G_TYPE_STRING. See
+ * hildon_touch_selector_column_set_text_column().
+ *
+ * This method could change the current #HildonTouchSelector:hildon-ui-mode.
+ * %HILDON_UI_MODE_NORMAL is only allowed with one column, so if the selector
+ * is in this mode, and a additional column is added,
+ * #HildonTouchSelector:hildon-ui-mode will change to %HILDON_UI_MODE_EDIT.
  *
  * Returns: the new column added added, %NULL otherwise.
  *
@@ -1205,6 +1346,8 @@ hildon_touch_selector_append_column (HildonTouchSelector * selector,
     hildon_touch_selector_emit_value_changed (selector, colnum);
   }
 
+  hildon_touch_selector_check_ui_mode_coherence (selector);
+
   return new_column;
 }
 
@@ -1397,6 +1540,10 @@ hildon_touch_selector_get_column_selection_mode (HildonTouchSelector * selector)
  *
  * Sets the selection mode for @selector. See #HildonTouchSelectorSelectionMode.
  *
+ * The new @mode will be set, but take into into account that the
+ * #HildonTouchSelectorSelectionMode is ignored if the @selector
+ * #HildonTouchSelector:hildon-ui-mode property is set to %HILDON_UI_MODE_NORMAL
+ *
  * Since: 2.2
  **/
 void
@@ -1451,11 +1598,8 @@ hildon_touch_selector_set_column_selection_mode (HildonTouchSelector * selector,
  * @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.
+ * Sets the function to be used by hildon_touch_selector_get_current_text().
+ * See hildon_touch_selector_set_print_func_full().
  *
  * Since: 2.2
  **/
@@ -1815,6 +1959,31 @@ hildon_touch_selector_get_model (HildonTouchSelector * selector, gint column)
 }
 
 static void
+on_row_changed (GtkTreeModel *model,
+                GtkTreePath *path,
+                GtkTreeIter *iter,
+                gpointer userdata)
+{
+  HildonTouchSelector *selector;
+  HildonTouchSelectorColumn *current_column;
+
+  gint column = 0;
+  GSList *col;
+
+  selector = HILDON_TOUCH_SELECTOR (userdata);
+
+  for (col = selector->priv->columns; col != NULL; col = col->next) {
+    current_column = HILDON_TOUCH_SELECTOR_COLUMN (col->data);
+    if (current_column->priv->model == model &&
+        gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (current_column->priv->tree_view),
+                                             path)) {
+      hildon_touch_selector_emit_value_changed (selector, column);
+    }
+    column ++;
+  }
+}
+
+static void
 _hildon_touch_selector_set_model (HildonTouchSelector * selector,
                                   gint column, GtkTreeModel * model)
 {
@@ -1823,9 +1992,15 @@ _hildon_touch_selector_set_model (HildonTouchSelector * selector,
   current_column =
     HILDON_TOUCH_SELECTOR_COLUMN (g_slist_nth_data (selector->priv->columns, column));
 
+  if (current_column->priv->model) {
+    g_signal_handlers_disconnect_by_func (current_column->priv->model,
+                                          on_row_changed, selector);
+  }
   current_column->priv->model = model;
   gtk_tree_view_set_model (current_column->priv->tree_view,
                            current_column->priv->model);
+  g_signal_connect (model, "row-changed",
+                    G_CALLBACK (on_row_changed), selector);
 }
 
 /**
@@ -2104,6 +2279,19 @@ hildon_touch_selector_get_column (HildonTouchSelector * selector,
  * will be scrolled to ensure the selected item that is closest to the
  * currently visible area is shown.
  *
+ * The #HildonTouchSelector:initial-scroll property configure the widget
+ * in order to use this function at the first show.
+ *
+ * Take into account that the element is not centered until the widget is
+ * realized. If the widget is not realized when the function is called, it
+ * will be postponed. If you call this functions several times before the
+ * widgets is realized, only the last one will be used.
+ *
+ * This behaviour includes any call to hildon_touch_selector_center_on_index(),
+ * so take care calling this functions, or with the
+ * #HildonTouchSelector:initial-scroll property in order to get centered on the
+ * proper element.
+ *
  * Since: 2.2
  **/
 void
@@ -2118,3 +2306,226 @@ hildon_touch_selector_center_on_selected         (HildonTouchSelector *selector)
                                                     HILDON_TOUCH_SELECTOR_COLUMN (iter->data));
   }
 }
+
+/**
+ * hildon_touch_selector_optimal_size_request
+ * @selector: a #HildonTouchSelector
+ * @requisition: a #GtkRequisition
+ *
+ * Gets the optimal size request of the touch selector. This function is mostly
+ * intended for dialog implementations that include a #HildonTouchSelector and
+ * want to optimize the screen real state, for example, when you want a dialog
+ * to show as much of the selector, avoiding any extra empty space below the
+ * selector.
+ *
+ * See #HildonPickerDialog implementation for an example.
+ *
+ * This function is oriented to be used in the size_request of a dialog or window,
+ * if you are not sure do not use it.
+ *
+ * There is a precondition to this function: Since this function does not
+ * call the "size_request" method, it can only be used when you know that
+ * gtk_widget_size_request() has been called since the last time a resize was
+ * queued.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_touch_selector_optimal_size_request      (HildonTouchSelector *selector,
+                                                 GtkRequisition *requisition)
+{
+  GSList *iter = NULL;
+  gint height = 0;
+  gint base_height = 0;
+
+  g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
+
+  iter = selector->priv->columns;
+
+  /* Default optimal values are the current ones */
+  gtk_widget_get_child_requisition (GTK_WIDGET (selector),
+                                    requisition);
+
+  if (iter == NULL) {
+    height = requisition->height;
+  } else {
+    /* we use the normal requisition as base, as the touch selector can has
+       extra widgets, not only the columns (ie: HildonTouchSelectorEntry) */
+    base_height = requisition->height;
+  }
+
+  /* Compute optimal height for the columns */
+  while (iter) {
+    HildonTouchSelectorColumn *column;
+    GtkWidget *child;
+    GtkRequisition child_requisition = {0};
+
+    column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
+    child = GTK_WIDGET (column->priv->tree_view);
+
+    gtk_widget_get_child_requisition (child, &child_requisition);
+
+    height = MAX (height, child_requisition.height);
+
+    iter = g_slist_next (iter);
+  }
+
+  requisition->height = base_height + height;
+}
+
+
+
+/**
+ * hildon_touch_selector_get_hildon_ui_mode
+ * @selector: a #HildonTouchSelector
+ *
+ * Gets the current hildon-ui-mode, see #HildonUIMode for more information
+ *
+ * Returns: the current hildon-ui-mode
+ *
+ * Since: 2.2
+ **/
+HildonUIMode
+hildon_touch_selector_get_hildon_ui_mode        (HildonTouchSelector *selector)
+{
+  g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), HILDON_UI_MODE_EDIT);
+
+  return selector->priv->hildon_ui_mode;
+}
+
+/**
+ * hildon_touch_selector_set_hildon_ui_mode
+ * @selector: a #HildonTouchSelector
+ * @mode: a #HildonUIMode
+ *
+ * Sets the value of the property #HildonTouchSelector:hildon-ui-mode to be @mode,
+ * see #HildonUIMode for more information
+ *
+ * Note that the %HILDON_UI_MODE_NORMAL can be only used when the selector has
+ * one column, use the return value to check if the change was effective.
+ *
+ * Returns: %TRUE if #HildonTouchSelector:hildon-ui-mode was changed
+ *          %FALSE otherwise
+ *
+ * Since: 2.2
+ **/
+gboolean
+hildon_touch_selector_set_hildon_ui_mode        (HildonTouchSelector *selector,
+                                                 HildonUIMode         mode)
+{
+  gint num = 0;
+  GSList *iter = NULL;
+  HildonTouchSelectorColumn *column = NULL;
+  GtkTreeView *tree_view = NULL;
+
+  g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR (selector), FALSE);
+  num = hildon_touch_selector_get_num_columns (selector);
+  g_return_val_if_fail ((mode == HILDON_UI_MODE_EDIT) || (num == 1), FALSE);
+
+  if (mode == selector->priv->hildon_ui_mode) {
+    return FALSE;
+  }
+
+  for (iter = selector->priv->columns; iter; iter = g_slist_next (iter)) {
+    column = HILDON_TOUCH_SELECTOR_COLUMN (iter->data);
+    tree_view = column->priv->tree_view;
+
+    hildon_tree_view_set_hildon_ui_mode (tree_view, mode);
+
+    /* looking at the code of hildon_tree_view_set_hildon_ui_mode, it seems
+       that it call the unselect_all, but it is required anyway */
+    if (mode == HILDON_UI_MODE_NORMAL) {
+      GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
+
+      gtk_tree_selection_unselect_all (selection);
+    }
+  }
+
+  selector->priv->hildon_ui_mode = mode;
+
+  return TRUE;
+}
+
+/**
+ * hildon_touch_selector_get_last_activated_row
+ * @selector: a #HildonTouchSelector
+ * @column: column number
+ *
+ * Gets a #GtkTreePath of the last row activated in a column (the last row that
+ * emitted a #GtkTreeView::row-activated signal). This is mainly useful if the
+ * @selector #HildonTouchSelector:hildon-ui-mode in set to %HILDON_UI_MODE_NORMAL,
+ * as using this state there is no real selection, so a method like
+ * hildon_touch_selector_get_selected_rows() will return always a empty
+ * selection.
+ *
+ * Anyway, this method works as well on %HILDON_UI_MODE_EDIT, but in this case
+ * is better, and more useful, to get the current selection.
+ *
+ * Returns: a newly allocated #GtkTreePath pointing to the last activated row
+ *          NULL if no row were activated.
+ *
+ * Since: 2.2
+ **/
+GtkTreePath*
+hildon_touch_selector_get_last_activated_row    (HildonTouchSelector *selector,
+                                                 gint                 column)
+{
+  HildonTouchSelectorColumn *selector_column = NULL;
+
+  /* this method with check selector and that the column number is correct*/
+  selector_column = hildon_touch_selector_get_column (selector, column);
+
+  if (selector_column == NULL) {
+    return NULL;
+  }
+
+  if (selector_column->priv->last_activated != NULL) {
+    return gtk_tree_row_reference_get_path (selector_column->priv->last_activated);
+  } else {
+    return NULL;
+  }
+}
+
+
+/**
+ * hildon_touch_selector_center_on_index:
+ * @selector: a #HildonTouchSelector
+ * @column: column number
+ * @index: the index of the item to center on
+ *
+ * Ensures that the column number @column shows the element @index
+ *
+ * This is similar to hildon_touch_selector_center_on_selected() but with the
+ * difference that allows to center on a column item not selected.
+ *
+ * Take into account that the element is not centered until the widget is
+ * realized. If the widget is not realized when the function is called, it will
+ * be postponed. If you call this function several times before the widget is
+ * realized, only the last one will be used.
+ *
+ * This behaviour includes any call to hildon_touch_selector_center_on_selected().
+ * Check this function for more tips.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_touch_selector_center_on_index (HildonTouchSelector *selector,
+                                       gint column,
+                                       gint index)
+{
+  HildonTouchSelectorColumn *current_column = NULL;
+  GtkTreePath *path = NULL;
+
+  g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
+  g_return_if_fail ((column >= 0) && (column < hildon_touch_selector_get_num_columns (selector)));
+  g_return_if_fail (index >= 0);
+
+  current_column = g_slist_nth_data (selector->priv->columns, column);
+
+  path = gtk_tree_path_new_from_indices (index, -1);
+
+  hildon_touch_selector_scroll_to (current_column,
+                                   current_column->priv->tree_view,
+                                   path);
+  gtk_tree_path_free (path);
+}