summaryrefslogtreecommitdiff
path: root/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff
diff options
context:
space:
mode:
Diffstat (limited to 'openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff')
-rw-r--r--openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff2253
1 files changed, 0 insertions, 2253 deletions
diff --git a/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff b/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff
deleted file mode 100644
index 87ccffa86..000000000
--- a/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff
+++ /dev/null
@@ -1,2253 +0,0 @@
---- gtk+-2.6.4/gtk/gtktreeview.c 2005-02-24 00:38:20.000000000 +0200
-+++ gtk+-2.6.4/gtk/gtktreeview.c 2005-04-06 16:19:38.274719720 +0300
-@@ -42,6 +42,7 @@
- #include "gtkentry.h"
- #include "gtkframe.h"
- #include "gtktreemodelsort.h"
-+#include "gtkscrolledwindow.h"
-
- #define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
- #define GTK_TREE_VIEW_PRIORITY_SCROLL_SYNC (GTK_TREE_VIEW_PRIORITY_VALIDATE + 2)
-@@ -114,6 +115,7 @@
- EXPAND_COLLAPSE_CURSOR_ROW,
- SELECT_CURSOR_PARENT,
- START_INTERACTIVE_SEARCH,
-+ ROW_INSENSITIVE,
- LAST_SIGNAL
- };
-
-@@ -132,7 +134,10 @@
- PROP_SEARCH_COLUMN,
- PROP_FIXED_HEIGHT_MODE,
- PROP_HOVER_SELECTION,
-- PROP_HOVER_EXPAND
-+ PROP_HOVER_EXPAND,
-+ PROP_DOTTED_LINES,
-+ PROP_FORCE_LIST_KLUDGE,
-+ PROP_ALLOW_CHECKBOX_MODE
- };
-
- static void gtk_tree_view_class_init (GtkTreeViewClass *klass);
-@@ -338,8 +343,6 @@
- static void gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view,
- GtkRBTree *tree,
- GtkRBNode *node);
--static void gtk_tree_view_clamp_column_visible (GtkTreeView *tree_view,
-- GtkTreeViewColumn *column);
- static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
- GdkEventMotion *event);
- static void gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view);
-@@ -372,6 +375,18 @@
- gpointer data);
- static gboolean expand_collapse_timeout (gpointer data);
- static gboolean do_expand_collapse (GtkTreeView *tree_view);
-+static void update_checkbox_mode (GObject *object,
-+ GParamSpec *pspec,
-+ gpointer data);
-+static void set_dotted_lines (GtkTreeView *tree_view,
-+ gboolean enable);
-+static void selection_changed (GtkTreeSelection *selection,
-+ gpointer data);
-+static void check_if_can_focus (GtkTreeView *tree_view);
-+static gint scroll_row_timeout (gpointer data);
-+
-+static void add_scroll_timeout (GtkTreeView *tree_view);
-+static void remove_scroll_timeout (GtkTreeView *tree_view);
-
- /* interactive search */
- static void gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view);
-@@ -694,8 +709,54 @@
- FALSE,
- G_PARAM_READWRITE));
-
-+ /**
-+ * GtkTreeView:dotted-lines:
-+ *
-+ * Enables or disables the dotted lines for hierarchical trees.
-+ * Hildon patch.
-+ */
-+ g_object_class_install_property (o_class,
-+ PROP_DOTTED_LINES,
-+ g_param_spec_boolean ("dotted_lines",
-+ P_("Dotted Lines"),
-+ P_("Whether to show or hide dotted lines for hierarchical trees"),
-+ FALSE,
-+ G_PARAM_READWRITE));
-+
-+ /**
-+ * GtkTreeView:force-list-kludge:
-+ *
-+ * Hildon kludge for fixing file tree behaviour until a cleaner
-+ * implementation is scheduled: if this property is set, then rows
-+ * can be activated by tapping even if the underlying tree model is
-+ * not technically a list.
-+ */
-+ g_object_class_install_property (o_class,
-+ PROP_FORCE_LIST_KLUDGE,
-+ g_param_spec_boolean ("force_list_kludge",
-+ P_("Force List Behaviour"),
-+ P_("Whether to activate tapped focused items even if model was not a list"),
-+ FALSE,
-+ G_PARAM_READWRITE));
-+
-+ /**
-+ * GtkTreeView:enable-checkbox-mode:
-+ *
-+ * Another Hildon kludge for allowing the existence of GtkTreeViews
-+ * that have activatable columns but that still is not a Text Listbox
-+ * in multiple selection with checkboxes mode.
-+ */
-+ g_object_class_install_property (o_class,
-+ PROP_ALLOW_CHECKBOX_MODE,
-+ g_param_spec_boolean ("allow_checkbox_mode",
-+ P_("Enable Checkbox Mode"),
-+ P_("Whether to behave like a Listbox in a multiple selection with checkboxes mode, if checkboxes exist"),
-+ TRUE,
-+ G_PARAM_READWRITE));
-+
- /* Style properties */
- #define _TREE_VIEW_EXPANDER_SIZE 12
-+#define _TREE_VIEW_EXPANDER_INDENT 10
- #define _TREE_VIEW_VERTICAL_SEPARATOR 2
- #define _TREE_VIEW_HORIZONTAL_SEPARATOR 2
-
-@@ -709,6 +770,15 @@
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property (widget_class,
-+ g_param_spec_int ("expander_indent",
-+ P_("Expander intent"),
-+ P_("Defines the expanders indent"),
-+ 0,
-+ G_MAXINT,
-+ _TREE_VIEW_EXPANDER_INDENT,
-+ G_PARAM_READABLE));
-+
-+ gtk_widget_class_install_style_property (widget_class,
- g_param_spec_int ("vertical_separator",
- P_("Vertical Separator Width"),
- P_("Vertical space between cells. Must be an even number"),
-@@ -754,6 +824,13 @@
- GDK_TYPE_COLOR,
- G_PARAM_READABLE));
-
-+ gtk_widget_class_install_style_property (widget_class,
-+ g_param_spec_boolean ("passive_focus",
-+ P_("Enables passive focus"),
-+ P_("Used for tree view passive focus"),
-+ TRUE,
-+ G_PARAM_READABLE));
-+
- /* Signals */
- widget_class->set_scroll_adjustments_signal =
- g_signal_new ("set_scroll_adjustments",
-@@ -917,6 +994,16 @@
- _gtk_marshal_BOOLEAN__NONE,
- G_TYPE_BOOLEAN, 0);
-
-+ tree_view_signals[ROW_INSENSITIVE] =
-+ g_signal_new ("row_insensitive",
-+ G_TYPE_FROM_CLASS (o_class),
-+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-+ G_STRUCT_OFFSET (GtkTreeViewClass, row_insensitive),
-+ NULL, NULL,
-+ _gtk_marshal_VOID__OBJECT,
-+ G_TYPE_NONE, 1,
-+ GTK_TYPE_TREE_PATH);
-+
- /* Key bindings */
- gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0,
- GTK_MOVEMENT_DISPLAY_LINES, -1);
-@@ -1004,12 +1091,13 @@
-
- gtk_binding_entry_add_signal (binding_set, GDK_space, 0, "select_cursor_row", 1,
- G_TYPE_BOOLEAN, TRUE);
-+ /* Hildon change: Enter shouldn't select
- gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "select_cursor_row", 1,
- G_TYPE_BOOLEAN, TRUE);
- gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, "select_cursor_row", 1,
- G_TYPE_BOOLEAN, TRUE);
- gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "select_cursor_row", 1,
-- G_TYPE_BOOLEAN, TRUE);
-+ G_TYPE_BOOLEAN, TRUE);*/
-
- /* expand and collapse rows */
- gtk_binding_entry_add_signal (binding_set, GDK_plus, 0, "expand_collapse_cursor_row", 3,
-@@ -1123,19 +1211,31 @@
- gtk_binding_entry_add_signal (binding_set, GDK_f, GDK_CONTROL_MASK, "start_interactive_search", 0);
-
- gtk_binding_entry_add_signal (binding_set, GDK_F, GDK_CONTROL_MASK, "start_interactive_search", 0);
-+
-+ /* Hildon addition: Add key bindings to Right and Left arrows */
-+ gtk_binding_entry_add_signal (binding_set, GDK_Right, 0, "expand_collapse_cursor_row", 3,
-+ G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE, G_TYPE_BOOLEAN, FALSE);
-+ gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_SHIFT_MASK, "expand_collapse_cursor_row", 3,
-+ G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE, G_TYPE_BOOLEAN, TRUE);
-+ gtk_binding_entry_add_signal (binding_set, GDK_Left, 0, "expand_collapse_cursor_row", 3,
-+ G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE);
-+ gtk_binding_entry_add_signal (binding_set, GDK_Left, GDK_SHIFT_MASK, "expand_collapse_cursor_row", 3,
-+ G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE);
- }
-
- static void
- gtk_tree_view_init (GtkTreeView *tree_view)
- {
- tree_view->priv = g_new0 (GtkTreeViewPrivate, 1);
-- GTK_WIDGET_SET_FLAGS (tree_view, GTK_CAN_FOCUS);
-+
-+ /* Hildon: focus cannot be gained until at least one row is added */
-+ GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
-
- gtk_widget_set_redraw_on_allocate (GTK_WIDGET (tree_view), FALSE);
-
-+ /* Hildon: Headers invisible by default */
- tree_view->priv->flags = GTK_TREE_VIEW_SHOW_EXPANDERS
-- | GTK_TREE_VIEW_DRAW_KEYFOCUS
-- | GTK_TREE_VIEW_HEADERS_VISIBLE;
-+ | GTK_TREE_VIEW_DRAW_KEYFOCUS;
-
- /* We need some padding */
- tree_view->priv->dy = 0;
-@@ -1165,6 +1265,26 @@
-
- tree_view->priv->hover_selection = FALSE;
- tree_view->priv->hover_expand = FALSE;
-+
-+ tree_view->priv->ctrl_pressed = FALSE;
-+ tree_view->priv->shift_pressed = FALSE;
-+
-+ tree_view->priv->checkbox_mode = FALSE;
-+ tree_view->priv->allow_checkbox_mode = TRUE;
-+ tree_view->priv->pen_down = FALSE;
-+ tree_view->priv->pen_drag_active = FALSE;
-+ tree_view->priv->pen_drag_reverse = FALSE;
-+ tree_view->priv->first_drag_row = NULL;
-+ tree_view->priv->last_drag_row = NULL;
-+ tree_view->priv->queued_expand_row = NULL;
-+ tree_view->priv->queued_select_row = NULL;
-+ tree_view->priv->pen_focus = TRUE;
-+
-+ /* Hildon: cursor should follow when selection changes */
-+ g_signal_connect (tree_view->priv->selection, "changed",
-+ G_CALLBACK (selection_changed), tree_view);
-+
-+ gtk_widget_set_name (GTK_WIDGET (tree_view), "treeview");
- }
-
-
-@@ -1223,6 +1343,27 @@
- case PROP_HOVER_EXPAND:
- tree_view->priv->hover_expand = g_value_get_boolean (value);
- break;
-+ case PROP_DOTTED_LINES:
-+ set_dotted_lines (tree_view, g_value_get_boolean (value));
-+ break;
-+ case PROP_FORCE_LIST_KLUDGE:
-+ tree_view->priv->force_list_kludge = g_value_get_boolean (value);
-+ break;
-+ case PROP_ALLOW_CHECKBOX_MODE:
-+ if ((tree_view->priv->allow_checkbox_mode = g_value_get_boolean (value)))
-+ {
-+ gtk_widget_set_name (GTK_WIDGET(tree_view), "treeview");
-+ update_checkbox_mode (NULL, NULL, tree_view);
-+ }
-+ else
-+ {
-+ /* ugly hack - to ensure that checkboxes are independent of the
-+ selection if !allow_checkbox_mode, we must be able to use
-+ different theming in that case */
-+ gtk_widget_set_name (GTK_WIDGET(tree_view), "no_checkbox_mode");
-+ tree_view->priv->checkbox_mode = FALSE;
-+ }
-+ break;
- default:
- break;
- }
-@@ -1276,6 +1417,15 @@
- case PROP_HOVER_EXPAND:
- g_value_set_boolean (value, tree_view->priv->hover_expand);
- break;
-+ case PROP_DOTTED_LINES:
-+ g_value_set_boolean (value, tree_view->priv->dotted_lines);
-+ break;
-+ case PROP_FORCE_LIST_KLUDGE:
-+ g_value_set_boolean (value, tree_view->priv->force_list_kludge);
-+ break;
-+ case PROP_ALLOW_CHECKBOX_MODE:
-+ g_value_set_boolean (value, tree_view->priv->allow_checkbox_mode);
-+ break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
-@@ -1376,6 +1526,27 @@
- tree_view->priv->destroy_count_data = NULL;
- }
-
-+ if (tree_view->priv->first_drag_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
-+ tree_view->priv->first_drag_row = NULL;
-+ }
-+ if (tree_view->priv->last_drag_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+ tree_view->priv->last_drag_row = NULL;
-+ }
-+ if (tree_view->priv->queued_expand_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
-+ tree_view->priv->queued_expand_row = NULL;
-+ }
-+ if (tree_view->priv->queued_select_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
-+ tree_view->priv->queued_select_row = NULL;
-+ }
-+
- gtk_tree_row_reference_free (tree_view->priv->cursor);
- tree_view->priv->cursor = NULL;
-
-@@ -1494,6 +1665,8 @@
- gtk_tree_view_map_buttons (tree_view);
-
- gdk_window_show (widget->window);
-+
-+ check_if_can_focus (tree_view);
- }
-
- static void
-@@ -1895,6 +2068,8 @@
- gint full_requested_width = 0;
- gint number_of_expand_columns = 0;
- gboolean rtl;
-+ GtkWidget *scroll;
-+ GtkPolicyType ptype;
-
- tree_view = GTK_TREE_VIEW (widget);
-
-@@ -1969,6 +2144,19 @@
- allocation.x = width;
- column->width = real_requested_width;
-
-+ /* a dirty Hildon hack to force truncation if not enough space. This hack is applied
-+ * only if we are NOT in a scrolled window with hscroll*/
-+ scroll = gtk_widget_get_ancestor(widget, GTK_TYPE_SCROLLED_WINDOW);
-+ if ((!scroll ||
-+ (gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (scroll), &ptype, NULL), ptype == GTK_POLICY_NEVER))
-+ && (width + real_requested_width > widget->allocation.width))
-+ {
-+ column->width = widget->allocation.width - width;
-+ if (column->width < 1)
-+ column->width = 1;
-+ gtk_widget_queue_draw (widget);
-+ }
-+
- if (column->expand)
- {
- if (number_of_expand_columns == 1)
-@@ -2153,6 +2341,23 @@
- GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
- }
-
-+/* helper function for gtk_tree_view_button_press */
-+static void
-+activate_callback (GtkTreeModel *model,
-+ GtkTreePath *path,
-+ GtkTreeIter *iter,
-+ gpointer data)
-+{
-+ GtkTreeView *tree_view = GTK_TREE_VIEW (data);
-+
-+ /* Hildon: if the tree view has no active focus we don't activate
-+ * the selected row */
-+ if ( !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET(data)) )
-+ return;
-+
-+ gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
-+}
-+
- static gboolean
- gtk_tree_view_button_press (GtkWidget *widget,
- GdkEventButton *event)
-@@ -2166,6 +2371,7 @@
- gint vertical_separator;
- gint horizontal_separator;
- gboolean rtl;
-+ gint expander_indent;
-
- g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-@@ -2176,6 +2382,7 @@
- gtk_widget_style_get (widget,
- "vertical_separator", &vertical_separator,
- "horizontal_separator", &horizontal_separator,
-+ "expander_indent", &expander_indent,
- NULL);
-
-
-@@ -2199,6 +2406,14 @@
- gint column_handled_click = FALSE;
- gboolean row_double_click = FALSE;
- gboolean rtl;
-+ gboolean force_list_kludge;
-+ GtkRBNode *cursor = NULL;
-+ gboolean focus_grab = FALSE;
-+
-+ if (!GTK_WIDGET_HAS_FOCUS (widget))
-+ focus_grab = TRUE;
-+
-+ GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
-
- /* Empty tree? */
- if (tree_view->priv->tree == NULL)
-@@ -2207,7 +2422,9 @@
- return TRUE;
- }
-
-- /* are we in an arrow? */
-+ /* In Hildon we don't want to use the arrows */
-+#if 0
-+ /* are we in an arrow? */
- if (tree_view->priv->prelight_node &&
- GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT))
- {
-@@ -2226,6 +2443,7 @@
- grab_focus_and_unset_draw_keyfocus (tree_view);
- return TRUE;
- }
-+#endif
-
- /* find the node that was clicked */
- new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
-@@ -2247,6 +2465,65 @@
- background_area.height = ROW_HEIGHT (tree_view, GTK_RBNODE_GET_HEIGHT (node));
- background_area.x = 0;
-
-+ if (tree_view->priv->first_drag_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
-+ tree_view->priv->first_drag_row = NULL;
-+ }
-+ if (tree_view->priv->last_drag_row)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+ tree_view->priv->last_drag_row = NULL;
-+ }
-+ tree_view->priv->first_drag_row =
-+ gtk_tree_row_reference_new (tree_view->priv->model, path);
-+ tree_view->priv->last_drag_row = gtk_tree_row_reference_copy (tree_view->priv->first_drag_row);
-+
-+ /* force_list_kludge allows pen dragging even if
-+ GTK_TREE_MODEL_LIST_ONLY is not set (to fix file tree) */
-+ g_object_get (widget, "force_list_kludge", &force_list_kludge, NULL);
-+
-+ /* Hildon: activate pen dragging, if listbox is not hierarchical and
-+ the pen was not put down in a position that initiates drag'n'drop */
-+ if (!tree_view->priv->pen_down &&
-+ (force_list_kludge ||
-+ (gtk_tree_model_get_flags(tree_view->priv->model)
-+ & GTK_TREE_MODEL_LIST_ONLY)) &&
-+ (tree_view->priv->checkbox_mode ||
-+ !gtk_tree_selection_path_is_selected(tree_view->priv->selection, path)))
-+ {
-+ gpointer drag_data;
-+
-+ tree_view->priv->pen_down = TRUE;
-+ tree_view->priv->pen_focus = TRUE;
-+
-+ /* also block attached dnd signal handler */
-+ drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
-+ if (drag_data)
-+ g_signal_handlers_block_matched (widget,
-+ G_SIGNAL_MATCH_DATA,
-+ 0, 0, NULL, NULL,
-+ drag_data);
-+ }
-+
-+ /* For the Hildon buttonpress find out the previously selected row */
-+ GtkRBTree *cursor_tree = NULL;
-+ GtkTreePath *cursor_path = NULL;
-+
-+ if (tree_view->priv->cursor)
-+ {
-+ cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+ if (cursor_path)
-+ {
-+ _gtk_tree_view_find_node (tree_view, cursor_path,
-+ &cursor_tree, &cursor);
-+ gtk_tree_path_free (cursor_path);
-+ }
-+ }
-+
-+ /* Hildon: in checkbox mode, dragging sets all checkboxes
-+ to the same state as the first toggled checkbox */
-+ tree_view->priv->new_state = !gtk_tree_selection_path_is_selected(tree_view->priv->selection, path);
-
- /* Let the column have a chance at selecting it. */
- rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
-@@ -2275,8 +2552,11 @@
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
- {
-- cell_area.x += depth * tree_view->priv->expander_size;
-- cell_area.width -= depth * tree_view->priv->expander_size;
-+ gint adjust;
-+
-+ adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
-+ cell_area.x += adjust;
-+ cell_area.width -= adjust;
- }
- break;
- }
-@@ -2364,15 +2644,19 @@
- */
- if (event->type == GDK_BUTTON_PRESS)
- {
-+ /* Hildon: ignore Ctrl and Shift */
-+#if 0
- if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
- tree_view->priv->ctrl_pressed = TRUE;
- if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
- tree_view->priv->shift_pressed = TRUE;
-+#endif
-
- focus_cell = _gtk_tree_view_column_get_cell_at_pos (column, event->x - background_area.x);
- if (focus_cell)
- gtk_tree_view_column_focus_cell (column, focus_cell);
-
-+#if 0
- if (event->state & GDK_CONTROL_MASK)
- {
- gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE);
-@@ -2387,6 +2671,86 @@
- {
- gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE);
- }
-+#endif
-+ if (tree_view->priv->checkbox_mode)
-+ {
-+ GtkRBTree *tree = NULL;
-+ GtkRBNode *node = NULL;
-+
-+ _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-+
-+ /* cursor cannot move to an insensitive row, so we
-+ need to check here to avoid toggling the current
-+ row by clicking on an insensitive row */
-+ if (_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ node, path))
-+ {
-+ gtk_tree_view_real_set_cursor (tree_view, path,
-+ FALSE, TRUE);
-+ gtk_tree_view_real_toggle_cursor_row (tree_view);
-+ }
-+ else
-+ /* Usually this would be emitted by real_set_cursor.
-+ However in this case we never call it. */
-+ g_signal_emit (tree_view, tree_view_signals[ROW_INSENSITIVE], 0, path);
-+ }
-+ else
-+ {
-+ gboolean queue_row = TRUE;
-+ gboolean force_list_kludge;
-+
-+ /* force_list_kludge allows rows to be activated even if
-+ GTK_TREE_MODEL_LIST_ONLY is not set (to fix file tree) */
-+ g_object_get (widget, "force_list_kludge",
-+ &force_list_kludge, NULL);
-+ if ((force_list_kludge ||
-+ (gtk_tree_model_get_flags (tree_view->priv->model) &
-+ GTK_TREE_MODEL_LIST_ONLY)) &&
-+ gtk_tree_row_reference_valid (tree_view->priv->cursor))
-+ {
-+ /* special case: text listbox without checkboxes
-+ should activate selected rows when user taps
-+ on cursor row, but not affect selection*/
-+ GtkTreePath *cursor_path =
-+ gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+ if (gtk_tree_path_compare (cursor_path, path) == 0)
-+ {
-+ gtk_tree_selection_selected_foreach (tree_view->priv->selection,
-+ activate_callback,
-+ tree_view);
-+ queue_row = FALSE;
-+ }
-+ }
-+
-+ if (queue_row &&
-+ (gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE) &&
-+ gtk_tree_selection_path_is_selected (tree_view->priv->selection, path))
-+ {
-+ GtkTreePath *old_cursor_path = NULL;
-+
-+ /* we don't know if the user is selecting an item or performing
-+ multiple item drag and drop until we know where button is released */
-+ if (tree_view->priv->queued_select_row)
-+ gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
-+ tree_view->priv->queued_select_row =
-+ gtk_tree_row_reference_new (tree_view->priv->model, path);
-+
-+ /* however, move focus */
-+ if (tree_view->priv->cursor)
-+ {
-+ old_cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+ gtk_tree_row_reference_free (tree_view->priv->cursor);
-+ }
-+ tree_view->priv->cursor = gtk_tree_row_reference_new (tree_view->priv->model,
-+ path);
-+ gtk_tree_view_queue_draw_path (tree_view, path, NULL);
-+ if (old_cursor_path)
-+ gtk_tree_view_queue_draw_path (tree_view, old_cursor_path, NULL);
-+ }
-+ else
-+ gtk_tree_view_real_set_cursor (tree_view, path,
-+ queue_row, TRUE);
-+ }
-
- tree_view->priv->ctrl_pressed = FALSE;
- tree_view->priv->shift_pressed = FALSE;
-@@ -2412,6 +2776,15 @@
- tree_view->priv->press_start_y = event->y;
- }
-
-+ /* Hildon: if selected row is tapped -> the row gets activated and expands */
-+ if (!focus_grab)
-+ {
-+ /* ...although not until button is released */
-+ gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
-+ tree_view->priv->queued_expand_row =
-+ gtk_tree_row_reference_new (tree_view->priv->model, path);
-+ }
-+
- /* Test if a double click happened on the same row. */
- if (event->button == 1)
- {
-@@ -2433,6 +2806,8 @@
- }
- }
-
-+ /* Hildon doesn't support double clicks */
-+#if 0
- if (row_double_click)
- {
- if (tree_view->priv->last_button_press)
-@@ -2443,6 +2818,7 @@
- tree_view->priv->last_button_press_2 = NULL;
- }
- else
-+#endif
- {
- if (tree_view->priv->last_button_press)
- gtk_tree_row_reference_free (tree_view->priv->last_button_press);
-@@ -2626,6 +3002,28 @@
-
- tree_view = GTK_TREE_VIEW (widget);
-
-+ /* unblock attached dnd signal handler */
-+ if (tree_view->priv->pen_down)
-+ {
-+ gpointer drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
-+ if (drag_data)
-+ g_signal_handlers_unblock_matched (widget,
-+ G_SIGNAL_MATCH_DATA,
-+ 0, 0, NULL, NULL,
-+ drag_data);
-+ }
-+
-+ /* stop pen dragging */
-+ if (tree_view->priv->first_drag_row)
-+ gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
-+ if (tree_view->priv->last_drag_row)
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+ tree_view->priv->first_drag_row = NULL;
-+ tree_view->priv->last_drag_row = NULL;
-+ tree_view->priv->pen_down = FALSE;
-+ tree_view->priv->pen_drag_active = FALSE;
-+ remove_scroll_timeout (tree_view);
-+
- if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
- return gtk_tree_view_button_release_drag_column (widget, event);
-
-@@ -2635,6 +3033,65 @@
- if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE))
- return gtk_tree_view_button_release_column_resize (widget, event);
-
-+ if (gtk_tree_row_reference_valid (tree_view->priv->queued_select_row))
-+ {
-+ /* unselect other nodes - but only if not drag'n'dropping */
-+ if (event->window == tree_view->priv->bin_window)
-+ gtk_tree_selection_unselect_all (tree_view->priv->selection);
-+
-+ gtk_tree_view_real_set_cursor (tree_view,
-+ gtk_tree_row_reference_get_path (tree_view->priv->queued_select_row),
-+ FALSE, TRUE);
-+ gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
-+ tree_view->priv->queued_select_row = NULL;
-+ }
-+
-+ /* for handling expand/collapse postponed from button_press (since we
-+ don't want expand/collapse before tap on node has been completed) */
-+ if (gtk_tree_row_reference_valid (tree_view->priv->queued_expand_row) &&
-+ tree_view->priv->tree != NULL)
-+ {
-+ GtkTreePath *queued_expand_path;
-+ GtkRBTree *tree;
-+ GtkRBNode *node;
-+ GtkRBNode *old_node;
-+ gint y;
-+
-+ queued_expand_path =
-+ gtk_tree_row_reference_get_path (tree_view->priv->queued_expand_row);
-+
-+ if (queued_expand_path)
-+ {
-+ /* must check that cursor hasn't moved elsewhere since button_press */
-+ y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->y);
-+ _gtk_rbtree_find_offset (tree_view->priv->tree, y, &tree, &node);
-+
-+ _gtk_tree_view_find_node (tree_view, queued_expand_path,
-+ &tree, &old_node);
-+
-+ if (node && old_node == node)
-+ {
-+ if (node->children == NULL)
-+ gtk_tree_view_real_expand_row (tree_view,
-+ queued_expand_path,
-+ tree,
-+ node,
-+ FALSE, TRUE);
-+ else
-+ gtk_tree_view_real_collapse_row (tree_view,
-+ queued_expand_path,
-+ tree,
-+ node,
-+ TRUE);
-+ }
-+
-+ gtk_tree_path_free (queued_expand_path);
-+ }
-+
-+ gtk_tree_row_reference_free( tree_view->priv->queued_expand_row);
-+ tree_view->priv->queued_expand_row = NULL;
-+ }
-+
- if (tree_view->priv->button_pressed_node == NULL)
- return FALSE;
-
-@@ -3311,6 +3768,7 @@
- GtkTreeView *tree_view;
- GtkRBTree *tree;
- GtkRBNode *node;
-+ GtkTreePath *path, *last_drag_path, *current_path;
- gint new_y;
-
- tree_view = (GtkTreeView *) widget;
-@@ -3319,7 +3777,8 @@
- return FALSE;
-
- /* only check for an initiated drag when a button is pressed */
-- if (tree_view->priv->pressed_button >= 0)
-+ /* Hildon: active pen drag overrides drag and drop */
-+ if (tree_view->priv->pressed_button >= 0 && !tree_view->priv->pen_down)
- gtk_tree_view_maybe_begin_dragging_row (tree_view, event);
-
- new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
-@@ -3328,6 +3787,99 @@
-
- _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
-
-+ /* Hildon: pen dragging */
-+ if (tree_view->priv->pen_down && node != NULL &&
-+ tree_view->priv->queued_select_row == NULL &&
-+ gtk_tree_row_reference_valid (tree_view->priv->last_drag_row))
-+ {
-+ gint direction;
-+
-+ last_drag_path = gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row);
-+ path = _gtk_tree_view_find_path (tree_view, tree, node);
-+ direction = gtk_tree_path_compare (path, last_drag_path);
-+
-+ if (direction != 0)
-+ {
-+ current_path = gtk_tree_path_copy (last_drag_path);
-+
-+ /* we must ensure that no row is skipped because stylus
-+ is moving faster than motion events are generated */
-+ do {
-+ if (direction > 0)
-+ {
-+ /* gtk_tree_path_next does not let us know when it failed */
-+ GtkTreeIter iter;
-+ gtk_tree_model_get_iter (tree_view->priv->model, &iter, current_path);
-+ if (!gtk_tree_model_iter_next (tree_view->priv->model, &iter))
-+ break;
-+
-+ gtk_tree_path_next (current_path);
-+ }
-+ else if (!gtk_tree_path_prev (current_path))
-+ break;
-+
-+ /* set cursor, and start scrolling */
-+ gtk_tree_view_real_set_cursor (tree_view, current_path, FALSE, FALSE);
-+ add_scroll_timeout (tree_view);
-+
-+ if (tree_view->priv->checkbox_mode)
-+ {
-+ /* always set to same state as the first tapped node */
-+ if (tree_view->priv->new_state)
-+ gtk_tree_selection_select_path (tree_view->priv->selection,
-+ current_path);
-+ else
-+ gtk_tree_selection_unselect_path (tree_view->priv->selection,
-+ current_path);
-+ }
-+ else
-+ {
-+ if (gtk_tree_selection_path_is_selected (tree_view->priv->selection,
-+ current_path))
-+ {
-+ /* apparently we have reversed the pen drag direction */
-+ GtkTreePath *reverse_path;
-+ gint reverse_direction;
-+
-+ reverse_direction = gtk_tree_path_compare (current_path,
-+ last_drag_path);
-+ reverse_path = gtk_tree_path_copy (last_drag_path);
-+ do {
-+ gtk_tree_selection_unselect_path (tree_view->priv->selection,
-+ reverse_path);
-+ tree_view->priv->pen_drag_reverse = TRUE;
-+ if (reverse_direction > 0)
-+ {
-+ GtkTreeIter iter;
-+ gtk_tree_model_get_iter (tree_view->priv->model, &iter, reverse_path);
-+ if (!gtk_tree_model_iter_next (tree_view->priv->model, &iter))
-+ break;
-+
-+ gtk_tree_path_next (reverse_path);
-+ }
-+ else if (!gtk_tree_path_prev (reverse_path))
-+ break;
-+ } while (gtk_tree_path_compare (reverse_path, current_path) != 0);
-+ gtk_tree_path_free (reverse_path);
-+ }
-+ else
-+ {
-+ gtk_tree_selection_select_path (tree_view->priv->selection,
-+ current_path);
-+ tree_view->priv->pen_drag_reverse = FALSE;
-+ }
-+ }
-+ } while (gtk_tree_path_compare(current_path, path) != 0);
-+ gtk_tree_path_free (current_path);
-+
-+ /* update last_drag_row */
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+ tree_view->priv->last_drag_row =
-+ gtk_tree_row_reference_new (tree_view->priv->model, path);
-+ gtk_tree_path_free (path);
-+ }
-+ }
-+
- /* If we are currently pressing down a button, we don't want to prelight anything else. */
- if ((tree_view->priv->button_pressed_node != NULL) &&
- (tree_view->priv->button_pressed_node != node))
-@@ -3404,6 +3956,22 @@
- 1, 1, w, h);
- }
-
-+/* Hildon: helper function for dotted slash drawing;
-+ returns TRUE or FALSE, depending it there are
-+ more nodes at current level */
-+static gboolean
-+iter_has_next (GtkTreeModel *model, GtkTreeIter *iter)
-+{
-+ GtkTreeIter *check_iter;
-+ gboolean result;
-+
-+ check_iter = gtk_tree_iter_copy(iter);
-+ result = gtk_tree_model_iter_next (model, check_iter);
-+
-+ gtk_tree_iter_free (check_iter);
-+ return result;
-+}
-+
- /* Warning: Very scary function.
- * Modify at your own risk
- *
-@@ -3433,16 +4001,25 @@
- guint flags;
- gint highlight_x;
- gint bin_window_width;
-- GtkTreePath *cursor_path;
-- GtkTreePath *drag_dest_path;
-+ GtkTreePath *cursor_path = NULL;
-+ GtkTreePath *drag_dest_path = NULL;
- GList *last_column;
- gint vertical_separator;
- gint horizontal_separator;
-+ gint expander_indent;
- gint focus_line_width;
- gboolean allow_rules;
- gboolean has_special_cell;
- gboolean rtl;
- gint n_visible_columns;
-+ gboolean dottedlines, passivefocus, res;
-+
-+ /* Hildon: these variables are added for dotted slash drawing
-+ (Hierarchical listbox) */
-+ gint i;
-+ gint node_elements = 64;
-+ gboolean *iter_value = NULL;
-+ GtkTreeIter node_iter, parent_iter;
-
- g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
-
-@@ -3455,8 +4032,12 @@
- "vertical_separator", &vertical_separator,
- "allow_rules", &allow_rules,
- "focus-line-width", &focus_line_width,
-+ "expander_indent", &expander_indent,
-+ "passive_focus", &passivefocus,
- NULL);
-
-+ g_object_get (widget, "dotted_lines", &dottedlines, NULL);
-+
- if (tree_view->priv->tree == NULL)
- {
- draw_empty_focus (tree_view, &event->area);
-@@ -3478,6 +4059,8 @@
- if (node == NULL)
- return TRUE;
-
-+ iter_value = g_new (gboolean, node_elements);
-+
- /* find the path for the node */
- path = _gtk_tree_view_find_path ((GtkTreeView *)widget,
- tree,
-@@ -3486,11 +4069,25 @@
- &iter,
- path);
- depth = gtk_tree_path_get_depth (path);
-+
-+ node_iter = iter;
-+ for (i = depth - 1; i >= 1; i--)
-+ {
-+ res = gtk_tree_model_iter_parent (tree_view->priv->model, &parent_iter, &node_iter);
-+ /* Check, if we should grow array */
-+ if (i >= node_elements - 1)
-+ {
-+ node_elements *= 2;
-+ iter_value = g_renew (gboolean, iter_value, node_elements);
-+ if (!iter_value)
-+ goto done;
-+ }
-+ iter_value[i] = iter_has_next (tree_view->priv->model, &parent_iter);
-+ node_iter = parent_iter;
-+ }
-+ gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
- gtk_tree_path_free (path);
-
-- cursor_path = NULL;
-- drag_dest_path = NULL;
--
- if (tree_view->priv->cursor)
- cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-
-@@ -3533,6 +4130,7 @@
- do
- {
- gboolean parity;
-+ gboolean is_first = TRUE;
- gboolean is_separator = FALSE;
-
- if (tree_view->priv->row_separator_func)
-@@ -3570,6 +4168,7 @@
- GtkTreeViewColumn *column = list->data;
- const gchar *detail = NULL;
- GtkStateType state;
-+ gboolean is_last = (rtl ? !list->prev : !list->next);
-
- if (!column->visible)
- continue;
-@@ -3660,31 +4259,152 @@
- else
- state = GTK_STATE_NORMAL;
-
-- /* Draw background */
-- gtk_paint_flat_box (widget->style,
-- event->window,
-- state,
-- GTK_SHADOW_NONE,
-- &event->area,
-- widget,
-- detail,
-- background_area.x,
-- background_area.y,
-- background_area.width,
-- background_area.height);
-+ if (tree_view->priv->pen_focus)
-+ {
-+ if (node != cursor ||
-+ (!GTK_WIDGET_HAS_FOCUS (widget) && !passivefocus))
-+ {
-+ if ((flags & GTK_CELL_RENDERER_SELECTED)
-+ && !tree_view->priv->checkbox_mode)
-+ state = GTK_STATE_SELECTED;
-+ else
-+ state = GTK_STATE_NORMAL;
-+
-+ /* Draw background */
-+ gtk_paint_flat_box (widget->style,
-+ event->window,
-+ state,
-+ GTK_SHADOW_NONE,
-+ &event->area,
-+ widget,
-+ detail,
-+ background_area.x,
-+ background_area.y,
-+ background_area.width,
-+ background_area.height);
-+ }
-+ else if ((flags & GTK_CELL_RENDERER_SELECTED) &&
-+ !tree_view->priv->checkbox_mode &&
-+ node != cursor)
-+ {
-+ gtk_paint_flat_box (widget->style,
-+ event->window,
-+ GTK_STATE_SELECTED,
-+ GTK_SHADOW_NONE,
-+ &event->area,
-+ widget,
-+ detail,
-+ background_area.x,
-+ background_area.y,
-+ background_area.width,
-+ background_area.height);
-+ }
-+ }
-+ else
-+ {
-+ /* Draw background */
-+ gtk_paint_flat_box (widget->style,
-+ event->window,
-+ state,
-+ GTK_SHADOW_NONE,
-+ &event->area,
-+ widget,
-+ detail,
-+ background_area.x,
-+ background_area.y,
-+ background_area.width,
-+ background_area.height);
-+ }
-+
-+ /* Hildon change: drawing focus is moved here because it didn't work
-+ properly before. Some changes where also made.*/
-+ /* draw the big row-spanning focus rectangle, if needed */
-+ if (node == cursor &&
-+ (!passivefocus || GTK_WIDGET_HAS_FOCUS (widget)))
-+ {
-+ gtk_paint_focus (widget->style,
-+ event->window,
-+ GTK_STATE_ACTIVE,
-+ &event->area,
-+ widget,
-+ (is_first
-+ ? (is_last ? "full" : "left")
-+ : (is_last ? "right" : "middle")),
-+ background_area.x - (is_first ? 0 : horizontal_separator / 2),
-+ background_area.y - vertical_separator / 2,
-+ background_area.width + (is_first ? 0 : (is_last ? horizontal_separator / 2 : horizontal_separator)),
-+ background_area.height + vertical_separator);
-+
-+ is_first = FALSE;
-+ }
-+ else if (node == cursor && passivefocus &&
-+ !GTK_WIDGET_HAS_FOCUS (widget))
-+ {
-+ GtkStyle *style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (widget),
-+ "hildon-focus",
-+ NULL,
-+ G_TYPE_NONE);
-+ gtk_style_attach (style, event->window);
-+
-+ gtk_paint_focus (style, event->window, GTK_STATE_SELECTED,
-+ &event->area, widget,
-+ (is_first
-+ ? (is_last ? "full" : "left")
-+ : (is_last ? "right" : "middle")),
-+ background_area.x - (is_first ? 0 : horizontal_separator / 2),
-+ background_area.y - vertical_separator / 2,
-+ background_area.width + (is_first ? 0 : (is_last ? horizontal_separator / 2 : horizontal_separator)),
-+ background_area.height + vertical_separator);
-+
-+ is_first = FALSE;
-+ }
-+
-+ if (node == cursor)
-+ {
-+ gint width, x_offset;
-+ GtkStateType focus_rect_state;
-+ focus_rect_state =
-+ flags & GTK_CELL_RENDERER_FOCUSED ? GTK_STATE_ACTIVE :
-+ (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
-+ (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE :
-+ (flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
-+ GTK_STATE_NORMAL)));
-+
-+ gtk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, NULL);
-+ gdk_drawable_get_size (tree_view->priv->bin_window, &width, NULL);
-+ }
-
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
- {
-+ gint px, px2, py, i;
-+
-+ if (depth <= 1)
-+ px = 0;
-+ else
-+ px = (depth - 1) * tree_view->priv->expander_size +
-+ (depth - 2) * expander_indent;
-+
-+ /* Hildonlike hack for making the indent look better.
-+ * indent is added to all rows except the first one */
-+
- if (!rtl)
-- cell_area.x += depth * tree_view->priv->expander_size;
-- cell_area.width -= depth * tree_view->priv->expander_size;
-+ cell_area.x += depth * tree_view->priv->expander_size + (depth-1) * expander_indent;
-+ cell_area.width -= depth * tree_view->priv->expander_size + (depth-1) * expander_indent;
-
- /* If we have an expander column, the highlight underline
- * starts with that column, so that it indicates which
- * level of the tree we're dropping at.
- */
- highlight_x = cell_area.x;
-+
-+ if (!GTK_WIDGET_IS_SENSITIVE (widget))
-+ {
-+ flags &= ~ (GTK_CELL_RENDERER_PRELIT + GTK_CELL_RENDERER_INSENSITIVE +
-+ GTK_CELL_RENDERER_FOCUSED);
-+ flags &= GTK_CELL_RENDERER_INSENSITIVE;
-+ }
-+
- if (is_separator)
- gtk_paint_hline (widget->style,
- event->window,
-@@ -3702,6 +4422,48 @@
- &cell_area,
- &event->area,
- flags);
-+
-+ /* Hildon dotted slash line drawing for Hierarchical Listbox
-+ widget */
-+ if (dottedlines)
-+ {
-+ py = cell_area.y + cell_area.height / 2;
-+ px2 = depth * tree_view->priv->expander_size +
-+ (depth - 1) * expander_indent;
-+
-+ gdk_gc_set_line_attributes (widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_BEVEL);
-+
-+ gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ px, py, px2, py);
-+
-+ if (depth > 1)
-+ {
-+ gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ px, cell_area.y, px, py);
-+ if (iter_has_next (tree_view->priv->model, &iter))
-+ {
-+ gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ px, py, px, cell_area.y + cell_area.height);
-+ }
-+ }
-+
-+ if (node->children)
-+ {
-+ gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ px2, py, px2, cell_area.y + cell_area.height);
-+ }
-+ for (i = depth - 1; i >= 2; i--)
-+ {
-+ if (iter_value[i])
-+ {
-+ px = (i - 1)* tree_view->priv->expander_size + (i - 2) * expander_indent;
-+ gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-+ px, cell_area.y, px, cell_area.y + cell_area.height);
-+ }
-+ }
-+ }
-+
- if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
- {
- gint x, y;
-@@ -3803,6 +4565,8 @@
- }
- }
-
-+ /* Hildon: disabled this */
-+#if 0
- /* draw the big row-spanning focus rectangle, if needed */
- if (!has_special_cell && node == cursor &&
- GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS) &&
-@@ -3830,6 +4594,7 @@
- width,
- ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node)));
- }
-+#endif
-
- y_offset += max_height;
- if (node->children)
-@@ -3847,6 +4612,17 @@
- has_child = gtk_tree_model_iter_children (tree_view->priv->model,
- &iter,
- &parent);
-+
-+ /* Check if we need to grow array */
-+ if (depth >= node_elements - 1)
-+ {
-+ node_elements *= 2;
-+ iter_value = g_renew (gboolean, iter_value, node_elements);
-+ if (!iter_value)
-+ goto done;
-+ }
-+ iter_value[depth] = iter_has_next (tree_view->priv->model, &parent);
-+
- depth++;
-
- /* Sanity Check! */
-@@ -3897,6 +4673,9 @@
- if (drag_dest_path)
- gtk_tree_path_free (drag_dest_path);
-
-+ if (iter_value)
-+ g_free (iter_value);
-+
- return FALSE;
- }
-
-@@ -4179,6 +4958,63 @@
-
- rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
-
-+ /* Special Hildon keyboard interactions */
-+ if (event->keyval == GDK_Escape)
-+ gtk_tree_selection_unselect_all (tree_view->priv->selection);
-+
-+ if (event->keyval == GDK_Return &&
-+ gtk_tree_row_reference_valid (tree_view->priv->cursor))
-+ {
-+ gboolean force_list_kludge;
-+
-+ g_object_get (widget, "force_list_kludge", &force_list_kludge, NULL);
-+ if (force_list_kludge ||
-+ (gtk_tree_model_get_flags (tree_view->priv->model) &
-+ GTK_TREE_MODEL_LIST_ONLY))
-+ {
-+ /* text listbox */
-+ if (tree_view->priv->checkbox_mode)
-+ {
-+ /* multisel with checkboxes: select key toggles focused */
-+ gtk_tree_view_real_toggle_cursor_row (tree_view);
-+ }
-+ else
-+ {
-+ /* no checkboxes: select key activates focused */
-+ GtkTreePath *cursor_path =
-+ gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+
-+ gtk_tree_view_row_activated (tree_view, cursor_path,
-+ tree_view->priv->focus_column);
-+
-+ gtk_tree_path_free (cursor_path);
-+ }
-+ }
-+ else
-+ {
-+ /* hierarchical listbox */
-+ GtkTreePath *cursor_path;
-+ GtkRBTree *tree;
-+ GtkRBNode *node;
-+
-+ cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+ _gtk_tree_view_find_node (tree_view, cursor_path, &tree, &node);
-+
-+ if (node->children == NULL)
-+ gtk_tree_view_real_expand_row (tree_view,
-+ cursor_path,
-+ tree,
-+ node,
-+ FALSE, TRUE);
-+ else
-+ gtk_tree_view_real_collapse_row (tree_view,
-+ cursor_path,
-+ tree,
-+ node,
-+ TRUE);
-+ }
-+ }
-+
- if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
- {
- if (event->keyval == GDK_Escape)
-@@ -4420,6 +5256,7 @@
-
- /* FIXME Is this function necessary? Can I get an enter_notify event
- * w/o either an expose event or a mouse motion event?
-+ * Hildon => it is necessary to make pen dragging work correctly
- */
- static gboolean
- gtk_tree_view_enter_notify (GtkWidget *widget,
-@@ -4434,6 +5271,10 @@
-
- tree_view = GTK_TREE_VIEW (widget);
-
-+ /* stop "automatic" pen dragging */
-+ tree_view->priv->pen_drag_active = FALSE;
-+ remove_scroll_timeout (tree_view);
-+
- /* Sanity check it */
- if (event->window != tree_view->priv->bin_window)
- return FALSE;
-@@ -4463,6 +5304,9 @@
- tree_view = GTK_TREE_VIEW (widget);
- tree_view->priv->pressed_button = -1;
-
-+ if (tree_view->priv->pen_down && tree_view->priv->queued_select_row == NULL)
-+ tree_view->priv->pen_drag_active = TRUE;
-+
- if (event->mode == GDK_CROSSING_GRAB)
- return TRUE;
-
-@@ -4535,6 +5379,7 @@
- gboolean retval = FALSE;
- gboolean is_separator = FALSE;
- gint focus_pad;
-+ gint expander_indent;
-
- /* double check the row needs validating */
- if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) &&
-@@ -4551,6 +5396,7 @@
- gtk_widget_style_get (GTK_WIDGET (tree_view),
- "focus-padding", &focus_pad,
- "horizontal_separator", &horizontal_separator,
-+ "expander_indent", &expander_indent,
- NULL);
-
- for (list = tree_view->priv->columns; list; list = list->next)
-@@ -4577,13 +5423,16 @@
- {
- height = MAX (height, tmp_height);
- height = MAX (height, tree_view->priv->expander_size);
-+
-+ /* Hildon addition */
-+ height -= 1;
- }
- else
- height = 2 + 2 * focus_pad;
-
- if (gtk_tree_view_is_expander_column (tree_view, column) && TREE_VIEW_DRAW_EXPANDERS (tree_view))
- {
-- tmp_width = tmp_width + horizontal_separator + depth * (tree_view->priv->expander_size);
-+ tmp_width = tmp_width + horizontal_separator + depth * (tree_view->priv->expander_size) + (depth - 1) * expander_indent;
- }
- else
- tmp_width = tmp_width + horizontal_separator;
-@@ -5585,6 +6434,16 @@
- #endif /* 0 */
-
- static void
-+add_scroll_timeout (GtkTreeView *tree_view)
-+{
-+ if (tree_view->priv->scroll_timeout == 0)
-+ {
-+ tree_view->priv->scroll_timeout =
-+ g_timeout_add (150, scroll_row_timeout, tree_view);
-+ }
-+}
-+
-+static void
- remove_scroll_timeout (GtkTreeView *tree_view)
- {
- if (tree_view->priv->scroll_timeout != 0)
-@@ -6130,10 +6989,9 @@
- tree_view->priv->open_dest_timeout =
- g_timeout_add (AUTO_EXPAND_TIMEOUT, open_row_timeout, tree_view);
- }
-- else if (tree_view->priv->scroll_timeout == 0)
-+ else
- {
-- tree_view->priv->scroll_timeout =
-- g_timeout_add (150, scroll_row_timeout, tree_view);
-+ add_scroll_timeout (tree_view);
- }
-
- if (target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
-@@ -6901,8 +7759,6 @@
- GtkMovementStep step,
- gint count)
- {
-- GdkModifierType state;
--
- g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
- g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
- step == GTK_MOVEMENT_VISUAL_POSITIONS ||
-@@ -6919,6 +7775,8 @@
- GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
- gtk_widget_grab_focus (GTK_WIDGET (tree_view));
-
-+ /* Hildon: Ignore ctrl and shift */
-+#if 0
- if (gtk_get_current_event_state (&state))
- {
- if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
-@@ -6926,6 +7784,7 @@
- if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
- tree_view->priv->shift_pressed = TRUE;
- }
-+#endif
- /* else we assume not pressed */
-
- switch (step)
-@@ -7092,6 +7951,27 @@
- done:
- if (!tree_view->priv->fixed_height_mode)
- install_presize_handler (tree_view);
-+
-+ /* Hildon: has row now been dimmed? If so, unselect it */
-+ _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-+ if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ node,
-+ path))
-+ {
-+ if (gtk_tree_path_compare (path,
-+ gtk_tree_row_reference_get_path(tree_view->priv->cursor))
-+ == 0)
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->cursor);
-+ tree_view->priv->cursor = NULL;
-+ }
-+
-+ gtk_tree_selection_unselect_path (tree_view->priv->selection, path);
-+ gtk_tree_view_collapse_row (tree_view, path);
-+ }
-+
-+ check_if_can_focus (tree_view);
-+
- if (free_path)
- gtk_tree_path_free (path);
- }
-@@ -7196,6 +8076,11 @@
- install_presize_handler (tree_view);
- if (free_path)
- gtk_tree_path_free (path);
-+
-+ /* Hildon: after a focusable row has been added, the
-+ entire widget becomes focusable if it wasn't before */
-+ if ((GTK_WIDGET_FLAGS (tree_view) & GTK_CAN_FOCUS) == 0)
-+ check_if_can_focus (tree_view);
- }
-
- static void
-@@ -7295,6 +8180,16 @@
- _gtk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, check_selection_helper, data);
- }
-
-+static gboolean
-+check_if_can_focus_idle (GtkTreeView *tree_view)
-+{
-+ check_if_can_focus (tree_view);
-+
-+ tree_view->priv->check_if_can_focus_idle_id = 0;
-+
-+ return FALSE;
-+}
-+
- static void
- gtk_tree_view_row_deleted (GtkTreeModel *model,
- GtkTreePath *path,
-@@ -7357,6 +8252,11 @@
- tree_view->priv->tree = NULL;
-
- _gtk_rbtree_remove (tree);
-+
-+ /* Hildon: no nodes -> not focusable */
-+ /* FIXME this looks superfluos to me. check_if_can_focus is called
-+ * at the end of this function .. -- Jorn */
-+ GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
- }
- else
- {
-@@ -7375,6 +8275,13 @@
-
- if (selection_changed)
- g_signal_emit_by_name (tree_view->priv->selection, "changed");
-+
-+ /* FIXME whacky hack to work around the treeview not being in a clean state
-+ * when in a tree a row has been removed, but has_child_toggled not been
-+ * called yet */
-+ if (tree_view->priv->check_if_can_focus_idle_id == 0)
-+ tree_view->priv->check_if_can_focus_idle_id =
-+ g_idle_add ((GSourceFunc) check_if_can_focus_idle, tree_view);
- }
-
- static void
-@@ -7508,6 +8415,7 @@
- GList *list;
- GtkTreeViewColumn *tmp_column = NULL;
- gint total_width;
-+ gint expander_indent, depth;
- gboolean indent_expanders;
- gboolean rtl;
-
-@@ -7535,14 +8443,19 @@
-
- gtk_widget_style_get (GTK_WIDGET (tree_view),
- "indent_expanders", &indent_expanders,
-+ "expander_indent", &expander_indent,
- NULL);
-
-+ /* Hildonlike hack for making the indent look better.
-+ * indent is added to all rows except the first one */
-+ depth = _gtk_rbtree_get_depth (tree);
-+
- if (indent_expanders)
- {
- if (rtl)
-- x_offset -= tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
-+ x_offset -= tree_view->priv->expander_size * depth + (depth) * expander_indent;
- else
-- x_offset += tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
-+ x_offset += tree_view->priv->expander_size * depth + (depth) * expander_indent;
- }
- if (x1)
- {
-@@ -7617,9 +8530,11 @@
- gboolean retval = FALSE;
- gint tmpheight;
- gint horizontal_separator;
-+ gint expander_indent;
-
- gtk_widget_style_get (GTK_WIDGET (tree_view),
- "horizontal_separator", &horizontal_separator,
-+ "expander_indent", &expander_indent,
- NULL);
-
- if (height)
-@@ -7657,7 +8572,7 @@
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS (tree_view))
- {
-- if (depth * tree_view->priv->expander_size + horizontal_separator + width > column->requested_width)
-+ if ((depth - 1) *expander_indent + depth * tree_view->priv->expander_size + horizontal_separator + width > column->requested_width)
- {
- _gtk_tree_view_column_cell_set_dirty (column, TRUE);
- retval = TRUE;
-@@ -7747,6 +8662,7 @@
- }
- }
-
-+#if 0
- static void
- gtk_tree_view_clamp_column_visible (GtkTreeView *tree_view,
- GtkTreeViewColumn *column)
-@@ -7762,6 +8678,7 @@
- gtk_adjustment_set_value (tree_view->priv->hadjustment,
- column->button->allocation.x);
- }
-+#endif
-
- /* This function could be more efficient. I'll optimize it if profiling seems
- * to imply that it is important */
-@@ -8290,7 +9207,7 @@
-
- area.x = x_offset;
- area.y = CELL_FIRST_PIXEL (tree_view, tree, node, vertical_separator);
-- area.width = expander_size + 2;
-+ area.width = expander_size;
- area.height = MAX (CELL_HEIGHT (node, vertical_separator), (expander_size - vertical_separator));
-
- if (node == tree_view->priv->button_pressed_node)
-@@ -8397,7 +9314,10 @@
- GtkRBNode *cursor_node = NULL;
- GtkRBTree *new_cursor_tree = NULL;
- GtkRBNode *new_cursor_node = NULL;
-+ GtkRBTree *old_cursor_tree;
-+ GtkRBNode *old_cursor_node;
- GtkTreePath *cursor_path = NULL;
-+ GtkTreePath *new_cursor_path = NULL;
-
- if (! GTK_WIDGET_HAS_FOCUS (tree_view))
- return;
-@@ -8415,12 +9335,30 @@
- if (cursor_tree == NULL)
- /* FIXME: we lost the cursor; should we get the first? */
- return;
-- if (count == -1)
-- _gtk_rbtree_prev_full (cursor_tree, cursor_node,
-- &new_cursor_tree, &new_cursor_node);
-- else
-- _gtk_rbtree_next_full (cursor_tree, cursor_node,
-- &new_cursor_tree, &new_cursor_node);
-+
-+ old_cursor_tree = cursor_tree;
-+ old_cursor_node = cursor_node;
-+ do {
-+ if (count == -1)
-+ _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
-+ &new_cursor_tree, &new_cursor_node);
-+ else
-+ _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
-+ &new_cursor_tree, &new_cursor_node);
-+
-+ if (new_cursor_node)
-+ {
-+ if (new_cursor_path)
-+ gtk_tree_path_free (new_cursor_path);
-+
-+ new_cursor_path = _gtk_tree_view_find_path (tree_view, new_cursor_tree, new_cursor_node);
-+ old_cursor_tree = new_cursor_tree;
-+ old_cursor_node = new_cursor_node;
-+ }
-+ } while (new_cursor_node &&
-+ !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ new_cursor_node,
-+ new_cursor_path));
-
- /*
- * If the list has only one item and multi-selection is set then select
-@@ -8450,7 +9388,33 @@
- if (new_cursor_node)
- {
- cursor_path = _gtk_tree_view_find_path (tree_view, new_cursor_tree, new_cursor_node);
-- gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
-+
-+ if (tree_view->priv->checkbox_mode)
-+ gtk_tree_view_real_set_cursor (tree_view, cursor_path, FALSE, TRUE);
-+ else
-+ gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
-+
-+ if (tree_view->priv->pen_drag_active)
-+ {
-+ if (gtk_tree_path_compare (gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row),
-+ gtk_tree_row_reference_get_path (tree_view->priv->first_drag_row)) == 0)
-+ tree_view->priv->pen_drag_reverse = FALSE;
-+
-+ if (tree_view->priv->pen_drag_reverse)
-+ {
-+ gtk_tree_selection_select_path (tree_view->priv->selection,
-+ cursor_path);
-+ gtk_tree_selection_unselect_path (tree_view->priv->selection,
-+ gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row));
-+ }
-+
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+
-+ tree_view->priv->last_drag_row =
-+ gtk_tree_row_reference_new (tree_view->priv->model,
-+ cursor_path);
-+ }
-+
- gtk_tree_path_free (cursor_path);
- }
- else
-@@ -8467,6 +9431,8 @@
- {
- GtkRBTree *cursor_tree = NULL;
- GtkRBNode *cursor_node = NULL;
-+ GtkRBTree *old_cursor_tree = NULL;
-+ GtkRBNode *old_cursor_node = NULL;
- GtkTreePath *cursor_path = NULL;
- gint y;
- gint vertical_separator;
-@@ -8474,6 +9440,9 @@
- if (! GTK_WIDGET_HAS_FOCUS (tree_view))
- return;
-
-+ if (tree_view->priv->tree == NULL)
-+ return;
-+
- if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
- cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
- else
-@@ -8504,7 +9473,65 @@
-
- _gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
- cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
-- g_return_if_fail (cursor_path != NULL);
-+
-+ while (cursor_node &&
-+ !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ cursor_node,
-+ cursor_path))
-+ {
-+ old_cursor_tree = cursor_tree;
-+ old_cursor_node = cursor_node;
-+
-+ if (count < 0)
-+ _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
-+ &cursor_tree, &cursor_node);
-+ else
-+ _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
-+ &cursor_tree, &cursor_node);
-+
-+ if (cursor_path)
-+ {
-+ gtk_tree_path_free(cursor_path);
-+ cursor_path = NULL;
-+ }
-+
-+ if (cursor_node)
-+ cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
-+ }
-+
-+ if (cursor_path == NULL)
-+ {
-+ /* looks like we reached the end without finding a sensitive row,
-+ so search backwards and try to find the last sensitive row as
-+ the next best thing */
-+ _gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
-+ cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
-+ while (cursor_node &&
-+ !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ cursor_node,
-+ cursor_path))
-+ {
-+ old_cursor_tree = cursor_tree;
-+ old_cursor_node = cursor_node;
-+
-+ if (count < 0)
-+ _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
-+ &cursor_tree, &cursor_node);
-+ else
-+ _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
-+ &cursor_tree, &cursor_node);
-+
-+ if (cursor_path)
-+ {
-+ gtk_tree_path_free(cursor_path);
-+ cursor_path = NULL;
-+ }
-+
-+ if (cursor_node)
-+ cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
-+ }
-+ }
-+
- gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
- gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
- gtk_tree_path_free (cursor_path);
-@@ -8514,6 +9541,8 @@
- gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
- gint count)
- {
-+ /* Hildon: cursor is always displayed on an entire row anyway */
-+#if 0
- GtkRBTree *cursor_tree = NULL;
- GtkRBNode *cursor_node = NULL;
- GtkTreePath *cursor_path = NULL;
-@@ -8589,12 +9618,15 @@
- g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0);
- }
- gtk_tree_view_clamp_column_visible (tree_view, tree_view->priv->focus_column);
-+#endif
- }
-
- static void
- gtk_tree_view_move_cursor_start_end (GtkTreeView *tree_view,
- gint count)
- {
-+ /* Hildon: cursor is always displayed on an entire row anyway */
-+#if 0
- GtkRBTree *cursor_tree;
- GtkRBNode *cursor_node;
- GtkTreePath *path;
-@@ -8631,6 +9663,7 @@
- path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
- gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE);
- gtk_tree_path_free (path);
-+#endif
- }
-
- static gboolean
-@@ -8670,7 +9703,7 @@
- GtkTreePath *cursor_path = NULL;
- GtkTreeSelectMode mode = 0;
-
-- if (! GTK_WIDGET_HAS_FOCUS (tree_view))
-+ if (! GTK_WIDGET_HAS_FOCUS (tree_view) && !tree_view->priv->checkbox_mode)
- return FALSE;
-
- if (tree_view->priv->cursor)
-@@ -8731,7 +9764,7 @@
- GtkRBNode *cursor_node = NULL;
- GtkTreePath *cursor_path = NULL;
-
-- if (! GTK_WIDGET_HAS_FOCUS (tree_view))
-+ if (! GTK_WIDGET_HAS_FOCUS (tree_view) && !tree_view->priv->checkbox_mode)
- return FALSE;
-
- cursor_path = NULL;
-@@ -8774,6 +9807,7 @@
- GtkTreePath *cursor_path = NULL;
- GtkRBTree *tree;
- GtkRBNode *node;
-+ gboolean hildon_row;
-
- if (! GTK_WIDGET_HAS_FOCUS (tree_view))
- return FALSE;
-@@ -8796,10 +9830,32 @@
- && gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL)
- expand = !expand;
-
-- if (expand)
-- gtk_tree_view_real_expand_row (tree_view, cursor_path, tree, node, open_all, TRUE);
-+ /* Keyboard Navigation: if we can't expand/collapse row, we should either move active focus
-+ to child item (right arrow) or move active focus to the parent item (left arrow) */
-+ if (expand)
-+ {
-+ hildon_row = gtk_tree_view_real_expand_row (tree_view, cursor_path, tree,
-+ node, open_all, TRUE);
-+
-+ if (!hildon_row || !node->children)
-+ g_signal_emit_by_name (gtk_widget_get_ancestor (GTK_WIDGET (tree_view),
-+ GTK_TYPE_WINDOW),
-+ "move_focus",
-+ GTK_DIR_TAB_FORWARD);
-+ }
- else
-- gtk_tree_view_real_collapse_row (tree_view, cursor_path, tree, node, TRUE);
-+ {
-+ hildon_row = gtk_tree_view_real_collapse_row (tree_view, cursor_path, tree, node, TRUE);
-+
-+ if (hildon_row == FALSE)
-+ {
-+ g_signal_emit_by_name (gtk_widget_get_ancestor (GTK_WIDGET(tree_view),
-+ GTK_TYPE_WINDOW),
-+ "move_focus",
-+ GTK_DIR_TAB_BACKWARD);
-+ gtk_tree_view_real_select_cursor_parent (tree_view);
-+ }
-+ }
-
- gtk_tree_path_free (cursor_path);
-
-@@ -9327,6 +10383,14 @@
- tree_view->priv->last_button_press_2 = NULL;
- gtk_tree_row_reference_free (tree_view->priv->scroll_to_path);
- tree_view->priv->scroll_to_path = NULL;
-+ gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
-+ tree_view->priv->first_drag_row = NULL;
-+ gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
-+ tree_view->priv->last_drag_row = NULL;
-+ gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
-+ tree_view->priv->queued_expand_row = NULL;
-+ gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
-+ tree_view->priv->queued_select_row = NULL;
-
- tree_view->priv->scroll_to_column = NULL;
-
-@@ -9402,6 +10466,8 @@
- install_presize_handler (tree_view);
- }
-
-+ check_if_can_focus (tree_view);
-+
- g_object_notify (G_OBJECT (tree_view), "model");
-
- if (GTK_WIDGET_REALIZED (tree_view))
-@@ -9744,6 +10810,10 @@
- G_CALLBACK (column_sizing_notify),
- tree_view);
-
-+ g_signal_handlers_disconnect_by_func (column,
-+ G_CALLBACK (update_checkbox_mode),
-+ tree_view);
-+
- _gtk_tree_view_column_unset_tree_view (column);
-
- tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column);
-@@ -9773,6 +10843,8 @@
- g_object_unref (column);
- g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
-
-+ update_checkbox_mode (NULL, NULL, tree_view);
-+
- return tree_view->priv->n_columns;
- }
-
-@@ -9815,6 +10887,9 @@
- g_signal_connect (column, "notify::sizing",
- G_CALLBACK (column_sizing_notify), tree_view);
-
-+ g_signal_connect (column, "notify::visible",
-+ G_CALLBACK (update_checkbox_mode), tree_view);
-+
- tree_view->priv->columns = g_list_insert (tree_view->priv->columns,
- column, position);
- tree_view->priv->n_columns++;
-@@ -9838,6 +10913,9 @@
-
- g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
-
-+ update_checkbox_mode (NULL, NULL, tree_view);
-+ check_if_can_focus (tree_view);
-+
- return tree_view->priv->n_columns;
- }
-
-@@ -10295,7 +11373,6 @@
- GtkTreeViewColumn *column)
- {
- g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
--
- g_signal_emit (tree_view, tree_view_signals[ROW_ACTIVATED], 0, path, column);
- }
-
-@@ -10560,6 +11637,16 @@
- GtkTreeIter iter;
- GtkTreeIter temp;
- gboolean expand;
-+ gint vertical_separator;
-+ GtkTreePath *collapse_path;
-+ GtkRBTree *tree2;
-+ GtkRBNode *node2;
-+ GtkTreePath *child_path = NULL;
-+ GtkTreeIter parent_iter;
-+ GtkTreeIter child_iter;
-+ GdkRectangle visible_rect;
-+ gint children, n;
-+ guint total_height;
-
- remove_auto_expand_timeout (tree_view);
-
-@@ -10573,8 +11660,12 @@
- if (! gtk_tree_model_iter_has_child (tree_view->priv->model, &iter))
- return FALSE;
-
-+ /* Hildon: insensitive rows cannot be expanded */
-+ if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ node, path))
-+ return FALSE;
-
-- if (node->children && open_all)
-+ if (node->children && open_all)
- {
- gboolean retval = FALSE;
- GtkTreePath *tmp_path = gtk_tree_path_copy (path);
-@@ -10603,6 +11694,37 @@
- return retval;
- }
-
-+ /* Hildon: collapse other items in the same level */
-+ gtk_widget_style_get (GTK_WIDGET (tree_view),
-+ "vertical_separator", &vertical_separator, NULL);
-+
-+ /* find the first child */
-+ collapse_path = gtk_tree_path_copy (path);
-+ while (gtk_tree_path_prev (collapse_path))
-+ ;
-+
-+ do {
-+ if (gtk_tree_path_compare (collapse_path, path) != 0)
-+ {
-+ _gtk_tree_view_find_node (tree_view, collapse_path, &tree2, &node2);
-+
-+ if (tree2 == NULL)
-+ /* end reached already */
-+ break;
-+
-+ if (node2->children != NULL &&
-+ gtk_tree_view_real_collapse_row (tree_view, collapse_path,
-+ tree2, node2, FALSE))
-+ /* no need to do anything else since only one row may
-+ be expanded on any particular level at any time */
-+ break;
-+ }
-+
-+ gtk_tree_path_next (collapse_path);
-+ } while (1);
-+
-+ gtk_tree_path_free (collapse_path);
-+
- g_signal_emit (tree_view, tree_view_signals[TEST_EXPAND_ROW], 0, &iter, path, &expand);
-
- if (expand)
-@@ -10643,6 +11765,42 @@
- GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
- }
-
-+ /* autoscroll if necessary */
-+ validate_visible_area (tree_view);
-+ gtk_tree_model_get_iter (tree_view->priv->model, &parent_iter, path);
-+ _gtk_tree_view_find_node (tree_view, path, &tree2, &node2);
-+ validate_row (tree_view, tree2, node2, &parent_iter, path);
-+ total_height = CELL_HEIGHT (node2, vertical_separator);
-+ children = gtk_tree_model_iter_n_children (tree_view->priv->model, &parent_iter);
-+ for (n = 0; n < children; n++)
-+ {
-+ gtk_tree_model_iter_nth_child (tree_view->priv->model,
-+ &child_iter, &parent_iter, n);
-+
-+ /* must free here so the path of last child is kept for later */
-+ if (child_path != NULL)
-+ gtk_tree_path_free (child_path);
-+
-+ child_path = gtk_tree_model_get_path (tree_view->priv->model, &child_iter);
-+ _gtk_tree_view_find_node (tree_view, child_path, &tree2, &node2);
-+
-+ if (CELL_HEIGHT (node2, 0) == 0)
-+ validate_row (tree_view, tree2, node2, &child_iter, child_path);
-+
-+ total_height += CELL_HEIGHT (node2, vertical_separator);
-+ }
-+
-+ gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
-+
-+ /* KNOWN BUG: If no autocollapse was performed earlier above, these calls
-+ to gtk_tree_view_scroll_to_cell do nothing although they should. */
-+ if (total_height > visible_rect.height)
-+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.0, 0.0);
-+ else
-+ gtk_tree_view_scroll_to_cell (tree_view, child_path, NULL, FALSE, 0.0, 0.0);
-+
-+ gtk_tree_path_free (child_path);
-+
- install_presize_handler (tree_view);
-
- g_signal_emit (tree_view, tree_view_signals[ROW_EXPANDED], 0, &iter, path);
-@@ -11070,6 +12228,16 @@
- GtkRBTree *tree = NULL;
- GtkRBNode *node = NULL;
-
-+ _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-+
-+ /* Hildon: cursor cannot move to an insensitive row */
-+ if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ node, path))
-+ {
-+ g_signal_emit (tree_view, tree_view_signals[ROW_INSENSITIVE], 0, path);
-+ return;
-+ }
-+
- if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
- {
- GtkTreePath *cursor_path;
-@@ -11083,7 +12251,6 @@
- tree_view->priv->cursor = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view),
- tree_view->priv->model,
- path);
-- _gtk_tree_view_find_node (tree_view, path, &tree, &node);
- if (tree != NULL)
- {
- GtkRBTree *new_tree = NULL;
-@@ -11093,7 +12260,8 @@
- {
- GtkTreeSelectMode mode = 0;
-
-- if (tree_view->priv->ctrl_pressed)
-+ if (tree_view->priv->ctrl_pressed ||
-+ tree_view->priv->pen_drag_active)
- mode |= GTK_TREE_SELECT_MODE_TOGGLE;
- if (tree_view->priv->shift_pressed)
- mode |= GTK_TREE_SELECT_MODE_EXTEND;
-@@ -11213,6 +12381,9 @@
- {
- g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
- g_return_if_fail (path != NULL);
-+
-+ tree_view->priv->pen_focus = FALSE;
-+
- if (focus_column)
- g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (focus_column));
- if (focus_cell)
-@@ -11414,6 +12585,7 @@
- GtkRBNode *node = NULL;
- gint vertical_separator;
- gint horizontal_separator;
-+ gint expander_indent;
-
- g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
- g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column));
-@@ -11424,6 +12596,7 @@
- gtk_widget_style_get (GTK_WIDGET (tree_view),
- "vertical_separator", &vertical_separator,
- "horizontal_separator", &horizontal_separator,
-+ "expander_indent", &expander_indent,
- NULL);
-
- rect->x = 0;
-@@ -11453,9 +12626,11 @@
- TREE_VIEW_DRAW_EXPANDERS (tree_view))
- {
- gint depth = gtk_tree_path_get_depth (path) - 1;
-+ gint adjust;
-
-- rect->x += depth * tree_view->priv->expander_size;
-- rect->width -= depth * tree_view->priv->expander_size;
-+ adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
-+ rect->x += adjust;
-+ rect->width -= adjust;
- rect->width = MAX (rect->width, 0);
- }
- }
-@@ -12077,8 +13252,13 @@
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
- {
-- cell_area.x += depth * tree_view->priv->expander_size;
-- cell_area.width -= depth * tree_view->priv->expander_size;
-+ gint adjust, expander_indent;
-+
-+ gtk_widget_style_get (widget, "expander_indent", &expander_indent, NULL);
-+
-+ adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
-+ cell_area.x += adjust;
-+ cell_area.width -= adjust;
- }
-
- if (gtk_tree_view_column_cell_is_visible (column))
-@@ -13062,3 +14242,138 @@
- tree_view->priv->pressed_button = -1;
- }
-
-+/* Hildon addition: iterates through columns and cells, looks for
-+ a cell with "activatable" attribute and sets or unsets
-+ priv->checkbox_mode accordingly (except when checkbox mode
-+ is disabled by unsetting allow_checkbox_mode).
-+ */
-+static void
-+update_checkbox_mode (GObject *object, GParamSpec *pspec, gpointer data)
-+{
-+ GtkTreeView *tree_view = GTK_TREE_VIEW (data);
-+ GList *columns = gtk_tree_view_get_columns (tree_view);
-+ GList *list;
-+ gboolean allow_checkbox_mode;
-+
-+ g_object_get (GTK_WIDGET (data),
-+ "allow_checkbox_mode", &allow_checkbox_mode, NULL);
-+ g_return_if_fail (allow_checkbox_mode);
-+
-+ for (list = columns; list; list = list->next)
-+ {
-+ GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN (list->data);
-+ if (gtk_tree_view_column_get_visible (col) &&
-+ _gtk_tree_view_column_has_activatable_cell (col))
-+ {
-+ /* checkbox column found */
-+ tree_view->priv->checkbox_mode = TRUE;
-+ g_list_free (columns);
-+ return;
-+ }
-+ }
-+
-+ /* no checkbox column was found */
-+ tree_view->priv->checkbox_mode = FALSE;
-+ g_list_free (columns);
-+}
-+
-+static void
-+set_dotted_lines (GtkTreeView *tree_view, gboolean enable)
-+{
-+ if (enable != tree_view->priv->dotted_lines)
-+ {
-+ tree_view->priv->dotted_lines = enable;
-+ gtk_widget_queue_draw (GTK_WIDGET (tree_view));
-+ }
-+}
-+
-+/* This function is used to ensure two things:
-+ * - in single selection mode, focus will always equal selection
-+ * - in multiple selection mode, focus is removed if cursor row is
-+ * explicitly unselected
-+ */
-+static void
-+selection_changed (GtkTreeSelection *selection, gpointer data)
-+{
-+ GtkTreeView *tree_view = GTK_TREE_VIEW(data);
-+ GtkTreePath *cursor_path = NULL;
-+ GtkTreeIter iter;
-+
-+ /* if there are checkboxes, cursor row doesn't have to be selected */
-+ if (tree_view->priv->checkbox_mode)
-+ return;
-+
-+ if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
-+ cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
-+
-+ if (cursor_path == NULL ||
-+ !gtk_tree_selection_path_is_selected (selection, cursor_path))
-+ {
-+ GtkTreePath *selected_path;
-+ GtkRBTree *tree = NULL;
-+ GtkRBNode *node = NULL;
-+
-+ if (gtk_tree_selection_get_mode (selection) != GTK_SELECTION_MULTIPLE &&
-+ gtk_tree_selection_get_selected (selection, NULL, &iter))
-+ {
-+ selected_path = gtk_tree_model_get_path (tree_view->priv->model,
-+ &iter);
-+ gtk_tree_view_real_set_cursor (tree_view, selected_path, TRUE, TRUE);
-+ _gtk_tree_view_find_node (tree_view, selected_path, &tree, &node);
-+ gtk_tree_view_clamp_node_visible (tree_view, tree, node);
-+ gtk_tree_path_free (selected_path);
-+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
-+ }
-+ else
-+ {
-+ gtk_tree_row_reference_free (tree_view->priv->cursor);
-+ tree_view->priv->cursor = NULL;
-+ }
-+ }
-+
-+ if (cursor_path)
-+ gtk_tree_path_free (cursor_path);
-+}
-+
-+/* Helper function for ensuring that GtkTreeView is focusable
-+ * if and only if it contains at least one sensitive top-level row.
-+ * Should be called whenever the existence of a sensitive top-level row
-+ * might have changed.
-+ */
-+static void
-+check_if_can_focus (GtkTreeView *tree_view)
-+{
-+ GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
-+ GtkTreeIter iter;
-+
-+ if (model == NULL || !GTK_WIDGET_MAPPED (tree_view))
-+ return;
-+
-+ if (gtk_tree_model_get_iter_first (model, &iter) == FALSE)
-+ {
-+ GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
-+ return;
-+ }
-+
-+ do {
-+ GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
-+ GtkRBTree *tree;
-+ GtkRBNode *node;
-+
-+ _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-+
-+ if (_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
-+ node, path))
-+ {
-+ GTK_WIDGET_SET_FLAGS (tree_view, GTK_CAN_FOCUS);
-+ if (!gtk_tree_row_reference_valid (tree_view->priv->cursor))
-+ gtk_tree_view_real_set_cursor (tree_view, path,
-+ !tree_view->priv->checkbox_mode,
-+ TRUE);
-+
-+ return;
-+ }
-+ } while (gtk_tree_model_iter_next (model, &iter));
-+
-+ GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
-+}