Index: src/nautilus-bookmark-list.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-bookmark-list.c,v
retrieving revision 1.44
diff -u -r1.44 nautilus-bookmark-list.c
--- src/nautilus-bookmark-list.c	21 Oct 2003 12:51:00 -0000	1.44
+++ src/nautilus-bookmark-list.c	21 Jun 2005 11:14:46 -0000
@@ -36,10 +36,19 @@
 #include <gtk/gtksignal.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-icon-factory.h>
+#include <libgnome/gnome-macros.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <stdlib.h>
 
+#define MAX_TITLE_LENGTH 180
+
 enum {
 	CONTENTS_CHANGED,
 	LAST_SIGNAL
@@ -49,15 +58,78 @@
 static char *window_geometry;
 
 /* forward declarations */
-static void        append_bookmark_node                 (gpointer              list_element,
-							 gpointer              user_data);
+
 static void        destroy                              (GtkObject            *object);
-static const char *nautilus_bookmark_list_get_file_path (NautilusBookmarkList *bookmarks);
+static char * 	   nautilus_bookmark_list_get_file_path ();
+static void	   nautilus_bookmark_list_class_init 	(NautilusBookmarkListClass *class);
 static void        nautilus_bookmark_list_load_file     (NautilusBookmarkList *bookmarks);
 static void        nautilus_bookmark_list_save_file     (NautilusBookmarkList *bookmarks);
 static void        set_window_geometry_internal         (const char           *string);
 static void        stop_monitoring_bookmark             (NautilusBookmarkList *bookmarks,
 							 NautilusBookmark     *bookmark);
+static void 	   bookmark_monitor_notify_cb 		(GnomeVFSMonitorHandle    *handle,
+		   	    				 const gchar              *monitor_uri,
+					                 const gchar              *info_uri,
+		            				 GnomeVFSMonitorEventType  event_type,
+		            				 gpointer                  user_data);
+
+
+static char *
+compute_default_title (const char *text_uri)
+{
+	NautilusFile *file;
+	GnomeVFSURI *uri;
+	char *title, *displayname;
+	const char *hostname;
+
+	hostname = NULL;
+
+	if (text_uri) {
+		file = nautilus_file_get (text_uri);
+		uri = gnome_vfs_uri_new (text_uri);
+		if (uri && !gnome_vfs_uri_is_local (uri)) {
+			hostname = gnome_vfs_uri_get_host_name (uri);
+		}
+		displayname = nautilus_file_get_display_name (file);
+		if (hostname) {
+			title = g_strdup_printf (("%s on %s"), displayname, hostname);
+			g_free (displayname);
+		} else {
+			title = displayname;
+		}
+		if (uri) {
+			gnome_vfs_uri_unref (uri);
+		}
+		nautilus_file_unref (file);
+	} else {
+		title = g_strdup ("");
+	}
+	title = eel_str_middle_truncate (title, MAX_TITLE_LENGTH);	
+	return title;
+
+}
+
+static NautilusBookmark *
+new_bookmark_from_uri (const char *uri)
+{
+	NautilusBookmark *new_bookmark;
+	char *name;
+
+	name = compute_default_title (uri);
+	new_bookmark = nautilus_bookmark_new_with_icon (uri, name, "gnome-fs-directory");
+	g_free (name);
+	return new_bookmark;
+}
+
+static char *
+nautilus_bookmark_list_get_file_path ()
+{
+	char *file_path;
+	file_path = g_build_filename (g_get_home_dir (),
+			       		      ".gtk-bookmarks",
+			       		      NULL);
+	return file_path;
+}
 
 /* Initialization.  */
 
@@ -83,8 +155,18 @@
 
 static void
 nautilus_bookmark_list_init (NautilusBookmarkList *bookmarks)
-{
+{	
+	
+	char 		      *uri;
+
 	nautilus_bookmark_list_load_file (bookmarks);
+	uri = nautilus_bookmark_list_get_file_path ();
+	gnome_vfs_monitor_add ( &bookmarks->handle,
+				uri,
+				GNOME_VFS_MONITOR_FILE,
+				bookmark_monitor_notify_cb,
+				bookmarks);
+	g_free (uri);
 }
 
 EEL_CLASS_BOILERPLATE (NautilusBookmarkList, nautilus_bookmark_list, GTK_TYPE_OBJECT)
@@ -110,46 +192,13 @@
 static void
 destroy (GtkObject *object)
 {
+	if (NAUTILUS_BOOKMARK_LIST (object)->handle != NULL) {
+		gnome_vfs_monitor_cancel (NAUTILUS_BOOKMARK_LIST (object)->handle);
+	}
 	clear (NAUTILUS_BOOKMARK_LIST (object));
 }
 
-/**
- * append_bookmark_node:
- * 
- * Foreach function; add a single bookmark xml node to a root node.
- * @data: a NautilusBookmark * that is the data of a GList node
- * @user_data: the xmlNodePtr to add a node to.
- **/
-static void
-append_bookmark_node (gpointer data, gpointer user_data)
-{
-	xmlNodePtr root_node, bookmark_node;
-	NautilusBookmark *bookmark;
-	char *icon;
-	char *bookmark_uri, *bookmark_name;
 
-	g_assert (NAUTILUS_IS_BOOKMARK (data));
-
-	bookmark = NAUTILUS_BOOKMARK (data);
-	root_node = (xmlNodePtr) user_data;	
-
-	bookmark_name = nautilus_bookmark_get_name (bookmark);
-	bookmark_uri = nautilus_bookmark_get_uri (bookmark);
-
-	bookmark_node = xmlNewChild (root_node, NULL, "bookmark", NULL);
-	xmlSetProp (bookmark_node, "name", bookmark_name);
-	xmlSetProp (bookmark_node, "uri", bookmark_uri);
-
-	g_free (bookmark_name);
-	g_free (bookmark_uri);
-
-	icon = nautilus_bookmark_get_icon (bookmark);
-	if (icon != NULL) {
-		/* Don't bother storing modifier or embedded text for bookmarks. */
-		xmlSetProp (bookmark_node, "icon_name", icon);
-		g_free (icon);
-	}
-}
 
 static void
 bookmark_in_list_changed_callback (NautilusBookmark *bookmark,
@@ -310,22 +359,7 @@
 	}
 }
 
-static const char *
-nautilus_bookmark_list_get_file_path (NautilusBookmarkList *bookmarks)
-{
-	/* currently hardwired */
-
-	static char *file_path = NULL;
-	char *user_directory;
 
-	if (file_path == NULL) {
-		user_directory = nautilus_get_user_directory ();
-		file_path = g_build_filename (user_directory, "bookmarks.xml", NULL);
-		g_free (user_directory);
-	}
-
-	return file_path;
-}
 
 /**
  * nautilus_bookmark_list_get_window_geometry:
@@ -409,41 +443,38 @@
 static void
 nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
 {
-	xmlDocPtr doc;
-	xmlNodePtr node;
 
 	/* Wipe out old list. */
+
+	gchar *filename;
+  	gchar *contents;
+
+
+	filename = nautilus_bookmark_list_get_file_path ();
+
 	clear (bookmarks);
 
-	if (!g_file_test (nautilus_bookmark_list_get_file_path (bookmarks),
+	if (!g_file_test (nautilus_bookmark_list_get_file_path (),
 			  G_FILE_TEST_EXISTS)) {
 		return;
 	}
 
 	/* Read new list from file */
-	doc = xmlParseFile (nautilus_bookmark_list_get_file_path (bookmarks));
-	for (node = eel_xml_get_root_children (doc);
-	     node != NULL;
-	     node = node->next) {
-
-		if (node->type != XML_ELEMENT_NODE) {
-			continue;
-		}
-
-		if (strcmp (node->name, "bookmark") == 0) {
-			insert_bookmark_internal (bookmarks, 
-						  nautilus_bookmark_new_from_node (node), 
-						  -1);
-		} else if (strcmp (node->name, "window") == 0) {
-			xmlChar *geometry_string;
-			
-			geometry_string = xmlGetProp (node, "geometry");
-			set_window_geometry_internal (geometry_string);
-			xmlFree (geometry_string);
+	GError **error = NULL;
+	if (g_file_get_contents (filename, &contents, NULL, error)) {
+        	gchar **lines = g_strsplit (contents, "\n", -1);
+      		int i;
+      	 	for (i = 0; lines[i]; i++) {
+	  		if (lines[i][0]) {
+				insert_bookmark_internal (bookmarks, 
+						          new_bookmark_from_uri (lines[i]), 
+						          -1);
+			}
 		}
+      		g_free (contents);
+       		g_strfreev (lines);
 	}
-	
-	xmlFreeDoc(doc);
+	g_free (filename);
 }
 
 /**
@@ -474,26 +505,91 @@
 static void
 nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
 {
-	xmlDocPtr doc;
-	xmlNodePtr root, node;
+	char *tmp_filename;
+	char *filename, *uri;
+	NautilusBookmark *bookmark;
+	FILE *file;
+	int fd;
+	int saved_errno;
+
+	filename = nautilus_bookmark_list_get_file_path ();
+	tmp_filename = g_strconcat(filename, "XXXXXX", NULL); 
+ 
+ 	/* First, write a temporary file */                                                                                     
+	fd = g_mkstemp (tmp_filename);
+  	if (fd == -1) {
+		g_warning ("make %s failed", tmp_filename);
+      		saved_errno = errno;
+      		goto io_error;
+    	}
+
+  	if ((file = fdopen (fd, "w")) != NULL) {
+      		GList *l;
+
+	      	for (l = bookmarks->list; l; l = l->next) {
+			bookmark = NAUTILUS_BOOKMARK (l->data);
+			uri = nautilus_bookmark_get_uri (bookmark);
+			if (fputs (uri, file) == EOF || fputs ("\n", file) == EOF) {
+	    			saved_errno = errno;
+				g_warning ("writing %s to file failed", uri); 
+	    			goto io_error;
+			}	
+			g_free (uri);  		
+		}
 
-	doc = xmlNewDoc ("1.0");
-	root = xmlNewDocNode (doc, NULL, "bookmarks", NULL);
-	xmlDocSetRootElement (doc, root);
-
-	/* save window position */
-	if (window_geometry != NULL) {
-		node = xmlNewChild (root, NULL, "window", NULL);
-		xmlSetProp (node, "geometry", window_geometry);
-	}
+		if (fclose (file) == EOF) {
+	  		saved_errno = errno;
+			g_warning ("fclose file failed");
+	  		goto io_error;
+		}
+
+
+		/* temporarily disable bookmark file monitoring when writing file */
+		if (bookmarks->handle != NULL) {
+			gnome_vfs_monitor_cancel (bookmarks->handle);
+		}
+
+      		if (rename (tmp_filename, filename) == -1) {
+			g_warning ("rename failed");
+	  		saved_errno = errno;
+	  		goto io_error;
+		}
+
+      		goto out;
+    	} else {
+      		saved_errno = errno;
+
+      		/* fdopen() failed, so we can't do much error checking here anyway */
+      		close (fd);
+    	}
 
-	/* save bookmarks */
-	g_list_foreach (bookmarks->list, append_bookmark_node, root);
+io_error:
+
+	g_warning ("Bookmark saving failed (%d)", saved_errno );
+
+
+	if (fd != -1) {
+		unlink (tmp_filename); /* again, not much error checking we can do here */
+	}	
+
+out:	
+	
+	uri = nautilus_bookmark_list_get_file_path ();
+
+	/* re-enable bookmark file monitoring */
+	gnome_vfs_monitor_add (&bookmarks->handle,
+			        uri,
+				GNOME_VFS_MONITOR_FILE,
+				bookmark_monitor_notify_cb,
+				bookmarks);
+	
+	g_free (uri);
+	g_free (filename);
+  	g_free (tmp_filename);
 
-	xmlSaveFile (nautilus_bookmark_list_get_file_path (bookmarks), doc);
-	xmlFreeDoc (doc);
 }
 
+
 /**
  * nautilus_bookmark_list_set_window_geometry:
  * 
@@ -521,3 +617,19 @@
 	g_free (window_geometry);
 	window_geometry = g_strdup (string);
 }
+
+static void 
+bookmark_monitor_notify_cb (GnomeVFSMonitorHandle    *handle,
+		   	    const gchar              *monitor_uri,
+		            const gchar              *info_uri,
+		            GnomeVFSMonitorEventType  event_type,
+		            gpointer                  user_data)
+{
+	if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) {
+		g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (NAUTILUS_BOOKMARK_LIST(user_data)));
+		nautilus_bookmark_list_load_file (NAUTILUS_BOOKMARK_LIST(user_data));
+		g_signal_emit (user_data, 
+			       signals[CONTENTS_CHANGED], 0);
+	}
+}
+
Index: src/nautilus-bookmark-list.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-bookmark-list.h,v
retrieving revision 1.7
diff -u -r1.7 nautilus-bookmark-list.h
--- src/nautilus-bookmark-list.h	4 Feb 2003 10:36:09 -0000	1.7
+++ src/nautilus-bookmark-list.h	21 Jun 2005 11:14:47 -0000
@@ -29,6 +29,7 @@
 #define NAUTILUS_BOOKMARK_LIST_H
 
 #include <libnautilus-private/nautilus-bookmark.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
 
 typedef struct NautilusBookmarkList NautilusBookmarkList;
 typedef struct NautilusBookmarkListClass NautilusBookmarkListClass;
@@ -46,7 +47,8 @@
 
 struct NautilusBookmarkList {
 	GtkObject object;
-	GList *list;
+	GList *list; 
+	GnomeVFSMonitorHandle *handle;
 };
 
 struct NautilusBookmarkListClass {
