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
This commit is contained in:
Federico Mena Quintero 2011-09-29 09:24:57 -05:00
parent 91b3ad95c6
commit d0196e99e1
4 changed files with 507 additions and 0 deletions

View File

@ -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 \

431
gtk/gtkbookmarksmanager.c Normal file
View File

@ -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);
}

73
gtk/gtkbookmarksmanager.h Normal file
View File

@ -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__ */

View File

@ -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