[PATCH] - Fix for 155928 -Adds GTK2 Bookmarks to Nautilus



There is a demand for GTK2 bookmarks in both bugzilla -

http://bugzilla.gnome.org/show_bug.cgi?id=155928

and ubuntu -

http://udu.wiki.ubuntu.com/FileManagerImprovement

This patch replaces the nautilus bookmarks in the browser with the GTK2 ones (IE the same ones as found in the file chooser). This patch also adds file monitoring so that adding bookmarks in the file chooser also updates nautilus automatically (subject to file monitoring working!).

(Jeff : Feel free to add this to breezer badger if its not accepted upstream)

jamie.
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 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]