diff options
author | John Harper <jsh@eazel.com> | 2001-02-22 00:44:08 +0000 |
---|---|---|
committer | John Harper <jsh@src.gnome.org> | 2001-02-22 00:44:08 +0000 |
commit | 7e85ae9d5c9f14e66ed6163a7ab8df0d4d3d81de (patch) | |
tree | 1748722490630a98726c786205700724aad6a6b7 /components | |
parent | 26d0560700fe7f7eb4d16b392d41c669a1ea109b (diff) | |
download | nautilus-7e85ae9d5c9f14e66ed6163a7ab8df0d4d3d81de.tar.gz |
reviewed by: Darin Adler <darin@eazel.com>
2001-02-21 John Harper <jsh@eazel.com>
reviewed by: Darin Adler <darin@eazel.com>
Fixed bug 6828 (Moving directories in tree view makes contents
become top-level nodes):
* components/tree/nautilus-tree-node.h,
components/tree/nautilus-tree-node.c,
components/tree/nautilus-tree-node-private.h
(nautilus_tree_node_update_uri): new private function, updates
the node's cached URI from its NautilusFile and updates the new
is_toplevel flag
(nautilus_tree_node_is_toplevel): new function, returns true if
the node shouldn't have a parent node
* components/tree/nautilus-tree-model.c: track nodes that have
no parent but aren't top-level nodes. If suitable parents later
appear the unparented nodes will be connected to them
* components/tree/nautilus-tree-view.c,
components/tree/nautilus-tree-view-private.h: do similar
tracking of unparented nodes (but from the point of view of the
view, not the model)
[ Having both modules duplicate this similar functionality
isn't ideal, but I don't see how to unify it ]
Fixed bug 6820 (directory sort order is different in tree
view):
* components/tree/nautilus-tree-view.c (ctree_compare_rows):
new function, set as the comparison function for tree views.
It calls nautilus_file_compare_for_sort () on the files
associated with the tree rows (with hardcoded type
NAUTILUS_FILE_SORT_BY_NAME for now)
* libnautilus-extensions/nautilus-ctree.c
(nautilus_ctree_insert_node): for sorted insertions, link the
inserted node into the tree before finding the correct place,
then move it afterwards. This ensures that the comparison
function is able to find the node pointers from the row
pointers that it's given
Diffstat (limited to 'components')
-rw-r--r-- | components/tree/nautilus-tree-model.c | 65 | ||||
-rw-r--r-- | components/tree/nautilus-tree-node-private.h | 4 | ||||
-rw-r--r-- | components/tree/nautilus-tree-node.c | 23 | ||||
-rw-r--r-- | components/tree/nautilus-tree-node.h | 1 | ||||
-rw-r--r-- | components/tree/nautilus-tree-view-private.h | 2 | ||||
-rw-r--r-- | components/tree/nautilus-tree-view.c | 204 |
6 files changed, 236 insertions, 63 deletions
diff --git a/components/tree/nautilus-tree-model.c b/components/tree/nautilus-tree-model.c index 7acbb5f5a..487764f5a 100644 --- a/components/tree/nautilus-tree-model.c +++ b/components/tree/nautilus-tree-model.c @@ -50,6 +50,7 @@ struct NautilusTreeModelDetails { GHashTable *file_to_node_map; GList *monitor_clients; + GList *unparented_nodes; NautilusTreeNode *root_node; gboolean root_node_reported; @@ -629,6 +630,54 @@ report_root_node_if_possible (NautilusTreeModel *model) } } +static void +register_unparented_node (NautilusTreeModel *model, NautilusTreeNode *node) +{ + if (!nautilus_tree_node_is_toplevel (node) && g_list_find (model->details->unparented_nodes, node) == NULL) { + model->details->unparented_nodes = g_list_prepend (model->details->unparented_nodes, node); + } +} + +static void +forget_unparented_node (NautilusTreeModel *model, NautilusTreeNode *node) +{ + model->details->unparented_nodes = g_list_remove (model->details->unparented_nodes, node); +} + +static void +connect_unparented_nodes (NautilusTreeModel *model, NautilusTreeNode *parent) +{ + NautilusDirectory *parent_directory; + char *parent_uri; + NautilusTreeNode *node; + GList *p, *to_parent; + + parent_uri = nautilus_file_get_uri (parent->details->file); + parent_directory = nautilus_directory_get (parent_uri); + g_free (parent_uri); + + if (parent_directory != NULL) { + to_parent = NULL; + + for (p = model->details->unparented_nodes; p != NULL; p = p->next) { + node = p->data; + if (nautilus_directory_contains_file (parent_directory, node->details->file)) { + to_parent = g_list_prepend (to_parent, node); + } + } + + for (p = to_parent; p != NULL; p = p->next) { + node = p->data; + nautilus_tree_node_set_parent (node, parent); + model->details->unparented_nodes = g_list_remove (model->details->unparented_nodes, node); + } + + g_list_free (to_parent); + + nautilus_directory_unref (parent_directory); + } +} + static void report_node_changed (NautilusTreeModel *model, @@ -672,6 +721,8 @@ report_node_changed (NautilusTreeModel *model, if (parent_node != NULL) { nautilus_tree_node_set_parent (node, parent_node); + } else { + register_unparented_node (model, node); } g_free (parent_uri); @@ -685,6 +736,9 @@ report_node_changed (NautilusTreeModel *model, gtk_signal_emit (GTK_OBJECT (model), signals[NODE_ADDED], node); + + connect_unparented_nodes (model, node); + } else { /* really changed */ @@ -695,7 +749,6 @@ report_node_changed (NautilusTreeModel *model, gtk_signal_emit (GTK_OBJECT (model), signals[NODE_CHANGED], node); - g_free (file_uri); } else { /* A move or rename - model it as a remove followed by an add */ @@ -712,8 +765,7 @@ report_node_changed (NautilusTreeModel *model, report_node_removed (model, node); - g_free (node->details->uri); - node->details->uri = file_uri; + nautilus_tree_node_update_uri (node); #if 0 if (node->details->directory != NULL) { @@ -730,6 +782,8 @@ report_node_changed (NautilusTreeModel *model, gtk_object_unref (GTK_OBJECT (node)); } + + g_free (file_uri); } g_free (node_uri); @@ -741,6 +795,7 @@ report_node_removed_internal (NautilusTreeModel *model, gboolean signal) { NautilusTreeNode *parent_node; + GList *p; if (node == NULL) { return; @@ -755,11 +810,15 @@ report_node_removed_internal (NautilusTreeModel *model, nautilus_tree_node_remove_from_parent (node); } + for (p = node->details->children; p != NULL; p = p->next) { + register_unparented_node (model, p->data); + } nautilus_tree_node_remove_children (node); g_hash_table_remove (model->details->file_to_node_map, nautilus_tree_node_get_file (node)); + forget_unparented_node (model, node); if (signal) { gtk_signal_emit (GTK_OBJECT (model), diff --git a/components/tree/nautilus-tree-node-private.h b/components/tree/nautilus-tree-node-private.h index 4f73c818a..38650cfac 100644 --- a/components/tree/nautilus-tree-node-private.h +++ b/components/tree/nautilus-tree-node-private.h @@ -44,10 +44,14 @@ struct NautilusTreeNodeDetails { NautilusTreeNode *parent; GList *children; + + gboolean is_toplevel; }; NautilusTreeNode *nautilus_tree_node_new (NautilusFile *file); +void nautilus_tree_node_update_uri (NautilusTreeNode *node); + void nautilus_tree_node_set_parent (NautilusTreeNode *node, NautilusTreeNode *parent); diff --git a/components/tree/nautilus-tree-node.c b/components/tree/nautilus-tree-node.c index dfe0ff11e..32f1b0863 100644 --- a/components/tree/nautilus-tree-node.c +++ b/components/tree/nautilus-tree-node.c @@ -93,7 +93,7 @@ nautilus_tree_node_new (NautilusFile *file) gtk_object_sink (GTK_OBJECT (node)); node->details->file = nautilus_file_ref (file); - node->details->uri = nautilus_file_get_uri (file); + nautilus_tree_node_update_uri (node); return node; } @@ -124,6 +124,21 @@ nautilus_tree_node_get_uri (NautilusTreeNode *node) return g_strdup (node->details->uri); } +void +nautilus_tree_node_update_uri (NautilusTreeNode *node) +{ + char *uri, *parent_uri; + + uri = nautilus_file_get_uri (node->details->file); + + g_free (node->details->uri); + node->details->uri = uri; + + parent_uri = nautilus_file_get_parent_uri (node->details->file); + node->details->is_toplevel = (parent_uri == NULL || *parent_uri == '\0'); + g_free (parent_uri); +} + NautilusDirectory * nautilus_tree_node_get_directory (NautilusTreeNode *node) @@ -141,6 +156,12 @@ nautilus_tree_node_set_parent (NautilusTreeNode *node, parent->details->children = g_list_append (parent->details->children, node); } +gboolean +nautilus_tree_node_is_toplevel (NautilusTreeNode *node) +{ + return node->details->is_toplevel; +} + void nautilus_tree_node_remove_from_parent (NautilusTreeNode *node) diff --git a/components/tree/nautilus-tree-node.h b/components/tree/nautilus-tree-node.h index b095bfbf0..a938f8a5d 100644 --- a/components/tree/nautilus-tree-node.h +++ b/components/tree/nautilus-tree-node.h @@ -59,6 +59,7 @@ GList *nautilus_tree_node_get_children (NautilusTreeNode *node); NautilusFile *nautilus_tree_node_get_file (NautilusTreeNode *node); char *nautilus_tree_node_get_uri (NautilusTreeNode *node); NautilusDirectory *nautilus_tree_node_get_directory (NautilusTreeNode *node); +gboolean nautilus_tree_node_is_toplevel (NautilusTreeNode *node); #endif /* NAUTILUS_TREE_NODE_H */ diff --git a/components/tree/nautilus-tree-view-private.h b/components/tree/nautilus-tree-view-private.h index 34489d4e8..a7c6b7e73 100644 --- a/components/tree/nautilus-tree-view-private.h +++ b/components/tree/nautilus-tree-view-private.h @@ -65,6 +65,8 @@ struct NautilusTreeViewDetails { NautilusTreeChangeQueue *change_queue; guint pending_idle_id; + GList *unparented_tree_nodes; + TreeViewCallback root_seen_callback; char *wait_uri; NautilusTreeNode *wait_node; diff --git a/components/tree/nautilus-tree-view.c b/components/tree/nautilus-tree-view.c index c8c1d2999..5addab5f8 100644 --- a/components/tree/nautilus-tree-view.c +++ b/components/tree/nautilus-tree-view.c @@ -108,6 +108,12 @@ static void nautilus_tree_view_initialize_class (NautilusTreeViewClass *klass); static void nautilus_tree_view_initialize (NautilusTreeView *view); static void nautilus_tree_view_destroy (GtkObject *object); +static void register_unparented_node (NautilusTreeView *view, + NautilusTreeNode *node); +static void forget_unparented_node (NautilusTreeView *view, + NautilusTreeNode *node); +static void insert_unparented_nodes (NautilusTreeView *view, + NautilusTreeNode *node); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusTreeView, nautilus_tree_view, GTK_TYPE_SCROLLED_WINDOW) @@ -249,73 +255,78 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * #endif - text[0] = nautilus_file_get_name (file); - text[1] = NULL; - - if (nautilus_tree_view_model_node_to_view_node (view, node) == NULL) { - nautilus_icon_factory_get_pixmap_and_mask_for_file (file, - NULL, - NAUTILUS_ICON_SIZE_FOR_MENUS, - &closed_pixmap, - &closed_mask); - - nautilus_icon_factory_get_pixmap_and_mask_for_file (file, - "accept", - NAUTILUS_ICON_SIZE_FOR_MENUS, - &open_pixmap, - &open_mask); - - - view_node = nautilus_ctree_insert_node (NAUTILUS_CTREE (view->details->tree), - parent_view_node, - NULL, - text, - TREE_SPACING, - closed_pixmap, closed_mask, open_pixmap, open_mask, - ! nautilus_file_is_directory (file), - FALSE); - gdk_pixmap_unref (closed_pixmap); - gdk_pixmap_unref (open_pixmap); - if (closed_mask != NULL) { - gdk_bitmap_unref (closed_mask); - } - if (open_mask != NULL) { - gdk_bitmap_unref (open_mask); - } + if (parent_view_node == NULL && !nautilus_tree_node_is_toplevel (node)) { + register_unparented_node (view, node); + } else { + text[0] = nautilus_file_get_name (file); + text[1] = NULL; + + if (nautilus_tree_view_model_node_to_view_node (view, node) == NULL) { + nautilus_icon_factory_get_pixmap_and_mask_for_file (file, + NULL, + NAUTILUS_ICON_SIZE_FOR_MENUS, + &closed_pixmap, + &closed_mask); + + nautilus_icon_factory_get_pixmap_and_mask_for_file (file, + "accept", + NAUTILUS_ICON_SIZE_FOR_MENUS, + &open_pixmap, + &open_mask); + + + view_node = nautilus_ctree_insert_node (NAUTILUS_CTREE (view->details->tree), + parent_view_node, + NULL, + text, + TREE_SPACING, + closed_pixmap, closed_mask, open_pixmap, open_mask, + ! nautilus_file_is_directory (file), + FALSE); + gdk_pixmap_unref (closed_pixmap); + gdk_pixmap_unref (open_pixmap); + if (closed_mask != NULL) { + gdk_bitmap_unref (closed_mask); + } + if (open_mask != NULL) { + gdk_bitmap_unref (open_mask); + } - nautilus_ctree_node_set_row_data (NAUTILUS_CTREE (view->details->tree), - view_node, - node); + nautilus_ctree_node_set_row_data (NAUTILUS_CTREE (view->details->tree), + view_node, + node); - g_assert (g_hash_table_lookup (view->details->file_to_node_map, file) == NULL); + g_assert (g_hash_table_lookup (view->details->file_to_node_map, file) == NULL); - nautilus_file_ref (file); - g_hash_table_insert (view->details->file_to_node_map, file, view_node); + nautilus_file_ref (file); + g_hash_table_insert (view->details->file_to_node_map, file, view_node); - uri = nautilus_file_get_uri (file); - link_view_node_with_uri (view, view_node, uri); - - if (nautilus_file_is_directory (nautilus_tree_node_get_file (node))) { - if (nautilus_tree_expansion_state_is_node_expanded (view->details->expansion_state, uri)) { - if (!ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), - view_node)) { - nautilus_ctree_expand (NAUTILUS_CTREE (view->details->tree), - view_node); - } - } else { - if (ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), - view_node)) { - nautilus_ctree_collapse (NAUTILUS_CTREE (view->details->tree), - view_node); + uri = nautilus_file_get_uri (file); + link_view_node_with_uri (view, view_node, uri); + + if (nautilus_file_is_directory (nautilus_tree_node_get_file (node))) { + if (nautilus_tree_expansion_state_is_node_expanded (view->details->expansion_state, uri)) { + if (!ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + view_node)) { + nautilus_ctree_expand (NAUTILUS_CTREE (view->details->tree), + view_node); + } + } else { + if (ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + view_node)) { + nautilus_ctree_collapse (NAUTILUS_CTREE (view->details->tree), + view_node); + } } } - } - } else { - nautilus_tree_view_update_model_node (view, node); - } - g_free (text[0]); + insert_unparented_nodes (view, node); + } else { + nautilus_tree_view_update_model_node (view, node); + } + g_free (text[0]); + } notify_node_seen (view, node); } @@ -327,6 +338,8 @@ forget_view_node (NautilusTreeView *view, file = nautilus_tree_view_node_to_file (view, view_node); + forget_unparented_node (view, nautilus_tree_view_node_to_model_node (view, view_node)); + g_hash_table_remove (view->details->file_to_node_map, file); nautilus_file_unref (file); @@ -490,11 +503,61 @@ nautilus_tree_view_update_model_node (NautilusTreeView *view, NautilusTreeNode * g_free (uri); } + + insert_unparented_nodes (view, node); } else { nautilus_tree_view_insert_model_node (view, node); } } +static void +register_unparented_node (NautilusTreeView *view, NautilusTreeNode *node) +{ + g_return_if_fail (!nautilus_tree_node_is_toplevel (node)); + + if (g_list_find (view->details->unparented_tree_nodes, node) == NULL) { + view->details->unparented_tree_nodes = g_list_prepend (view->details->unparented_tree_nodes, node); + } +} + +static void +forget_unparented_node (NautilusTreeView *view, NautilusTreeNode *node) +{ + view->details->unparented_tree_nodes = g_list_remove (view->details->unparented_tree_nodes, node); +} + +static void +insert_unparented_nodes (NautilusTreeView *view, NautilusTreeNode *node) +{ + NautilusFile *file, *sub_file; + NautilusDirectory *directory; + GList *p, *to_add; + NautilusTreeNode *sub_node; + + file = nautilus_tree_node_get_file (node); + + if (nautilus_file_is_directory (file)) { + directory = nautilus_tree_node_get_directory (node); + if (directory != NULL) { + to_add = NULL; + for (p = view->details->unparented_tree_nodes; p != NULL; p = p->next) { + sub_node = p->data; + sub_file = nautilus_tree_node_get_file (sub_node); + if (nautilus_directory_contains_file (directory, sub_file)) { + to_add = g_list_prepend (to_add, sub_node); + } + } + for (p = to_add; p != NULL; p = p->next) { + sub_node = p->data; + view->details->unparented_tree_nodes = g_list_remove (view->details->unparented_tree_nodes, sub_node); + nautilus_tree_view_insert_model_node (view, sub_node); + + } + g_list_free (to_add); + } + } +} + static void notify_done_loading (NautilusTreeView *view, @@ -749,6 +812,27 @@ filtering_changed_callback (gpointer callback_data) } +static gint +ctree_compare_rows (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2) +{ + NautilusTreeView *view; + NautilusFile *file1, *file2; + + view = gtk_object_get_data (GTK_OBJECT (clist), "tree_view"); + g_assert (view != NULL); + + file1 = nautilus_tree_view_node_to_file (view, nautilus_ctree_find_node_ptr (NAUTILUS_CTREE (view->details->tree), (NautilusCTreeRow *) ptr1)); + file2 = nautilus_tree_view_node_to_file (view, nautilus_ctree_find_node_ptr (NAUTILUS_CTREE (view->details->tree), (NautilusCTreeRow *) ptr2)); + + if (file1 == NULL || file2 == NULL) { + return 0; + } + + return nautilus_file_compare_for_sort (file1, file2, NAUTILUS_FILE_SORT_BY_NAME); +} + static void nautilus_tree_view_initialize (NautilusTreeView *view) { @@ -778,6 +862,8 @@ nautilus_tree_view_initialize (NautilusTreeView *view) gtk_clist_set_selection_mode (GTK_CLIST (view->details->tree), GTK_SELECTION_SINGLE); gtk_clist_set_auto_sort (GTK_CLIST (view->details->tree), TRUE); gtk_clist_set_sort_type (GTK_CLIST (view->details->tree), GTK_SORT_ASCENDING); + gtk_clist_set_compare_func (GTK_CLIST (view->details->tree), + ctree_compare_rows); gtk_clist_set_column_auto_resize (GTK_CLIST (view->details->tree), 0, TRUE); gtk_clist_columns_autosize (GTK_CLIST (view->details->tree)); gtk_clist_set_reorderable (GTK_CLIST (view->details->tree), FALSE); |