diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtktreemodel.c | 35 | ||||
-rw-r--r-- | gtk/gtktreemodel.h | 2 | ||||
-rw-r--r-- | gtk/gtktreemodelsort.c | 22 | ||||
-rw-r--r-- | gtk/gtktreeview.c | 116 |
4 files changed, 106 insertions, 69 deletions
diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c index 3d854d1708..ed34611314 100644 --- a/gtk/gtktreemodel.c +++ b/gtk/gtktreemodel.c @@ -1443,6 +1443,14 @@ gtk_tree_row_reference_new_proxy (GObject *proxy, return reference; } +/** + * gtk_tree_row_reference_get_path: + * @reference: A #GtkTreeRowReference + * + * Returns a path that the row reference currently points to, or NULL if + * + * Return value: A current path, or NULL. + **/ GtkTreePath * gtk_tree_row_reference_get_path (GtkTreeRowReference *reference) { @@ -1457,12 +1465,37 @@ gtk_tree_row_reference_get_path (GtkTreeRowReference *reference) return gtk_tree_path_copy (reference->path); } +/** + * gtk_tree_row_reference_valid: + * @reference: A #GtkTreeRowReference, or NULL + * + * Returns TRUE if the %reference is non-NULL and refers to a current valid + * path. + * + * Return value: TRUE if %reference points to a valid path. + **/ +gboolean +gtk_tree_row_reference_valid (GtkTreeRowReference *reference) +{ + if (reference == NULL || reference->path == NULL) + return FALSE; + + return TRUE; +} + +/** + * gtk_tree_row_reference_free: + * @reference: A #GtkTreeRowReference, or NULL + * + * Free's %reference. %reference may be NULL. + **/ void gtk_tree_row_reference_free (GtkTreeRowReference *reference) { RowRefList *refs; - g_return_if_fail (reference != NULL); + if (reference == NULL) + return; refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING); diff --git a/gtk/gtktreemodel.h b/gtk/gtktreemodel.h index dd7554a163..37555fb3c5 100644 --- a/gtk/gtktreemodel.h +++ b/gtk/gtktreemodel.h @@ -149,8 +149,8 @@ GtkTreeRowReference *gtk_tree_row_reference_new_proxy (GObject *prox GtkTreeModel *model, GtkTreePath *path); GtkTreePath *gtk_tree_row_reference_get_path (GtkTreeRowReference *reference); +gboolean gtk_tree_row_reference_valid (GtkTreeRowReference *reference); void gtk_tree_row_reference_free (GtkTreeRowReference *reference); - /* These two functions are only needed if you created the row reference with a * proxy object */ void gtk_tree_row_reference_inserted (GObject *proxy, diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c index cdc81a27e7..d331a9e852 100644 --- a/gtk/gtktreemodelsort.c +++ b/gtk/gtktreemodelsort.c @@ -247,7 +247,7 @@ gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model) * gtk_tree_model_sort_set_model: * @tree_model_sort: The #GtkTreeModelSort. * @child_model: A #GtkTreeModel, or NULL. - * + * * Sets the model of @tree_model_sort to be @model. If @model is NULL, then the * old model is unset. **/ @@ -299,13 +299,13 @@ gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort, G_CALLBACK (gtk_tree_model_sort_range_changed), tree_model_sort, FALSE); - tree_model_sort->inserted_id = + tree_model_sort->inserted_id = g_signal_connectc (child_model, "inserted", G_CALLBACK (gtk_tree_model_sort_inserted), tree_model_sort, FALSE); - tree_model_sort->has_child_toggled_id = + tree_model_sort->has_child_toggled_id = g_signal_connectc (child_model, "has_child_toggled", G_CALLBACK (gtk_tree_model_sort_has_child_toggled), @@ -331,9 +331,9 @@ gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort, /** * gtk_tree_model_sort_get_model: * @tree_model: a #GtkTreeModelSort - * + * * Returns the model the #GtkTreeModelSort is sorting. - * + * * Return value: the "child model" being sorted **/ GtkTreeModel* @@ -348,11 +348,11 @@ gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model) * gtk_tree_model_sort_convert_path: * @tree_model_sort: The #GtkTreeModelSort. * @child_path: A #GtkTreePath, relative to the child model. - * + * * Converts the @child_path to a new path, relative to the sorted position. In other * words, the value found in the @tree_model_sort ->child_model at the @child_path, is * identical to that found in the @tree_model_sort and the return value. - * + * * Return value: A new path, or NULL if @child_path does not exist in @tree_model_sort * ->child_model. **/ @@ -427,7 +427,7 @@ gtk_tree_model_sort_range_changed (GtkTreeModel *s_model, * sorting is changed, we can check the prev and next element to see if * they're different. */ - + /* Now we need to resort things. */ index = gtk_tree_model_sort_array_find_insert (tree_model_sort, array, @@ -913,7 +913,7 @@ gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model, GtkTreeIter *iter) { - + } static gboolean @@ -1123,7 +1123,7 @@ gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort, return retval; } - + static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortElt *place) @@ -1138,7 +1138,7 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, if (place) parent_iter = & (place->iter); - + n = gtk_tree_model_iter_n_children (tree_model_sort->child_model, parent_iter); if (n == 0) diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 6284e9106a..008e7ce5b7 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -266,8 +266,8 @@ static void gtk_tree_view_add_move_binding (GtkBindingSet *binding_se guint modmask, GtkMovementStep step, gint count); -static void gtk_tree_view_unref_tree (GtkTreeView *tree_view, - GtkRBTree *tree); +static gint gtk_tree_view_unref_and_check_selection_tree (GtkTreeView *tree_view, + GtkRBTree *tree); static void gtk_tree_view_queue_draw_node (GtkTreeView *tree_view, GtkRBTree *tree, GtkRBNode *node, @@ -950,7 +950,7 @@ gtk_tree_view_destroy (GtkObject *object) if (tree_view->priv->tree != NULL) { - gtk_tree_view_unref_tree (tree_view, tree_view->priv->tree); + 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; } @@ -976,12 +976,6 @@ gtk_tree_view_destroy (GtkObject *object) tree_view->priv->selection = NULL; } - if (tree_view->priv->anchor != NULL) - { - gtk_tree_row_reference_free (tree_view->priv->anchor); - tree_view->priv->anchor = NULL; - } - if (tree_view->priv->scroll_to_path != NULL) { gtk_tree_path_free (tree_view->priv->scroll_to_path); @@ -994,12 +988,7 @@ gtk_tree_view_destroy (GtkObject *object) tree_view->priv->drag_dest_row = NULL; } - if (tree_view->priv->cursor) - { - gtk_tree_row_reference_free (tree_view->priv->cursor); - tree_view->priv->cursor = NULL; - } - + if (tree_view->priv->column_drop_func_data && tree_view->priv->column_drop_func_data_destroy) { @@ -1007,6 +996,12 @@ gtk_tree_view_destroy (GtkObject *object) tree_view->priv->column_drop_func_data = NULL; } + gtk_tree_row_reference_free (tree_view->priv->cursor); + tree_view->priv->cursor = NULL; + + gtk_tree_row_reference_free (tree_view->priv->anchor); + tree_view->priv->anchor = NULL; + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -1845,6 +1840,7 @@ static void ensure_unprelighted (GtkTreeView *tree_view) { do_unprelight (tree_view, -1000, -1000); /* coords not possibly over an arrow */ + g_assert (tree_view->priv->prelight_node == NULL); } @@ -2315,12 +2311,10 @@ gtk_tree_view_draw_focus (GtkWidget *widget) if (! GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS)) return; - if (tree_view->priv->cursor == NULL) + if (! gtk_tree_row_reference_valid (tree_view->priv->cursor)) return; cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor); - if (cursor_path == NULL) - return; _gtk_tree_view_find_node (tree_view, cursor_path, &tree, &node); @@ -4441,30 +4435,9 @@ gtk_tree_view_deleted (GtkTreeModel *model, gtk_tree_row_reference_deleted (G_OBJECT (data), path); - /* next, update the selection */ - if (tree_view->priv->anchor) - { - GtkTreePath *anchor_path; - - /* the row reference may not have been updated yet. If it has not, - * then anchor_path and path being equal indicates that the anchor - * row was deleted. If it has, then anchor_path == NULL indicates the - * the anchor row was deleted. - */ - - anchor_path = gtk_tree_row_reference_get_path (tree_view->priv->anchor); - - if (anchor_path == NULL || - gtk_tree_path_compare (path, anchor_path) == 0) - { - if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) && - tree_view->priv->selection) - g_signal_emit_by_name (G_OBJECT (tree_view->priv->selection), "changed"); - } - - if (anchor_path) - gtk_tree_path_free (anchor_path); - } + /* Change the selection */ + if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED)) + g_signal_emit_by_name (G_OBJECT (tree_view->priv->selection), "changed"); for (list = tree_view->priv->columns; list; list = list->next) if (((GtkTreeViewColumn *)list->data)->visible && @@ -4474,8 +4447,6 @@ gtk_tree_view_deleted (GtkTreeModel *model, /* Ensure we don't have a dangling pointer to a dead node */ ensure_unprelighted (tree_view); - g_assert (tree_view->priv->prelight_node == NULL); - if (tree->root->count == 1) { if (tree_view->priv->tree == tree) @@ -5207,15 +5178,16 @@ gtk_tree_view_add_move_binding (GtkBindingSet *binding_set, GTK_TYPE_INT, count); } -static void +static gint gtk_tree_view_unref_tree_helper (GtkTreeModel *model, GtkTreeIter *iter, GtkRBTree *tree, GtkRBNode *node) { + gint retval = FALSE; do { - g_return_if_fail (node != NULL); + g_return_val_if_fail (node != NULL, FALSE); if (node->children) { @@ -5229,34 +5201,41 @@ gtk_tree_view_unref_tree_helper (GtkTreeModel *model, while (new_node && new_node->left != new_tree->nil) new_node = new_node->left; - g_return_if_fail (gtk_tree_model_iter_children (model, &child, iter)); - gtk_tree_view_unref_tree_helper (model, &child, new_tree, new_node); + g_return_val_if_fail (gtk_tree_model_iter_children (model, &child, iter), FALSE); + retval = retval || gtk_tree_view_unref_tree_helper (model, &child, new_tree, new_node); } + if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED)) + retval = TRUE; gtk_tree_model_unref_node (model, iter); node = _gtk_rbtree_next (tree, node); } while (gtk_tree_model_iter_next (model, iter)); + + return retval; } -static void -gtk_tree_view_unref_tree (GtkTreeView *tree_view, - GtkRBTree *tree) +static gint +gtk_tree_view_unref_and_check_selection_tree (GtkTreeView *tree_view, + GtkRBTree *tree) { GtkTreeIter iter; GtkTreePath *path; GtkRBNode *node; + gint retval; node = tree->root; while (node && node->left != tree->nil) node = node->left; - g_return_if_fail (node != NULL); + g_return_val_if_fail (node != NULL, FALSE); path = _gtk_tree_view_find_path (tree_view, tree, node); gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->priv->model), &iter, path); - gtk_tree_view_unref_tree_helper (GTK_TREE_MODEL (tree_view->priv->model), &iter, tree, node); + retval = gtk_tree_view_unref_tree_helper (GTK_TREE_MODEL (tree_view->priv->model), &iter, tree, node); gtk_tree_path_free (path); + + return retval; } static void @@ -7157,9 +7136,8 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, /* Ensure we don't have a dangling pointer to a dead node */ ensure_unprelighted (tree_view); - g_assert (tree_view->priv->prelight_node == NULL); - - gtk_tree_view_unref_tree (tree_view, node->children); + if (gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children)) + g_signal_emit_by_name (G_OBJECT (tree_view->priv->selection), "changed", 0); _gtk_rbtree_remove (node->children); if (GTK_WIDGET_MAPPED (tree_view)) @@ -7168,6 +7146,32 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, _gtk_tree_view_update_size (tree_view); } + if (gtk_tree_row_reference_valid (tree_view->priv->cursor)) + { + GtkTreePath *cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor); + + if (gtk_tree_path_is_ancestor (path, cursor_path)) + { + gtk_tree_row_reference_free (tree_view->priv->cursor); + tree_view->priv->cursor = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), + tree_view->priv->model, + path); + } + gtk_tree_path_free (cursor_path); + } + + if (gtk_tree_row_reference_valid (tree_view->priv->anchor)) + { + GtkTreePath *anchor_path = gtk_tree_row_reference_get_path (tree_view->priv->anchor); + if (gtk_tree_path_is_ancestor (path, anchor_path)) + { + gtk_tree_row_reference_free (tree_view->priv->anchor); + tree_view->priv->anchor = NULL; + } + gtk_tree_path_free (anchor_path); + + } + g_signal_emit (G_OBJECT (tree_view), tree_view_signals[ROW_COLLAPSED], 0, &iter, path); return TRUE; |