[PATCH] - Fix for 155928 -Adds GTK2 Bookmarks to Nautilus
- From: Jamie McCracken <jamiemcc blueyonder co uk>
- To: "nautilus-list gnome org" <nautilus-list gnome org>
- Cc: Jeff Waugh <jdub perkypants org>
- Subject: [PATCH] - Fix for 155928 -Adds GTK2 Bookmarks to Nautilus
- Date: Tue, 21 Jun 2005 12:45:52 +0100
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]