summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2002-02-12 00:56:13 +0000
committerDarin Adler <darin@src.gnome.org>2002-02-12 00:56:13 +0000
commit0d57173363597346713e872fc1dad9501d18b7e9 (patch)
tree50d3025ddadf6bc9e1f8ecfbe001d41a574e30b4 /components
parente414ada1b132e8dd5c8446be209e650eba7020b4 (diff)
downloadnautilus-0d57173363597346713e872fc1dad9501d18b7e9.tar.gz
Require at least libxml 2.4.7, since that's the version where xmlFree and
* configure.in: Require at least libxml 2.4.7, since that's the version where xmlFree and friends were moved out of <libxml/xmlmemory.h>. * components/news/nautilus-news.c: * components/text/nautilus-text-view.c: * libnautilus-private/nautilus-customization-data.c: * libnautilus-private/nautilus-directory-async.c: * libnautilus-private/nautilus-find-icon-image.c: * libnautilus-private/nautilus-link-desktop-file.c: * libnautilus-private/nautilus-link-historical.c: * libnautilus-private/nautilus-link.c: * libnautilus-private/nautilus-metafile.c: * libnautilus-private/nautilus-theme.c: * libnautilus-private/nautilus-volume-monitor.c: * src/nautilus-bookmark-list.c: * src/nautilus-property-browser.c: * src/nautilus-window-menus.c: Remove unneeded include of <libxml/xmlmemory.h>. * components/tree/nautilus-tree-model.c: (get_node_uri): New, used only for logging ref. counts. (decrement_ref_count): New. (abandon_node_ref_count): New. (abandon_dummy_row_ref_count): New. (report_dummy_row_inserted): Do nothing if the parent is not yet in the inserted state. (report_dummy_row_deleted): Make it abandon any lingering ref count that's still in the dummy row. (report_node_inserted): Make it report that the dummy node is inserted if the node starts with a dummy child. Also, set the new inserted state so we know this node is live. (report_node_contents_changed): Do nothing if the node is not yet in the inserted state. (report_node_has_child_toggled): Do nothing if the node is not yet in the inserted state. (report_dummy_row_contents_changed): Do nothing if the parent is not yet in the inserted state. (stop_monitoring_directory): Set done_loading to FALSE so we'll get a dummy node for directories we are not monitoring. (destroy_node_without_reporting): Abandon any ref count left in the node. Also set the inserted state to FALSE before destroying children. (destroy_node): Report if the parent gains a dummy node as a result of destroying this node. (update_node_without_reporting): Don't clear done_loading any more, since stop_monitoring_directory does it now. (reparent_node): Abandon any ref count that's still in the node before reparenting it. (schedule_destroy_unneeded_children): New. (last_child_unref): Use new schedule_destroy_unneeded_children function so we cna share code with the new abandon ref count functions. (nautilus_tree_model_ref_node), (nautilus_tree_model_unref_node): Add some logging for debugging purposes. * components/tree/nautilus-tree-view.c: (compare_rows): Sort function to use when GtkTreeModelSort works. (create_tree): Hook up sort function.
Diffstat (limited to 'components')
-rw-r--r--components/news/nautilus-news.c1
-rw-r--r--components/text/nautilus-text-view.c1
-rw-r--r--components/tree/nautilus-tree-model.c215
-rw-r--r--components/tree/nautilus-tree-view.c43
4 files changed, 221 insertions, 39 deletions
diff --git a/components/news/nautilus-news.c b/components/news/nautilus-news.c
index 4c9d16ac1..591036e01 100644
--- a/components/news/nautilus-news.c
+++ b/components/news/nautilus-news.c
@@ -49,7 +49,6 @@
#include <libgnome/gnome-util.h>
#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
#include <libgnomevfs/gnome-vfs-utils.h>
diff --git a/components/text/nautilus-text-view.c b/components/text/nautilus-text-view.c
index c5821ae9a..5947b2cf8 100644
--- a/components/text/nautilus-text-view.c
+++ b/components/text/nautilus-text-view.c
@@ -43,7 +43,6 @@
#include <ghttp.h>
#endif
#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
#include <gnome.h>
#include <gtk/gtkeventbox.h>
#include <libgnome/gnome-i18n.h>
diff --git a/components/tree/nautilus-tree-model.c b/components/tree/nautilus-tree-model.c
index 3dda95d34..317083f4f 100644
--- a/components/tree/nautilus-tree-model.c
+++ b/components/tree/nautilus-tree-model.c
@@ -47,6 +47,9 @@ typedef struct TreeNode TreeNode;
struct TreeNode {
/* part of this node for the file itself */
+ gboolean inserted;
+ int ref_count;
+
NautilusFile *file;
char *display_name;
GdkPixbuf *closed_pixbuf;
@@ -54,11 +57,12 @@ struct TreeNode {
TreeNode *parent;
TreeNode *next;
- TreeNode *prev;
+ TreeNode *prev;
/* part of the node used only for directories */
- int child_ref_count;
+ int dummy_child_ref_count;
+ int all_children_ref_count;
NautilusDirectory *directory;
guint done_loading_id;
@@ -87,8 +91,9 @@ typedef struct {
static GObjectClass *parent_class;
-static void destroy_node_without_reporting (NautilusTreeModel *model,
- TreeNode *node);
+static void schedule_destroy_unneeded_children (NautilusTreeModel *model);
+static void destroy_node_without_reporting (NautilusTreeModel *model,
+ TreeNode *node);
static void
object_unref_if_not_NULL (gpointer object)
@@ -143,6 +148,7 @@ static void
tree_node_destroy (TreeNode *node)
{
g_assert (node->first_child == NULL);
+ g_assert (node->ref_count == 0);
tree_node_unparent (node);
@@ -360,6 +366,73 @@ create_node_for_file (NautilusTreeModel *model, NautilusFile *file)
return node;
}
+#if LOG_REF_COUNTS
+
+static char *
+get_node_uri (GtkTreeIter *iter)
+{
+ TreeNode *node, *parent;
+ char *parent_uri, *node_uri;
+
+ node = iter->user_data;
+ if (node != NULL) {
+ return nautilus_file_get_uri (node->file);
+ }
+
+ parent = iter->user_data2;
+ parent_uri = nautilus_file_get_uri (parent->file);
+ node_uri = g_strconcat (parent_uri, " -- DUMMY", NULL);
+ g_free (parent_uri);
+ return node_uri;
+}
+
+#endif
+
+static void
+decrement_ref_count (NautilusTreeModel *model, TreeNode *node, int count)
+{
+ node->all_children_ref_count -= count;
+ if (node->all_children_ref_count == 0) {
+ schedule_destroy_unneeded_children (model);
+ }
+}
+
+static void
+abandon_node_ref_count (NautilusTreeModel *model, TreeNode *node)
+{
+ if (node->parent != NULL) {
+ decrement_ref_count (model, node->parent, node->ref_count);
+#if LOG_REF_COUNTS
+ if (node->ref_count != 0) {
+ char *uri;
+
+ uri = nautilus_file_get_uri (node->file);
+ g_message ("abandoning %d ref of %s, count is now %d",
+ node->ref_count, uri, node->parent->all_children_ref_count);
+ g_free (uri);
+ }
+#endif
+ }
+ node->ref_count = 0;
+}
+
+static void
+abandon_dummy_row_ref_count (NautilusTreeModel *model, TreeNode *node)
+{
+ decrement_ref_count (model, node, node->dummy_child_ref_count);
+ if (node->dummy_child_ref_count != 0) {
+#if LOG_REF_COUNTS
+ char *uri;
+
+ uri = nautilus_file_get_uri (node->file);
+ g_message ("abandoning %d ref of %s -- DUMMY, count is now %d",
+ node->dummy_child_ref_count, uri, node->all_children_ref_count);
+ g_free (uri);
+#endif
+ }
+ node->dummy_child_ref_count = 0;
+}
+
static void
report_row_inserted (NautilusTreeModel *model, GtkTreeIter *iter)
{
@@ -400,55 +473,73 @@ get_node_path (NautilusTreeModel *model, TreeNode *node)
}
static void
-report_node_inserted (NautilusTreeModel *model, TreeNode *node)
+report_dummy_row_inserted (NautilusTreeModel *model, TreeNode *parent)
{
GtkTreeIter iter;
- make_iter_for_node (node, &iter, model->details->stamp);
- report_row_inserted (model, &iter);
- if (node->directory != NULL) {
- report_row_has_child_toggled (model, &iter);
+ if (!parent->inserted) {
+ return;
}
+ make_iter_for_dummy_row (parent, &iter, model->details->stamp);
+ report_row_inserted (model, &iter);
}
static void
-report_node_contents_changed (NautilusTreeModel *model, TreeNode *node)
+report_dummy_row_deleted (NautilusTreeModel *model, TreeNode *parent)
{
GtkTreeIter iter;
+ GtkTreePath *path;
- make_iter_for_node (node, &iter, model->details->stamp);
- report_row_contents_changed (model, &iter);
+ abandon_dummy_row_ref_count (model, parent);
+ if (!parent->inserted) {
+ return;
+ }
+ make_iter_for_node (parent, &iter, model->details->stamp);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+ gtk_tree_path_append_index (path, 0);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+ gtk_tree_path_free (path);
}
static void
-report_node_has_child_toggled (NautilusTreeModel *model, TreeNode *node)
+report_node_inserted (NautilusTreeModel *model, TreeNode *node)
{
GtkTreeIter iter;
make_iter_for_node (node, &iter, model->details->stamp);
- report_row_has_child_toggled (model, &iter);
+ report_row_inserted (model, &iter);
+ node->inserted = TRUE;
+
+ if (tree_node_has_dummy_child (node)) {
+ report_dummy_row_inserted (model, node);
+ }
+ if (node->directory != NULL) {
+ report_row_has_child_toggled (model, &iter);
+ }
}
static void
-report_dummy_row_inserted (NautilusTreeModel *model, TreeNode *parent)
+report_node_contents_changed (NautilusTreeModel *model, TreeNode *node)
{
GtkTreeIter iter;
- make_iter_for_dummy_row (parent, &iter, model->details->stamp);
- report_row_inserted (model, &iter);
+ if (!node->inserted) {
+ return;
+ }
+ make_iter_for_node (node, &iter, model->details->stamp);
+ report_row_contents_changed (model, &iter);
}
static void
-report_dummy_row_deleted (NautilusTreeModel *model, TreeNode *parent)
+report_node_has_child_toggled (NautilusTreeModel *model, TreeNode *node)
{
GtkTreeIter iter;
- GtkTreePath *path;
- make_iter_for_node (parent, &iter, model->details->stamp);
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
- gtk_tree_path_append_index (path, 0);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
- gtk_tree_path_free (path);
+ if (!node->inserted) {
+ return;
+ }
+ make_iter_for_node (node, &iter, model->details->stamp);
+ report_row_has_child_toggled (model, &iter);
}
static void
@@ -456,6 +547,9 @@ report_dummy_row_contents_changed (NautilusTreeModel *model, TreeNode *parent)
{
GtkTreeIter iter;
+ if (!parent->inserted) {
+ return;
+ }
make_iter_for_dummy_row (parent, &iter, model->details->stamp);
report_row_contents_changed (model, &iter);
}
@@ -465,6 +559,8 @@ stop_monitoring_directory (NautilusTreeModel *model, TreeNode *node)
{
NautilusDirectory *directory;
+ node->done_loading = FALSE;
+
if (node->done_loading_id == 0) {
g_assert (node->files_added_id == 0);
g_assert (node->files_changed_id == 0);
@@ -495,23 +591,38 @@ destroy_children_without_reporting (NautilusTreeModel *model, TreeNode *parent)
static void
destroy_node_without_reporting (NautilusTreeModel *model, TreeNode *node)
{
+ abandon_node_ref_count (model, node);
stop_monitoring_directory (model, node);
+ node->inserted = FALSE;
destroy_children_without_reporting (model, node);
g_hash_table_remove (model->details->file_to_node_map, node->file);
- tree_node_destroy (node);
+ tree_node_destroy (node);
}
static void
destroy_node (NautilusTreeModel *model, TreeNode *node)
{
+ TreeNode *parent;
+ gboolean parent_had_dummy_child;
GtkTreePath *path;
+ parent = node->parent;
+ parent_had_dummy_child = tree_node_has_dummy_child (parent);
+
path = get_node_path (model, node);
destroy_node_without_reporting (model, node);
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
gtk_tree_path_free (path);
+
+ if (tree_node_has_dummy_child (parent)) {
+ if (!parent_had_dummy_child) {
+ report_dummy_row_inserted (model, parent);
+ }
+ } else {
+ g_assert (!parent_had_dummy_child);
+ }
}
static void
@@ -536,7 +647,6 @@ update_node_without_reporting (NautilusTreeModel *model, TreeNode *node)
destroy_children (model, node);
nautilus_directory_unref (node->directory);
node->directory = NULL;
- node->done_loading = FALSE;
}
changed |= tree_node_update_display_name (node);
@@ -568,6 +678,7 @@ reparent_node (NautilusTreeModel *model, TreeNode *node)
path = get_node_path (model, node);
+ abandon_node_ref_count (model, node);
tree_node_unparent (node);
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
@@ -1054,7 +1165,7 @@ destroy_unneeded_children (NautilusTreeModel *model, TreeNode *node)
{
TreeNode *child;
- if (node->child_ref_count == 0) {
+ if (node->all_children_ref_count == 0) {
stop_monitoring_directory (model, node);
destroy_children (model, node);
} else {
@@ -1076,9 +1187,17 @@ destroy_unneeded_children_idle_callback (gpointer callback_data)
}
static void
+schedule_destroy_unneeded_children (NautilusTreeModel *model)
+{
+ if (model->details->destroy_unneeded_children_idle_id == 0) {
+ g_idle_add (destroy_unneeded_children_idle_callback, model);
+ }
+}
+
+static void
first_child_ref (NautilusTreeModel *model, TreeNode *node)
{
- g_assert (node->child_ref_count == 1);
+ g_assert (node->all_children_ref_count == 1);
start_monitoring_directory (model, node);
}
@@ -1089,16 +1208,17 @@ last_child_unref (NautilusTreeModel *model, TreeNode *node)
* use GtkTreeModelSort. I'm not sure if this is a bug or by
* design. For now, sidestep this issue by deferring until idle.
*/
- g_assert (node->child_ref_count == 0);
- if (model->details->destroy_unneeded_children_idle_id == 0) {
- g_idle_add (destroy_unneeded_children_idle_callback, model);
- }
+ g_assert (node->all_children_ref_count == 0);
+ schedule_destroy_unneeded_children (model);
}
static void
nautilus_tree_model_ref_node (GtkTreeModel *model, GtkTreeIter *iter)
{
TreeNode *node, *parent;
+#if LOG_REF_COUNTS
+ char *uri;
+#endif
g_return_if_fail (NAUTILUS_IS_TREE_MODEL (model));
g_return_if_fail (iter_is_valid (NAUTILUS_TREE_MODEL (model), iter));
@@ -1106,17 +1226,27 @@ nautilus_tree_model_ref_node (GtkTreeModel *model, GtkTreeIter *iter)
node = iter->user_data;
if (node == NULL) {
parent = iter->user_data2;
+ g_assert (parent->dummy_child_ref_count >= 0);
+ ++parent->dummy_child_ref_count;
} else {
parent = node->parent;
+ g_assert (node->ref_count >= 0);
+ ++node->ref_count;
}
if (parent == NULL) {
g_assert (node == NAUTILUS_TREE_MODEL (model)->details->root_node);
} else {
- g_assert (parent->child_ref_count >= 0);
- if (++parent->child_ref_count == 1) {
+ g_assert (parent->all_children_ref_count >= 0);
+ if (++parent->all_children_ref_count == 1) {
first_child_ref (NAUTILUS_TREE_MODEL (model), parent);
}
+#if LOG_REF_COUNTS
+ uri = get_node_uri (iter);
+ g_message ("ref of %s, count is now %d",
+ uri, parent->all_children_ref_count);
+ g_free (uri);
+#endif
}
}
@@ -1124,6 +1254,9 @@ static void
nautilus_tree_model_unref_node (GtkTreeModel *model, GtkTreeIter *iter)
{
TreeNode *node, *parent;
+#if LOG_REF_COUNTS
+ char *uri;
+#endif
g_return_if_fail (NAUTILUS_IS_TREE_MODEL (model));
g_return_if_fail (iter_is_valid (NAUTILUS_TREE_MODEL (model), iter));
@@ -1131,15 +1264,25 @@ nautilus_tree_model_unref_node (GtkTreeModel *model, GtkTreeIter *iter)
node = iter->user_data;
if (node == NULL) {
parent = iter->user_data2;
+ g_assert (parent->dummy_child_ref_count > 0);
+ --parent->dummy_child_ref_count;
} else {
parent = node->parent;
+ g_assert (node->ref_count > 0);
+ --node->ref_count;
}
if (parent == NULL) {
g_assert (node == NAUTILUS_TREE_MODEL (model)->details->root_node);
} else {
- g_assert (parent->child_ref_count > 0);
- if (--parent->child_ref_count == 0) {
+ g_assert (parent->all_children_ref_count > 0);
+#if LOG_REF_COUNTS
+ uri = get_node_uri (iter);
+ g_message ("unref of %s, count is now %d",
+ uri, parent->all_children_ref_count - 1);
+ g_free (uri);
+#endif
+ if (--parent->all_children_ref_count == 0) {
last_child_unref (NAUTILUS_TREE_MODEL (model), parent);
}
}
diff --git a/components/tree/nautilus-tree-view.c b/components/tree/nautilus-tree-view.c
index cd37bc98b..3f044c10b 100644
--- a/components/tree/nautilus-tree-view.c
+++ b/components/tree/nautilus-tree-view.c
@@ -208,6 +208,46 @@ row_activated_callback (GtkTreeView *tree_widget,
g_list_free (attrs);
}
+#if SORT_MODEL_WORKS
+
+static int
+compare_rows (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer callback_data)
+{
+ NautilusTreeView *view;
+ NautilusFile *file_a, *file_b;
+ char *uri_a, *uri_b;
+ int result;
+
+ view = NAUTILUS_TREE_VIEW (callback_data);
+
+ file_a = nautilus_tree_model_iter_get_file (NAUTILUS_TREE_MODEL (model), a);
+ file_b = nautilus_tree_model_iter_get_file (NAUTILUS_TREE_MODEL (model), b);
+
+ if (file_a == file_b) {
+ result = 0;
+ } else if (file_a == NULL) {
+ result = -1;
+ } else if (file_b == NULL) {
+ result = +1;
+ } else {
+ uri_a = nautilus_file_get_uri (file_a);
+ uri_b = nautilus_file_get_uri (file_b);
+ g_message ("comparing %s with %s", uri_a, uri_b);
+ g_free (uri_a);
+ g_free (uri_b);
+ result = nautilus_file_compare_for_sort (file_a, file_b,
+ NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
+ FALSE, FALSE);
+ }
+
+ nautilus_file_unref (file_a);
+ nautilus_file_unref (file_b);
+
+ return result;
+}
+
+#endif
+
static void
create_tree (NautilusTreeView *view)
{
@@ -225,7 +265,8 @@ create_tree (NautilusTreeView *view)
g_object_unref (view->details->sort_model);
#if SORT_MODEL_WORKS
- /* gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort_model), func, data); */
+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (view->details->sort_model),
+ compare_rows, view, NULL);
#endif
gtk_tree_view_set_headers_visible (view->details->tree_widget, FALSE);