]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtktreeview.c.diff
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / gtk+ / gtk+-2.6.4-1.osso7 / gtktreeview.c.diff
1 --- gtk+-2.6.4/gtk/gtktreeview.c        2005-02-24 00:38:20.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtktreeview.c        2005-04-06 16:19:38.274719720 +0300
3 @@ -42,6 +42,7 @@
4  #include "gtkentry.h"
5  #include "gtkframe.h"
6  #include "gtktreemodelsort.h"
7 +#include "gtkscrolledwindow.h"
8  
9  #define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
10  #define GTK_TREE_VIEW_PRIORITY_SCROLL_SYNC (GTK_TREE_VIEW_PRIORITY_VALIDATE + 2)
11 @@ -114,6 +115,7 @@
12    EXPAND_COLLAPSE_CURSOR_ROW,
13    SELECT_CURSOR_PARENT,
14    START_INTERACTIVE_SEARCH,
15 +  ROW_INSENSITIVE,
16    LAST_SIGNAL
17  };
18  
19 @@ -132,7 +134,10 @@
20    PROP_SEARCH_COLUMN,
21    PROP_FIXED_HEIGHT_MODE,
22    PROP_HOVER_SELECTION,
23 -  PROP_HOVER_EXPAND
24 +  PROP_HOVER_EXPAND,
25 +  PROP_DOTTED_LINES,
26 +  PROP_FORCE_LIST_KLUDGE,
27 +  PROP_ALLOW_CHECKBOX_MODE
28  };
29  
30  static void     gtk_tree_view_class_init           (GtkTreeViewClass *klass);
31 @@ -338,8 +343,6 @@
32  static void     gtk_tree_view_clamp_node_visible             (GtkTreeView       *tree_view,
33                                                               GtkRBTree         *tree,
34                                                               GtkRBNode         *node);
35 -static void     gtk_tree_view_clamp_column_visible           (GtkTreeView       *tree_view,
36 -                                                             GtkTreeViewColumn *column);
37  static gboolean gtk_tree_view_maybe_begin_dragging_row       (GtkTreeView       *tree_view,
38                                                               GdkEventMotion    *event);
39  static void     gtk_tree_view_focus_to_cursor                (GtkTreeView       *tree_view);
40 @@ -372,6 +375,18 @@
41                                                                gpointer           data);
42  static gboolean expand_collapse_timeout                      (gpointer           data);
43  static gboolean do_expand_collapse                           (GtkTreeView       *tree_view);
44 +static void update_checkbox_mode                             (GObject *object,
45 +                                                              GParamSpec *pspec,
46 +                                                              gpointer data);
47 +static void set_dotted_lines                                 (GtkTreeView       *tree_view,
48 +                                                              gboolean           enable);
49 +static void selection_changed                                (GtkTreeSelection  *selection,
50 +                                                              gpointer           data);
51 +static void check_if_can_focus                               (GtkTreeView       *tree_view);
52 +static gint scroll_row_timeout                               (gpointer           data);
53 +
54 +static void add_scroll_timeout                               (GtkTreeView *tree_view);
55 +static void remove_scroll_timeout                            (GtkTreeView *tree_view);
56  
57  /* interactive search */
58  static void     gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view);
59 @@ -694,8 +709,54 @@
60                                                             FALSE,
61                                                             G_PARAM_READWRITE));
62  
63 +    /**
64 +     * GtkTreeView:dotted-lines:
65 +     *
66 +     * Enables or disables the dotted lines for hierarchical trees.
67 +     * Hildon patch.
68 +     */
69 +    g_object_class_install_property (o_class,
70 +                                     PROP_DOTTED_LINES,
71 +                                     g_param_spec_boolean ("dotted_lines",
72 +                                                           P_("Dotted Lines"),
73 +                                                           P_("Whether to show or hide dotted lines for hierarchical trees"),
74 +                                                           FALSE,
75 +                                                           G_PARAM_READWRITE));
76 +
77 +    /**
78 +     * GtkTreeView:force-list-kludge:
79 +     *
80 +     * Hildon kludge for fixing file tree behaviour until a cleaner
81 +     * implementation is scheduled: if this property is set, then rows
82 +     * can be activated by tapping even if the underlying tree model is
83 +     * not technically a list.
84 +     */
85 +    g_object_class_install_property (o_class,
86 +                                     PROP_FORCE_LIST_KLUDGE,
87 +                                     g_param_spec_boolean ("force_list_kludge",
88 +                                                           P_("Force List Behaviour"),
89 +                                                           P_("Whether to activate tapped focused items even if model was not a list"),
90 +                                                           FALSE,
91 +                                                           G_PARAM_READWRITE));
92 +
93 +    /**
94 +     * GtkTreeView:enable-checkbox-mode:
95 +     *
96 +     * Another Hildon kludge for allowing the existence of GtkTreeViews
97 +     * that have activatable columns but that still is not a Text Listbox
98 +     * in multiple selection with checkboxes mode.
99 +     */
100 +    g_object_class_install_property (o_class,
101 +                                     PROP_ALLOW_CHECKBOX_MODE,
102 +                                     g_param_spec_boolean ("allow_checkbox_mode",
103 +                                                           P_("Enable Checkbox Mode"),
104 +                                                           P_("Whether to behave like a Listbox in a multiple selection with checkboxes mode, if checkboxes exist"),
105 +                                                           TRUE,
106 +                                                           G_PARAM_READWRITE));
107 +
108    /* Style properties */
109  #define _TREE_VIEW_EXPANDER_SIZE 12
110 +#define _TREE_VIEW_EXPANDER_INDENT 10
111  #define _TREE_VIEW_VERTICAL_SEPARATOR 2
112  #define _TREE_VIEW_HORIZONTAL_SEPARATOR 2
113      
114 @@ -709,6 +770,15 @@
115                                                              G_PARAM_READABLE));
116  
117    gtk_widget_class_install_style_property (widget_class,
118 +                                           g_param_spec_int ("expander_indent",
119 +                                                             P_("Expander intent"),
120 +                                                             P_("Defines the expanders indent"),
121 +                                                             0,
122 +                                                             G_MAXINT,
123 +                                                             _TREE_VIEW_EXPANDER_INDENT,
124 +                                                             G_PARAM_READABLE));
125 +
126 +  gtk_widget_class_install_style_property (widget_class,
127                                            g_param_spec_int ("vertical_separator",
128                                                              P_("Vertical Separator Width"),
129                                                              P_("Vertical space between cells.  Must be an even number"),
130 @@ -754,6 +824,13 @@
131                                                                GDK_TYPE_COLOR,
132  G_PARAM_READABLE));
133  
134 +  gtk_widget_class_install_style_property (widget_class,
135 +                                           g_param_spec_boolean ("passive_focus",
136 +                                                                 P_("Enables passive focus"),
137 +                                                                 P_("Used for tree view passive focus"),
138 +                                                                 TRUE,
139 +                                                                 G_PARAM_READABLE));
140 +
141    /* Signals */
142    widget_class->set_scroll_adjustments_signal =
143      g_signal_new ("set_scroll_adjustments",
144 @@ -917,6 +994,16 @@
145                   _gtk_marshal_BOOLEAN__NONE,
146                   G_TYPE_BOOLEAN, 0);
147  
148 +  tree_view_signals[ROW_INSENSITIVE] =
149 +     g_signal_new ("row_insensitive",
150 +                  G_TYPE_FROM_CLASS (o_class),
151 +                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
152 +                  G_STRUCT_OFFSET (GtkTreeViewClass, row_insensitive),
153 +                  NULL, NULL,
154 +                  _gtk_marshal_VOID__OBJECT,
155 +                  G_TYPE_NONE, 1,
156 +                  GTK_TYPE_TREE_PATH);
157 +
158    /* Key bindings */
159    gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0,
160                                   GTK_MOVEMENT_DISPLAY_LINES, -1);
161 @@ -1004,12 +1091,13 @@
162  
163    gtk_binding_entry_add_signal (binding_set, GDK_space, 0, "select_cursor_row", 1,
164                                 G_TYPE_BOOLEAN, TRUE);
165 +  /* Hildon change: Enter shouldn't select
166    gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "select_cursor_row", 1,
167                                 G_TYPE_BOOLEAN, TRUE);
168    gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, "select_cursor_row", 1,
169                                 G_TYPE_BOOLEAN, TRUE);
170    gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "select_cursor_row", 1,
171 -                               G_TYPE_BOOLEAN, TRUE);
172 +                               G_TYPE_BOOLEAN, TRUE);*/
173  
174    /* expand and collapse rows */
175    gtk_binding_entry_add_signal (binding_set, GDK_plus, 0, "expand_collapse_cursor_row", 3,
176 @@ -1123,19 +1211,31 @@
177    gtk_binding_entry_add_signal (binding_set, GDK_f, GDK_CONTROL_MASK, "start_interactive_search", 0);
178  
179    gtk_binding_entry_add_signal (binding_set, GDK_F, GDK_CONTROL_MASK, "start_interactive_search", 0);
180 +
181 +  /* Hildon addition: Add key bindings to Right and Left arrows */
182 +  gtk_binding_entry_add_signal (binding_set, GDK_Right, 0, "expand_collapse_cursor_row", 3,
183 +                                G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE, G_TYPE_BOOLEAN, FALSE);
184 +  gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_SHIFT_MASK, "expand_collapse_cursor_row", 3,
185 +                                G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE, G_TYPE_BOOLEAN, TRUE);
186 +  gtk_binding_entry_add_signal (binding_set, GDK_Left, 0, "expand_collapse_cursor_row", 3,
187 +                                G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE);
188 +  gtk_binding_entry_add_signal (binding_set, GDK_Left, GDK_SHIFT_MASK, "expand_collapse_cursor_row", 3,
189 +                                G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, FALSE, G_TYPE_BOOLEAN, TRUE);
190  }
191  
192  static void
193  gtk_tree_view_init (GtkTreeView *tree_view)
194  {
195    tree_view->priv = g_new0 (GtkTreeViewPrivate, 1);
196 -  GTK_WIDGET_SET_FLAGS (tree_view, GTK_CAN_FOCUS);
197 +
198 +  /* Hildon: focus cannot be gained until at least one row is added */
199 +  GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
200  
201    gtk_widget_set_redraw_on_allocate (GTK_WIDGET (tree_view), FALSE);
202  
203 +  /* Hildon: Headers invisible by default */
204    tree_view->priv->flags =  GTK_TREE_VIEW_SHOW_EXPANDERS
205 -                            | GTK_TREE_VIEW_DRAW_KEYFOCUS
206 -                            | GTK_TREE_VIEW_HEADERS_VISIBLE;
207 +                            | GTK_TREE_VIEW_DRAW_KEYFOCUS;
208  
209    /* We need some padding */
210    tree_view->priv->dy = 0;
211 @@ -1165,6 +1265,26 @@
212            
213    tree_view->priv->hover_selection = FALSE;
214    tree_view->priv->hover_expand = FALSE;
215 +
216 +  tree_view->priv->ctrl_pressed = FALSE;
217 +  tree_view->priv->shift_pressed = FALSE;
218 +
219 +  tree_view->priv->checkbox_mode = FALSE;
220 +  tree_view->priv->allow_checkbox_mode = TRUE;
221 +  tree_view->priv->pen_down = FALSE;
222 +  tree_view->priv->pen_drag_active = FALSE;
223 +  tree_view->priv->pen_drag_reverse = FALSE;
224 +  tree_view->priv->first_drag_row = NULL;
225 +  tree_view->priv->last_drag_row = NULL;
226 +  tree_view->priv->queued_expand_row = NULL;
227 +  tree_view->priv->queued_select_row = NULL;
228 +  tree_view->priv->pen_focus = TRUE;
229 +
230 +  /* Hildon: cursor should follow when selection changes */
231 +  g_signal_connect (tree_view->priv->selection, "changed",
232 +                    G_CALLBACK (selection_changed), tree_view);
233 +
234 +  gtk_widget_set_name (GTK_WIDGET (tree_view), "treeview");
235  }
236  
237  \f
238 @@ -1223,6 +1343,27 @@
239      case PROP_HOVER_EXPAND:
240        tree_view->priv->hover_expand = g_value_get_boolean (value);
241        break;
242 +    case PROP_DOTTED_LINES:
243 +      set_dotted_lines (tree_view, g_value_get_boolean (value));
244 +      break;
245 +    case PROP_FORCE_LIST_KLUDGE:
246 +      tree_view->priv->force_list_kludge = g_value_get_boolean (value);
247 +      break;
248 +    case PROP_ALLOW_CHECKBOX_MODE:
249 +      if ((tree_view->priv->allow_checkbox_mode = g_value_get_boolean (value)))
250 +        {
251 +          gtk_widget_set_name (GTK_WIDGET(tree_view), "treeview");
252 +          update_checkbox_mode (NULL, NULL, tree_view);
253 +        }
254 +      else
255 +        {
256 +          /* ugly hack - to ensure that checkboxes are independent of the
257 +             selection if !allow_checkbox_mode, we must be able to use
258 +             different theming in that case */
259 +          gtk_widget_set_name (GTK_WIDGET(tree_view), "no_checkbox_mode");
260 +          tree_view->priv->checkbox_mode = FALSE;
261 +        }
262 +      break;
263      default:
264        break;
265      }
266 @@ -1276,6 +1417,15 @@
267      case PROP_HOVER_EXPAND:
268        g_value_set_boolean (value, tree_view->priv->hover_expand);
269        break;
270 +    case PROP_DOTTED_LINES:
271 +      g_value_set_boolean (value, tree_view->priv->dotted_lines);
272 +      break;
273 +    case PROP_FORCE_LIST_KLUDGE:
274 +      g_value_set_boolean (value, tree_view->priv->force_list_kludge);
275 +      break;
276 +    case PROP_ALLOW_CHECKBOX_MODE:
277 +      g_value_set_boolean (value, tree_view->priv->allow_checkbox_mode);
278 +      break;
279      default:
280        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
281        break;
282 @@ -1376,6 +1526,27 @@
283        tree_view->priv->destroy_count_data = NULL;
284      }
285  
286 +  if (tree_view->priv->first_drag_row)
287 +    {
288 +      gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
289 +      tree_view->priv->first_drag_row = NULL;
290 +    }
291 +  if (tree_view->priv->last_drag_row)
292 +    {
293 +      gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
294 +      tree_view->priv->last_drag_row = NULL;
295 +    }
296 +  if (tree_view->priv->queued_expand_row)
297 +    {
298 +      gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
299 +      tree_view->priv->queued_expand_row = NULL;
300 +    }
301 +  if (tree_view->priv->queued_select_row)
302 +    {
303 +      gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
304 +      tree_view->priv->queued_select_row = NULL;
305 +    }
306 +
307    gtk_tree_row_reference_free (tree_view->priv->cursor);
308    tree_view->priv->cursor = NULL;
309  
310 @@ -1494,6 +1665,8 @@
311    gtk_tree_view_map_buttons (tree_view);
312  
313    gdk_window_show (widget->window);
314 +
315 +  check_if_can_focus (tree_view);
316  }
317  
318  static void
319 @@ -1895,6 +2068,8 @@
320    gint full_requested_width = 0;
321    gint number_of_expand_columns = 0;
322    gboolean rtl;
323 +  GtkWidget *scroll;
324 +  GtkPolicyType ptype;
325    
326    tree_view = GTK_TREE_VIEW (widget);
327  
328 @@ -1969,6 +2144,19 @@
329        allocation.x = width;
330        column->width = real_requested_width;
331  
332 +      /* a dirty Hildon hack to force truncation if not enough space. This hack is applied
333 +       * only if we are NOT in a scrolled window with hscroll*/
334 +      scroll = gtk_widget_get_ancestor(widget, GTK_TYPE_SCROLLED_WINDOW);
335 +      if ((!scroll ||
336 +          (gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (scroll), &ptype, NULL), ptype == GTK_POLICY_NEVER))
337 +        && (width + real_requested_width > widget->allocation.width))
338 +      {
339 +          column->width = widget->allocation.width - width;
340 +          if (column->width < 1)
341 +            column->width = 1;
342 +          gtk_widget_queue_draw (widget);
343 +      }
344 +
345        if (column->expand)
346         {
347           if (number_of_expand_columns == 1)
348 @@ -2153,6 +2341,23 @@
349    GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
350  }
351  
352 +/* helper function for gtk_tree_view_button_press */
353 +static void
354 +activate_callback (GtkTreeModel *model,
355 +                   GtkTreePath  *path,
356 +                   GtkTreeIter  *iter,
357 +                   gpointer      data)
358 +{
359 +  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
360 +
361 +  /* Hildon: if the tree view has no active focus we don't activate
362 +   * the selected row */
363 +  if ( !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET(data)) )
364 +      return;
365 +  
366 +  gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
367 +}
368 +
369  static gboolean
370  gtk_tree_view_button_press (GtkWidget      *widget,
371                             GdkEventButton *event)
372 @@ -2166,6 +2371,7 @@
373    gint vertical_separator;
374    gint horizontal_separator;
375    gboolean rtl;
376 +  gint expander_indent;
377  
378    g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
379    g_return_val_if_fail (event != NULL, FALSE);
380 @@ -2176,6 +2382,7 @@
381    gtk_widget_style_get (widget,
382                         "vertical_separator", &vertical_separator,
383                         "horizontal_separator", &horizontal_separator,
384 +                        "expander_indent", &expander_indent,
385                         NULL);
386  
387  
388 @@ -2199,6 +2406,14 @@
389        gint column_handled_click = FALSE;
390        gboolean row_double_click = FALSE;
391        gboolean rtl;
392 +      gboolean force_list_kludge;
393 +      GtkRBNode *cursor = NULL;
394 +      gboolean focus_grab = FALSE;
395 +
396 +      if (!GTK_WIDGET_HAS_FOCUS (widget))
397 +         focus_grab = TRUE;
398 +      
399 +      GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
400  
401        /* Empty tree? */
402        if (tree_view->priv->tree == NULL)
403 @@ -2207,7 +2422,9 @@
404           return TRUE;
405         }
406  
407 -      /* are we in an arrow? */
408 +      /* In Hildon we don't want to use the arrows */
409 +#if 0
410 +      /* are we in an arrow? */ 
411        if (tree_view->priv->prelight_node &&
412            GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT))
413         {
414 @@ -2226,6 +2443,7 @@
415           grab_focus_and_unset_draw_keyfocus (tree_view);
416           return TRUE;
417         }
418 +#endif
419  
420        /* find the node that was clicked */
421        new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
422 @@ -2247,6 +2465,65 @@
423        background_area.height = ROW_HEIGHT (tree_view, GTK_RBNODE_GET_HEIGHT (node));
424        background_area.x = 0;
425  
426 +      if (tree_view->priv->first_drag_row)
427 +        {
428 +          gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
429 +          tree_view->priv->first_drag_row = NULL;
430 +        }
431 +      if (tree_view->priv->last_drag_row)
432 +        {
433 +          gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
434 +          tree_view->priv->last_drag_row = NULL;
435 +        }
436 +      tree_view->priv->first_drag_row =
437 +        gtk_tree_row_reference_new (tree_view->priv->model, path);
438 +      tree_view->priv->last_drag_row = gtk_tree_row_reference_copy (tree_view->priv->first_drag_row);
439 +
440 +      /* force_list_kludge allows pen dragging even if
441 +         GTK_TREE_MODEL_LIST_ONLY is not set (to fix file tree) */
442 +      g_object_get (widget, "force_list_kludge", &force_list_kludge, NULL);
443 +
444 +      /* Hildon: activate pen dragging, if listbox is not hierarchical and
445 +         the pen was not put down in a position that initiates drag'n'drop */
446 +      if (!tree_view->priv->pen_down &&
447 +          (force_list_kludge ||
448 +           (gtk_tree_model_get_flags(tree_view->priv->model)
449 +            & GTK_TREE_MODEL_LIST_ONLY)) &&
450 +          (tree_view->priv->checkbox_mode ||
451 +           !gtk_tree_selection_path_is_selected(tree_view->priv->selection, path)))
452 +        {
453 +          gpointer drag_data;
454 +
455 +          tree_view->priv->pen_down = TRUE;
456 +          tree_view->priv->pen_focus = TRUE;
457 +
458 +         /* also block attached dnd signal handler */
459 +         drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
460 +         if (drag_data)
461 +           g_signal_handlers_block_matched (widget,
462 +                                            G_SIGNAL_MATCH_DATA,
463 +                                            0, 0, NULL, NULL,
464 +                                            drag_data);
465 +        }
466 +
467 +      /* For the Hildon buttonpress find out the previously selected row */
468 +      GtkRBTree *cursor_tree = NULL;
469 +      GtkTreePath *cursor_path = NULL;
470 +  
471 +      if (tree_view->priv->cursor)
472 +        {
473 +          cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
474 +          if (cursor_path)
475 +            {
476 +              _gtk_tree_view_find_node (tree_view, cursor_path,
477 +                                        &cursor_tree, &cursor);
478 +              gtk_tree_path_free (cursor_path);
479 +            }
480 +         }
481 +
482 +      /* Hildon: in checkbox mode, dragging sets all checkboxes
483 +         to the same state as the first toggled checkbox */
484 +      tree_view->priv->new_state = !gtk_tree_selection_path_is_selected(tree_view->priv->selection, path);
485  
486        /* Let the column have a chance at selecting it. */
487        rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
488 @@ -2275,8 +2552,11 @@
489           if (gtk_tree_view_is_expander_column (tree_view, column) &&
490                TREE_VIEW_DRAW_EXPANDERS(tree_view))
491             {
492 -             cell_area.x += depth * tree_view->priv->expander_size;
493 -             cell_area.width -= depth * tree_view->priv->expander_size;
494 +              gint adjust;
495 +
496 +              adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
497 +              cell_area.x += adjust;
498 +              cell_area.width -= adjust;
499             }
500           break;
501         }
502 @@ -2364,15 +2644,19 @@
503         */
504        if (event->type == GDK_BUTTON_PRESS)
505          {
506 +          /* Hildon: ignore Ctrl and Shift */
507 +#if 0
508            if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
509              tree_view->priv->ctrl_pressed = TRUE;
510            if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
511              tree_view->priv->shift_pressed = TRUE;
512 +#endif
513  
514            focus_cell = _gtk_tree_view_column_get_cell_at_pos (column, event->x - background_area.x);
515            if (focus_cell)
516              gtk_tree_view_column_focus_cell (column, focus_cell);
517  
518 +#if 0
519            if (event->state & GDK_CONTROL_MASK)
520              {
521                gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE);
522 @@ -2387,6 +2671,86 @@
523              {
524                gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE);
525              }
526 +#endif
527 +          if (tree_view->priv->checkbox_mode)
528 +            {
529 +              GtkRBTree *tree = NULL;
530 +              GtkRBNode *node = NULL;
531 +
532 +              _gtk_tree_view_find_node (tree_view, path, &tree, &node);
533 +
534 +              /* cursor cannot move to an insensitive row, so we
535 +                 need to check here to avoid toggling the current
536 +                 row by clicking on an insensitive row */
537 +              if (_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
538 +                                                         node, path))
539 +                {
540 +                  gtk_tree_view_real_set_cursor (tree_view, path,
541 +                                                 FALSE, TRUE);
542 +                  gtk_tree_view_real_toggle_cursor_row (tree_view);
543 +                }
544 +              else
545 +                /* Usually this would be emitted by real_set_cursor.
546 +                   However in this case we never call it. */
547 +                g_signal_emit (tree_view, tree_view_signals[ROW_INSENSITIVE], 0, path);
548 +            }
549 +          else
550 +            {
551 +              gboolean queue_row = TRUE;
552 +              gboolean force_list_kludge;
553 +
554 +              /* force_list_kludge allows rows to be activated even if
555 +                 GTK_TREE_MODEL_LIST_ONLY is not set (to fix file tree) */
556 +              g_object_get (widget, "force_list_kludge",
557 +                            &force_list_kludge, NULL);
558 +              if ((force_list_kludge ||
559 +                   (gtk_tree_model_get_flags (tree_view->priv->model) &
560 +                    GTK_TREE_MODEL_LIST_ONLY)) &&
561 +                  gtk_tree_row_reference_valid (tree_view->priv->cursor))
562 +                {
563 +                  /* special case: text listbox without checkboxes
564 +                     should activate selected rows when user taps
565 +                     on cursor row, but not affect selection*/
566 +                  GtkTreePath *cursor_path =
567 +                    gtk_tree_row_reference_get_path (tree_view->priv->cursor);
568 +                  if (gtk_tree_path_compare (cursor_path, path) == 0)
569 +                    {
570 +                      gtk_tree_selection_selected_foreach (tree_view->priv->selection,
571 +                                                           activate_callback,
572 +                                                           tree_view);
573 +                      queue_row = FALSE;
574 +                    }
575 +                }
576 +
577 +              if (queue_row &&
578 +                  (gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE) &&
579 +                   gtk_tree_selection_path_is_selected (tree_view->priv->selection, path))
580 +                {
581 +                  GtkTreePath *old_cursor_path = NULL;
582 +
583 +                  /* we don't know if the user is selecting an item or performing
584 +                     multiple item drag and drop until we know where button is released */
585 +                  if (tree_view->priv->queued_select_row)
586 +                    gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
587 +                  tree_view->priv->queued_select_row =
588 +                    gtk_tree_row_reference_new (tree_view->priv->model, path);
589 +
590 +                  /* however, move focus */
591 +                  if (tree_view->priv->cursor)
592 +                    {
593 +                      old_cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
594 +                      gtk_tree_row_reference_free (tree_view->priv->cursor);
595 +                    }
596 +                  tree_view->priv->cursor = gtk_tree_row_reference_new (tree_view->priv->model,
597 +                                                                            path);
598 +                  gtk_tree_view_queue_draw_path (tree_view, path, NULL);
599 +                  if (old_cursor_path)
600 +                    gtk_tree_view_queue_draw_path (tree_view, old_cursor_path, NULL);
601 +                }
602 +              else
603 +                gtk_tree_view_real_set_cursor (tree_view, path,
604 +                                               queue_row, TRUE);
605 +            }
606  
607            tree_view->priv->ctrl_pressed = FALSE;
608            tree_view->priv->shift_pressed = FALSE;
609 @@ -2412,6 +2776,15 @@
610            tree_view->priv->press_start_y = event->y;
611          }
612  
613 +      /* Hildon: if selected row is tapped -> the row gets activated and expands */
614 +      if (!focus_grab)
615 +        {
616 +          /* ...although not until button is released */
617 +          gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
618 +          tree_view->priv->queued_expand_row =
619 +            gtk_tree_row_reference_new (tree_view->priv->model, path);
620 +        }
621 +
622        /* Test if a double click happened on the same row. */
623        if (event->button == 1)
624          {
625 @@ -2433,6 +2806,8 @@
626                  }
627              }
628  
629 +          /* Hildon doesn't support double clicks */
630 +#if 0
631            if (row_double_click)
632              {
633                if (tree_view->priv->last_button_press)
634 @@ -2443,6 +2818,7 @@
635                tree_view->priv->last_button_press_2 = NULL;
636              }
637            else
638 +#endif
639              {
640                if (tree_view->priv->last_button_press)
641                  gtk_tree_row_reference_free (tree_view->priv->last_button_press);
642 @@ -2626,6 +3002,28 @@
643  
644    tree_view = GTK_TREE_VIEW (widget);
645  
646 +  /* unblock attached dnd signal handler */
647 +  if (tree_view->priv->pen_down)
648 +    {
649 +      gpointer drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
650 +      if (drag_data)
651 +        g_signal_handlers_unblock_matched (widget,
652 +                                           G_SIGNAL_MATCH_DATA,
653 +                                           0, 0, NULL, NULL,
654 +                                           drag_data);
655 +    }
656 +
657 +  /* stop pen dragging */
658 +  if (tree_view->priv->first_drag_row)
659 +    gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
660 +  if (tree_view->priv->last_drag_row)
661 +    gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
662 +  tree_view->priv->first_drag_row = NULL;
663 +  tree_view->priv->last_drag_row = NULL;
664 +  tree_view->priv->pen_down = FALSE;
665 +  tree_view->priv->pen_drag_active = FALSE;
666 +  remove_scroll_timeout (tree_view);
667 +
668    if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
669      return gtk_tree_view_button_release_drag_column (widget, event);
670  
671 @@ -2635,6 +3033,65 @@
672    if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE))
673      return gtk_tree_view_button_release_column_resize (widget, event);
674  
675 +  if (gtk_tree_row_reference_valid (tree_view->priv->queued_select_row))
676 +    {
677 +      /* unselect other nodes - but only if not drag'n'dropping */
678 +      if (event->window == tree_view->priv->bin_window)
679 +        gtk_tree_selection_unselect_all (tree_view->priv->selection);
680 +
681 +      gtk_tree_view_real_set_cursor (tree_view,
682 +                                     gtk_tree_row_reference_get_path (tree_view->priv->queued_select_row),
683 +                                     FALSE, TRUE);
684 +      gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
685 +      tree_view->priv->queued_select_row = NULL;
686 +    }
687 +
688 +  /* for handling expand/collapse postponed from button_press (since we
689 +     don't want expand/collapse before tap on node has been completed) */
690 +  if (gtk_tree_row_reference_valid (tree_view->priv->queued_expand_row) &&
691 +      tree_view->priv->tree != NULL)
692 +    {
693 +      GtkTreePath *queued_expand_path;
694 +      GtkRBTree *tree;
695 +      GtkRBNode *node;
696 +      GtkRBNode *old_node;
697 +      gint y;
698 +
699 +      queued_expand_path =
700 +        gtk_tree_row_reference_get_path (tree_view->priv->queued_expand_row);
701 +
702 +      if (queued_expand_path)
703 +        {
704 +          /* must check that cursor hasn't moved elsewhere since button_press */
705 +          y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->y);
706 +          _gtk_rbtree_find_offset (tree_view->priv->tree, y, &tree, &node);
707 +
708 +          _gtk_tree_view_find_node (tree_view, queued_expand_path,
709 +                                    &tree, &old_node);
710 +
711 +          if (node && old_node == node)
712 +            {
713 +              if (node->children == NULL)
714 +                gtk_tree_view_real_expand_row (tree_view,
715 +                                               queued_expand_path,
716 +                                               tree,
717 +                                               node,
718 +                                               FALSE, TRUE);
719 +              else
720 +                gtk_tree_view_real_collapse_row (tree_view,
721 +                                                 queued_expand_path,
722 +                                                 tree,
723 +                                                 node,
724 +                                                 TRUE);
725 +            }
726 +
727 +          gtk_tree_path_free (queued_expand_path);
728 +        }
729 +
730 +      gtk_tree_row_reference_free( tree_view->priv->queued_expand_row);
731 +      tree_view->priv->queued_expand_row = NULL;
732 +    }
733 +
734    if (tree_view->priv->button_pressed_node == NULL)
735      return FALSE;
736  
737 @@ -3311,6 +3768,7 @@
738    GtkTreeView *tree_view;
739    GtkRBTree *tree;
740    GtkRBNode *node;
741 +  GtkTreePath *path, *last_drag_path, *current_path;
742    gint new_y;
743  
744    tree_view = (GtkTreeView *) widget;
745 @@ -3319,7 +3777,8 @@
746      return FALSE;
747  
748    /* only check for an initiated drag when a button is pressed */
749 -  if (tree_view->priv->pressed_button >= 0)
750 +  /* Hildon: active pen drag overrides drag and drop */
751 +  if (tree_view->priv->pressed_button >= 0 && !tree_view->priv->pen_down)
752      gtk_tree_view_maybe_begin_dragging_row (tree_view, event);
753  
754    new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
755 @@ -3328,6 +3787,99 @@
756  
757    _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
758  
759 +  /* Hildon: pen dragging */
760 +  if (tree_view->priv->pen_down && node != NULL &&
761 +      tree_view->priv->queued_select_row == NULL &&
762 +      gtk_tree_row_reference_valid (tree_view->priv->last_drag_row))
763 +    {
764 +      gint direction;
765 +
766 +      last_drag_path = gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row);
767 +      path = _gtk_tree_view_find_path (tree_view, tree, node);
768 +      direction = gtk_tree_path_compare (path, last_drag_path);
769 +
770 +      if (direction != 0)
771 +        {
772 +          current_path = gtk_tree_path_copy (last_drag_path);
773 +
774 +          /* we must ensure that no row is skipped because stylus
775 +             is moving faster than motion events are generated */
776 +          do {
777 +            if (direction > 0)
778 +              {
779 +                /* gtk_tree_path_next does not let us know when it failed */
780 +                GtkTreeIter iter;
781 +                gtk_tree_model_get_iter (tree_view->priv->model, &iter, current_path);
782 +                if (!gtk_tree_model_iter_next (tree_view->priv->model, &iter))
783 +                  break;
784 +
785 +                gtk_tree_path_next (current_path);
786 +              }
787 +            else if (!gtk_tree_path_prev (current_path))
788 +              break;
789 +      
790 +            /* set cursor, and start scrolling */
791 +            gtk_tree_view_real_set_cursor (tree_view, current_path, FALSE, FALSE);
792 +            add_scroll_timeout (tree_view);
793 +
794 +            if (tree_view->priv->checkbox_mode)
795 +              {
796 +                /* always set to same state as the first tapped node */
797 +                if (tree_view->priv->new_state)
798 +                  gtk_tree_selection_select_path (tree_view->priv->selection,
799 +                                                  current_path);
800 +                else
801 +                  gtk_tree_selection_unselect_path (tree_view->priv->selection,
802 +                                                    current_path);
803 +              }
804 +            else
805 +              {
806 +                if (gtk_tree_selection_path_is_selected (tree_view->priv->selection,
807 +                                                         current_path))
808 +                  {
809 +                    /* apparently we have reversed the pen drag direction */
810 +                    GtkTreePath *reverse_path;
811 +                    gint reverse_direction;
812 +
813 +                    reverse_direction = gtk_tree_path_compare (current_path,
814 +                                                               last_drag_path);
815 +                    reverse_path = gtk_tree_path_copy (last_drag_path);
816 +                    do {
817 +                      gtk_tree_selection_unselect_path (tree_view->priv->selection,
818 +                                                        reverse_path);
819 +                      tree_view->priv->pen_drag_reverse = TRUE;
820 +                      if (reverse_direction > 0)
821 +                        {
822 +                          GtkTreeIter iter;
823 +                          gtk_tree_model_get_iter (tree_view->priv->model, &iter, reverse_path);
824 +                          if (!gtk_tree_model_iter_next (tree_view->priv->model, &iter))
825 +                            break;
826 +
827 +                          gtk_tree_path_next (reverse_path);
828 +                        }
829 +                      else if (!gtk_tree_path_prev (reverse_path))
830 +                        break;
831 +                    } while (gtk_tree_path_compare (reverse_path, current_path) != 0);
832 +                    gtk_tree_path_free (reverse_path);
833 +                  }
834 +                else
835 +                  {
836 +                    gtk_tree_selection_select_path (tree_view->priv->selection,
837 +                                                    current_path);
838 +                    tree_view->priv->pen_drag_reverse = FALSE;
839 +                  }
840 +              }
841 +          } while (gtk_tree_path_compare(current_path, path) != 0);
842 +          gtk_tree_path_free (current_path);
843 +
844 +          /* update last_drag_row */
845 +          gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
846 +          tree_view->priv->last_drag_row =
847 +            gtk_tree_row_reference_new (tree_view->priv->model, path);
848 +          gtk_tree_path_free (path);
849 +        }
850 +    }
851 +
852    /* If we are currently pressing down a button, we don't want to prelight anything else. */
853    if ((tree_view->priv->button_pressed_node != NULL) &&
854        (tree_view->priv->button_pressed_node != node))
855 @@ -3404,6 +3956,22 @@
856                      1, 1, w, h);
857  }
858  
859 +/* Hildon: helper function for dotted slash drawing;
860 +   returns TRUE or FALSE, depending it there are
861 +   more nodes at current level */
862 +static gboolean
863 +iter_has_next (GtkTreeModel *model, GtkTreeIter *iter)
864 +{
865 +  GtkTreeIter *check_iter;
866 +  gboolean result;
867 +    
868 +  check_iter = gtk_tree_iter_copy(iter);
869 +  result = gtk_tree_model_iter_next (model, check_iter);
870 +
871 +  gtk_tree_iter_free (check_iter);   
872 +  return result;
873 +}
874 +
875  /* Warning: Very scary function.
876   * Modify at your own risk
877   *
878 @@ -3433,16 +4001,25 @@
879    guint flags;
880    gint highlight_x;
881    gint bin_window_width;
882 -  GtkTreePath *cursor_path;
883 -  GtkTreePath *drag_dest_path;
884 +  GtkTreePath *cursor_path = NULL;
885 +  GtkTreePath *drag_dest_path = NULL;
886    GList *last_column;
887    gint vertical_separator;
888    gint horizontal_separator;
889 +  gint expander_indent;
890    gint focus_line_width;
891    gboolean allow_rules;
892    gboolean has_special_cell;
893    gboolean rtl;
894    gint n_visible_columns;
895 +  gboolean dottedlines, passivefocus, res;
896 +
897 +  /* Hildon: these variables are added for dotted slash drawing
898 +     (Hierarchical listbox) */
899 +  gint i;
900 +  gint node_elements = 64;
901 +  gboolean *iter_value = NULL;
902 +  GtkTreeIter node_iter, parent_iter;
903  
904    g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
905  
906 @@ -3455,8 +4032,12 @@
907                         "vertical_separator", &vertical_separator,
908                         "allow_rules", &allow_rules,
909                         "focus-line-width", &focus_line_width,
910 +                        "expander_indent", &expander_indent,
911 +                        "passive_focus", &passivefocus,
912                         NULL);
913  
914 +  g_object_get (widget, "dotted_lines", &dottedlines, NULL);
915 +
916    if (tree_view->priv->tree == NULL)
917      {
918        draw_empty_focus (tree_view, &event->area);
919 @@ -3478,6 +4059,8 @@
920    if (node == NULL)
921      return TRUE;
922  
923 +  iter_value = g_new (gboolean, node_elements);
924 +
925    /* find the path for the node */
926    path = _gtk_tree_view_find_path ((GtkTreeView *)widget,
927                                    tree,
928 @@ -3486,11 +4069,25 @@
929                            &iter,
930                            path);
931    depth = gtk_tree_path_get_depth (path);
932 +
933 +  node_iter = iter;
934 +  for (i = depth - 1; i >= 1; i--)
935 +    {
936 +      res = gtk_tree_model_iter_parent (tree_view->priv->model, &parent_iter, &node_iter);
937 +      /* Check, if we should grow array */
938 +      if (i >= node_elements - 1)
939 +        {
940 +          node_elements *= 2;
941 +          iter_value = g_renew (gboolean, iter_value, node_elements);
942 +          if (!iter_value)
943 +            goto done;
944 +        }
945 +      iter_value[i] = iter_has_next (tree_view->priv->model, &parent_iter);
946 +      node_iter = parent_iter;
947 +    }
948 +  gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
949    gtk_tree_path_free (path);
950    
951 -  cursor_path = NULL;
952 -  drag_dest_path = NULL;
953 -
954    if (tree_view->priv->cursor)
955      cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
956  
957 @@ -3533,6 +4130,7 @@
958    do
959      {
960        gboolean parity;
961 +      gboolean is_first = TRUE;
962        gboolean is_separator = FALSE;
963        
964        if (tree_view->priv->row_separator_func)
965 @@ -3570,6 +4168,7 @@
966           GtkTreeViewColumn *column = list->data;
967           const gchar *detail = NULL;
968           GtkStateType state;
969 +          gboolean is_last = (rtl ? !list->prev : !list->next);
970  
971           if (!column->visible)
972              continue;
973 @@ -3660,31 +4259,152 @@
974           else
975             state = GTK_STATE_NORMAL;
976  
977 -         /* Draw background */
978 -          gtk_paint_flat_box (widget->style,
979 -                              event->window,
980 -                             state,
981 -                              GTK_SHADOW_NONE,
982 -                              &event->area,
983 -                              widget,
984 -                              detail,
985 -                              background_area.x,
986 -                              background_area.y,
987 -                              background_area.width,
988 -                              background_area.height);
989 +          if (tree_view->priv->pen_focus)
990 +            {
991 +              if (node != cursor ||
992 +                  (!GTK_WIDGET_HAS_FOCUS (widget) && !passivefocus))
993 +                { 
994 +                  if ((flags & GTK_CELL_RENDERER_SELECTED)      
995 +                      && !tree_view->priv->checkbox_mode)
996 +                    state = GTK_STATE_SELECTED;         
997 +                  else          
998 +                    state = GTK_STATE_NORMAL; 
999 +
1000 +                  /* Draw background */
1001 +                  gtk_paint_flat_box (widget->style,
1002 +                                      event->window,
1003 +                                      state,
1004 +                                      GTK_SHADOW_NONE,
1005 +                                      &event->area,
1006 +                                      widget,
1007 +                                      detail,
1008 +                                      background_area.x,
1009 +                                      background_area.y,
1010 +                                      background_area.width,
1011 +                                      background_area.height);
1012 +                 }
1013 +               else if ((flags & GTK_CELL_RENDERER_SELECTED) &&
1014 +                        !tree_view->priv->checkbox_mode &&
1015 +                        node != cursor)
1016 +                 {
1017 +                   gtk_paint_flat_box (widget->style,
1018 +                                       event->window,
1019 +                                       GTK_STATE_SELECTED,
1020 +                                       GTK_SHADOW_NONE,
1021 +                                       &event->area,
1022 +                                       widget,
1023 +                                       detail,
1024 +                                       background_area.x,
1025 +                                       background_area.y,
1026 +                                       background_area.width,
1027 +                                       background_area.height);
1028 +                 }
1029 +            }
1030 +          else
1031 +            {
1032 +              /* Draw background */
1033 +              gtk_paint_flat_box (widget->style,
1034 +                                  event->window,
1035 +                                  state,
1036 +                                  GTK_SHADOW_NONE,
1037 +                                  &event->area,
1038 +                                  widget,
1039 +                                  detail,
1040 +                                  background_area.x,
1041 +                                  background_area.y,
1042 +                                  background_area.width,
1043 +                                  background_area.height);
1044 +            }
1045 +
1046 +          /* Hildon change: drawing focus is moved here because it didn't work
1047 +             properly before. Some changes where also made.*/
1048 +          /* draw the big row-spanning focus rectangle, if needed */
1049 +          if (node == cursor &&
1050 +              (!passivefocus || GTK_WIDGET_HAS_FOCUS (widget)))
1051 +            {
1052 +              gtk_paint_focus (widget->style,
1053 +                               event->window,
1054 +                               GTK_STATE_ACTIVE,
1055 +                               &event->area,
1056 +                               widget,
1057 +                               (is_first
1058 +                                ? (is_last ? "full" : "left")
1059 +                                : (is_last ? "right" : "middle")),
1060 +                               background_area.x - (is_first ? 0 : horizontal_separator / 2),
1061 +                               background_area.y - vertical_separator / 2,
1062 +                               background_area.width + (is_first ? 0 : (is_last ? horizontal_separator / 2 : horizontal_separator)),
1063 +                               background_area.height + vertical_separator);
1064 +
1065 +              is_first = FALSE;
1066 +            }
1067 +          else if (node == cursor && passivefocus &&
1068 +                  !GTK_WIDGET_HAS_FOCUS (widget))
1069 +            {
1070 +              GtkStyle *style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (widget),
1071 +                                                           "hildon-focus",
1072 +                                                            NULL,
1073 +                                                            G_TYPE_NONE);
1074 +              gtk_style_attach (style, event->window);
1075 +                         
1076 +              gtk_paint_focus (style, event->window, GTK_STATE_SELECTED,
1077 +                               &event->area, widget,
1078 +                               (is_first
1079 +                                ? (is_last ? "full" : "left")
1080 +                                : (is_last ? "right" : "middle")),
1081 +                                background_area.x - (is_first ? 0 : horizontal_separator / 2),
1082 +                               background_area.y - vertical_separator / 2,
1083 +                               background_area.width + (is_first ? 0 : (is_last ? horizontal_separator / 2 : horizontal_separator)),
1084 +                               background_area.height + vertical_separator);
1085 +
1086 +              is_first = FALSE;
1087 +            }
1088 +
1089 +          if (node == cursor)
1090 +            {
1091 +              gint width, x_offset;
1092 +              GtkStateType focus_rect_state; 
1093 +              focus_rect_state =
1094 +                flags & GTK_CELL_RENDERER_FOCUSED ? GTK_STATE_ACTIVE :
1095 +                 (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
1096 +                  (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE :
1097 +                   (flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
1098 +                    GTK_STATE_NORMAL)));
1099 +
1100 +              gtk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, NULL);
1101 +              gdk_drawable_get_size (tree_view->priv->bin_window, &width, NULL);
1102 +            }
1103  
1104           if (gtk_tree_view_is_expander_column (tree_view, column) &&
1105                TREE_VIEW_DRAW_EXPANDERS(tree_view))
1106             {
1107 +              gint px, px2, py, i;
1108 +
1109 +              if (depth <= 1)
1110 +                px = 0;
1111 +              else
1112 +                px = (depth - 1) * tree_view->priv->expander_size +
1113 +                     (depth - 2) * expander_indent;
1114 +
1115 +              /* Hildonlike hack for making the indent look better.
1116 +               * indent is added to all rows except the first one */
1117 +
1118               if (!rtl)
1119 -               cell_area.x += depth * tree_view->priv->expander_size;
1120 -             cell_area.width -= depth * tree_view->priv->expander_size;
1121 +                cell_area.x += depth * tree_view->priv->expander_size + (depth-1) * expander_indent;
1122 +              cell_area.width -= depth * tree_view->priv->expander_size + (depth-1) * expander_indent;
1123  
1124                /* If we have an expander column, the highlight underline
1125                 * starts with that column, so that it indicates which
1126                 * level of the tree we're dropping at.
1127                 */
1128                highlight_x = cell_area.x;
1129 +
1130 +              if (!GTK_WIDGET_IS_SENSITIVE (widget))
1131 +                {
1132 +                  flags &= ~ (GTK_CELL_RENDERER_PRELIT + GTK_CELL_RENDERER_INSENSITIVE +
1133 +                              GTK_CELL_RENDERER_FOCUSED);
1134 +                  flags &= GTK_CELL_RENDERER_INSENSITIVE;
1135 +                }
1136 +
1137               if (is_separator)
1138                 gtk_paint_hline (widget->style,
1139                                  event->window,
1140 @@ -3702,6 +4422,48 @@
1141                                                    &cell_area,
1142                                                    &event->area,
1143                                                    flags);
1144 +
1145 +              /* Hildon dotted slash line drawing for Hierarchical Listbox
1146 +                 widget */
1147 +              if (dottedlines)
1148 +                {
1149 +                  py = cell_area.y + cell_area.height / 2;
1150 +                  px2 = depth * tree_view->priv->expander_size +
1151 +                    (depth - 1) * expander_indent;
1152 +
1153 +                  gdk_gc_set_line_attributes (widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1154 +                                              1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_BEVEL);
1155 +
1156 +                  gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1157 +                                 px, py, px2, py);
1158 +
1159 +                  if (depth > 1)
1160 +                    {
1161 +                      gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1162 +                                     px, cell_area.y, px, py);
1163 +                      if (iter_has_next (tree_view->priv->model, &iter))
1164 +                        {
1165 +                          gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1166 +                                        px, py, px, cell_area.y + cell_area.height);
1167 +                        }
1168 +                    }
1169 +
1170 +                  if (node->children)
1171 +                    {
1172 +                      gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1173 +                                     px2, py, px2, cell_area.y + cell_area.height);
1174 +                    }
1175 +                  for (i = depth - 1; i >= 2; i--)
1176 +                    {
1177 +                      if (iter_value[i])
1178 +                        {
1179 +                          px = (i - 1)* tree_view->priv->expander_size + (i - 2) * expander_indent;
1180 +                          gdk_draw_line (tree_view->priv->bin_window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
1181 +                                         px, cell_area.y, px, cell_area.y + cell_area.height);
1182 +                        }
1183 +                    }
1184 +                }
1185 +              
1186               if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
1187                 {
1188                   gint x, y;
1189 @@ -3803,6 +4565,8 @@
1190              }
1191          }
1192  
1193 +      /* Hildon: disabled this */
1194 +#if 0
1195        /* draw the big row-spanning focus rectangle, if needed */
1196        if (!has_special_cell && node == cursor &&
1197           GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS) &&
1198 @@ -3830,6 +4594,7 @@
1199                            width,
1200                            ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node)));
1201         }
1202 +#endif
1203  
1204        y_offset += max_height;
1205        if (node->children)
1206 @@ -3847,6 +4612,17 @@
1207           has_child = gtk_tree_model_iter_children (tree_view->priv->model,
1208                                                     &iter,
1209                                                     &parent);
1210 +
1211 +          /* Check if we need to grow array */
1212 +          if (depth >= node_elements - 1)
1213 +            {
1214 +              node_elements *= 2;
1215 +              iter_value = g_renew (gboolean, iter_value, node_elements);
1216 +              if (!iter_value)
1217 +                goto done;
1218 +            }
1219 +          iter_value[depth] = iter_has_next (tree_view->priv->model, &parent);
1220 +
1221           depth++;
1222  
1223           /* Sanity Check! */
1224 @@ -3897,6 +4673,9 @@
1225    if (drag_dest_path)
1226      gtk_tree_path_free (drag_dest_path);
1227  
1228 +  if (iter_value)
1229 +    g_free (iter_value);
1230 +
1231    return FALSE;
1232  }
1233  
1234 @@ -4179,6 +4958,63 @@
1235  
1236    rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
1237  
1238 +  /* Special Hildon keyboard interactions */
1239 +  if (event->keyval == GDK_Escape)
1240 +    gtk_tree_selection_unselect_all (tree_view->priv->selection);
1241 +
1242 +  if (event->keyval == GDK_Return &&
1243 +      gtk_tree_row_reference_valid (tree_view->priv->cursor))
1244 +    {
1245 +      gboolean force_list_kludge;
1246 +
1247 +      g_object_get (widget, "force_list_kludge", &force_list_kludge, NULL);
1248 +      if (force_list_kludge ||
1249 +          (gtk_tree_model_get_flags (tree_view->priv->model) &
1250 +           GTK_TREE_MODEL_LIST_ONLY))
1251 +        {
1252 +          /* text listbox */
1253 +          if (tree_view->priv->checkbox_mode)
1254 +            {
1255 +              /* multisel with checkboxes: select key toggles focused */
1256 +              gtk_tree_view_real_toggle_cursor_row (tree_view);
1257 +            }
1258 +          else
1259 +            {
1260 +              /* no checkboxes: select key activates focused */
1261 +              GtkTreePath *cursor_path =
1262 +                gtk_tree_row_reference_get_path (tree_view->priv->cursor);
1263 +
1264 +              gtk_tree_view_row_activated (tree_view, cursor_path,
1265 +                                           tree_view->priv->focus_column);
1266 +
1267 +              gtk_tree_path_free (cursor_path);
1268 +             }
1269 +         }
1270 +       else
1271 +         {
1272 +           /* hierarchical listbox */
1273 +           GtkTreePath *cursor_path;
1274 +           GtkRBTree *tree;
1275 +           GtkRBNode *node;
1276 +
1277 +           cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
1278 +           _gtk_tree_view_find_node (tree_view, cursor_path, &tree, &node);
1279 +
1280 +           if (node->children == NULL)
1281 +             gtk_tree_view_real_expand_row (tree_view,
1282 +                                            cursor_path,
1283 +                                            tree,
1284 +                                            node,
1285 +                                            FALSE, TRUE);
1286 +           else
1287 +             gtk_tree_view_real_collapse_row (tree_view,
1288 +                                              cursor_path,
1289 +                                              tree,
1290 +                                              node,
1291 +                                              TRUE);
1292 +         }
1293 +     }
1294 +
1295    if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
1296      {
1297        if (event->keyval == GDK_Escape)
1298 @@ -4420,6 +5256,7 @@
1299  
1300  /* FIXME Is this function necessary? Can I get an enter_notify event
1301   * w/o either an expose event or a mouse motion event?
1302 + * Hildon => it is necessary to make pen dragging work correctly
1303   */
1304  static gboolean
1305  gtk_tree_view_enter_notify (GtkWidget        *widget,
1306 @@ -4434,6 +5271,10 @@
1307  
1308    tree_view = GTK_TREE_VIEW (widget);
1309  
1310 +  /* stop "automatic" pen dragging */
1311 +  tree_view->priv->pen_drag_active = FALSE;
1312 +  remove_scroll_timeout (tree_view);
1313 +
1314    /* Sanity check it */
1315    if (event->window != tree_view->priv->bin_window)
1316      return FALSE;
1317 @@ -4463,6 +5304,9 @@
1318    tree_view = GTK_TREE_VIEW (widget);
1319    tree_view->priv->pressed_button = -1;
1320  
1321 +  if (tree_view->priv->pen_down && tree_view->priv->queued_select_row == NULL)
1322 +    tree_view->priv->pen_drag_active = TRUE;
1323 +
1324    if (event->mode == GDK_CROSSING_GRAB)
1325      return TRUE;
1326  
1327 @@ -4535,6 +5379,7 @@
1328    gboolean retval = FALSE;
1329    gboolean is_separator = FALSE;
1330    gint focus_pad;
1331 +  gint expander_indent;
1332        
1333    /* double check the row needs validating */
1334    if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) &&
1335 @@ -4551,6 +5396,7 @@
1336    gtk_widget_style_get (GTK_WIDGET (tree_view),
1337                         "focus-padding", &focus_pad,
1338                         "horizontal_separator", &horizontal_separator,
1339 +                        "expander_indent", &expander_indent,
1340                         NULL);
1341    
1342    for (list = tree_view->priv->columns; list; list = list->next)
1343 @@ -4577,13 +5423,16 @@
1344         {
1345           height = MAX (height, tmp_height);
1346           height = MAX (height, tree_view->priv->expander_size);
1347 +
1348 +          /* Hildon addition */
1349 +          height -= 1;
1350         }
1351        else
1352         height = 2 + 2 * focus_pad;
1353  
1354        if (gtk_tree_view_is_expander_column (tree_view, column) && TREE_VIEW_DRAW_EXPANDERS (tree_view))
1355          {
1356 -         tmp_width = tmp_width + horizontal_separator + depth * (tree_view->priv->expander_size);
1357 +         tmp_width = tmp_width + horizontal_separator + depth * (tree_view->priv->expander_size) + (depth - 1) * expander_indent;
1358         }
1359        else
1360         tmp_width = tmp_width + horizontal_separator;
1361 @@ -5585,6 +6434,16 @@
1362  #endif /* 0 */
1363  
1364  static void
1365 +add_scroll_timeout (GtkTreeView *tree_view)
1366 +{
1367 +  if (tree_view->priv->scroll_timeout == 0)
1368 +    {
1369 +      tree_view->priv->scroll_timeout =
1370 +        g_timeout_add (150, scroll_row_timeout, tree_view);
1371 +    }
1372 +}
1373 +
1374 +static void
1375  remove_scroll_timeout (GtkTreeView *tree_view)
1376  {
1377    if (tree_view->priv->scroll_timeout != 0)
1378 @@ -6130,10 +6989,9 @@
1379            tree_view->priv->open_dest_timeout =
1380              g_timeout_add (AUTO_EXPAND_TIMEOUT, open_row_timeout, tree_view);
1381          }
1382 -      else if (tree_view->priv->scroll_timeout == 0)
1383 +      else
1384          {
1385 -         tree_view->priv->scroll_timeout =
1386 -           g_timeout_add (150, scroll_row_timeout, tree_view);
1387 +          add_scroll_timeout (tree_view);
1388         }
1389  
1390        if (target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
1391 @@ -6901,8 +7759,6 @@
1392                                 GtkMovementStep    step,
1393                                 gint               count)
1394  {
1395 -  GdkModifierType state;
1396 -
1397    g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
1398    g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
1399                         step == GTK_MOVEMENT_VISUAL_POSITIONS ||
1400 @@ -6919,6 +7775,8 @@
1401    GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
1402    gtk_widget_grab_focus (GTK_WIDGET (tree_view));
1403  
1404 +  /* Hildon: Ignore ctrl and shift */
1405 +#if 0
1406    if (gtk_get_current_event_state (&state))
1407      {
1408        if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
1409 @@ -6926,6 +7784,7 @@
1410        if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
1411          tree_view->priv->shift_pressed = TRUE;
1412      }
1413 +#endif
1414    /* else we assume not pressed */
1415  
1416    switch (step)
1417 @@ -7092,6 +7951,27 @@
1418   done:
1419    if (!tree_view->priv->fixed_height_mode)
1420      install_presize_handler (tree_view);
1421 +
1422 +  /* Hildon: has row now been dimmed? If so, unselect it */
1423 +  _gtk_tree_view_find_node (tree_view, path, &tree, &node);
1424 +  if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
1425 +                                              node,
1426 +                                              path))
1427 +    {
1428 +      if (gtk_tree_path_compare (path,
1429 +                                 gtk_tree_row_reference_get_path(tree_view->priv->cursor))
1430 +          == 0)
1431 +        {
1432 +          gtk_tree_row_reference_free (tree_view->priv->cursor);
1433 +          tree_view->priv->cursor = NULL;
1434 +        }
1435 +
1436 +      gtk_tree_selection_unselect_path (tree_view->priv->selection, path);
1437 +      gtk_tree_view_collapse_row (tree_view, path);
1438 +    }
1439 +
1440 +  check_if_can_focus (tree_view);
1441 +  
1442    if (free_path)
1443      gtk_tree_path_free (path);
1444  }
1445 @@ -7196,6 +8076,11 @@
1446      install_presize_handler (tree_view);
1447    if (free_path)
1448      gtk_tree_path_free (path);
1449 +
1450 +  /* Hildon: after a focusable row has been added, the
1451 +     entire widget becomes focusable if it wasn't before */
1452 +  if ((GTK_WIDGET_FLAGS (tree_view) & GTK_CAN_FOCUS) == 0)
1453 +    check_if_can_focus (tree_view);
1454  }
1455  
1456  static void
1457 @@ -7295,6 +8180,16 @@
1458      _gtk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, check_selection_helper, data);
1459  }
1460  
1461 +static gboolean
1462 +check_if_can_focus_idle (GtkTreeView *tree_view)
1463 +{
1464 +  check_if_can_focus (tree_view);
1465 +
1466 +  tree_view->priv->check_if_can_focus_idle_id = 0;
1467 +  
1468 +  return FALSE;
1469 +}
1470 +
1471  static void
1472  gtk_tree_view_row_deleted (GtkTreeModel *model,
1473                            GtkTreePath  *path,
1474 @@ -7357,6 +8252,11 @@
1475         tree_view->priv->tree = NULL;
1476  
1477        _gtk_rbtree_remove (tree);
1478 +
1479 +      /* Hildon: no nodes -> not focusable */
1480 +      /* FIXME this looks superfluos to me. check_if_can_focus is called
1481 +       * at the end of this function .. -- Jorn */
1482 +      GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
1483      }
1484    else
1485      {
1486 @@ -7375,6 +8275,13 @@
1487  
1488    if (selection_changed)
1489      g_signal_emit_by_name (tree_view->priv->selection, "changed");
1490 +
1491 +  /* FIXME whacky hack to work around the treeview not being in a clean state
1492 +   * when in a tree a row has been removed, but has_child_toggled not been
1493 +   * called yet */
1494 +  if (tree_view->priv->check_if_can_focus_idle_id == 0)
1495 +    tree_view->priv->check_if_can_focus_idle_id =
1496 +      g_idle_add ((GSourceFunc) check_if_can_focus_idle, tree_view);
1497  }
1498  
1499  static void
1500 @@ -7508,6 +8415,7 @@
1501    GList *list;
1502    GtkTreeViewColumn *tmp_column = NULL;
1503    gint total_width;
1504 +  gint expander_indent, depth;
1505    gboolean indent_expanders;
1506    gboolean rtl;
1507  
1508 @@ -7535,14 +8443,19 @@
1509  
1510    gtk_widget_style_get (GTK_WIDGET (tree_view),
1511                         "indent_expanders", &indent_expanders,
1512 +                        "expander_indent", &expander_indent,
1513                         NULL);
1514  
1515 +  /* Hildonlike hack for making the indent look better.
1516 +   * indent is added to all rows except the first one */
1517 +  depth = _gtk_rbtree_get_depth (tree);
1518 +
1519    if (indent_expanders)
1520      {
1521        if (rtl)
1522 -       x_offset -= tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
1523 +       x_offset -= tree_view->priv->expander_size * depth + (depth) * expander_indent;
1524        else
1525 -       x_offset += tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
1526 +       x_offset += tree_view->priv->expander_size * depth + (depth) * expander_indent;
1527      }
1528    if (x1)
1529      {
1530 @@ -7617,9 +8530,11 @@
1531    gboolean retval = FALSE;
1532    gint tmpheight;
1533    gint horizontal_separator;
1534 +  gint expander_indent;
1535  
1536    gtk_widget_style_get (GTK_WIDGET (tree_view),
1537                         "horizontal_separator", &horizontal_separator,
1538 +                        "expander_indent", &expander_indent,
1539                         NULL);
1540  
1541    if (height)
1542 @@ -7657,7 +8572,7 @@
1543        if (gtk_tree_view_is_expander_column (tree_view, column) &&
1544            TREE_VIEW_DRAW_EXPANDERS (tree_view))
1545         {
1546 -         if (depth * tree_view->priv->expander_size + horizontal_separator + width > column->requested_width)
1547 +          if ((depth - 1) *expander_indent + depth * tree_view->priv->expander_size + horizontal_separator + width > column->requested_width)
1548             {
1549               _gtk_tree_view_column_cell_set_dirty (column, TRUE);
1550               retval = TRUE;
1551 @@ -7747,6 +8662,7 @@
1552      }
1553  }
1554  
1555 +#if 0
1556  static void
1557  gtk_tree_view_clamp_column_visible (GtkTreeView       *tree_view,
1558                                     GtkTreeViewColumn *column)
1559 @@ -7762,6 +8678,7 @@
1560      gtk_adjustment_set_value (tree_view->priv->hadjustment,
1561                               column->button->allocation.x);
1562  }
1563 +#endif
1564  
1565  /* This function could be more efficient.  I'll optimize it if profiling seems
1566   * to imply that it is important */
1567 @@ -8290,7 +9207,7 @@
1568  
1569    area.x = x_offset;
1570    area.y = CELL_FIRST_PIXEL (tree_view, tree, node, vertical_separator);
1571 -  area.width = expander_size + 2;
1572 +  area.width = expander_size;
1573    area.height = MAX (CELL_HEIGHT (node, vertical_separator), (expander_size - vertical_separator));
1574  
1575    if (node == tree_view->priv->button_pressed_node)
1576 @@ -8397,7 +9314,10 @@
1577    GtkRBNode *cursor_node = NULL;
1578    GtkRBTree *new_cursor_tree = NULL;
1579    GtkRBNode *new_cursor_node = NULL;
1580 +  GtkRBTree *old_cursor_tree;
1581 +  GtkRBNode *old_cursor_node;
1582    GtkTreePath *cursor_path = NULL;
1583 +  GtkTreePath *new_cursor_path = NULL;
1584  
1585    if (! GTK_WIDGET_HAS_FOCUS (tree_view))
1586      return;
1587 @@ -8415,12 +9335,30 @@
1588    if (cursor_tree == NULL)
1589      /* FIXME: we lost the cursor; should we get the first? */
1590      return;
1591 -  if (count == -1)
1592 -    _gtk_rbtree_prev_full (cursor_tree, cursor_node,
1593 -                          &new_cursor_tree, &new_cursor_node);
1594 -  else
1595 -    _gtk_rbtree_next_full (cursor_tree, cursor_node,
1596 -                          &new_cursor_tree, &new_cursor_node);
1597 +
1598 +  old_cursor_tree = cursor_tree;
1599 +  old_cursor_node = cursor_node;
1600 +  do {
1601 +    if (count == -1)
1602 +      _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
1603 +                             &new_cursor_tree, &new_cursor_node);
1604 +    else
1605 +      _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
1606 +                             &new_cursor_tree, &new_cursor_node);
1607 +
1608 +    if (new_cursor_node)
1609 +      {
1610 +        if (new_cursor_path)
1611 +          gtk_tree_path_free (new_cursor_path);
1612 +
1613 +        new_cursor_path = _gtk_tree_view_find_path (tree_view, new_cursor_tree, new_cursor_node);
1614 +        old_cursor_tree = new_cursor_tree;
1615 +        old_cursor_node = new_cursor_node;
1616 +      }
1617 +  } while (new_cursor_node &&
1618 +           !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
1619 +                                                   new_cursor_node,
1620 +                                                   new_cursor_path));
1621  
1622    /*
1623     * If the list has only one item and multi-selection is set then select
1624 @@ -8450,7 +9388,33 @@
1625    if (new_cursor_node)
1626      {
1627        cursor_path = _gtk_tree_view_find_path (tree_view, new_cursor_tree, new_cursor_node);
1628 -      gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
1629 +
1630 +      if (tree_view->priv->checkbox_mode)
1631 +        gtk_tree_view_real_set_cursor (tree_view, cursor_path, FALSE, TRUE);
1632 +      else
1633 +        gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
1634 +
1635 +      if (tree_view->priv->pen_drag_active)
1636 +        {
1637 +          if (gtk_tree_path_compare (gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row),
1638 +                                     gtk_tree_row_reference_get_path (tree_view->priv->first_drag_row)) == 0)
1639 +            tree_view->priv->pen_drag_reverse = FALSE;
1640 +
1641 +          if (tree_view->priv->pen_drag_reverse)
1642 +            {
1643 +              gtk_tree_selection_select_path (tree_view->priv->selection,
1644 +                                              cursor_path);
1645 +              gtk_tree_selection_unselect_path (tree_view->priv->selection,
1646 +                                                gtk_tree_row_reference_get_path (tree_view->priv->last_drag_row));
1647 +            }
1648 +          
1649 +          gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
1650 +          
1651 +          tree_view->priv->last_drag_row =
1652 +            gtk_tree_row_reference_new (tree_view->priv->model,
1653 +                                        cursor_path);
1654 +        }
1655 +
1656        gtk_tree_path_free (cursor_path);
1657      }
1658    else
1659 @@ -8467,6 +9431,8 @@
1660  {
1661    GtkRBTree *cursor_tree = NULL;
1662    GtkRBNode *cursor_node = NULL;
1663 +  GtkRBTree *old_cursor_tree = NULL;
1664 +  GtkRBNode *old_cursor_node = NULL;
1665    GtkTreePath *cursor_path = NULL;
1666    gint y;
1667    gint vertical_separator;
1668 @@ -8474,6 +9440,9 @@
1669    if (! GTK_WIDGET_HAS_FOCUS (tree_view))
1670      return;
1671  
1672 +  if (tree_view->priv->tree == NULL)
1673 +    return;
1674 +
1675    if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
1676      cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
1677    else
1678 @@ -8504,7 +9473,65 @@
1679  
1680    _gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
1681    cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
1682 -  g_return_if_fail (cursor_path != NULL);
1683 +
1684 +  while (cursor_node &&
1685 +         !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
1686 +                                                 cursor_node,
1687 +                                                 cursor_path))
1688 +    {
1689 +      old_cursor_tree = cursor_tree;
1690 +      old_cursor_node = cursor_node;
1691 +
1692 +      if (count < 0)
1693 +        _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
1694 +                               &cursor_tree, &cursor_node);
1695 +      else
1696 +        _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
1697 +                               &cursor_tree, &cursor_node);
1698 +
1699 +      if (cursor_path)
1700 +        {
1701 +          gtk_tree_path_free(cursor_path);
1702 +          cursor_path = NULL;
1703 +        }
1704 +
1705 +      if (cursor_node)
1706 +        cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
1707 +    }
1708 +
1709 +  if (cursor_path == NULL)
1710 +    {
1711 +       /* looks like we reached the end without finding a sensitive row,
1712 +          so search backwards and try to find the last sensitive row as
1713 +          the next best thing */
1714 +      _gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
1715 +      cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
1716 +      while (cursor_node &&
1717 +             !_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
1718 +                                                     cursor_node,
1719 +                                                     cursor_path))
1720 +        {
1721 +          old_cursor_tree = cursor_tree;
1722 +          old_cursor_node = cursor_node;
1723 +
1724 +          if (count < 0)
1725 +            _gtk_rbtree_next_full (old_cursor_tree, old_cursor_node,
1726 +                                   &cursor_tree, &cursor_node);
1727 +          else
1728 +            _gtk_rbtree_prev_full (old_cursor_tree, old_cursor_node,
1729 +                                   &cursor_tree, &cursor_node);
1730 +
1731 +          if (cursor_path)
1732 +            {
1733 +              gtk_tree_path_free(cursor_path);
1734 +              cursor_path = NULL;
1735 +            }
1736 +
1737 +          if (cursor_node)
1738 +            cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
1739 +        }
1740 +    }
1741 +
1742    gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, TRUE);
1743    gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
1744    gtk_tree_path_free (cursor_path);
1745 @@ -8514,6 +9541,8 @@
1746  gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
1747                                       gint         count)
1748  {
1749 +  /* Hildon: cursor is always displayed on an entire row anyway */
1750 +#if 0
1751    GtkRBTree *cursor_tree = NULL;
1752    GtkRBNode *cursor_node = NULL;
1753    GtkTreePath *cursor_path = NULL;
1754 @@ -8589,12 +9618,15 @@
1755        g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0);
1756      }
1757    gtk_tree_view_clamp_column_visible (tree_view, tree_view->priv->focus_column);
1758 +#endif
1759  }
1760  
1761  static void
1762  gtk_tree_view_move_cursor_start_end (GtkTreeView *tree_view,
1763                                      gint         count)
1764  {
1765 +  /* Hildon: cursor is always displayed on an entire row anyway */
1766 +#if 0
1767    GtkRBTree *cursor_tree;
1768    GtkRBNode *cursor_node;
1769    GtkTreePath *path;
1770 @@ -8631,6 +9663,7 @@
1771    path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
1772    gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE);
1773    gtk_tree_path_free (path);
1774 +#endif
1775  }
1776  
1777  static gboolean
1778 @@ -8670,7 +9703,7 @@
1779    GtkTreePath *cursor_path = NULL;
1780    GtkTreeSelectMode mode = 0;
1781  
1782 -  if (! GTK_WIDGET_HAS_FOCUS (tree_view))
1783 +  if (! GTK_WIDGET_HAS_FOCUS (tree_view) && !tree_view->priv->checkbox_mode)
1784      return FALSE;
1785  
1786    if (tree_view->priv->cursor)
1787 @@ -8731,7 +9764,7 @@
1788    GtkRBNode *cursor_node = NULL;
1789    GtkTreePath *cursor_path = NULL;
1790  
1791 -  if (! GTK_WIDGET_HAS_FOCUS (tree_view))
1792 +  if (! GTK_WIDGET_HAS_FOCUS (tree_view) && !tree_view->priv->checkbox_mode)
1793      return FALSE;
1794  
1795    cursor_path = NULL;
1796 @@ -8774,6 +9807,7 @@
1797    GtkTreePath *cursor_path = NULL;
1798    GtkRBTree *tree;
1799    GtkRBNode *node;
1800 +  gboolean hildon_row;
1801  
1802    if (! GTK_WIDGET_HAS_FOCUS (tree_view))
1803      return FALSE;
1804 @@ -8796,10 +9830,32 @@
1805        && gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL)
1806      expand = !expand;
1807  
1808 -  if (expand)
1809 -    gtk_tree_view_real_expand_row (tree_view, cursor_path, tree, node, open_all, TRUE);
1810 +  /* Keyboard Navigation: if we can't expand/collapse row, we should either move active focus
1811 +     to child item (right arrow) or move active focus to the parent item (left arrow) */
1812 +  if (expand) 
1813 +    {
1814 +      hildon_row = gtk_tree_view_real_expand_row (tree_view, cursor_path, tree,
1815 +                                                   node, open_all, TRUE);
1816 +
1817 +      if (!hildon_row || !node->children)
1818 +        g_signal_emit_by_name (gtk_widget_get_ancestor (GTK_WIDGET (tree_view),
1819 +                                                        GTK_TYPE_WINDOW),
1820 +                               "move_focus",
1821 +                               GTK_DIR_TAB_FORWARD);
1822 +    }
1823    else
1824 -    gtk_tree_view_real_collapse_row (tree_view, cursor_path, tree, node, TRUE);
1825 +    {
1826 +      hildon_row = gtk_tree_view_real_collapse_row (tree_view, cursor_path, tree, node, TRUE);
1827 +
1828 +      if (hildon_row == FALSE)
1829 +        {
1830 +          g_signal_emit_by_name (gtk_widget_get_ancestor (GTK_WIDGET(tree_view),
1831 +                                                          GTK_TYPE_WINDOW),
1832 +                                 "move_focus",
1833 +                                 GTK_DIR_TAB_BACKWARD);
1834 +          gtk_tree_view_real_select_cursor_parent (tree_view);
1835 +        }
1836 +    }
1837  
1838    gtk_tree_path_free (cursor_path);
1839  
1840 @@ -9327,6 +10383,14 @@
1841        tree_view->priv->last_button_press_2 = NULL;
1842        gtk_tree_row_reference_free (tree_view->priv->scroll_to_path);
1843        tree_view->priv->scroll_to_path = NULL;
1844 +      gtk_tree_row_reference_free (tree_view->priv->first_drag_row);
1845 +      tree_view->priv->first_drag_row = NULL;
1846 +      gtk_tree_row_reference_free (tree_view->priv->last_drag_row);
1847 +      tree_view->priv->last_drag_row = NULL;
1848 +      gtk_tree_row_reference_free (tree_view->priv->queued_expand_row);
1849 +      tree_view->priv->queued_expand_row = NULL;
1850 +      gtk_tree_row_reference_free (tree_view->priv->queued_select_row);
1851 +      tree_view->priv->queued_select_row = NULL;
1852  
1853        tree_view->priv->scroll_to_column = NULL;
1854  
1855 @@ -9402,6 +10466,8 @@
1856        install_presize_handler (tree_view);
1857      }
1858  
1859 +  check_if_can_focus (tree_view);
1860 +
1861    g_object_notify (G_OBJECT (tree_view), "model");
1862  
1863    if (GTK_WIDGET_REALIZED (tree_view))
1864 @@ -9744,6 +10810,10 @@
1865                                          G_CALLBACK (column_sizing_notify),
1866                                          tree_view);
1867  
1868 +  g_signal_handlers_disconnect_by_func (column,
1869 +                                        G_CALLBACK (update_checkbox_mode),
1870 +                                        tree_view);
1871 +
1872    _gtk_tree_view_column_unset_tree_view (column);
1873  
1874    tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column);
1875 @@ -9773,6 +10843,8 @@
1876    g_object_unref (column);
1877    g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
1878  
1879 +  update_checkbox_mode (NULL, NULL, tree_view);
1880 +
1881    return tree_view->priv->n_columns;
1882  }
1883  
1884 @@ -9815,6 +10887,9 @@
1885    g_signal_connect (column, "notify::sizing",
1886                      G_CALLBACK (column_sizing_notify), tree_view);
1887  
1888 +  g_signal_connect (column, "notify::visible",
1889 +                    G_CALLBACK (update_checkbox_mode), tree_view);
1890 +
1891    tree_view->priv->columns = g_list_insert (tree_view->priv->columns,
1892                                             column, position);
1893    tree_view->priv->n_columns++;
1894 @@ -9838,6 +10913,9 @@
1895  
1896    g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
1897  
1898 +  update_checkbox_mode (NULL, NULL, tree_view);
1899 +  check_if_can_focus (tree_view);
1900 +
1901    return tree_view->priv->n_columns;
1902  }
1903  
1904 @@ -10295,7 +11373,6 @@
1905                              GtkTreeViewColumn *column)
1906  {
1907    g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
1908 -
1909    g_signal_emit (tree_view, tree_view_signals[ROW_ACTIVATED], 0, path, column);
1910  }
1911  
1912 @@ -10560,6 +11637,16 @@
1913    GtkTreeIter iter;
1914    GtkTreeIter temp;
1915    gboolean expand;
1916 +  gint vertical_separator;
1917 +  GtkTreePath *collapse_path;
1918 +  GtkRBTree *tree2;
1919 +  GtkRBNode *node2;
1920 +  GtkTreePath *child_path = NULL;
1921 +  GtkTreeIter parent_iter;
1922 +  GtkTreeIter child_iter;
1923 +  GdkRectangle visible_rect;
1924 +  gint children, n;
1925 +  guint total_height;
1926  
1927    remove_auto_expand_timeout (tree_view);
1928  
1929 @@ -10573,8 +11660,12 @@
1930    if (! gtk_tree_model_iter_has_child (tree_view->priv->model, &iter))
1931      return FALSE;
1932  
1933 +  /* Hildon: insensitive rows cannot be expanded */
1934 +  if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
1935 +                                              node, path))
1936 +    return FALSE;
1937  
1938 -   if (node->children && open_all)
1939 +  if (node->children && open_all)
1940      {
1941        gboolean retval = FALSE;
1942        GtkTreePath *tmp_path = gtk_tree_path_copy (path);
1943 @@ -10603,6 +11694,37 @@
1944        return retval;
1945      }
1946  
1947 +  /* Hildon: collapse other items in the same level */
1948 +  gtk_widget_style_get (GTK_WIDGET (tree_view),
1949 +                        "vertical_separator", &vertical_separator, NULL);
1950 +
1951 +  /* find the first child */
1952 +  collapse_path = gtk_tree_path_copy (path);
1953 +  while (gtk_tree_path_prev (collapse_path))
1954 +    ;
1955 +
1956 +  do {
1957 +    if (gtk_tree_path_compare (collapse_path, path) != 0)
1958 +      {
1959 +        _gtk_tree_view_find_node (tree_view, collapse_path, &tree2, &node2);
1960
1961 +        if (tree2 == NULL)
1962 +          /* end reached already */
1963 +          break;
1964
1965 +        if (node2->children != NULL &&
1966 +            gtk_tree_view_real_collapse_row (tree_view, collapse_path,
1967 +                                             tree2, node2, FALSE))
1968 +            /* no need to do anything else since only one row may
1969 +               be expanded on any particular level at any time */
1970 +            break;
1971 +      }
1972 +
1973 +    gtk_tree_path_next (collapse_path);
1974 +  } while (1);
1975 +
1976 +  gtk_tree_path_free (collapse_path);
1977 +
1978    g_signal_emit (tree_view, tree_view_signals[TEST_EXPAND_ROW], 0, &iter, path, &expand);
1979  
1980    if (expand)
1981 @@ -10643,6 +11765,42 @@
1982        GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
1983      }
1984  
1985 +  /* autoscroll if necessary */
1986 +  validate_visible_area (tree_view);
1987 +  gtk_tree_model_get_iter (tree_view->priv->model, &parent_iter, path);
1988 +  _gtk_tree_view_find_node (tree_view, path, &tree2, &node2);
1989 +  validate_row (tree_view, tree2, node2, &parent_iter, path);
1990 +  total_height = CELL_HEIGHT (node2, vertical_separator);
1991 +  children = gtk_tree_model_iter_n_children (tree_view->priv->model, &parent_iter);
1992 +  for (n = 0; n < children; n++)
1993 +    {
1994 +      gtk_tree_model_iter_nth_child (tree_view->priv->model,
1995 +                                     &child_iter, &parent_iter, n);
1996 +
1997 +      /* must free here so the path of last child is kept for later */
1998 +      if (child_path != NULL)
1999 +        gtk_tree_path_free (child_path);
2000 +
2001 +      child_path = gtk_tree_model_get_path (tree_view->priv->model, &child_iter);
2002 +      _gtk_tree_view_find_node (tree_view, child_path, &tree2, &node2);
2003 +
2004 +      if (CELL_HEIGHT (node2, 0) == 0)
2005 +        validate_row (tree_view, tree2, node2, &child_iter, child_path);
2006 +
2007 +      total_height += CELL_HEIGHT (node2, vertical_separator);
2008 +    }
2009 +
2010 +  gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
2011 +
2012 +  /* KNOWN BUG: If no autocollapse was performed earlier above, these calls
2013 +     to gtk_tree_view_scroll_to_cell do nothing although they should. */
2014 +  if (total_height > visible_rect.height)
2015 +    gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.0, 0.0);
2016 +  else
2017 +    gtk_tree_view_scroll_to_cell (tree_view, child_path, NULL, FALSE, 0.0, 0.0);
2018 +
2019 +  gtk_tree_path_free (child_path);
2020 +
2021    install_presize_handler (tree_view);
2022  
2023    g_signal_emit (tree_view, tree_view_signals[ROW_EXPANDED], 0, &iter, path);
2024 @@ -11070,6 +12228,16 @@
2025    GtkRBTree *tree = NULL;
2026    GtkRBNode *node = NULL;
2027  
2028 +  _gtk_tree_view_find_node (tree_view, path, &tree, &node);
2029 +
2030 +  /* Hildon: cursor cannot move to an insensitive row */
2031 +  if (!_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
2032 +                                              node, path))
2033 +    {
2034 +      g_signal_emit (tree_view, tree_view_signals[ROW_INSENSITIVE], 0, path);
2035 +      return;
2036 +    }
2037 +
2038    if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
2039      {
2040        GtkTreePath *cursor_path;
2041 @@ -11083,7 +12251,6 @@
2042    tree_view->priv->cursor = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view),
2043                                                               tree_view->priv->model,
2044                                                               path);
2045 -  _gtk_tree_view_find_node (tree_view, path, &tree, &node);
2046    if (tree != NULL)
2047      {
2048        GtkRBTree *new_tree = NULL;
2049 @@ -11093,7 +12260,8 @@
2050          {
2051            GtkTreeSelectMode mode = 0;
2052  
2053 -          if (tree_view->priv->ctrl_pressed)
2054 +          if (tree_view->priv->ctrl_pressed ||
2055 +              tree_view->priv->pen_drag_active)
2056              mode |= GTK_TREE_SELECT_MODE_TOGGLE;
2057            if (tree_view->priv->shift_pressed)
2058              mode |= GTK_TREE_SELECT_MODE_EXTEND;
2059 @@ -11213,6 +12381,9 @@
2060  {
2061    g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
2062    g_return_if_fail (path != NULL);
2063 +
2064 +  tree_view->priv->pen_focus = FALSE;
2065 +  
2066    if (focus_column)
2067      g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (focus_column));
2068    if (focus_cell)
2069 @@ -11414,6 +12585,7 @@
2070    GtkRBNode *node = NULL;
2071    gint vertical_separator;
2072    gint horizontal_separator;
2073 +  gint expander_indent;
2074  
2075    g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
2076    g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column));
2077 @@ -11424,6 +12596,7 @@
2078    gtk_widget_style_get (GTK_WIDGET (tree_view),
2079                         "vertical_separator", &vertical_separator,
2080                         "horizontal_separator", &horizontal_separator,
2081 +                        "expander_indent", &expander_indent,
2082                         NULL);
2083  
2084    rect->x = 0;
2085 @@ -11453,9 +12626,11 @@
2086           TREE_VIEW_DRAW_EXPANDERS (tree_view))
2087         {
2088           gint depth = gtk_tree_path_get_depth (path) - 1;
2089 +          gint adjust;
2090  
2091 -         rect->x += depth * tree_view->priv->expander_size;
2092 -         rect->width -= depth * tree_view->priv->expander_size;
2093 +          adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
2094 +          rect->x += adjust;
2095 +          rect->width -= adjust;
2096           rect->width = MAX (rect->width, 0);
2097         }
2098      }
2099 @@ -12077,8 +13252,13 @@
2100        if (gtk_tree_view_is_expander_column (tree_view, column) &&
2101            TREE_VIEW_DRAW_EXPANDERS(tree_view))
2102          {
2103 -          cell_area.x += depth * tree_view->priv->expander_size;
2104 -          cell_area.width -= depth * tree_view->priv->expander_size;
2105 +          gint adjust, expander_indent;
2106 +
2107 +          gtk_widget_style_get (widget, "expander_indent", &expander_indent, NULL);
2108 +
2109 +          adjust = depth * tree_view->priv->expander_size + (depth - 1) * expander_indent;
2110 +          cell_area.x += adjust;
2111 +          cell_area.width -= adjust;
2112          }
2113  
2114        if (gtk_tree_view_column_cell_is_visible (column))
2115 @@ -13062,3 +14242,138 @@
2116      tree_view->priv->pressed_button = -1;
2117  }
2118  
2119 +/* Hildon addition: iterates through columns and cells, looks for
2120 +    a cell with "activatable" attribute and sets or unsets
2121 +    priv->checkbox_mode accordingly (except when checkbox mode
2122 +    is disabled by unsetting allow_checkbox_mode).
2123 + */
2124 +static void
2125 +update_checkbox_mode (GObject *object, GParamSpec *pspec, gpointer data)
2126 +{
2127 +  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
2128 +  GList *columns = gtk_tree_view_get_columns (tree_view);
2129 +  GList *list;
2130 +  gboolean allow_checkbox_mode;
2131 +
2132 +  g_object_get (GTK_WIDGET (data),
2133 +                "allow_checkbox_mode", &allow_checkbox_mode, NULL);
2134 +  g_return_if_fail (allow_checkbox_mode);
2135 +
2136 +  for (list = columns; list; list = list->next)
2137 +    {
2138 +      GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN (list->data);
2139 +      if (gtk_tree_view_column_get_visible (col) &&
2140 +          _gtk_tree_view_column_has_activatable_cell (col))
2141 +        {
2142 +          /* checkbox column found */
2143 +          tree_view->priv->checkbox_mode = TRUE;
2144 +          g_list_free (columns);
2145 +          return;
2146 +        }
2147 +    }
2148 +
2149 +  /* no checkbox column was found */
2150 +  tree_view->priv->checkbox_mode = FALSE;
2151 +  g_list_free (columns);
2152 +}
2153 +
2154 +static void
2155 +set_dotted_lines (GtkTreeView *tree_view, gboolean enable)
2156 +{
2157 +  if (enable != tree_view->priv->dotted_lines)
2158 +    {
2159 +      tree_view->priv->dotted_lines = enable;
2160 +      gtk_widget_queue_draw (GTK_WIDGET (tree_view));
2161 +    }
2162 +}
2163 +
2164 +/* This function is used to ensure two things:
2165 + * - in single selection mode, focus will always equal selection
2166 + * - in multiple selection mode, focus is removed if cursor row is
2167 + *   explicitly unselected
2168 + */
2169 +static void
2170 +selection_changed (GtkTreeSelection *selection, gpointer data)
2171 +{
2172 +  GtkTreeView *tree_view = GTK_TREE_VIEW(data);
2173 +  GtkTreePath *cursor_path = NULL;
2174 +  GtkTreeIter iter;
2175 +
2176 +  /* if there are checkboxes, cursor row doesn't have to be selected */
2177 +  if (tree_view->priv->checkbox_mode)
2178 +    return;
2179 +
2180 +  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
2181 +    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
2182 +
2183 +  if (cursor_path == NULL ||
2184 +      !gtk_tree_selection_path_is_selected (selection, cursor_path))
2185 +    {
2186 +      GtkTreePath *selected_path;
2187 +      GtkRBTree *tree = NULL;
2188 +      GtkRBNode *node = NULL;
2189 +        
2190 +      if (gtk_tree_selection_get_mode (selection) != GTK_SELECTION_MULTIPLE &&
2191 +          gtk_tree_selection_get_selected (selection, NULL, &iter))
2192 +        {
2193 +          selected_path = gtk_tree_model_get_path (tree_view->priv->model,
2194 +                                                   &iter);
2195 +          gtk_tree_view_real_set_cursor (tree_view, selected_path, TRUE, TRUE);
2196 +          _gtk_tree_view_find_node (tree_view, selected_path, &tree, &node);
2197 +          gtk_tree_view_clamp_node_visible (tree_view, tree, node);
2198 +          gtk_tree_path_free (selected_path);
2199 +          gtk_widget_grab_focus (GTK_WIDGET (tree_view));
2200 +        }
2201 +      else
2202 +        {
2203 +          gtk_tree_row_reference_free (tree_view->priv->cursor);
2204 +          tree_view->priv->cursor = NULL;
2205 +        }
2206 +    }
2207 +
2208 +  if (cursor_path)
2209 +    gtk_tree_path_free (cursor_path);
2210 +}
2211 +
2212 +/* Helper function for ensuring that GtkTreeView is focusable
2213 + * if and only if it contains at least one sensitive top-level row.
2214 + * Should be called whenever the existence of a sensitive top-level row
2215 + * might have changed.
2216 + */
2217 +static void
2218 +check_if_can_focus (GtkTreeView *tree_view)
2219 +{
2220 +  GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
2221 +  GtkTreeIter iter;
2222 +
2223 +  if (model == NULL || !GTK_WIDGET_MAPPED (tree_view))
2224 +    return;
2225 +
2226 +  if (gtk_tree_model_get_iter_first (model, &iter) == FALSE)
2227 +    {
2228 +      GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
2229 +      return;
2230 +    }
2231 +
2232 +  do {
2233 +    GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
2234 +    GtkRBTree *tree;
2235 +    GtkRBNode *node;
2236 +
2237 +    _gtk_tree_view_find_node (tree_view, path, &tree, &node);
2238 +
2239 +    if (_gtk_tree_selection_is_row_selectable (tree_view->priv->selection,
2240 +                                               node, path))
2241 +      {
2242 +        GTK_WIDGET_SET_FLAGS (tree_view, GTK_CAN_FOCUS);
2243 +        if (!gtk_tree_row_reference_valid (tree_view->priv->cursor))
2244 +          gtk_tree_view_real_set_cursor (tree_view, path,
2245 +                                         !tree_view->priv->checkbox_mode,
2246 +                                         TRUE);
2247 +
2248 +        return;
2249 +      }
2250 +  } while (gtk_tree_model_iter_next (model, &iter));
2251 +
2252 +  GTK_WIDGET_UNSET_FLAGS (tree_view, GTK_CAN_FOCUS);
2253 +}