Re: [PATCH] - Fix for 155928 -Adds GTK2 Bookmarks to Nautilus
- From: Jamie McCracken <jamiemcc blueyonder co uk>
- To: Alexander Larsson <alexl redhat com>
- Cc: Michele Cella <michele cella gmail com>, nautilus-list gnome org
- Subject: Re: [PATCH] - Fix for 155928 -Adds GTK2 Bookmarks to Nautilus
- Date: Wed, 22 Jun 2005 13:48:03 +0100
Alexander Larsson wrote:
On Wed, 2005-06-22 at 08:40 +0200, Alexander Larsson wrote:
On Tue, 2005-06-21 at 19:01 +0200, Michele Cella wrote:
Dave Camp wrote:
It should probably just be removed outright for now.
-dave
gtk 2.7.0 supports this [1]. Maybe you should add a conditional check
because it's not clear if gnome 2.12 will depend on gtk 2.8.
That sounds good. We should try to be compatible with that.
The format looks simple:
file:///home/alex/bin MyBinDir
Should be easy to handle.
Its not that easy! :)
That format is forwards compatible but not backwards compatible so
GTKFileChooser in 2.6 cant use that so I have to tread carefully.
I have created a new patch that allows nautilus to use, edit and store
bookmarks in both formats. (I copied some of the code from gtk 2.7 so if
its buggy complain to them!)
To prevent new format being written in Nautilus, the patch will make the
Name field in the bookmarks editing window insensitive if compiled with
-dUSING_GTK_2_6. This is the easiest way to do this without
changing/removing a whole load of code. I also had to add a flag to the
bookmarks to indicate whether it has a user defined name.
I haven't changed the autotools stuff as Im not an expert in that area
so I would appreciate if the maintainers could alter them where necessary.
The function get_default_bookmark_name is slightly different to
compute_default_title (it truncates!) so I have not centralised that in
libnautilus-private.
jamie.
Index: libnautilus-private/nautilus-bookmark.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-bookmark.c,v
retrieving revision 1.61
diff -u -r1.61 nautilus-bookmark.c
--- libnautilus-private/nautilus-bookmark.c 29 Nov 2004 16:39:31 -0000 1.61
+++ libnautilus-private/nautilus-bookmark.c 22 Jun 2005 12:35:07 -0000
@@ -55,6 +55,7 @@
struct NautilusBookmarkDetails
{
char *name;
+ gboolean has_custom_name;
char *uri;
char *icon;
NautilusFile *file;
@@ -192,6 +193,7 @@
return nautilus_bookmark_new_with_icon (
bookmark->details->uri,
bookmark->details->name,
+ bookmark->details->has_custom_name,
bookmark->details->icon);
}
@@ -203,6 +205,16 @@
return g_strdup (bookmark->details->name);
}
+
+gboolean
+nautilus_bookmark_get_has_custom_name (NautilusBookmark *bookmark)
+{
+ g_return_val_if_fail(NAUTILUS_IS_BOOKMARK (bookmark), FALSE);
+
+ return (bookmark->details->has_custom_name);
+}
+
+
GdkPixbuf *
nautilus_bookmark_get_pixbuf (NautilusBookmark *bookmark,
guint icon_size,
@@ -282,6 +294,12 @@
return TRUE;
}
+void
+nautilus_bookmark_set_has_custom_name (NautilusBookmark *bookmark, gboolean has_custom_name)
+{
+ bookmark->details->has_custom_name = has_custom_name;
+}
+
static gboolean
nautilus_bookmark_icon_is_different (NautilusBookmark *bookmark,
char *new_icon)
@@ -409,7 +427,7 @@
NautilusBookmark *
nautilus_bookmark_new (const char *uri, const char *name)
{
- return nautilus_bookmark_new_with_icon (uri, name, NULL);
+ return nautilus_bookmark_new_with_icon (uri, name, FALSE, NULL);
}
static void
@@ -459,7 +477,7 @@
}
NautilusBookmark *
-nautilus_bookmark_new_with_icon (const char *uri, const char *name,
+nautilus_bookmark_new_with_icon (const char *uri, const char *name, gboolean has_custom_name,
const char *icon)
{
NautilusBookmark *new_bookmark;
@@ -470,7 +488,7 @@
new_bookmark->details->name = g_strdup (name);
new_bookmark->details->uri = g_strdup (uri);
-
+ new_bookmark->details->has_custom_name = has_custom_name;
new_bookmark->details->icon = g_strdup (icon);
nautilus_bookmark_connect_file (new_bookmark);
Index: libnautilus-private/nautilus-bookmark.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-bookmark.h,v
retrieving revision 1.21
diff -u -r1.21 nautilus-bookmark.h
--- libnautilus-private/nautilus-bookmark.h 10 Mar 2003 16:45:39 -0000 1.21
+++ libnautilus-private/nautilus-bookmark.h 22 Jun 2005 12:35:07 -0000
@@ -71,13 +71,17 @@
const char *name);
NautilusBookmark * nautilus_bookmark_new_with_icon (const char *uri,
const char *name,
+ gboolean has_custom_name,
const char *icon);
NautilusBookmark * nautilus_bookmark_copy (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_name (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_uri (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_icon (NautilusBookmark *bookmark);
+gboolean nautilus_bookmark_get_has_custom_name (NautilusBookmark *bookmark);
gboolean nautilus_bookmark_set_name (NautilusBookmark *bookmark,
const char *new_name);
+void nautilus_bookmark_set_has_custom_name (NautilusBookmark *bookmark,
+ gboolean has_custom_name);
gboolean nautilus_bookmark_uri_known_not_to_exist (NautilusBookmark *bookmark);
int nautilus_bookmark_compare_with (gconstpointer a,
gconstpointer b);
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 22 Jun 2005 12:35:09 -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 80
+
enum {
CONTENTS_CHANGED,
LAST_SIGNAL
@@ -49,15 +58,103 @@
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 *
+get_default_bookmark_name (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, const char *label)
+{
+ NautilusBookmark *new_bookmark;
+ NautilusFile *file;
+ char *name, *icon_name = NULL;
+ gboolean has_label = FALSE;
+
+
+ if (!label) {
+ name = get_default_bookmark_name (uri);
+ } else {
+ name = g_strdup (label);
+ has_label = TRUE;
+ }
+
+ if (uri) {
+ file = nautilus_file_get (uri);
+ if (nautilus_icon_factory_is_icon_ready_for_file (file)) {
+ icon_name = nautilus_icon_factory_get_icon_for_file (file, FALSE);
+ }
+ if (!icon_name) {
+ icon_name = g_strdup ("gnome-fs-directory");
+ }
+
+ new_bookmark = nautilus_bookmark_new_with_icon (uri, name, has_label, icon_name);
+ nautilus_file_unref (file);
+ g_free (icon_name);
+ g_free (name);
+
+ return new_bookmark;
+ }
+
+ g_free (name);
+ return NULL;
+}
+
+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 +180,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 +217,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 +384,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 +468,49 @@
static void
nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
{
- xmlDocPtr doc;
- xmlNodePtr node;
/* Wipe out old list. */
+
+ char *filename, *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)) {
+ char **lines = g_strsplit (contents, "\n", -1);
+ int i;
+ for (i = 0; lines[i]; i++) {
+ if (lines[i][0]) {
+ /* gtk 2.7/2.8 might have labels appended to bookmarks which are separated by a space */
+ /* we must seperate the bookmark uri and the potential label */
+ char *space, *label = NULL;
+
+ space = strchr (lines[i], ' ');
+ if (space) {
+ *space = '\0';
+ label = g_strdup (space + 1);
+ }
+ insert_bookmark_internal (bookmarks,
+ new_bookmark_from_uri (lines[i], label),
+ -1);
+
+ if (label) {
+ g_free (label);
+ }
+ }
}
+ g_free (contents);
+ g_strfreev (lines);
}
-
- xmlFreeDoc(doc);
+ g_free (filename);
}
/**
@@ -474,26 +541,100 @@
static void
nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
{
- xmlDocPtr doc;
- xmlNodePtr root, node;
+ char *tmp_filename, *filename;
+ 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) {
+ char *bookmark_string;
+ bookmark = NAUTILUS_BOOKMARK (l->data);
+
+ /* make sure we save label if it has one for compatibility with GTK 2.7 and 2.8 */
+ if (nautilus_bookmark_get_has_custom_name (bookmark)) {
+ char *label, *uri;
+ label = nautilus_bookmark_get_name (bookmark);
+ uri = nautilus_bookmark_get_uri (bookmark);
+ bookmark_string = g_strconcat (uri, " ", label, NULL);
+ g_free (uri);
+ g_free (label);
+ } else {
+ bookmark_string = nautilus_bookmark_get_uri (bookmark);
+ }
+ if (fputs (bookmark_string, file) == EOF || fputs ("\n", file) == EOF) {
+ saved_errno = errno;
+ g_warning ("writing %s to file failed", bookmark_string);
+ g_free (bookmark_string);
+ goto io_error;
+ }
+ g_free (bookmark_string);
+ }
+
+ 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);
+ }
+
+io_error:
+ g_warning ("Bookmark saving failed (%d)", saved_errno );
- 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);
- }
- /* save bookmarks */
- g_list_foreach (bookmarks->list, append_bookmark_node, root);
+ if (fd != -1) {
+ unlink (tmp_filename); /* again, not much error checking we can do here */
+ }
+
+out:
+
+
+ /* re-enable bookmark file monitoring */
+ gnome_vfs_monitor_add (&bookmarks->handle,
+ filename,
+ GNOME_VFS_MONITOR_FILE,
+ bookmark_monitor_notify_cb,
+ bookmarks);
+
+ 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 +662,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 22 Jun 2005 12:35:09 -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 {
Index: src/nautilus-bookmark-parsing.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-bookmark-parsing.c,v
retrieving revision 1.15
diff -u -r1.15 nautilus-bookmark-parsing.c
--- src/nautilus-bookmark-parsing.c 18 Sep 2002 18:26:11 -0000 1.15
+++ src/nautilus-bookmark-parsing.c 22 Jun 2005 12:35:09 -0000
@@ -45,7 +45,7 @@
uri = xmlGetProp (node, "uri");
icon_name = xmlGetProp (node, "icon_name");
- new_bookmark = nautilus_bookmark_new_with_icon (uri, name, icon_name);
+ new_bookmark = nautilus_bookmark_new_with_icon (uri, name, FALSE, icon_name);
xmlFree (name);
xmlFree (uri);
Index: src/nautilus-bookmarks-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-bookmarks-window.c,v
retrieving revision 1.83
diff -u -r1.83 nautilus-bookmarks-window.c
--- src/nautilus-bookmarks-window.c 14 Feb 2005 10:59:23 -0000 1.83
+++ src/nautilus-bookmarks-window.c 22 Jun 2005 12:35:11 -0000
@@ -57,6 +57,7 @@
static GtkWidget *remove_button = NULL;
static GtkWidget *jump_button = NULL;
static gboolean text_changed = FALSE;
+static gboolean name_text_changed = FALSE;
static GtkWidget *uri_field = NULL;
static int uri_field_changed_signal_id;
static int row_changed_signal_id;
@@ -302,6 +303,7 @@
GTK_TREE_SELECTION (gtk_tree_view_get_selection (bookmark_list_widget));
name_field = nautilus_entry_new ();
+
gtk_widget_show (name_field);
gtk_box_pack_start (GTK_BOX (glade_xml_get_widget (gui, "bookmark_name_placeholder")),
name_field, TRUE, TRUE, 0);
@@ -311,6 +313,10 @@
GTK_LABEL (glade_xml_get_widget (gui, "bookmark_name_label")),
name_field);
+#ifdef USING_GTK_2_6
+ gtk_widget_set_sensitive (name_field, FALSE);
+#endif
+
uri_field = nautilus_entry_new ();
gtk_widget_show (uri_field);
gtk_box_pack_start (GTK_BOX (glade_xml_get_widget (gui, "bookmark_location_placeholder")),
@@ -529,6 +535,7 @@
gtk_entry_get_text (GTK_ENTRY (name_field)),
-1);
text_changed = TRUE;
+ name_text_changed = TRUE;
}
static void
@@ -751,7 +758,11 @@
/* Set the sensitivity of widgets that require a selection */
gtk_widget_set_sensitive (remove_button, selected != NULL);
gtk_widget_set_sensitive (jump_button, selected != NULL);
+
+#ifndef USING_GTK_2_6
gtk_widget_set_sensitive (name_field, selected != NULL);
+#endif
+
gtk_widget_set_sensitive (uri_field, selected != NULL);
g_signal_handler_block (name_field, name_field_changed_signal_id);
@@ -765,6 +776,7 @@
g_signal_handler_unblock (uri_field, uri_field_changed_signal_id);
text_changed = FALSE;
+ name_text_changed = FALSE;
g_free (name);
g_free (uri);
@@ -772,7 +784,7 @@
static void
-update_bookmark_from_text (void)
+update_bookmark_from_text ()
{
if (text_changed) {
NautilusBookmark *bookmark, *bookmark_in_list;
@@ -785,6 +797,8 @@
bookmark = nautilus_bookmark_new
(gtk_entry_get_text (GTK_ENTRY (uri_field)),
gtk_entry_get_text (GTK_ENTRY (name_field)));
+
+ nautilus_bookmark_set_has_custom_name (bookmark, name_text_changed);
selected_row = get_selected_row ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]