summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2003-06-27 15:14:22 +0000
committerAlexander Larsson <alexl@src.gnome.org>2003-06-27 15:14:22 +0000
commit0f758600b3f03bd7765d642647da9825c3f4e591 (patch)
treefe667a2a424b82d90f37f163201d16ac7c69c2ba
parentc2083b09fd202ea913ad3cd4a3ee299713767cf2 (diff)
downloadnautilus-0f758600b3f03bd7765d642647da9825c3f4e591.tar.gz
This is based on a patch by Jürg Billeter <j@bitron.ch> which was partly
2003-06-27 Alexander Larsson <alexl@redhat.com> This is based on a patch by Jürg Billeter <j@bitron.ch> which was partly based on a patch by Wolfgang Pichler <madmin@dialog-telekom.at>. * components/tree/nautilus-tree-model.[ch]: Support multiple roots. New row_loaded signal that gets fired when a directory has been fully loaded. New font-weight column. * components/tree/nautilus-tree-view.c: Remove tree expansion. Populate multiple roots: ~/, / and mounted removable media. Tree follows view uri. * libnautilus-private/nautilus-desktop-link-monitor.c: (create_volume_link), (nautilus_desktop_link_monitor_init), (desktop_link_monitor_finalize): Kill black_list, its moved to nautilus-volume-manager. * libnautilus-private/nautilus-desktop-link.c: (nautilus_desktop_link_new_from_volume): Move get_icon_for_volume to nautilus-volume-manager * libnautilus-private/nautilus-tree-view-drag-dest.c: (file_for_path), (get_drop_target): Handle NULL for root_uri, meaning drops on the background are not allowed. * libnautilus-private/nautilus-volume-monitor.[ch]: (nautilus_volume_get_icon), (nautilus_volume_is_in_removable_blacklist): Add get_icon and the removable media blacklist.
-rw-r--r--ChangeLog28
-rw-r--r--components/tree/nautilus-tree-model.c351
-rw-r--r--components/tree/nautilus-tree-model.h18
-rw-r--r--components/tree/nautilus-tree-view.c375
-rw-r--r--libnautilus-private/nautilus-desktop-link-monitor.c30
-rw-r--r--libnautilus-private/nautilus-desktop-link.c48
-rw-r--r--libnautilus-private/nautilus-tree-view-drag-dest.c11
-rw-r--r--libnautilus-private/nautilus-volume-monitor.c69
-rw-r--r--libnautilus-private/nautilus-volume-monitor.h3
9 files changed, 635 insertions, 298 deletions
diff --git a/ChangeLog b/ChangeLog
index 71e7cace9..8dde65af3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2003-06-27 Alexander Larsson <alexl@redhat.com>
+
+ This is based on a patch by Jürg Billeter <j@bitron.ch> which was
+ partly based on a patch by Wolfgang Pichler <madmin@dialog-telekom.at>.
+
+ * components/tree/nautilus-tree-model.[ch]:
+ Support multiple roots. New row_loaded signal that gets fired when a
+ directory has been fully loaded. New font-weight column.
+ * components/tree/nautilus-tree-view.c:
+ Remove tree expansion.
+ Populate multiple roots: ~/, / and mounted removable media.
+ Tree follows view uri.
+ * libnautilus-private/nautilus-desktop-link-monitor.c:
+ (create_volume_link), (nautilus_desktop_link_monitor_init),
+ (desktop_link_monitor_finalize):
+ Kill black_list, its moved to nautilus-volume-manager.
+ * libnautilus-private/nautilus-desktop-link.c:
+ (nautilus_desktop_link_new_from_volume):
+ Move get_icon_for_volume to nautilus-volume-manager
+ * libnautilus-private/nautilus-tree-view-drag-dest.c:
+ (file_for_path), (get_drop_target):
+ Handle NULL for root_uri, meaning drops on the background
+ are not allowed.
+ * libnautilus-private/nautilus-volume-monitor.[ch]:
+ (nautilus_volume_get_icon),
+ (nautilus_volume_is_in_removable_blacklist):
+ Add get_icon and the removable media blacklist.
+
2003-06-26 James Willcox <jwillcox@gnome.org>
* src/nautilus-property-browser.c: (emblem_dialog_clicked):
diff --git a/components/tree/nautilus-tree-model.c b/components/tree/nautilus-tree-model.c
index 6071898dd..2630cc74e 100644
--- a/components/tree/nautilus-tree-model.c
+++ b/components/tree/nautilus-tree-model.c
@@ -37,6 +37,13 @@
#include <libnautilus-private/nautilus-icon-factory.h>
#include <string.h>
+enum {
+ ROW_LOADED,
+ LAST_SIGNAL
+};
+
+static guint tree_model_signals[LAST_SIGNAL] = { 0 };
+
typedef gboolean (* FilePredicate) (NautilusFile *);
/* The user_data of the GtkTreeIter is the TreeNode pointer.
@@ -45,6 +52,7 @@ typedef gboolean (* FilePredicate) (NautilusFile *);
*/
typedef struct TreeNode TreeNode;
+typedef struct NautilusTreeModelRoot NautilusTreeModelRoot;
struct TreeNode {
/* part of this node for the file itself */
@@ -52,9 +60,12 @@ struct TreeNode {
NautilusFile *file;
char *display_name;
+ char *icon_name;
GdkPixbuf *closed_pixbuf;
GdkPixbuf *open_pixbuf;
+ NautilusTreeModelRoot *root;
+
TreeNode *parent;
TreeNode *next;
TreeNode *prev;
@@ -78,10 +89,8 @@ struct TreeNode {
struct NautilusTreeModelDetails {
int stamp;
- GHashTable *file_to_node_map;
TreeNode *root_node;
- gboolean root_node_parented;
guint monitoring_update_idle_id;
@@ -90,6 +99,17 @@ struct NautilusTreeModelDetails {
gboolean show_only_directories;
};
+struct NautilusTreeModelRoot {
+ NautilusTreeModel *model;
+
+ /* separate hash table for each root node needed */
+ GHashTable *file_to_node_map;
+
+ TreeNode *root_node;
+
+ gulong changed_handler_id;
+};
+
typedef struct {
NautilusDirectory *directory;
NautilusTreeModel *model;
@@ -112,18 +132,31 @@ object_unref_if_not_NULL (gpointer object)
g_object_unref (object);
}
+static NautilusTreeModelRoot *
+tree_model_root_new (NautilusTreeModel *model)
+{
+ NautilusTreeModelRoot *root;
+
+ root = g_new0 (NautilusTreeModelRoot, 1);
+ root->model = model;
+ root->file_to_node_map = g_hash_table_new (NULL, NULL);
+
+ return root;
+}
+
static TreeNode *
-tree_node_new (NautilusFile *file)
+tree_node_new (NautilusFile *file, NautilusTreeModelRoot *root)
{
TreeNode *node;
node = g_new0 (TreeNode, 1);
node->file = nautilus_file_ref (file);
+ node->root = root;
return node;
}
static void
-tree_node_unparent (TreeNode *node)
+tree_node_unparent (NautilusTreeModel *model, TreeNode *node)
{
TreeNode *parent, *next, *prev;
@@ -131,34 +164,35 @@ tree_node_unparent (TreeNode *node)
next = node->next;
prev = node->prev;
- if (parent == NULL) {
- g_assert (next == NULL);
- g_assert (prev == NULL);
- return;
+ if (parent == NULL &&
+ node == model->details->root_node) {
+ /* it's the first root node -> if there is a next then let it be the first root node */
+ model->details->root_node = next;
}
if (next != NULL) {
next->prev = prev;
}
- if (prev == NULL) {
+ if (prev == NULL && parent != NULL) {
g_assert (parent->first_child == node);
parent->first_child = next;
- } else {
+ } else if (prev != NULL) {
prev->next = next;
}
node->parent = NULL;
node->next = NULL;
node->prev = NULL;
+ node->root = NULL;
}
static void
-tree_node_destroy (TreeNode *node)
+tree_node_destroy (NautilusTreeModel *model, TreeNode *node)
{
g_assert (node->first_child == NULL);
g_assert (node->ref_count == 0);
- tree_node_unparent (node);
+ tree_node_unparent (model, node);
g_object_unref (node->file);
g_free (node->display_name);
@@ -186,6 +220,7 @@ tree_node_parent (TreeNode *node, TreeNode *parent)
first_child = parent->first_child;
node->parent = parent;
+ node->root = parent->root;
node->next = first_child;
if (first_child != NULL) {
@@ -200,6 +235,11 @@ static GdkPixbuf *
tree_node_get_pixbuf_from_factory (TreeNode *node,
const char *modifier)
{
+ if (node->parent == NULL) {
+ return nautilus_icon_factory_get_pixbuf_from_name
+ (node->icon_name, NULL,
+ NAUTILUS_ICON_SIZE_FOR_MENUS, NULL);
+ }
return nautilus_icon_factory_get_pixbuf_for_file
(node->file, modifier, NAUTILUS_ICON_SIZE_FOR_MENUS);
}
@@ -244,6 +284,10 @@ tree_node_update_display_name (TreeNode *node)
if (node->display_name == NULL) {
return FALSE;
}
+ /* don't update root node display names */
+ if (node->parent == NULL) {
+ return FALSE;
+ }
display_name = nautilus_file_get_display_name (node->file);
if (strcmp (display_name, node->display_name) == 0) {
g_free (display_name);
@@ -348,31 +392,31 @@ make_iter_for_dummy_row (TreeNode *parent, GtkTreeIter *iter, int stamp)
}
static TreeNode *
-get_node_from_file (NautilusTreeModel *model, NautilusFile *file)
+get_node_from_file (NautilusTreeModelRoot *root, NautilusFile *file)
{
- return g_hash_table_lookup (model->details->file_to_node_map, file);
+ return g_hash_table_lookup (root->file_to_node_map, file);
}
static TreeNode *
-get_parent_node_from_file (NautilusTreeModel *model, NautilusFile *file)
+get_parent_node_from_file (NautilusTreeModelRoot *root, NautilusFile *file)
{
NautilusFile *parent_file;
TreeNode *parent_node;
parent_file = nautilus_file_get_parent (file);
- parent_node = get_node_from_file (model, parent_file);
+ parent_node = get_node_from_file (root, parent_file);
nautilus_file_unref (parent_file);
return parent_node;
}
static TreeNode *
-create_node_for_file (NautilusTreeModel *model, NautilusFile *file)
+create_node_for_file (NautilusTreeModelRoot *root, NautilusFile *file)
{
TreeNode *node;
- g_assert (get_node_from_file (model, file) == NULL);
- node = tree_node_new (file);
- g_hash_table_insert (model->details->file_to_node_map, node->file, node);
+ g_assert (get_node_from_file (root, file) == NULL);
+ node = tree_node_new (file, root);
+ g_hash_table_insert (root->file_to_node_map, node->file, node);
return node;
}
@@ -603,8 +647,8 @@ destroy_node_without_reporting (NautilusTreeModel *model, TreeNode *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);
+ g_hash_table_remove (node->root->file_to_node_map, node->file);
+ tree_node_destroy (model, node);
}
static void
@@ -659,7 +703,10 @@ destroy_children_by_function (NautilusTreeModel *model, TreeNode *parent, FilePr
static void
destroy_by_function (NautilusTreeModel *model, FilePredicate f)
{
- destroy_children_by_function (model, model->details->root_node, f);
+ TreeNode *node;
+ for (node = model->details->root_node; node != NULL; node = node->next) {
+ destroy_children_by_function (model, node, f);
+ }
}
static gboolean
@@ -714,7 +761,7 @@ reparent_node (NautilusTreeModel *model, TreeNode *node)
GtkTreePath *path;
TreeNode *new_parent;
- new_parent = get_parent_node_from_file (model, node->file);
+ new_parent = get_parent_node_from_file (node->root, node->file);
if (new_parent == NULL || new_parent->directory == NULL) {
destroy_node (model, node);
return;
@@ -723,7 +770,7 @@ reparent_node (NautilusTreeModel *model, TreeNode *node)
path = get_node_path (model, node);
abandon_node_ref_count (model, node);
- tree_node_unparent (node);
+ tree_node_unparent (model, node);
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
gtk_tree_path_free (path);
@@ -735,6 +782,7 @@ static gboolean
should_show_file (NautilusTreeModel *model, NautilusFile *file)
{
gboolean should;
+ TreeNode *node;
should = nautilus_file_should_show (file,
model->details->show_hidden_files,
@@ -750,9 +798,10 @@ should_show_file (NautilusTreeModel *model, NautilusFile *file)
should = FALSE;
}
- if (!should && model->details->root_node != NULL
- && file == model->details->root_node->file) {
- should = TRUE;
+ for (node = model->details->root_node; node != NULL; node = node->next) {
+ if (!should && node != NULL && file == node->file) {
+ should = TRUE;
+ }
}
return should;
@@ -801,27 +850,27 @@ update_node (NautilusTreeModel *model, TreeNode *node)
}
static void
-process_file_change (NautilusTreeModel *model,
+process_file_change (NautilusTreeModelRoot *root,
NautilusFile *file)
{
TreeNode *node, *parent;
- node = get_node_from_file (model, file);
+ node = get_node_from_file (root, file);
if (node != NULL) {
- update_node (model, node);
+ update_node (root->model, node);
return;
}
- if (!should_show_file (model, file)) {
+ if (!should_show_file (root->model, file)) {
return;
}
- parent = get_parent_node_from_file (model, file);
+ parent = get_parent_node_from_file (root, file);
if (parent == NULL) {
return;
}
- insert_node (model, parent, create_node_for_file (model, file));
+ insert_node (root->model, parent, create_node_for_file (root, file));
}
static void
@@ -829,13 +878,13 @@ files_changed_callback (NautilusDirectory *directory,
GList *changed_files,
gpointer callback_data)
{
- NautilusTreeModel *model;
+ NautilusTreeModelRoot *root;
GList *node;
- model = NAUTILUS_TREE_MODEL (callback_data);
+ root = (NautilusTreeModelRoot *) (callback_data);
for (node = changed_files; node != NULL; node = node->next) {
- process_file_change (model, NAUTILUS_FILE (node->data));
+ process_file_change (root, NAUTILUS_FILE (node->data));
}
}
@@ -869,13 +918,20 @@ set_done_loading (NautilusTreeModel *model, TreeNode *node, gboolean done_loadin
static void
done_loading_callback (NautilusDirectory *directory,
- NautilusTreeModel *model)
+ NautilusTreeModelRoot *root)
{
NautilusFile *file;
+ TreeNode *node;
+ GtkTreeIter iter;
file = nautilus_directory_get_corresponding_file (directory);
- set_done_loading (model, get_node_from_file (model, file), TRUE);
+ node = get_node_from_file (root, file);
+ g_assert (node != NULL);
+ set_done_loading (root->model, node, TRUE);
nautilus_file_unref (file);
+
+ make_iter_for_node (node, &iter, root->model->details->stamp);
+ g_signal_emit_by_name (root->model, "row_loaded", &iter);
}
static NautilusFileAttributes
@@ -907,13 +963,13 @@ start_monitoring_directory (NautilusTreeModel *model, TreeNode *node)
node->done_loading_id = g_signal_connect
(directory, "done_loading",
- G_CALLBACK (done_loading_callback), model);
+ G_CALLBACK (done_loading_callback), node->root);
node->files_added_id = g_signal_connect
(directory, "files_added",
- G_CALLBACK (files_changed_callback), model);
+ G_CALLBACK (files_changed_callback), node->root);
node->files_changed_id = g_signal_connect
(directory, "files_changed",
- G_CALLBACK (files_changed_callback), model);
+ G_CALLBACK (files_changed_callback), node->root);
set_done_loading (model, node, nautilus_directory_are_all_files_seen (directory));
@@ -921,7 +977,7 @@ start_monitoring_directory (NautilusTreeModel *model, TreeNode *node)
nautilus_directory_file_monitor_add (directory, model,
model->details->show_hidden_files,
model->details->show_backup_files,
- attributes, files_changed_callback, model);
+ attributes, files_changed_callback, node->root);
}
static int
@@ -942,6 +998,8 @@ nautilus_tree_model_get_column_type (GtkTreeModel *model, int index)
return GDK_TYPE_PIXBUF;
case NAUTILUS_TREE_MODEL_FONT_STYLE_COLUMN:
return PANGO_TYPE_STYLE;
+ case NAUTILUS_TREE_MODEL_FONT_WEIGHT_COLUMN:
+ return PANGO_TYPE_WEIGHT;
default:
g_assert_not_reached ();
}
@@ -1012,9 +1070,10 @@ static GtkTreePath *
nautilus_tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
{
NautilusTreeModel *tree_model;
- TreeNode *node, *parent;
+ TreeNode *node, *parent, *cnode;
GtkTreePath *path;
GtkTreeIter parent_iter;
+ int i;
g_return_val_if_fail (NAUTILUS_IS_TREE_MODEL (model), NULL);
tree_model = NAUTILUS_TREE_MODEL (model);
@@ -1029,9 +1088,12 @@ nautilus_tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
} else {
parent = node->parent;
if (parent == NULL) {
- g_assert (node == tree_model->details->root_node);
+ i = 0;
+ for (cnode = tree_model->details->root_node; cnode != node; cnode = cnode->next) {
+ i++;
+ }
path = gtk_tree_path_new ();
- gtk_tree_path_append_index (path, 0);
+ gtk_tree_path_append_index (path, i);
return path;
}
}
@@ -1085,6 +1147,14 @@ nautilus_tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, int colum
g_value_set_enum (value, PANGO_STYLE_NORMAL);
}
break;
+ case NAUTILUS_TREE_MODEL_FONT_WEIGHT_COLUMN:
+ g_value_init (value, PANGO_TYPE_STYLE);
+ if (node != NULL && node->parent == NULL) {
+ g_value_set_enum (value, PANGO_WEIGHT_BOLD);
+ } else {
+ g_value_set_enum (value, PANGO_WEIGHT_NORMAL);
+ }
+ break;
default:
g_assert_not_reached ();
}
@@ -1131,8 +1201,7 @@ nautilus_tree_model_iter_children (GtkTreeModel *model, GtkTreeIter *iter, GtkTr
static gboolean
nautilus_tree_model_iter_parent (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *child_iter)
-{
- TreeNode *child, *parent;
+{ TreeNode *child, *parent;
g_return_val_if_fail (NAUTILUS_IS_TREE_MODEL (model), FALSE);
g_return_val_if_fail (iter_is_valid (NAUTILUS_TREE_MODEL (model), child_iter), FALSE);
@@ -1214,11 +1283,10 @@ nautilus_tree_model_iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
tree_model = NAUTILUS_TREE_MODEL (model);
if (parent_iter == NULL) {
- if (n != 0) {
- return make_iter_invalid (iter);
- }
- return make_iter_for_node (tree_model->details->root_node,
- iter, tree_model->details->stamp);
+ node = tree_model->details->root_node;
+ for (i = 0; i < n && node != NULL; i++, node = node->next);
+ return make_iter_for_node (node, iter,
+ tree_model->details->stamp);
}
parent = parent_iter->user_data;
@@ -1259,10 +1327,13 @@ static gboolean
update_monitoring_idle_callback (gpointer callback_data)
{
NautilusTreeModel *model;
+ TreeNode *node;
model = NAUTILUS_TREE_MODEL (callback_data);
model->details->monitoring_update_idle_id = 0;
- update_monitoring (model, model->details->root_node);
+ for (node = model->details->root_node; node != NULL; node = node->next) {
+ update_monitoring (model, node);
+ }
return FALSE;
}
@@ -1289,7 +1360,11 @@ stop_monitoring_directory_and_children (NautilusTreeModel *model, TreeNode *node
static void
stop_monitoring (NautilusTreeModel *model)
{
- stop_monitoring_directory_and_children (model, model->details->root_node);
+ TreeNode *node;
+
+ for (node = model->details->root_node; node != NULL; node = node->next) {
+ stop_monitoring_directory_and_children (model, node);
+ }
}
static void
@@ -1314,9 +1389,7 @@ nautilus_tree_model_ref_node (GtkTreeModel *model, GtkTreeIter *iter)
++node->ref_count;
}
- if (parent == NULL) {
- g_assert (node == NAUTILUS_TREE_MODEL (model)->details->root_node);
- } else {
+ if (parent != NULL) {
g_assert (parent->all_children_ref_count >= 0);
if (++parent->all_children_ref_count == 1) {
if (parent->first_child == NULL) {
@@ -1355,9 +1428,7 @@ nautilus_tree_model_unref_node (GtkTreeModel *model, GtkTreeIter *iter)
--node->ref_count;
}
- if (parent == NULL) {
- g_assert (node == NAUTILUS_TREE_MODEL (model)->details->root_node);
- } else {
+ if (parent != NULL) {
g_assert (parent->all_children_ref_count > 0);
#if LOG_REF_COUNTS
uri = get_node_uri (iter);
@@ -1372,27 +1443,41 @@ nautilus_tree_model_unref_node (GtkTreeModel *model, GtkTreeIter *iter)
}
static void
-root_node_file_changed_callback (NautilusFile *file, NautilusTreeModel *model)
+root_node_file_changed_callback (NautilusFile *file, NautilusTreeModelRoot *root)
{
- update_node (model, model->details->root_node);
+ if (root->root_node != NULL) {
+ update_node (root->model, root->root_node);
+ }
}
void
-nautilus_tree_model_set_root_uri (NautilusTreeModel *model, const char *root_uri)
+nautilus_tree_model_add_root_uri (NautilusTreeModel *model, const char *root_uri, const char *display_name, const char *icon_name)
{
NautilusFile *file;
- TreeNode *node;
+ TreeNode *node, *cnode;
NautilusFileAttributes attributes;
-
- g_return_if_fail (model->details->root_node == NULL);
+ NautilusTreeModelRoot *newroot;
file = nautilus_file_get (root_uri);
- node = create_node_for_file (model, file);
- model->details->root_node = node;
+ newroot = tree_model_root_new (model);
+ node = create_node_for_file (newroot, file);
+ node->display_name = g_strdup (display_name);
+ node->icon_name = g_strdup (icon_name);
+ newroot->root_node = node;
+ node->parent = NULL;
+ if (model->details->root_node == NULL) {
+ model->details->root_node = node;
+ } else {
+ /* append it */
+ for (cnode = model->details->root_node; cnode->next != NULL; cnode = cnode->next);
+ cnode->next = node;
+ node->prev = cnode;
+ }
- g_signal_connect_object (file, "changed",
- G_CALLBACK (root_node_file_changed_callback), model, 0);
+ newroot->changed_handler_id = g_signal_connect (node->file, "changed",
+ G_CALLBACK (root_node_file_changed_callback),
+ node->root);
attributes = get_tree_monitor_attributes ();
nautilus_file_monitor_add (file, model, attributes);
@@ -1403,15 +1488,53 @@ nautilus_tree_model_set_root_uri (NautilusTreeModel *model, const char *root_uri
report_node_inserted (model, node);
}
+void
+nautilus_tree_model_remove_root_uri (NautilusTreeModel *model, const char *uri)
+{
+ TreeNode *node;
+ GtkTreePath *path;
+ NautilusTreeModelRoot *root;
+ NautilusFile *file;
+
+ file = nautilus_file_get (uri);
+ for (node = model->details->root_node; node != NULL; node = node->next) {
+ if (file == node->file) {
+ break;
+ }
+ }
+ nautilus_file_unref (file);
+
+ if (node) {
+ /* remove the node */
+ nautilus_file_monitor_remove (node->file, model);
+ path = get_node_path (model, node);
+
+ if (node->prev) {
+ node->prev->next = node->next;
+ }
+ if (node->next) {
+ node->next->prev = node->prev;
+ }
+ if (node == model->details->root_node) {
+ model->details->root_node = node->next;
+ }
+
+ /* destroy the root identifier */
+ root = node->root;
+ destroy_node_without_reporting (model, node);
+ g_hash_table_destroy (root->file_to_node_map);
+ g_free (root);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+ gtk_tree_path_free (path);
+ }
+}
+
NautilusTreeModel *
-nautilus_tree_model_new (const char *opt_root_uri)
+nautilus_tree_model_new (void)
{
NautilusTreeModel *model;
model = g_object_new (NAUTILUS_TYPE_TREE_MODEL, NULL);
- if (opt_root_uri) {
- nautilus_tree_model_set_root_uri (model, opt_root_uri);
- }
return model;
}
@@ -1420,7 +1543,7 @@ static void
set_theme (TreeNode *node, NautilusTreeModel *model)
{
TreeNode *child;
-
+
tree_node_update_closed_pixbuf (node);
tree_node_update_open_pixbuf (node);
@@ -1434,9 +1557,15 @@ set_theme (TreeNode *node, NautilusTreeModel *model)
void
nautilus_tree_model_set_theme (NautilusTreeModel *model)
{
+ TreeNode *node;
+
g_return_if_fail (NAUTILUS_IS_TREE_MODEL (model));
- set_theme (model->details->root_node, model);
+ node = model->details->root_node;
+ while (node != NULL) {
+ set_theme (node, model);
+ node = node->next;
+ }
}
@@ -1515,30 +1644,70 @@ nautilus_tree_model_iter_get_file (NautilusTreeModel *model, GtkTreeIter *iter)
return node == NULL ? NULL : nautilus_file_ref (node->file);
}
+gboolean
+nautilus_tree_model_iter_is_root (NautilusTreeModel *model, GtkTreeIter *iter)
+{
+ TreeNode *node;
+
+ g_return_val_if_fail (NAUTILUS_IS_TREE_MODEL (model), 0);
+ g_return_val_if_fail (iter_is_valid (model, iter), 0);
+ node = iter->user_data;
+ if (node == NULL) {
+ return FALSE;
+ } else {
+ return (node->parent == NULL);
+ }
+}
+
+gboolean
+nautilus_tree_model_file_get_iter (NautilusTreeModel *model,
+ GtkTreeIter *iter,
+ NautilusFile *file,
+ GtkTreeIter *current_iter)
+{
+ TreeNode *node, *root_node;
+
+ if (current_iter != NULL && current_iter->user_data != NULL) {
+ node = get_node_from_file (((TreeNode *) current_iter->user_data)->root, file);
+ return make_iter_for_node (node, iter, model->details->stamp);
+ }
+
+ for (root_node = model->details->root_node; root_node != NULL; root_node = root_node->next) {
+ node = get_node_from_file (root_node->root, file);
+ if (node != NULL) {
+ return make_iter_for_node (node, iter, model->details->stamp);
+ }
+ }
+ return FALSE;
+}
+
static void
nautilus_tree_model_init (NautilusTreeModel *model)
{
model->details = g_new0 (NautilusTreeModelDetails, 1);
- do
+ do {
model->details->stamp = g_random_int ();
- while (model->details->stamp == 0);
-
- model->details->file_to_node_map = g_hash_table_new (NULL, NULL);
+ } while (model->details->stamp == 0);
}
static void
nautilus_tree_model_finalize (GObject *object)
{
NautilusTreeModel *model;
- TreeNode *root;
+ TreeNode *root_node, *next_root;
+ NautilusTreeModelRoot *root;
model = NAUTILUS_TREE_MODEL (object);
- root = model->details->root_node;
- if (root != NULL) {
- nautilus_file_monitor_remove (root->file, model);
- destroy_node_without_reporting (model, root);
+ for (root_node = model->details->root_node; root_node != NULL; root_node = next_root) {
+ next_root = root_node->next;
+ root = root_node->root;
+ g_signal_handler_disconnect (root_node->file, root->changed_handler_id);
+ nautilus_file_monitor_remove (root_node->file, model);
+ destroy_node_without_reporting (model, root_node);
+ g_hash_table_destroy (root->file_to_node_map);
+ g_free (root);
}
if (model->details->monitoring_update_idle_id != 0) {
@@ -1556,6 +1725,16 @@ nautilus_tree_model_class_init (NautilusTreeModelClass *class)
parent_class = g_type_class_peek_parent (class);
G_OBJECT_CLASS (class)->finalize = nautilus_tree_model_finalize;
+
+ tree_model_signals[ROW_LOADED] =
+ g_signal_new ("row_loaded",
+ NAUTILUS_TYPE_TREE_MODEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusTreeModelClass, row_loaded),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_TREE_ITER);
}
static void
diff --git a/components/tree/nautilus-tree-model.h b/components/tree/nautilus-tree-model.h
index 1a83d4dab..f41a05740 100644
--- a/components/tree/nautilus-tree-model.h
+++ b/components/tree/nautilus-tree-model.h
@@ -42,6 +42,7 @@ enum {
NAUTILUS_TREE_MODEL_CLOSED_PIXBUF_COLUMN,
NAUTILUS_TREE_MODEL_OPEN_PIXBUF_COLUMN,
NAUTILUS_TREE_MODEL_FONT_STYLE_COLUMN,
+ NAUTILUS_TREE_MODEL_FONT_WEIGHT_COLUMN,
NAUTILUS_TREE_MODEL_NUM_COLUMNS
};
@@ -54,10 +55,13 @@ typedef struct {
typedef struct {
GObjectClass parent_class;
+
+ void (* row_loaded) (NautilusTreeModel *tree_model,
+ GtkTreeIter *iter);
} NautilusTreeModelClass;
GType nautilus_tree_model_get_type (void);
-NautilusTreeModel *nautilus_tree_model_new (const char *opt_root_uri);
+NautilusTreeModel *nautilus_tree_model_new (void);
void nautilus_tree_model_set_show_hidden_files (NautilusTreeModel *model,
gboolean show_hidden_files);
void nautilus_tree_model_set_show_backup_files (NautilusTreeModel *model,
@@ -66,8 +70,18 @@ void nautilus_tree_model_set_show_only_directories (NautilusTreeMo
gboolean show_only_directories);
NautilusFile * nautilus_tree_model_iter_get_file (NautilusTreeModel *model,
GtkTreeIter *iter);
-void nautilus_tree_model_set_root_uri (NautilusTreeModel *model,
+void nautilus_tree_model_add_root_uri (NautilusTreeModel *model,
+ const char *root_uri,
+ const char *display_name,
+ const char *icon_name);
+void nautilus_tree_model_remove_root_uri (NautilusTreeModel *model,
const char *root_uri);
+gboolean nautilus_tree_model_iter_is_root (NautilusTreeModel *model,
+ GtkTreeIter *iter);
+gboolean nautilus_tree_model_file_get_iter (NautilusTreeModel *model,
+ GtkTreeIter *iter,
+ NautilusFile *file,
+ GtkTreeIter *currentIter);
void nautilus_tree_model_set_theme (NautilusTreeModel *model);
diff --git a/components/tree/nautilus-tree-view.c b/components/tree/nautilus-tree-view.c
index a67a21eff..1bd4b5491 100644
--- a/components/tree/nautilus-tree-view.c
+++ b/components/tree/nautilus-tree-view.c
@@ -42,6 +42,7 @@
#include <gtk/gtktreemodelsort.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtktreeview.h>
+#include <libgnome/gnome-i18n.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libnautilus-private/nautilus-file-attributes.h>
#include <libnautilus-private/nautilus-file-operations.h>
@@ -49,8 +50,7 @@
#include <libnautilus-private/nautilus-program-choosing.h>
#include <libnautilus-private/nautilus-tree-view-drag-dest.h>
#include <libnautilus-private/nautilus-icon-factory.h>
-
-#define NAUTILUS_PREFERENCES_TREE_VIEW_EXPANSION_STATE "tree-sidebar-panel/expansion_state"
+#include <libnautilus-private/nautilus-volume-monitor.h>
struct NautilusTreeViewDetails {
GtkWidget *scrolled_window;
@@ -59,9 +59,11 @@ struct NautilusTreeViewDetails {
NautilusTreeModel *child_model;
NautilusFile *activation_file;
- GHashTable *expanded_uris;
NautilusTreeViewDragDest *drag_dest;
+
+ char *selection_location;
+ gboolean selecting;
};
typedef struct {
@@ -72,107 +74,140 @@ typedef struct {
BONOBO_CLASS_BOILERPLATE (NautilusTreeView, nautilus_tree_view,
NautilusView, NAUTILUS_TYPE_VIEW)
-/*
- * The expansion state storage is pretty broken
- * conceptually we have a gconf key, but we can't
- * listen on it, since we don't want to sync all
- * tree views. We want to load the stored state per
- * new tree view we instantiate, and keep a track of
- * what nodes we are expanding.
- *
- * We then arbitrarily serialize all the tree
- * view's expansion state - and the last one to shut
- * wins the GConf key value - it sucks, but it's what
- * happened in Nautilus 1.0
- *
- * - Michael Meeks (23/5/2002)
- */
-
-static void
-populate_expansion_hash (const char *string,
- gpointer callback_data)
+static gboolean
+show_iter_for_file (NautilusTreeView *view, NautilusFile *file, GtkTreeIter *iter)
{
- char *key = g_strdup (string);
+ GtkTreeModel *model;
+ NautilusFile *parent_file;
+ GtkTreeIter parent_iter;
+ GtkTreePath *path, *sort_path;
+ GtkTreeIter cur_iter;
- g_hash_table_insert (callback_data, key, key);
-}
+ if (view->details->child_model == NULL) {
+ return FALSE;
+ }
+ model = GTK_TREE_MODEL (view->details->child_model);
+
+ /* check if file is visible in the same root as the currently selected folder is */
+ gtk_tree_view_get_cursor (view->details->tree_widget, &path, NULL);
+ if (path != NULL) {
+ if (gtk_tree_model_get_iter (model, &cur_iter, path)) {
+ if (nautilus_tree_model_file_get_iter (view->details->child_model,
+ iter, file, &cur_iter)) {
+ return TRUE;
+ }
+ }
+ }
+ /* check if file is visible at all */
+ if (nautilus_tree_model_file_get_iter (view->details->child_model,
+ iter, file, NULL)) {
+ return TRUE;
+ }
-static void
-load_expansion_state (NautilusTreeView *view)
-{
- EelStringList *uris;
+ parent_file = nautilus_file_get_parent (file);
- uris = eel_preferences_get_string_list (
- NAUTILUS_PREFERENCES_TREE_VIEW_EXPANSION_STATE);
+ if (parent_file == NULL) {
+ return FALSE;
+ }
+ if (!show_iter_for_file (view, parent_file, &parent_iter)) {
+ nautilus_file_unref (parent_file);
+ return FALSE;
+ }
+ nautilus_file_unref (parent_file);
- eel_string_list_for_each (uris, populate_expansion_hash,
- view->details->expanded_uris);
+ if (parent_iter.user_data == NULL || parent_iter.stamp == 0) {
+ return FALSE;
+ }
+ path = gtk_tree_model_get_path (model, &parent_iter);
+ sort_path = gtk_tree_model_sort_convert_child_path_to_path
+ (view->details->sort_model, path);
+ gtk_tree_path_free (path);
+ gtk_tree_view_expand_row (view->details->tree_widget, sort_path, FALSE);
+ gtk_tree_path_free (sort_path);
- eel_string_list_free (uris);
+ return FALSE;
}
-static void
-expand_row_if_stored (NautilusTreeView *view,
- GtkTreePath *path,
- const char *uri)
+static gboolean
+show_selection_idle_callback (gpointer callback_data)
{
- g_return_if_fail (NAUTILUS_IS_TREE_VIEW (view));
- g_return_if_fail (view->details != NULL);
-
- if (g_hash_table_lookup (view->details->expanded_uris, uri)) {
- if (!gtk_tree_view_expand_row (
- view->details->tree_widget, path, FALSE)) {
- g_warning ("Error expanding row '%s' '%s'", uri,
- gtk_tree_path_to_string (path));
+ NautilusTreeView *view;
+ NautilusFile *file, *old_file;
+ GtkTreeIter iter;
+ GtkTreePath *path, *sort_path;
+
+ view = NAUTILUS_TREE_VIEW (callback_data);
+
+ file = nautilus_file_get (view->details->selection_location);
+ if (file == NULL) {
+ return FALSE;
+ }
+
+ if (!nautilus_file_is_directory (file)) {
+ old_file = file;
+ file = nautilus_file_get_parent (file);
+ nautilus_file_unref (old_file);
+ if (file == NULL) {
+ return FALSE;
}
- g_hash_table_remove (view->details->expanded_uris, uri);
}
+
+ view->details->selecting = TRUE;
+ if (!show_iter_for_file (view, file, &iter)) {
+ nautilus_file_unref (file);
+ return FALSE;
+ }
+ view->details->selecting = FALSE;
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->details->child_model), &iter);
+ sort_path = gtk_tree_model_sort_convert_child_path_to_path
+ (view->details->sort_model, path);
+ gtk_tree_path_free (path);
+ gtk_tree_view_set_cursor (view->details->tree_widget, sort_path, NULL, FALSE);
+ gtk_tree_view_scroll_to_cell (view->details->tree_widget, sort_path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free (sort_path);
+
+ nautilus_file_unref (file);
+
+ return FALSE;
}
static void
-row_inserted_expand_node_callback (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- NautilusTreeView *view)
+row_loaded_callback (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ NautilusTreeView *view)
{
- char *uri;
- GtkTreeIter parent;
- GtkTreePath *sort_path, *parent_path;
- NautilusFile *file;
+ NautilusFile *file, *tmp_file, *selection_file;
- file = nautilus_tree_model_iter_get_file (view->details->child_model, iter);
-
- if (file) {
- /*
- * We can't expand a node as it's created,
- * we need to wait for the dummy child to be
- * made, so it has children, so 'expand_node'
- * doesn't fail.
- */
- nautilus_file_unref (file);
+ if (view->details->selection_location == NULL
+ || !view->details->selecting
+ || iter->user_data == NULL || iter->stamp == 0) {
return;
}
- if (!gtk_tree_model_iter_parent (tree_model, &parent, iter)) {
- g_warning ("Un-parented tree node");
+ file = nautilus_tree_model_iter_get_file (view->details->child_model, iter);
+ if (file == NULL) {
+ return;
+ }
+ if (!nautilus_file_is_directory (file)) {
+ nautilus_file_unref(file);
return;
}
- file = nautilus_tree_model_iter_get_file (view->details->child_model, &parent);
-
- uri = nautilus_file_get_uri (file);
- g_return_if_fail (uri != NULL);
-
- parent_path = gtk_tree_model_get_path (tree_model, &parent);
- sort_path = gtk_tree_model_sort_convert_child_path_to_path
- (view->details->sort_model, parent_path);
-
- expand_row_if_stored (view, sort_path, uri);
-
- gtk_tree_path_free (sort_path);
-
- g_free (uri);
+ /* if iter is ancestor of wanted selection_location then update selection */
+ selection_file = nautilus_file_get (view->details->selection_location);
+ while (selection_file != NULL) {
+ if (file == selection_file) {
+ nautilus_file_unref (file);
+ nautilus_file_unref (selection_file);
+ g_idle_add (show_selection_idle_callback, view);
+ return;
+ }
+ tmp_file = nautilus_file_get_parent (selection_file);
+ nautilus_file_unref (selection_file);
+ selection_file = tmp_file;
+ }
nautilus_file_unref (file);
}
@@ -197,42 +232,6 @@ sort_model_path_to_file (NautilusTreeView *view, GtkTreePath *path)
}
static void
-prepend_one_uri (GtkTreeView *tree_view,
- GtkTreePath *path,
- gpointer callback_data)
-{
- PrependURIParameters *p;
- NautilusFile *file;
-
- p = callback_data;
- file = sort_model_path_to_file (p->view, path);
- if (file == NULL) {
- return;
- }
- p->uris = g_list_prepend (p->uris, nautilus_file_get_uri (file));
- nautilus_file_unref (file);
-}
-
-static void
-save_expansion_state_callback (GtkTreeView *tree_widget,
- NautilusTreeView *view)
-{
- PrependURIParameters p;
- EelStringList *uris;
-
- g_return_if_fail (NAUTILUS_IS_TREE_VIEW (view));
-
- p.uris = NULL;
- p.view = view;
- gtk_tree_view_map_expanded_rows (tree_widget, prepend_one_uri, &p);
- p.uris = g_list_sort (p.uris, eel_strcmp_compare_func);
- uris = eel_string_list_new_from_g_list (p.uris, TRUE);
- eel_g_list_free_deep (p.uris);
- eel_preferences_set_string_list (NAUTILUS_PREFERENCES_TREE_VIEW_EXPANSION_STATE, uris);
- eel_string_list_free (uris);
-}
-
-static void
got_activation_uri_callback (NautilusFile *file, gpointer callback_data)
{
char *uri, *file_uri;
@@ -276,8 +275,15 @@ got_activation_uri_callback (NautilusFile *file, gpointer callback_data)
g_free (file_uri);
}
- } else if (uri != NULL) {
- nautilus_view_open_location_in_this_window (NAUTILUS_VIEW (view), uri);
+ } else if (uri != NULL) {
+ if (view->details->selection_location == NULL ||
+ strcmp (uri, view->details->selection_location) != 0) {
+ if (view->details->selection_location != NULL) {
+ g_free (view->details->selection_location);
+ }
+ view->details->selection_location = g_strdup (uri);
+ nautilus_view_open_location_in_this_window (NAUTILUS_VIEW (view), uri);
+ }
}
g_free (uri);
@@ -328,6 +334,19 @@ compare_rows (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer call
NautilusFile *file_a, *file_b;
int result;
+ if (a->user_data == NULL) {
+ return -1;
+ }
+ else if (b->user_data == NULL) {
+ return -1;
+ }
+
+ /* don't sort root nodes */
+ if (nautilus_tree_model_iter_is_root (NAUTILUS_TREE_MODEL (model), a)
+ || nautilus_tree_model_iter_is_root (NAUTILUS_TREE_MODEL (model), b)) {
+ return 0;
+ }
+
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);
@@ -358,7 +377,8 @@ get_root_uri_callback (NautilusTreeViewDragDest *dest,
view = NAUTILUS_TREE_VIEW (user_data);
- return g_strdup ("file:///");
+ /* Don't allow drops on background */
+ return NULL;
}
static NautilusFile *
@@ -405,22 +425,98 @@ theme_changed_callback (GObject *icon_factory, gpointer callback_data)
}
static void
+add_root_for_volume (NautilusTreeView *view,
+ const NautilusVolume *volume)
+{
+ char *icon, *mount_uri, *name;
+
+ if (nautilus_volume_is_in_removable_blacklist (volume)) {
+ return;
+ }
+
+ if (!nautilus_volume_is_removable (volume)) {
+ return;
+ }
+
+ /* Name uniqueness is handled by nautilus-desktop-link-monitor.c... */
+
+ icon = nautilus_volume_get_icon (volume);
+ mount_uri = nautilus_volume_get_target_uri (volume);
+ name = nautilus_volume_get_name (volume);
+
+ nautilus_tree_model_add_root_uri (view->details->child_model,
+ mount_uri, name, icon);
+
+ g_free (icon);
+ g_free (name);
+ g_free (mount_uri);
+
+}
+
+static void
+volume_mounted_callback (NautilusVolumeMonitor *volume_monitor,
+ NautilusVolume *volume,
+ NautilusTreeView *view)
+{
+ add_root_for_volume (view, volume);
+}
+
+static gboolean
+add_one_volume_root (const NautilusVolume *volume, gpointer callback_data)
+{
+ add_root_for_volume (NAUTILUS_TREE_VIEW (callback_data), volume);
+}
+
+static void
+volume_unmounted_callback (NautilusVolumeMonitor *volume_monitor,
+ NautilusVolume *volume,
+ NautilusTreeView *view)
+{
+ char *mount_uri;
+
+ mount_uri = nautilus_volume_get_target_uri (volume);
+ nautilus_tree_model_remove_root_uri (view->details->child_model,
+ mount_uri);
+ g_free (mount_uri);
+}
+
+
+static void
create_tree (NautilusTreeView *view)
{
GtkCellRenderer *cell;
GtkTreeViewColumn *column;
+ NautilusVolumeMonitor *volume_monitor;
+ char *home_uri;
- view->details->child_model = nautilus_tree_model_new (NULL);
+ view->details->child_model = nautilus_tree_model_new ();
view->details->sort_model = GTK_TREE_MODEL_SORT
(gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (view->details->child_model)));
view->details->tree_widget = GTK_TREE_VIEW
(gtk_tree_view_new_with_model (GTK_TREE_MODEL (view->details->sort_model)));
g_object_unref (view->details->sort_model);
g_signal_connect_object
- (view->details->child_model, "row_inserted",
- G_CALLBACK (row_inserted_expand_node_callback),
+ (view->details->child_model, "row_loaded",
+ G_CALLBACK (row_loaded_callback),
view, G_CONNECT_AFTER);
- nautilus_tree_model_set_root_uri (view->details->child_model, "file:///");
+ home_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
+ nautilus_tree_model_add_root_uri (view->details->child_model, home_uri, _("Home Folder"), "gnome-home");
+ g_free (home_uri);
+ nautilus_tree_model_add_root_uri (view->details->child_model, "file:///", _("Filesystem Root"), "gnome-folder");
+#ifdef NOT_YET_USABLE
+ nautilus_tree_model_add_root_uri (view->details->child_model, "network:///", _("Network Neighbourhood"), "gnome-fs-network");
+#endif
+
+ volume_monitor = nautilus_volume_monitor_get ();
+ nautilus_volume_monitor_each_mounted_volume (volume_monitor,
+ add_one_volume_root,
+ view);
+
+ g_signal_connect_object (volume_monitor, "volume_mounted",
+ G_CALLBACK (volume_mounted_callback), view, 0);
+ g_signal_connect_object (volume_monitor, "volume_unmounted",
+ G_CALLBACK (volume_unmounted_callback), view, 0);
+
g_object_unref (view->details->child_model);
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (view->details->sort_model),
@@ -428,9 +524,6 @@ create_tree (NautilusTreeView *view)
gtk_tree_view_set_headers_visible (view->details->tree_widget, FALSE);
- g_signal_connect_object (view->details->tree_widget, "destroy",
- G_CALLBACK (save_expansion_state_callback), view, 0);
-
view->details->drag_dest =
nautilus_tree_view_drag_dest_new (view->details->tree_widget);
g_signal_connect_object (view->details->drag_dest,
@@ -462,6 +555,7 @@ create_tree (NautilusTreeView *view)
gtk_tree_view_column_set_attributes (column, cell,
"text", NAUTILUS_TREE_MODEL_DISPLAY_NAME_COLUMN,
"style", NAUTILUS_TREE_MODEL_FONT_STYLE_COLUMN,
+ "weight", NAUTILUS_TREE_MODEL_FONT_WEIGHT_COLUMN,
NULL);
gtk_tree_view_append_column (view->details->tree_widget, column);
@@ -473,6 +567,8 @@ create_tree (NautilusTreeView *view)
g_signal_connect_object (gtk_tree_view_get_selection (GTK_TREE_VIEW (view->details->tree_widget)), "changed",
G_CALLBACK (selection_changed_callback), view, 0);
+
+ g_idle_add (show_selection_idle_callback, view);
}
static void
@@ -501,7 +597,6 @@ tree_activate_callback (BonoboControl *control, gboolean activating, gpointer us
view = NAUTILUS_TREE_VIEW (user_data);
if (activating && view->details->tree_widget == NULL) {
- load_expansion_state (view);
create_tree (view);
update_filtering_from_preferences (view);
}
@@ -514,6 +609,17 @@ filtering_changed_callback (gpointer callback_data)
}
static void
+load_location_callback (NautilusTreeView *view, char *location)
+{
+ if (view->details->selection_location != NULL) {
+ g_free (view->details->selection_location);
+ }
+ view->details->selection_location = g_strdup (location);
+
+ g_idle_add (show_selection_idle_callback, view);
+}
+
+static void
nautilus_tree_view_instance_init (NautilusTreeView *view)
{
BonoboControl *control;
@@ -521,8 +627,6 @@ nautilus_tree_view_instance_init (NautilusTreeView *view)
view->details = g_new0 (NautilusTreeViewDetails, 1);
view->details->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- view->details->expanded_uris = g_hash_table_new_full
- (g_str_hash, g_str_equal, g_free, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view->details->scrolled_window),
GTK_POLICY_AUTOMATIC,
@@ -536,6 +640,11 @@ nautilus_tree_view_instance_init (NautilusTreeView *view)
nautilus_view_construct_from_bonobo_control (NAUTILUS_VIEW (view), control);
+ view->details->selection_location = NULL;
+ g_signal_connect_object (view, "load_location",
+ G_CALLBACK (load_location_callback), view, 0);
+ view->details->selecting = FALSE;
+
eel_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
filtering_changed_callback, view);
eel_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
@@ -545,7 +654,7 @@ nautilus_tree_view_instance_init (NautilusTreeView *view)
g_signal_connect_object (nautilus_icon_factory_get(), "icons_changed",
G_CALLBACK (theme_changed_callback), view, 0);
-
+
}
static void
@@ -577,6 +686,10 @@ nautilus_tree_view_finalize (GObject *object)
cancel_activation (view);
+ if (view->details->selection_location != NULL) {
+ g_free (view->details->selection_location);
+ }
+
g_free (view->details);
G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/libnautilus-private/nautilus-desktop-link-monitor.c b/libnautilus-private/nautilus-desktop-link-monitor.c
index 15b154772..da3fb979f 100644
--- a/libnautilus-private/nautilus-desktop-link-monitor.c
+++ b/libnautilus-private/nautilus-desktop-link-monitor.c
@@ -49,8 +49,6 @@ struct NautilusDesktopLinkMonitorDetails {
NautilusDesktopLink *trash_link;
GList *volume_links;
-
- GList *mount_black_list;
};
@@ -112,23 +110,6 @@ nautilus_desktop_link_monitor_delete_link (NautilusDesktopLinkMonitor *monitor,
static gboolean
-volume_in_black_list (NautilusDesktopLinkMonitor *monitor,
- const NautilusVolume *volume)
-{
- GList *p;
-
- g_return_val_if_fail (NAUTILUS_IS_DESKTOP_LINK_MONITOR (monitor), TRUE);
-
- for (p = monitor->details->mount_black_list; p != NULL; p = p->next) {
- if (strcmp ((char *) p->data, nautilus_volume_get_mount_path (volume)) == 0) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static gboolean
volume_name_exists (NautilusDesktopLinkMonitor *monitor,
const char *name)
{
@@ -155,7 +136,7 @@ create_volume_link (NautilusDesktopLinkMonitor *monitor,
char *unique_name;
int index;
- if (volume_in_black_list (monitor, volume)) {
+ if (nautilus_volume_is_in_removable_blacklist (volume)) {
return;
}
@@ -273,17 +254,11 @@ static void
nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
{
NautilusDesktopLinkMonitor *monitor;
- GList *list;
monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object);
monitor->details = g_new0 (NautilusDesktopLinkMonitorDetails, 1);
- /* Set up default mount black list */
- list = g_list_prepend (NULL, g_strdup ("/proc"));
- list = g_list_prepend (list, g_strdup ("/boot"));
- monitor->details->mount_black_list = list;
-
/* We keep around a ref to the desktop dir */
monitor->details->desktop_dir = nautilus_directory_get (EEL_DESKTOP_URI);
@@ -338,9 +313,6 @@ desktop_link_monitor_finalize (GObject *object)
nautilus_directory_unref (monitor->details->desktop_dir);
monitor->details->desktop_dir = NULL;
- eel_g_list_free_deep (monitor->details->mount_black_list);
- monitor->details->mount_black_list = NULL;
-
eel_preferences_remove_callback (NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE,
desktop_home_visible_changed,
monitor);
diff --git a/libnautilus-private/nautilus-desktop-link.c b/libnautilus-private/nautilus-desktop-link.c
index 66eaa3a0b..e1ec5635e 100644
--- a/libnautilus-private/nautilus-desktop-link.c
+++ b/libnautilus-private/nautilus-desktop-link.c
@@ -161,52 +161,6 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
return link;
}
-static char *
-get_icon_for_volume (const NautilusVolume *volume)
-{
- char *icon_name;
-
- icon_name = "gnome-dev-harddisk";
- switch (nautilus_volume_get_device_type (volume)) {
- case NAUTILUS_DEVICE_AUDIO_CD:
- case NAUTILUS_DEVICE_CDROM_DRIVE:
- icon_name = "gnome-dev-cdrom";
- break;
-
- case NAUTILUS_DEVICE_FLOPPY_DRIVE:
- icon_name = "gnome-dev-floppy";
- break;
-
- case NAUTILUS_DEVICE_JAZ_DRIVE:
- icon_name = "gnome-dev-jazdisk";
- break;
-
- case NAUTILUS_DEVICE_MEMORY_STICK:
- icon_name = "gnome-dev-memory";
- break;
-
- case NAUTILUS_DEVICE_NFS:
- icon_name = "gnome-fs-nfs";
- break;
-
- case NAUTILUS_DEVICE_SMB:
- icon_name = "gnome-fs-smb";
- break;
-
- case NAUTILUS_DEVICE_ZIP_DRIVE:
- icon_name = "gnome-dev-zipdisk";
- break;
-
- case NAUTILUS_DEVICE_APPLE:
- case NAUTILUS_DEVICE_WINDOWS:
- case NAUTILUS_DEVICE_CAMERA:
- case NAUTILUS_DEVICE_UNKNOWN:
- break;
- }
-
- return g_strdup (icon_name);
-}
-
NautilusDesktopLink *
nautilus_desktop_link_new_from_volume (const NautilusVolume *volume)
{
@@ -239,7 +193,7 @@ nautilus_desktop_link_new_from_volume (const NautilusVolume *volume)
link->details->display_name = nautilus_volume_get_name (volume);
link->details->activation_uri = nautilus_volume_get_target_uri (volume);
- link->details->icon = get_icon_for_volume (volume);
+ link->details->icon = nautilus_volume_get_icon (volume);
create_icon_file (link);
diff --git a/libnautilus-private/nautilus-tree-view-drag-dest.c b/libnautilus-private/nautilus-tree-view-drag-dest.c
index b75b58400..acdc99e8e 100644
--- a/libnautilus-private/nautilus-tree-view-drag-dest.c
+++ b/libnautilus-private/nautilus-tree-view-drag-dest.c
@@ -254,8 +254,11 @@ file_for_path (NautilusTreeViewDragDest *dest, GtkTreePath *path)
g_signal_emit (dest, signals[GET_FILE_FOR_PATH], 0, path, &file);
} else {
uri = get_root_uri (dest);
-
- file = nautilus_file_get (uri);
+
+ file = NULL;
+ if (uri != NULL) {
+ file = nautilus_file_get (uri);
+ }
g_free (uri);
}
@@ -302,6 +305,10 @@ get_drop_target (NautilusTreeViewDragDest *dest,
char *target;
file = file_for_path (dest, path);
+ if (file == NULL) {
+ return NULL;
+ }
+
target = nautilus_file_get_drop_target_uri (file);
nautilus_file_unref (file);
diff --git a/libnautilus-private/nautilus-volume-monitor.c b/libnautilus-private/nautilus-volume-monitor.c
index 0eabca6b7..f3c7b50f2 100644
--- a/libnautilus-private/nautilus-volume-monitor.c
+++ b/libnautilus-private/nautilus-volume-monitor.c
@@ -834,6 +834,52 @@ nautilus_volume_get_name (const NautilusVolume *volume)
}
+char *
+nautilus_volume_get_icon (const NautilusVolume *volume)
+{
+ char *icon_name;
+
+ icon_name = "gnome-dev-harddisk";
+ switch (nautilus_volume_get_device_type (volume)) {
+ case NAUTILUS_DEVICE_AUDIO_CD:
+ case NAUTILUS_DEVICE_CDROM_DRIVE:
+ icon_name = "gnome-dev-cdrom";
+ break;
+
+ case NAUTILUS_DEVICE_FLOPPY_DRIVE:
+ icon_name = "gnome-dev-floppy";
+ break;
+
+ case NAUTILUS_DEVICE_JAZ_DRIVE:
+ icon_name = "gnome-dev-jazdisk";
+ break;
+
+ case NAUTILUS_DEVICE_MEMORY_STICK:
+ icon_name = "gnome-dev-memory";
+ break;
+
+ case NAUTILUS_DEVICE_NFS:
+ icon_name = "gnome-fs-nfs";
+ break;
+
+ case NAUTILUS_DEVICE_SMB:
+ icon_name = "gnome-fs-smb";
+ break;
+
+ case NAUTILUS_DEVICE_ZIP_DRIVE:
+ icon_name = "gnome-dev-zipdisk";
+ break;
+
+ case NAUTILUS_DEVICE_APPLE:
+ case NAUTILUS_DEVICE_WINDOWS:
+ case NAUTILUS_DEVICE_CAMERA:
+ case NAUTILUS_DEVICE_UNKNOWN:
+ break;
+ }
+
+ return g_strdup (icon_name);
+}
+
/* modify_volume_name_for_display
*
* Modify volume to be in human readable form
@@ -2172,6 +2218,29 @@ nautilus_volume_monitor_get_mount_name_for_display (NautilusVolumeMonitor *monit
}
}
+/*
+ * HORRORS OF HORROR.
+ * This really should be fixed to not be needed (if it is?).
+ * I just moved it from the desktop icon code so it can be shared
+ * between the desktop icons and the sidebar tree.
+*/
+
+gboolean
+nautilus_volume_is_in_removable_blacklist (const NautilusVolume *volume)
+{
+ char *blacklist[] = { "/proc", "/boot" };
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (blacklist); i++) {
+ if (strcmp (blacklist[i], nautilus_volume_get_mount_path (volume)) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
#ifdef HAVE_CDDA
static gboolean
diff --git a/libnautilus-private/nautilus-volume-monitor.h b/libnautilus-private/nautilus-volume-monitor.h
index 92c35d3ce..c827fbc5d 100644
--- a/libnautilus-private/nautilus-volume-monitor.h
+++ b/libnautilus-private/nautilus-volume-monitor.h
@@ -96,6 +96,7 @@ NautilusVolume *nautilus_volume_monitor_get_volume_for_path (Nau
/* Volume operations. */
char * nautilus_volume_get_name (const NautilusVolume *volume);
+char * nautilus_volume_get_icon (const NautilusVolume *volume);
NautilusDeviceType nautilus_volume_get_device_type (const NautilusVolume *volume);
gboolean nautilus_volume_is_removable (const NautilusVolume *volume);
gboolean nautilus_volume_is_read_only (const NautilusVolume *volume);
@@ -109,6 +110,6 @@ void nautilus_volume_free (Nau
guint nautilus_volume_hash (const NautilusVolume *volume);
gboolean nautilus_volume_is_equal (const NautilusVolume *volume1,
const NautilusVolume *volume2);
-
+gboolean nautilus_volume_is_in_removable_blacklist (const NautilusVolume *volume);
#endif /* NAUTILUS_VOLUME_MONITOR_H */