background: Add/Remove features in pictures source

Remember added files, so they cannot be added twice to the pictures
store (using UUID of the URI as key).

Implement removing items from the list.

Fix memory leaks.
This commit is contained in:
Bastien Nocera 2011-02-14 19:03:32 +00:00
parent db0b5b1195
commit a1dd22ea17
2 changed files with 150 additions and 1 deletions

View file

@ -42,8 +42,11 @@ struct _BgPicturesSourcePrivate
GCancellable *cancellable;
GnomeDesktopThumbnailFactory *thumb_factory;
GHashTable *known_items;
};
static char *bg_pictures_source_get_unique_filename (const char *uri);
static void
bg_pictures_source_get_property (GObject *object,
@ -95,6 +98,20 @@ bg_pictures_source_dispose (GObject *object)
static void
bg_pictures_source_finalize (GObject *object)
{
BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object);
if (bg_source->priv->thumb_factory)
{
g_object_unref (bg_source->priv->thumb_factory);
bg_source->priv->thumb_factory = NULL;
}
if (bg_source->priv->known_items)
{
g_hash_table_destroy (bg_source->priv->known_items);
bg_source->priv->known_items = NULL;
}
G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object);
}
@ -120,6 +137,7 @@ picture_scaled (GObject *source_object,
CcBackgroundItem *item;
GError *error = NULL;
GdkPixbuf *pixbuf;
const char *source_url;
GtkTreeIter iter;
GtkListStore *store;
@ -141,6 +159,35 @@ picture_scaled (GObject *source_object,
0, pixbuf,
1, item,
-1);
source_url = cc_background_item_get_source_url (item);
if (source_url != NULL)
{
g_hash_table_insert (bg_source->priv->known_items,
bg_pictures_source_get_unique_filename (source_url), GINT_TO_POINTER (TRUE));
}
else
{
char *cache_path;
GFile *file, *parent, *dir;
cache_path = bg_pictures_source_get_cache_path ();
dir = g_file_new_for_path (cache_path);
g_free (cache_path);
file = g_file_new_for_uri (cc_background_item_get_uri (item));
parent = g_file_get_parent (file);
if (g_file_equal (parent, dir))
{
char *basename;
basename = g_file_get_basename (file);
g_hash_table_insert (bg_source->priv->known_items,
basename, GINT_TO_POINTER (TRUE));
}
g_object_unref (file);
g_object_unref (parent);
}
g_object_unref (pixbuf);
}
@ -237,6 +284,50 @@ bg_pictures_source_add (BgPicturesSource *bg_source,
return retval;
}
gboolean
bg_pictures_source_remove (BgPicturesSource *bg_source,
CcBackgroundItem *item)
{
GtkTreeModel *model;
GtkTreeIter iter;
gboolean cont;
const char *uri;
gboolean retval;
retval = FALSE;
model = GTK_TREE_MODEL (bg_source_get_liststore (BG_SOURCE (bg_source)));
uri = cc_background_item_get_uri (item);
cont = gtk_tree_model_get_iter_first (model, &iter);
while (cont)
{
CcBackgroundItem *tmp_item;
const char *tmp_uri;
gtk_tree_model_get (model, &iter, 1, &tmp_item, -1);
tmp_uri = cc_background_item_get_uri (tmp_item);
if (g_str_equal (tmp_uri, uri))
{
GFile *file;
char *uuid;
file = g_file_new_for_uri (uri);
uuid = g_file_get_basename (file);
g_hash_table_insert (bg_source->priv->known_items,
uuid, NULL);
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
retval = TRUE;
g_file_trash (file, NULL, NULL);
g_object_unref (file);
break;
}
g_object_unref (tmp_item);
cont = gtk_tree_model_iter_next (model, &iter);
}
return retval;
}
static void
file_info_async_ready (GObject *source,
GAsyncResult *res,
@ -314,6 +405,55 @@ bg_pictures_source_get_cache_path (void)
NULL);
}
static char *
bg_pictures_source_get_unique_filename (const char *uri)
{
GChecksum *csum;
char *ret;
csum = g_checksum_new (G_CHECKSUM_SHA256);
g_checksum_update (csum, (guchar *) uri, -1);
ret = g_strdup (g_checksum_get_string (csum));
g_checksum_free (csum);
return ret;
}
char *
bg_pictures_source_get_unique_path (const char *uri)
{
GFile *parent, *file;
char *cache_path;
char *filename;
char *ret;
cache_path = bg_pictures_source_get_cache_path ();
parent = g_file_new_for_path (cache_path);
g_free (cache_path);
filename = bg_pictures_source_get_unique_filename (uri);
file = g_file_get_child (parent, filename);
g_free (filename);
ret = g_file_get_path (file);
g_object_unref (file);
return ret;
}
gboolean
bg_pictures_source_is_known (BgPicturesSource *bg_source,
const char *uri)
{
gboolean retval;
char *uuid;
uuid = bg_pictures_source_get_unique_filename (uri);
retval = (GPOINTER_TO_INT (g_hash_table_lookup (bg_source->priv->known_items, uuid)));
g_free (uuid);
return retval;
}
static void
bg_pictures_source_init (BgPicturesSource *self)
{
@ -325,6 +465,10 @@ bg_pictures_source_init (BgPicturesSource *self)
priv = self->priv = PICTURES_SOURCE_PRIVATE (self);
priv->cancellable = g_cancellable_new ();
priv->known_items = g_hash_table_new_full (g_str_hash,
g_str_equal,
(GDestroyNotify) g_free,
NULL);
pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
dir = g_file_new_for_path (pictures_path);
@ -346,7 +490,6 @@ bg_pictures_source_init (BgPicturesSource *self)
priv->thumb_factory =
gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
}
BgPicturesSource *

View file

@ -26,6 +26,7 @@
#include <gtk/gtk.h>
#include "bg-source.h"
#include "cc-background-item.h"
G_BEGIN_DECLS
@ -71,8 +72,13 @@ GType bg_pictures_source_get_type (void) G_GNUC_CONST;
BgPicturesSource *bg_pictures_source_new (void);
char *bg_pictures_source_get_cache_path (void);
char *bg_pictures_source_get_unique_path(const char *uri);
gboolean bg_pictures_source_add (BgPicturesSource *bg_source,
const char *uri);
gboolean bg_pictures_source_remove (BgPicturesSource *bg_source,
CcBackgroundItem *item);
gboolean bg_pictures_source_is_known (BgPicturesSource *bg_source,
const char *uri);
G_END_DECLS