X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreeview.c;h=19c5fffa268399ab199c596e4acd2d7e6549648a;hb=5ead07e1b2b959e5309d7f17409c3d4d9b01cf96;hp=f92feee66c372859d7bf9b5b81a3525f66e305c5;hpb=f4bbe8f0deb8d1c36829acfc791d632d27805f30;p=~andy%2Fgtk diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index f92feee66..19c5fffa2 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -303,6 +303,7 @@ static gboolean gtk_tree_view_is_expander_column (GtkTreeView static void gtk_tree_view_add_move_binding (GtkBindingSet *binding_set, guint keyval, guint modmask, + gboolean add_shifted_binding, GtkMovementStep step, gint count); static gint gtk_tree_view_unref_and_check_selection_tree (GtkTreeView *tree_view, @@ -385,7 +386,8 @@ static void gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_vi static void gtk_tree_view_search_dialog_hide (GtkWidget *search_dialog, GtkTreeView *tree_view); static void gtk_tree_view_search_position_func (GtkTreeView *tree_view, - GtkWidget *search_dialog); + GtkWidget *search_dialog, + gpointer user_data); static void gtk_tree_view_search_disable_popdown (GtkEntry *entry, GtkMenu *menu, gpointer data); @@ -484,7 +486,7 @@ gtk_tree_view_get_type (void) }; tree_view_type = - g_type_register_static (GTK_TYPE_CONTAINER, g_intern_static_string ("GtkTreeView"), + g_type_register_static (GTK_TYPE_CONTAINER, I_("GtkTreeView"), &tree_view_info, 0); } @@ -768,7 +770,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) /* Signals */ widget_class->set_scroll_adjustments_signal = - g_signal_new ("set_scroll_adjustments", + g_signal_new (I_("set_scroll_adjustments"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, set_scroll_adjustments), @@ -778,8 +780,23 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); + /** + * GtkTreeView::row-activated: + * @tree_view: the object on which the signal is emitted + * @path: the #GtkTreePath for the activated row + * @column: the #GtkTreeViewColumn in which the activation occurred + * + * The "row-activated" signal is emitted when the method + * gtk_tree_view_row_activated() is called or the user double clicks + * a treeview row. It is also emitted when a non-editable row is + * selected and one of the keys: Space, Shift+Space, Return or + * Enter is pressed. + * + * For selection handling refer to the tree + * widget conceptual overview as well as #GtkTreeSelection. + */ tree_view_signals[ROW_ACTIVATED] = - g_signal_new ("row_activated", + g_signal_new (I_("row_activated"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, row_activated), @@ -790,7 +807,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_TREE_VIEW_COLUMN); tree_view_signals[TEST_EXPAND_ROW] = - g_signal_new ("test_expand_row", + g_signal_new (I_("test_expand_row"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, test_expand_row), @@ -801,7 +818,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_TREE_PATH); tree_view_signals[TEST_COLLAPSE_ROW] = - g_signal_new ("test_collapse_row", + g_signal_new (I_("test_collapse_row"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, test_collapse_row), @@ -812,7 +829,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_TREE_PATH); tree_view_signals[ROW_EXPANDED] = - g_signal_new ("row_expanded", + g_signal_new (I_("row_expanded"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, row_expanded), @@ -823,7 +840,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_TREE_PATH); tree_view_signals[ROW_COLLAPSED] = - g_signal_new ("row_collapsed", + g_signal_new (I_("row_collapsed"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, row_collapsed), @@ -834,7 +851,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) GTK_TYPE_TREE_PATH); tree_view_signals[COLUMNS_CHANGED] = - g_signal_new ("columns_changed", + g_signal_new (I_("columns_changed"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, columns_changed), @@ -843,7 +860,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_NONE, 0); tree_view_signals[CURSOR_CHANGED] = - g_signal_new ("cursor_changed", + g_signal_new (I_("cursor_changed"), G_TYPE_FROM_CLASS (o_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkTreeViewClass, cursor_changed), @@ -852,7 +869,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_NONE, 0); tree_view_signals[MOVE_CURSOR] = - g_signal_new ("move_cursor", + g_signal_new (I_("move_cursor"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, move_cursor), @@ -863,7 +880,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_INT); tree_view_signals[SELECT_ALL] = - g_signal_new ("select_all", + g_signal_new (I_("select_all"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, select_all), @@ -872,7 +889,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN, 0); tree_view_signals[UNSELECT_ALL] = - g_signal_new ("unselect_all", + g_signal_new (I_("unselect_all"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, unselect_all), @@ -881,7 +898,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN, 0); tree_view_signals[SELECT_CURSOR_ROW] = - g_signal_new ("select_cursor_row", + g_signal_new (I_("select_cursor_row"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, select_cursor_row), @@ -891,7 +908,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN); tree_view_signals[TOGGLE_CURSOR_ROW] = - g_signal_new ("toggle_cursor_row", + g_signal_new (I_("toggle_cursor_row"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, toggle_cursor_row), @@ -900,7 +917,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN, 0); tree_view_signals[EXPAND_COLLAPSE_CURSOR_ROW] = - g_signal_new ("expand_collapse_cursor_row", + g_signal_new (I_("expand_collapse_cursor_row"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, expand_collapse_cursor_row), @@ -912,7 +929,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN); tree_view_signals[SELECT_CURSOR_PARENT] = - g_signal_new ("select_cursor_parent", + g_signal_new (I_("select_cursor_parent"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, select_cursor_parent), @@ -921,7 +938,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN, 0); tree_view_signals[START_INTERACTIVE_SEARCH] = - g_signal_new ("start_interactive_search", + g_signal_new (I_("start_interactive_search"), G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GtkTreeViewClass, start_interactive_search), @@ -930,40 +947,40 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) G_TYPE_BOOLEAN, 0); /* Key bindings */ - gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0, TRUE, GTK_MOVEMENT_DISPLAY_LINES, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_Up, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_Up, 0, TRUE, GTK_MOVEMENT_DISPLAY_LINES, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_Down, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_Down, 0, TRUE, GTK_MOVEMENT_DISPLAY_LINES, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_Down, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_Down, 0, TRUE, GTK_MOVEMENT_DISPLAY_LINES, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK, + gtk_tree_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK, FALSE, GTK_MOVEMENT_DISPLAY_LINES, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK, + gtk_tree_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK, FALSE, GTK_MOVEMENT_DISPLAY_LINES, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_Home, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_Home, 0, TRUE, GTK_MOVEMENT_BUFFER_ENDS, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_Home, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_Home, 0, TRUE, GTK_MOVEMENT_BUFFER_ENDS, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_End, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_End, 0, TRUE, GTK_MOVEMENT_BUFFER_ENDS, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_End, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_End, 0, TRUE, GTK_MOVEMENT_BUFFER_ENDS, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_Page_Up, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_Page_Up, 0, TRUE, GTK_MOVEMENT_PAGES, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0, TRUE, GTK_MOVEMENT_PAGES, -1); - gtk_tree_view_add_move_binding (binding_set, GDK_Page_Down, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_Page_Down, 0, TRUE, GTK_MOVEMENT_PAGES, 1); - gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0, + gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0, TRUE, GTK_MOVEMENT_PAGES, 1); @@ -1136,12 +1153,15 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) gtk_binding_entry_add_signal (binding_set, GDK_f, GDK_CONTROL_MASK, "start_interactive_search", 0); gtk_binding_entry_add_signal (binding_set, GDK_F, GDK_CONTROL_MASK, "start_interactive_search", 0); + + g_type_class_add_private (o_class, sizeof (GtkTreeViewPrivate)); } static void gtk_tree_view_init (GtkTreeView *tree_view) { - tree_view->priv = g_new0 (GtkTreeViewPrivate, 1); + tree_view->priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_view, GTK_TYPE_TREE_VIEW, GtkTreeViewPrivate); + GTK_WIDGET_SET_FLAGS (tree_view, GTK_CAN_FOCUS); gtk_widget_set_redraw_on_allocate (GTK_WIDGET (tree_view), FALSE); @@ -1170,8 +1190,9 @@ gtk_tree_view_init (GtkTreeView *tree_view) tree_view->priv->selection = _gtk_tree_selection_new_with_tree_view (tree_view); tree_view->priv->enable_search = TRUE; tree_view->priv->search_column = -1; - tree_view->priv->search_dialog_position_func = gtk_tree_view_search_position_func; + tree_view->priv->search_position_func = gtk_tree_view_search_position_func; tree_view->priv->search_equal_func = gtk_tree_view_search_equal_func; + tree_view->priv->search_custom_entry_set = FALSE; tree_view->priv->typeselect_flush_timeout = 0; tree_view->priv->init_hadjust_value = TRUE; tree_view->priv->width = 0; @@ -1265,6 +1286,9 @@ gtk_tree_view_get_property (GObject *object, case PROP_HEADERS_VISIBLE: g_value_set_boolean (value, gtk_tree_view_get_headers_visible (tree_view)); break; + case PROP_HEADERS_CLICKABLE: + g_value_set_boolean (value, gtk_tree_view_get_headers_clickable (tree_view)); + break; case PROP_EXPANDER_COLUMN: g_value_set_object (value, tree_view->priv->expander_column); break; @@ -1298,10 +1322,6 @@ gtk_tree_view_get_property (GObject *object, static void gtk_tree_view_finalize (GObject *object) { - GtkTreeView *tree_view = (GtkTreeView *) object; - - g_free (tree_view->priv); - (* G_OBJECT_CLASS (parent_class)->finalize) (object); } @@ -1310,6 +1330,20 @@ gtk_tree_view_finalize (GObject *object) /* GtkObject Methods */ +static void +gtk_tree_view_free_rbtree (GtkTreeView *tree_view) +{ + _gtk_rbtree_free (tree_view->priv->tree); + + tree_view->priv->tree = NULL; + tree_view->priv->button_pressed_node = NULL; + tree_view->priv->button_pressed_tree = NULL; + tree_view->priv->prelight_tree = NULL; + tree_view->priv->prelight_node = NULL; + tree_view->priv->expanded_collapsed_node = NULL; + tree_view->priv->expanded_collapsed_tree = NULL; +} + static void gtk_tree_view_destroy (GtkObject *object) { @@ -1334,8 +1368,8 @@ gtk_tree_view_destroy (GtkObject *object) if (tree_view->priv->tree != NULL) { gtk_tree_view_unref_and_check_selection_tree (tree_view, tree_view->priv->tree); - _gtk_rbtree_free (tree_view->priv->tree); - tree_view->priv->tree = NULL; + + gtk_tree_view_free_rbtree (tree_view); } if (tree_view->priv->selection != NULL) @@ -1408,13 +1442,19 @@ gtk_tree_view_destroy (GtkObject *object) } } - if (tree_view->priv->search_destroy) + if (tree_view->priv->search_destroy && tree_view->priv->search_user_data) { (* tree_view->priv->search_destroy) (tree_view->priv->search_user_data); tree_view->priv->search_user_data = NULL; } - if (tree_view->priv->row_separator_destroy) + if (tree_view->priv->search_position_destroy && tree_view->priv->search_position_user_data) + { + (* tree_view->priv->search_position_destroy) (tree_view->priv->search_position_user_data); + tree_view->priv->search_position_user_data = NULL; + } + + if (tree_view->priv->row_separator_destroy && tree_view->priv->row_separator_data) { (* tree_view->priv->row_separator_destroy) (tree_view->priv->row_separator_data); tree_view->priv->row_separator_data = NULL; @@ -1514,7 +1554,6 @@ gtk_tree_view_realize (GtkWidget *widget) { GList *tmp_list; GtkTreeView *tree_view; - GdkGCValues values; GdkWindowAttr attributes; gint attributes_mask; @@ -1576,12 +1615,6 @@ gtk_tree_view_realize (GtkWidget *widget) &attributes, attributes_mask); gdk_window_set_user_data (tree_view->priv->header_window, widget); - - values.foreground = (widget->style->white.pixel==0 ? - widget->style->black:widget->style->white); - values.function = GDK_XOR; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - /* Add them all up. */ widget->style = gtk_style_attach (widget->style, widget->window); gdk_window_set_background (widget->window, &widget->style->base[widget->state]); @@ -2105,6 +2138,9 @@ gtk_tree_view_size_allocate (GtkWidget *widget, /* now the adjustments and window sizes are in sync, we can sync toprow/dy again */ if (tree_view->priv->height <= tree_view->priv->vadjustment->page_size) gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), 0); + else if (tree_view->priv->vadjustment->value + tree_view->priv->vadjustment->page_size > tree_view->priv->height) + gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), + tree_view->priv->height - tree_view->priv->vadjustment->page_size); else if (gtk_tree_row_reference_valid (tree_view->priv->top_row)) gtk_tree_view_top_row_to_dy (tree_view); else @@ -2265,12 +2301,12 @@ gtk_tree_view_button_press (GtkWidget *widget, for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); list; list = (rtl ? list->prev : list->next)) { - column = list->data; + GtkTreeViewColumn *candidate = list->data; - if (!column->visible) + if (!candidate->visible) continue; - background_area.width = column->width; + background_area.width = candidate->width; if ((background_area.x > (gint) event->x) || (background_area.x + background_area.width <= (gint) event->x)) { @@ -2279,6 +2315,7 @@ gtk_tree_view_button_press (GtkWidget *widget, } /* we found the focus column */ + column = candidate; cell_area = background_area; cell_area.width -= horizontal_separator; cell_area.height -= vertical_separator; @@ -2705,7 +2742,7 @@ gtk_tree_view_configure (GtkWidget *widget, GtkTreeView *tree_view; tree_view = GTK_TREE_VIEW (widget); - tree_view->priv->search_dialog_position_func (tree_view, tree_view->priv->search_window); + tree_view->priv->search_position_func (tree_view, tree_view->priv->search_window); return FALSE; } @@ -3215,7 +3252,7 @@ gtk_tree_view_motion_resize_column (GtkWidget *widget, new_width = gtk_tree_view_new_column_width (tree_view, tree_view->priv->drag_pos, &x); if (x != tree_view->priv->x_drag && - (new_width != column->fixed_width)); + (new_width != column->fixed_width)) { column->use_resized_width = TRUE; column->resized_width = new_width; @@ -3454,13 +3491,14 @@ gtk_tree_view_bin_expose (GtkWidget *widget, GtkRBTree *drag_highlight_tree = NULL; GtkTreeIter iter; gint new_y; - gint y_offset, x_offset, cell_offset; + gint y_offset, cell_offset; gint max_height; gint depth; GdkRectangle background_area; GdkRectangle cell_area; guint flags; gint highlight_x; + gint expander_cell_width; gint bin_window_width; gint bin_window_height; GtkTreePath *cursor_path; @@ -3588,9 +3626,9 @@ gtk_tree_view_bin_expose (GtkWidget *widget, max_height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node)); - x_offset = -event->area.x; cell_offset = 0; highlight_x = 0; /* should match x coord of first cell */ + expander_cell_width = 0; background_area.y = y_offset + event->area.y; background_area.height = max_height; @@ -3747,6 +3785,8 @@ gtk_tree_view_bin_expose (GtkWidget *widget, * level of the tree we're dropping at. */ highlight_x = cell_area.x; + expander_cell_width = cell_area.width; + if (is_separator) gtk_paint_hline (widget->style, event->window, @@ -3860,10 +3900,10 @@ gtk_tree_view_bin_expose (GtkWidget *widget, if (highlight_y >= 0) { gdk_draw_line (event->window, - widget->style->black_gc, - highlight_x, + widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + rtl ? highlight_x + expander_cell_width : highlight_x, highlight_y, - bin_window_width - highlight_x, + rtl ? 0 : bin_window_width, highlight_y); } } @@ -4422,7 +4462,8 @@ gtk_tree_view_key_press (GtkWidget *widget, /* We pass the event to the search_entry. If its text changes, then we start * the typeahead find capabilities. */ - if (tree_view->priv->enable_search) + if (tree_view->priv->enable_search + && !tree_view->priv->search_custom_entry_set) { GdkEvent *new_event; char *old_text; @@ -4437,7 +4478,8 @@ gtk_tree_view_key_press (GtkWidget *widget, /* Make a copy of the current text */ old_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (tree_view->priv->search_entry))); new_event = gdk_event_copy ((GdkEvent *) event); - ((GdkEventKey *) new_event)->window = tree_view->priv->search_entry->window; + g_object_unref (((GdkEventKey *) new_event)->window); + ((GdkEventKey *) new_event)->window = g_object_ref (tree_view->priv->search_window->window); gtk_widget_realize (tree_view->priv->search_window); popup_menu_id = g_signal_connect (tree_view->priv->search_entry, @@ -4453,7 +4495,8 @@ gtk_tree_view_key_press (GtkWidget *widget, /* Send the event to the window. If the preedit_changed signal is emitted * during this event, we will set priv->imcontext_changed */ tree_view->priv->imcontext_changed = FALSE; - retval = gtk_widget_event (tree_view->priv->search_entry, new_event); + retval = gtk_widget_event (tree_view->priv->search_window, new_event); + gdk_event_free (new_event); gtk_widget_hide (tree_view->priv->search_window); g_signal_handler_disconnect (tree_view->priv->search_entry, @@ -5041,6 +5084,11 @@ validate_visible_area (GtkTreeView *tree_view) gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), 0); gtk_tree_view_dy_to_top_row (tree_view); } + else if (tree_view->priv->vadjustment->value + tree_view->priv->vadjustment->page_size > tree_view->priv->height) + { + gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), tree_view->priv->height - tree_view->priv->vadjustment->page_size); + gtk_tree_view_dy_to_top_row (tree_view); + } else gtk_tree_view_top_row_to_dy (tree_view); @@ -5491,7 +5539,7 @@ set_source_row (GdkDragContext *context, GtkTreePath *source_row) { g_object_set_data_full (G_OBJECT (context), - g_intern_static_string ("gtk-tree-view-source-row"), + I_("gtk-tree-view-source-row"), source_row ? gtk_tree_row_reference_new (model, source_row) : NULL, (GDestroyNotify) (source_row ? gtk_tree_row_reference_free : NULL)); } @@ -5539,7 +5587,7 @@ set_dest_row (GdkDragContext *context, if (!dest_row) { - g_object_set_data_full (G_OBJECT (context), g_intern_static_string ("gtk-tree-view-dest-row"), + g_object_set_data_full (G_OBJECT (context), I_("gtk-tree-view-dest-row"), NULL, NULL); return; } @@ -5551,7 +5599,7 @@ set_dest_row (GdkDragContext *context, dr->empty_view_drop = empty_view_drop; dr->drop_append_mode = drop_append_mode; - g_object_set_data_full (G_OBJECT (context), g_intern_static_string ("gtk-tree-view-dest-row"), + g_object_set_data_full (G_OBJECT (context), I_("gtk-tree-view-dest-row"), dr, (GDestroyNotify) dest_row_free); } @@ -5594,7 +5642,7 @@ set_status_pending (GdkDragContext *context, GdkDragAction suggested_action) { g_object_set_data (G_OBJECT (context), - g_intern_static_string ("gtk-tree-view-status-pending"), + I_("gtk-tree-view-status-pending"), GINT_TO_POINTER (suggested_action)); } @@ -5649,7 +5697,7 @@ ensure_info (GtkTreeView *tree_view) di = g_new0 (TreeViewDragInfo, 1); g_object_set_data_full (G_OBJECT (tree_view), - g_intern_static_string ("gtk-tree-view-drag-info"), + I_("gtk-tree-view-drag-info"), di, (GDestroyNotify) destroy_info); } @@ -5660,7 +5708,7 @@ ensure_info (GtkTreeView *tree_view) static void remove_info (GtkTreeView *tree_view) { - g_object_set_data (G_OBJECT (tree_view), g_intern_static_string ("gtk-tree-view-drag-info"), NULL); + g_object_set_data (G_OBJECT (tree_view), I_("gtk-tree-view-drag-info"), NULL); } #if 0 @@ -6156,7 +6204,7 @@ gtk_tree_view_drag_data_get (GtkWidget *widget, goto done; /* If drag_data_get does nothing, try providing row data. */ - if (selection_data->target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)) + if (selection_data->target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW")) { gtk_tree_set_row_drag_data (selection_data, model, @@ -6206,10 +6254,6 @@ gtk_tree_view_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time) { - TreeViewDragInfo *di; - - di = get_info (GTK_TREE_VIEW (widget)); - /* unset any highlight row */ gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), NULL, @@ -6229,7 +6273,6 @@ gtk_tree_view_drag_motion (GtkWidget *widget, { gboolean empty; GtkTreePath *path = NULL; - GtkTreeModel *model; GtkTreeViewDropPosition pos; GtkTreeView *tree_view; GdkDragAction suggested_action = 0; @@ -6243,7 +6286,6 @@ gtk_tree_view_drag_motion (GtkWidget *widget, gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos); /* we only know this *after* set_desination_row */ - model = gtk_tree_view_get_model (tree_view); empty = tree_view->priv->empty_view_drop; if (path == NULL && !empty) @@ -6266,7 +6308,7 @@ gtk_tree_view_drag_motion (GtkWidget *widget, g_timeout_add (150, scroll_row_timeout, tree_view); } - if (target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE)) + if (target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW")) { /* Request data so we can use the source row when * determining whether to accept the drop @@ -6676,7 +6718,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, GtkDirectionType dir) { GtkWidget *focus_child; - GtkContainer *container; GList *last_column, *first_column; GList *tmp_list; @@ -6686,7 +6727,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, return FALSE; focus_child = GTK_CONTAINER (tree_view)->focus_child; - container = GTK_CONTAINER (tree_view); first_column = tree_view->priv->columns; while (first_column) @@ -6815,9 +6855,10 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, { for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) if (GTK_TREE_VIEW_COLUMN (tmp_list->data)->button == focus_child) - break; - - tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (tmp_list->data); + { + tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (tmp_list->data); + break; + } /* If the following isn't true, then the view is smaller then the scrollpane. */ @@ -7000,8 +7041,7 @@ gtk_tree_view_set_adjustments (GtkTreeView *tree_view, if (tree_view->priv->hadjustment != hadj) { tree_view->priv->hadjustment = hadj; - g_object_ref (tree_view->priv->hadjustment); - gtk_object_sink (GTK_OBJECT (tree_view->priv->hadjustment)); + g_object_ref_sink (tree_view->priv->hadjustment); g_signal_connect (tree_view->priv->hadjustment, "value_changed", G_CALLBACK (gtk_tree_view_adjustment_changed), @@ -7012,8 +7052,7 @@ gtk_tree_view_set_adjustments (GtkTreeView *tree_view, if (tree_view->priv->vadjustment != vadj) { tree_view->priv->vadjustment = vadj; - g_object_ref (tree_view->priv->vadjustment); - gtk_object_sink (GTK_OBJECT (tree_view->priv->vadjustment)); + g_object_ref_sink (tree_view->priv->vadjustment); g_signal_connect (tree_view->priv->vadjustment, "value_changed", G_CALLBACK (gtk_tree_view_adjustment_changed), @@ -7205,6 +7244,11 @@ gtk_tree_view_row_changed (GtkTreeModel *model, if (tree == NULL) goto done; + /* Check if the node became insensitive, and if so, unselect it */ + if (!_gtk_tree_selection_row_is_selectable (tree_view->priv->selection, + node, path)) + gtk_tree_selection_unselect_path (tree_view->priv->selection, path); + if (tree_view->priv->fixed_height_mode && tree_view->priv->fixed_height >= 0) { @@ -7688,23 +7732,14 @@ gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view, else x_offset += tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree); } - if (x1) - { - *x1 = x_offset; - } + *x1 = x_offset; + if (tmp_column && tmp_column->visible) - { - /* +1 because x2 isn't included in the range. */ - if (x2) - *x2 = *x1 + tree_view->priv->expander_size + 1; - } + /* +1 because x2 isn't included in the range. */ + *x2 = *x1 + tree_view->priv->expander_size + 1; else - { - /* return an empty range, the expander column is hidden */ - if (x2) - *x2 = *x1; - } + *x2 = *x1; } static void @@ -8046,6 +8081,7 @@ static void gtk_tree_view_add_move_binding (GtkBindingSet *binding_set, guint keyval, guint modmask, + gboolean add_shifted_binding, GtkMovementStep step, gint count) { @@ -8055,10 +8091,11 @@ gtk_tree_view_add_move_binding (GtkBindingSet *binding_set, G_TYPE_ENUM, step, G_TYPE_INT, count); - gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK, - "move_cursor", 2, - G_TYPE_ENUM, step, - G_TYPE_INT, count); + if (add_shifted_binding) + gtk_binding_entry_add_signal (binding_set, keyval, GDK_SHIFT_MASK, + "move_cursor", 2, + G_TYPE_ENUM, step, + G_TYPE_INT, count); if ((modmask & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) return; @@ -8434,6 +8471,7 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view, GtkStateType state; GtkWidget *widget; gint x_offset = 0; + gint x2; gint vertical_separator; gint expander_size; GtkExpanderStyle expander_style; @@ -8448,7 +8486,7 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view, widget = GTK_WIDGET (tree_view); - gtk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, NULL); + gtk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, &x2); area.x = x_offset; area.y = CELL_FIRST_PIXEL (tree_view, tree, node, vertical_separator); @@ -9025,6 +9063,7 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view) return TRUE; } + static gboolean gtk_tree_view_search_entry_flush_timeout (GtkTreeView *tree_view) { @@ -9035,7 +9074,7 @@ gtk_tree_view_search_entry_flush_timeout (GtkTreeView *tree_view) GDK_THREADS_LEAVE (); - return TRUE; + return FALSE; } /* Cut and paste from gtkwindow.c */ @@ -9069,6 +9108,9 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view) { GtkWidget *frame, *vbox, *toplevel; + if (tree_view->priv->search_custom_entry_set) + return; + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tree_view)); if (tree_view->priv->search_window != NULL) @@ -9149,6 +9191,9 @@ gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view, if (!tree_view->priv->enable_search && !keybinding) return FALSE; + if (tree_view->priv->search_custom_entry_set) + return FALSE; + if (tree_view->priv->search_window != NULL && GTK_WIDGET_VISIBLE (tree_view->priv->search_window)) return TRUE; @@ -9183,7 +9228,7 @@ gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view, gtk_entry_set_text (GTK_ENTRY (tree_view->priv->search_entry), ""); /* done, show it */ - tree_view->priv->search_dialog_position_func (tree_view, tree_view->priv->search_window); + tree_view->priv->search_position_func (tree_view, tree_view->priv->search_window, tree_view->priv->search_position_user_data); gtk_widget_show (tree_view->priv->search_window); if (tree_view->priv->search_entry_changed_id == 0) { @@ -9218,6 +9263,7 @@ gtk_tree_view_start_interactive_search (GtkTreeView *tree_view) { return gtk_tree_view_real_start_interactive_search (tree_view, TRUE); } + /* this function returns the new width of the column being resized given * the column and x position of the cursor; the x cursor position is passed * in as a pointer and automagicly corrected if it's beyond min/max limits @@ -9478,15 +9524,7 @@ gtk_tree_view_set_model (GtkTreeView *tree_view, tree_view->priv->model); if (tree_view->priv->tree) - { - _gtk_rbtree_free (tree_view->priv->tree); - tree_view->priv->tree = NULL; - } - - tree_view->priv->prelight_node = NULL; - tree_view->priv->prelight_tree = NULL; - tree_view->priv->button_pressed_node = NULL; - tree_view->priv->button_pressed_tree = NULL; + gtk_tree_view_free_rbtree (tree_view); gtk_tree_row_reference_free (tree_view->priv->drag_dest_row); tree_view->priv->drag_dest_row = NULL; @@ -9515,7 +9553,6 @@ gtk_tree_view_set_model (GtkTreeView *tree_view, tree_view->priv->model = model; - if (tree_view->priv->model) { gint i; @@ -9579,6 +9616,9 @@ gtk_tree_view_set_model (GtkTreeView *tree_view, g_object_notify (G_OBJECT (tree_view), "model"); + if (tree_view->priv->selection) + _gtk_tree_selection_emit_changed (tree_view->priv->selection); + if (GTK_WIDGET_REALIZED (tree_view)) gtk_widget_queue_resize (GTK_WIDGET (tree_view)); } @@ -9809,6 +9849,30 @@ gtk_tree_view_set_headers_clickable (GtkTreeView *tree_view, } +/** + * gtk_tree_view_get_headers_clickable: + * @tree_view: A #GtkTreeView. + * + * Returns whether all header columns are clickable. + * + * Return value: %TRUE if all header columns are clickable, otherwise %FALSE + * + * Since: 2.10 + **/ +gboolean +gtk_tree_view_get_headers_clickable (GtkTreeView *tree_view) +{ + GList *list; + + g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE); + + for (list = tree_view->priv->columns; list; list = list->next) + if (!GTK_TREE_VIEW_COLUMN (list->data)->clickable) + return FALSE; + + return TRUE; +} + /** * gtk_tree_view_set_rules_hint * @tree_view: a #GtkTreeView @@ -9977,8 +10041,7 @@ gtk_tree_view_insert_column (GtkTreeView *tree_view, g_return_val_if_fail (gtk_tree_view_column_get_sizing (column) == GTK_TREE_VIEW_COLUMN_FIXED, -1); - g_object_ref (column); - gtk_object_sink (GTK_OBJECT (column)); + g_object_ref_sink (column); if (tree_view->priv->n_columns == 0 && GTK_WIDGET_REALIZED (tree_view) && @@ -10393,6 +10456,7 @@ gtk_tree_view_scroll_to_cell (GtkTreeView *tree_view, * it is much slower than just going to the point. */ if (! GTK_WIDGET_VISIBLE (tree_view) || + ! GTK_WIDGET_REALIZED (tree_view) || GTK_WIDGET_ALLOC_NEEDED (tree_view) || GTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, GTK_RBNODE_DESCENDANTS_INVALID)) { @@ -10708,6 +10772,11 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view, GtkTreeIter temp; gboolean expand; + if (animate) + g_object_get (gtk_widget_get_settings (GTK_WIDGET (tree_view)), + "gtk-enable-animations", &animate, + NULL); + remove_auto_expand_timeout (tree_view); if (node->children && !open_all) @@ -10851,9 +10920,13 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, gboolean collapse; gint x, y; GList *list; - GdkDisplay *display; GdkWindow *child, *parent; + if (animate) + g_object_get (gtk_widget_get_settings (GTK_WIDGET (tree_view)), + "gtk-enable-animations", &animate, + NULL); + remove_auto_expand_timeout (tree_view); if (node->children == NULL) @@ -10959,6 +11032,14 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, gtk_tree_path_free (lsc); } + if (tree_view->priv->expanded_collapsed_node != NULL) + { + GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED); + GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_COLLAPSED); + + tree_view->priv->expanded_collapsed_node = NULL; + } + if (gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children)) { _gtk_rbtree_remove (node->children); @@ -10973,14 +11054,6 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, tree_view->priv->expand_collapse_timeout = 0; } - if (tree_view->priv->expanded_collapsed_node != NULL) - { - GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED); - GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_COLLAPSED); - - tree_view->priv->expanded_collapsed_node = NULL; - } - if (animate) { tree_view->priv->expand_collapse_timeout = g_timeout_add (50, expand_collapse_timeout, tree_view); @@ -11002,7 +11075,6 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, /* now that we've collapsed all rows, we want to try to set the prelight * again. To do this, we fake a motion event and send it to ourselves. */ - display = gdk_drawable_get_display (tree_view->priv->bin_window); child = tree_view->priv->bin_window; parent = gdk_window_get_parent (child); @@ -11787,6 +11859,8 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view, * Sets @start_path and @end_path to be the first and last visible path. * Note that there may be invisible paths in between. * + * The paths should be freed with gtk_tree_path_free() after use. + * * Returns: %TRUE, if valid paths were placed in @start_path and @end_path. * * Since: 2.8 @@ -12188,8 +12262,8 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, * @tree_view: a #GtkTreeView * @path: a #GtkTreePath in @tree_view * - * Creates a #GdkPixmap representation of the row at @path. This image is used - * for a drag icon. + * Creates a #GdkPixmap representation of the row at @path. + * This image is used for a drag icon. * * Return value: a newly-allocated pixmap of the drag icon. **/ @@ -12212,8 +12286,14 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view, gint bin_window_width; gboolean is_separator = FALSE; + g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); + g_return_val_if_fail (path != NULL, NULL); + widget = GTK_WIDGET (tree_view); + if (!GTK_WIDGET_REALIZED (tree_view)) + return NULL; + depth = gtk_tree_path_get_depth (path); _gtk_tree_view_find_node (tree_view, @@ -12491,6 +12571,146 @@ gtk_tree_view_set_search_equal_func (GtkTreeView *tree_view, tree_view->priv->search_equal_func = gtk_tree_view_search_equal_func; } +/** + * gtk_tree_view_get_search_entry: + * @tree_view: A #GtkTreeView + * + * Returns the GtkEntry which is currently in use as interactive search + * entry for @tree_view. In case the built-in entry is being used, %NULL + * will be returned. + * + * Return value: the entry currently in use as search entry. + * + * Since: 2.10 + */ +GtkEntry * +gtk_tree_view_get_search_entry (GtkTreeView *tree_view) +{ + g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); + + if (tree_view->priv->search_custom_entry_set) + return GTK_ENTRY (tree_view->priv->search_entry); + + return NULL; +} + +/** + * gtk_tree_view_set_search_entry: + * @tree_view: A #GtkTreeView + * @entry: the entry the interactive search code of @tree_view should use or %NULL + * + * Sets the entry which the interactive search code will use for this + * @tree_view. This is useful when you want to provide a search entry + * in our interface at all time at a fixed position. Passing %NULL for + * @entry will make the interactive search code use the built-in popup + * entry again. + * + * Since: 2.10 + */ +void +gtk_tree_view_set_search_entry (GtkTreeView *tree_view, + GtkEntry *entry) +{ + g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + if (entry != NULL) + g_return_if_fail (GTK_IS_ENTRY (entry)); + + if (tree_view->priv->search_custom_entry_set) + { + if (tree_view->priv->search_entry_changed_id) + { + g_signal_handler_disconnect (tree_view->priv->search_entry, + tree_view->priv->search_entry_changed_id); + tree_view->priv->search_entry_changed_id = 0; + } + g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry, + G_CALLBACK (gtk_tree_view_search_key_press_event), + tree_view); + + g_object_unref (tree_view->priv->search_entry); + } + else if (tree_view->priv->search_window) + { + gtk_widget_destroy (tree_view->priv->search_window); + + tree_view->priv->search_window = NULL; + } + + if (entry) + { + tree_view->priv->search_entry = g_object_ref (entry); + tree_view->priv->search_custom_entry_set = TRUE; + + if (tree_view->priv->search_entry_changed_id == 0) + { + tree_view->priv->search_entry_changed_id = + g_signal_connect (tree_view->priv->search_entry, "changed", + G_CALLBACK (gtk_tree_view_search_init), + tree_view); + } + + g_signal_connect (tree_view->priv->search_entry, "key_press_event", + G_CALLBACK (gtk_tree_view_search_key_press_event), + tree_view); + + gtk_tree_view_search_init (tree_view->priv->search_entry, tree_view); + } + else + { + tree_view->priv->search_entry = NULL; + tree_view->priv->search_custom_entry_set = FALSE; + } +} + +/** + * gtk_tree_view_set_search_position_func: + * @tree_view: A #GtkTreeView + * @func: the function to use to position the search dialog + * @data: user data to pass to @func, or %NULL + * @destroy: Destroy notifier for @data, or %NULL + * + * Sets the function to use when positioning the seach dialog. + * + * Since: 2.10 + **/ +void +gtk_tree_view_set_search_position_func (GtkTreeView *tree_view, + GtkTreeViewSearchPositionFunc func, + gpointer user_data, + GDestroyNotify destroy) +{ + g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + g_return_if_fail (func !=NULL); + + if (tree_view->priv->search_position_destroy) + (* tree_view->priv->search_position_destroy) (tree_view->priv->search_position_user_data); + + tree_view->priv->search_position_func = func; + tree_view->priv->search_position_user_data = user_data; + tree_view->priv->search_position_destroy = destroy; + if (tree_view->priv->search_position_func == NULL) + tree_view->priv->search_position_func = gtk_tree_view_search_position_func; +} + +/** + * gtk_tree_view_get_search_position_func: + * @tree_view: A #GtkTreeView + * + * Returns the positioning function currently in use. + * + * Return value: the currently used function for positioning the search dialog. + * + * Since: 2.10 + */ +GtkTreeViewSearchPositionFunc +gtk_tree_view_get_search_position_func (GtkTreeView *tree_view) +{ + g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); + + return tree_view->priv->search_position_func; +} + + static void gtk_tree_view_search_dialog_hide (GtkWidget *search_dialog, GtkTreeView *tree_view) @@ -12518,7 +12738,8 @@ gtk_tree_view_search_dialog_hide (GtkWidget *search_dialog, static void gtk_tree_view_search_position_func (GtkTreeView *tree_view, - GtkWidget *search_dialog) + GtkWidget *search_dialog, + gpointer user_data) { gint x, y; gint tree_x, tree_y; @@ -12540,14 +12761,14 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view, &tree_height); gtk_widget_size_request (search_dialog, &requisition); - if (tree_x + tree_width - requisition.width > gdk_screen_get_width (screen)) + if (tree_x + tree_width > gdk_screen_get_width (screen)) x = gdk_screen_get_width (screen) - requisition.width; else if (tree_x + tree_width - requisition.width < 0) x = 0; else x = tree_x + tree_width - requisition.width; - if (tree_y + tree_height > gdk_screen_get_height (screen)) + if (tree_y + tree_height + requisition.height > gdk_screen_get_height (screen)) y = gdk_screen_get_height (screen) - requisition.height; else if (tree_y + tree_height < 0) /* isn't really possible ... */ y = 0; @@ -12694,8 +12915,11 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget, g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE); /* close window and cancel the search */ - if (event->keyval == GDK_Escape || - event->keyval == GDK_Tab) + if (!tree_view->priv->search_custom_entry_set + && (event->keyval == GDK_Escape || + event->keyval == GDK_Tab || + event->keyval == GDK_KP_Tab || + event->keyval == GDK_ISO_Left_Tab)) { gtk_tree_view_search_dialog_hide (widget, tree_view); return TRUE; @@ -12708,6 +12932,13 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget, retval = TRUE; } + if (((event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) + && (event->keyval == GDK_g || event->keyval == GDK_G)) + { + gtk_tree_view_search_move (widget, tree_view, TRUE); + retval = TRUE; + } + /* select next matching iter */ if (event->keyval == GDK_Down || event->keyval == GDK_KP_Down) { @@ -12715,7 +12946,7 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget, retval = TRUE; } - if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK + if (((event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == GDK_CONTROL_MASK) && (event->keyval == GDK_g || event->keyval == GDK_G)) { gtk_tree_view_search_move (widget, tree_view, FALSE); @@ -12723,7 +12954,8 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget, } /* renew the flush timeout */ - if (retval && tree_view->priv->typeselect_flush_timeout) + if (retval && tree_view->priv->typeselect_flush_timeout + && !tree_view->priv->search_custom_entry_set) { g_source_remove (tree_view->priv->typeselect_flush_timeout); tree_view->priv->typeselect_flush_timeout = @@ -12973,7 +13205,8 @@ gtk_tree_view_search_init (GtkWidget *entry, /* search */ gtk_tree_selection_unselect_all (selection); - if (tree_view->priv->typeselect_flush_timeout) + if (tree_view->priv->typeselect_flush_timeout + && tree_view->priv->search_custom_entry_set) { g_source_remove (tree_view->priv->typeselect_flush_timeout); tree_view->priv->typeselect_flush_timeout =