summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2011-09-29 09:24:57 -0500
committerFederico Mena Quintero <federico@gnome.org>2012-09-03 20:42:04 -0500
commitd0196e99e1312cf3c0629cf59a49621cd83b3de0 (patch)
tree2657172216c9c2ef261b5fe70921f3aeae6d84fc
parent91b3ad95c6f67f8f5c3903b1312d3144f5c8ac62 (diff)
downloadgtk+-d0196e99e1312cf3c0629cf59a49621cd83b3de0.tar.gz
Split out a GtkBookmarksManager from gtkfilesystem.[ch]
We had the bookmarks machinery in GtkFileSystem for historical reasons. Now, we'll keep this separately. This will allow us to make the bookmarks machinery public if needed in the future. Signed-off-by: Federico Mena Quintero <federico@gnome.org> Conflicts: gtk/Makefile.am
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/gtkbookmarksmanager.c431
-rw-r--r--gtk/gtkbookmarksmanager.h73
-rw-r--r--po/POTFILES.in1
4 files changed, 507 insertions, 0 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 5bcefd22fd..c386323ae5 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -414,6 +414,7 @@ gtk_private_h_sources = \
gtkbindingsprivate.h \
gtkbitmaskprivate.h \
gtkbitmaskprivateimpl.h \
+ gtkbookmarksmanager.h \
gtkborderimageprivate.h \
gtkboxprivate.h \
gtkbuilderprivate.h \
@@ -605,6 +606,7 @@ gtk_base_c_sources = \
gtkbbox.c \
gtkbin.c \
gtkbindings.c \
+ gtkbookmarksmanager.c \
gtkborder.c \
gtkborderimage.c \
gtkbox.c \
diff --git a/gtk/gtkbookmarksmanager.c b/gtk/gtkbookmarksmanager.c
new file mode 100644
index 0000000000..b998c4aa33
--- /dev/null
+++ b/gtk/gtkbookmarksmanager.c
@@ -0,0 +1,431 @@
+/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
+/* GTK - The GIMP Toolkit
+ * gtkbookmarksmanager.c: Utilities to manage and monitor ~/.gtk-bookmarks
+ * Copyright (C) 2003, Red Hat, Inc.
+ * Copyright (C) 2007-2008 Carlos Garnacho
+ * Copyright (C) 2011 Suse
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@gnome.org>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib/gi18n-lib.h>
+
+#include "gtkbookmarksmanager.h"
+#include "gtkfilechooser.h" /* for the GError types */
+
+static void
+_gtk_bookmark_free (GtkBookmark *bookmark)
+{
+ g_object_unref (bookmark->file);
+ g_free (bookmark->label);
+ g_slice_free (GtkBookmark, bookmark);
+}
+
+static GFile *
+get_bookmarks_file (void)
+{
+ GFile *file;
+ gchar *filename;
+
+ filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
+ file = g_file_new_for_path (filename);
+ g_free (filename);
+
+ return file;
+}
+
+static GSList *
+read_bookmarks (GFile *file)
+{
+ gchar *contents;
+ gchar **lines, *space;
+ GSList *bookmarks = NULL;
+ gint i;
+
+ if (!g_file_load_contents (file, NULL, &contents,
+ NULL, NULL, NULL))
+ return NULL;
+
+ lines = g_strsplit (contents, "\n", -1);
+
+ for (i = 0; lines[i]; i++)
+ {
+ GtkBookmark *bookmark;
+
+ if (!*lines[i])
+ continue;
+
+ if (!g_utf8_validate (lines[i], -1, NULL))
+ continue;
+
+ bookmark = g_slice_new0 (GtkBookmark);
+
+ if ((space = strchr (lines[i], ' ')) != NULL)
+ {
+ space[0] = '\0';
+ bookmark->label = g_strdup (space + 1);
+ }
+
+ bookmark->file = g_file_new_for_uri (lines[i]);
+ bookmarks = g_slist_prepend (bookmarks, bookmark);
+ }
+
+ bookmarks = g_slist_reverse (bookmarks);
+ g_strfreev (lines);
+ g_free (contents);
+
+ return bookmarks;
+}
+
+static void
+save_bookmarks (GFile *bookmarks_file,
+ GSList *bookmarks)
+{
+ GError *error = NULL;
+ GString *contents;
+ GSList *l;
+
+ contents = g_string_new ("");
+
+ for (l = bookmarks; l; l = l->next)
+ {
+ GtkBookmark *bookmark = l->data;
+ gchar *uri;
+
+ uri = g_file_get_uri (bookmark->file);
+ if (!uri)
+ continue;
+
+ g_string_append (contents, uri);
+
+ if (bookmark->label)
+ g_string_append_printf (contents, " %s", bookmark->label);
+
+ g_string_append_c (contents, '\n');
+ g_free (uri);
+ }
+
+ if (!g_file_replace_contents (bookmarks_file,
+ contents->str,
+ strlen (contents->str),
+ NULL, FALSE, 0, NULL,
+ NULL, &error))
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_string_free (contents, TRUE);
+}
+
+static void
+notify_changed (GtkBookmarksManager *manager)
+{
+ manager->changed_func (manager->changed_func_data);
+}
+
+static void
+bookmarks_file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event,
+ gpointer data)
+{
+ GtkBookmarksManager *manager = data;
+
+ switch (event)
+ {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_DELETED:
+ g_slist_foreach (manager->bookmarks, (GFunc) _gtk_bookmark_free, NULL);
+ g_slist_free (manager->bookmarks);
+
+ manager->bookmarks = read_bookmarks (file);
+
+ gdk_threads_enter ();
+ notify_changed (manager);
+ gdk_threads_leave ();
+ break;
+
+ default:
+ /* ignore at the moment */
+ break;
+ }
+}
+
+GtkBookmarksManager *
+_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, gpointer changed_func_data)
+{
+ GtkBookmarksManager *manager;
+ GFile *bookmarks_file;
+ GError *error;
+
+ g_return_val_if_fail (changed_func != NULL, NULL);
+
+ manager = g_new0 (GtkBookmarksManager, 1);
+
+ manager->changed_func = changed_func;
+ manager->changed_func_data = changed_func_data;
+
+ bookmarks_file = get_bookmarks_file ();
+ manager->bookmarks = read_bookmarks (bookmarks_file);
+
+ error = NULL;
+ manager->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
+ G_FILE_MONITOR_NONE,
+ NULL, &error);
+ if (error)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ else
+ g_signal_connect (manager->bookmarks_monitor, "changed",
+ G_CALLBACK (bookmarks_file_changed), manager);
+
+ g_object_unref (bookmarks_file);
+
+ return manager;
+}
+
+void
+_gtk_bookmarks_manager_free (GtkBookmarksManager *manager)
+{
+ g_return_if_fail (manager != NULL);
+
+ if (manager->bookmarks_monitor)
+ g_object_unref (manager->bookmarks_monitor);
+
+ if (manager->bookmarks)
+ {
+ g_slist_foreach (manager->bookmarks, (GFunc) _gtk_bookmark_free, NULL);
+ g_slist_free (manager->bookmarks);
+ }
+
+ g_free (manager);
+}
+
+GSList *
+_gtk_bookmarks_manager_list_bookmarks (GtkBookmarksManager *manager)
+{
+ GSList *bookmarks, *files = NULL;
+
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ bookmarks = manager->bookmarks;
+
+ while (bookmarks)
+ {
+ GtkBookmark *bookmark;
+
+ bookmark = bookmarks->data;
+ bookmarks = bookmarks->next;
+
+ files = g_slist_prepend (files, g_object_ref (bookmark->file));
+ }
+
+ return g_slist_reverse (files);
+}
+
+gboolean
+_gtk_bookmarks_manager_insert_bookmark (GtkBookmarksManager *manager,
+ GFile *file,
+ gint position,
+ GError **error)
+{
+ GSList *bookmarks;
+ GtkBookmark *bookmark;
+ gboolean result = TRUE;
+ GFile *bookmarks_file;
+
+ g_return_val_if_fail (manager != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ bookmarks = manager->bookmarks;
+
+ while (bookmarks)
+ {
+ bookmark = bookmarks->data;
+ bookmarks = bookmarks->next;
+
+ if (g_file_equal (bookmark->file, file))
+ {
+ /* File is already in bookmarks */
+ result = FALSE;
+ break;
+ }
+ }
+
+ if (!result)
+ {
+ gchar *uri = g_file_get_uri (file);
+
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
+ "%s already exists in the bookmarks list",
+ uri);
+
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ bookmark = g_slice_new0 (GtkBookmark);
+ bookmark->file = g_object_ref (file);
+
+ manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, position);
+
+ bookmarks_file = get_bookmarks_file ();
+ save_bookmarks (bookmarks_file, manager->bookmarks);
+ g_object_unref (bookmarks_file);
+
+ notify_changed (manager);
+
+ return TRUE;
+}
+
+gboolean
+_gtk_bookmarks_manager_remove_bookmark (GtkBookmarksManager *manager,
+ GFile *file,
+ GError **error)
+{
+ GtkBookmark *bookmark;
+ GSList *bookmarks;
+ gboolean result = FALSE;
+ GFile *bookmarks_file;
+
+ g_return_val_if_fail (manager != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (!manager->bookmarks)
+ return FALSE;
+
+ bookmarks = manager->bookmarks;
+
+ while (bookmarks)
+ {
+ bookmark = bookmarks->data;
+
+ if (g_file_equal (bookmark->file, file))
+ {
+ result = TRUE;
+ manager->bookmarks = g_slist_remove_link (manager->bookmarks, bookmarks);
+ _gtk_bookmark_free (bookmark);
+ g_slist_free_1 (bookmarks);
+ break;
+ }
+
+ bookmarks = bookmarks->next;
+ }
+
+ if (!result)
+ {
+ gchar *uri = g_file_get_uri (file);
+
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
+ "%s does not exist in the bookmarks list",
+ uri);
+
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ bookmarks_file = get_bookmarks_file ();
+ save_bookmarks (bookmarks_file, manager->bookmarks);
+ g_object_unref (bookmarks_file);
+
+ notify_changed (manager);
+
+ return TRUE;
+}
+
+gchar *
+_gtk_bookmarks_manager_get_bookmark_label (GtkBookmarksManager *manager,
+ GFile *file)
+{
+ GSList *bookmarks;
+ gchar *label = NULL;
+
+ g_return_val_if_fail (manager != NULL, NULL);
+ g_return_val_if_fail (file != NULL, NULL);
+
+ bookmarks = manager->bookmarks;
+
+ while (bookmarks)
+ {
+ GtkBookmark *bookmark;
+
+ bookmark = bookmarks->data;
+ bookmarks = bookmarks->next;
+
+ if (g_file_equal (file, bookmark->file))
+ {
+ label = g_strdup (bookmark->label);
+ break;
+ }
+ }
+
+ return label;
+}
+
+void
+_gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
+ GFile *file,
+ const gchar *label)
+{
+ gboolean changed = FALSE;
+ GFile *bookmarks_file;
+ GSList *bookmarks;
+
+ g_return_if_fail (manager != NULL);
+ g_return_if_fail (file != NULL);
+
+ bookmarks = manager->bookmarks;
+
+ while (bookmarks)
+ {
+ GtkBookmark *bookmark;
+
+ bookmark = bookmarks->data;
+ bookmarks = bookmarks->next;
+
+ if (g_file_equal (file, bookmark->file))
+ {
+ g_free (bookmark->label);
+ bookmark->label = g_strdup (label);
+ changed = TRUE;
+ break;
+ }
+ }
+
+ bookmarks_file = get_bookmarks_file ();
+ save_bookmarks (bookmarks_file, manager->bookmarks);
+ g_object_unref (bookmarks_file);
+
+ if (changed)
+ notify_changed (manager);
+}
diff --git a/gtk/gtkbookmarksmanager.h b/gtk/gtkbookmarksmanager.h
new file mode 100644
index 0000000000..ee98d875d6
--- /dev/null
+++ b/gtk/gtkbookmarksmanager.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
+/* GTK - The GIMP Toolkit
+ * gtkbookmarksmanager.h: Utilities to manage and monitor ~/.gtk-bookmarks
+ * Copyright (C) 2003, Red Hat, Inc.
+ * Copyright (C) 2007-2008 Carlos Garnacho
+ * Copyright (C) 2011 Suse
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@gnome.org>
+ */
+
+#ifndef __GTK_BOOKMARKS_MANAGER_H__
+#define __GTK_BOOKMARKS_MANAGER_H__
+
+#include <gio/gio.h>
+
+typedef void (* GtkBookmarksChangedFunc) (gpointer data);
+
+typedef struct
+{
+ /* This list contains GtkBookmark structs */
+ GSList *bookmarks;
+
+ GFileMonitor *bookmarks_monitor;
+
+ gpointer changed_func_data;
+ GtkBookmarksChangedFunc changed_func;
+} GtkBookmarksManager;
+
+typedef struct
+{
+ GFile *file;
+ gchar *label;
+} GtkBookmark;
+
+GtkBookmarksManager *_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func,
+ gpointer changed_func_data);
+
+
+void _gtk_bookmarks_manager_free (GtkBookmarksManager *manager);
+
+GSList *_gtk_bookmarks_manager_list_bookmarks (GtkBookmarksManager *manager);
+
+gboolean _gtk_bookmarks_manager_insert_bookmark (GtkBookmarksManager *manager,
+ GFile *file,
+ gint position,
+ GError **error);
+
+gboolean _gtk_bookmarks_manager_remove_bookmark (GtkBookmarksManager *manager,
+ GFile *file,
+ GError **error);
+
+gchar * _gtk_bookmarks_manager_get_bookmark_label (GtkBookmarksManager *manager,
+ GFile *file);
+
+void _gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
+ GFile *file,
+ const gchar *label);
+
+#endif /* __GTK_BOOKMARKS_MANAGER_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5006c06084..a8a1a99bb7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -48,6 +48,7 @@ gtk/gtkassistant.c
gtk/gtkbbox.c
gtk/gtkbin.c
gtk/gtkbindings.c
+gtk/gtkbookmarksmanager.c
gtk/gtkbox.c
gtk/gtkbuildable.c
gtk/gtkbuilder.c