static void
files_changed_cb (GFileMonitor      *monitor,
                  GFile             *file,
                  GFile             *other_file,
                  GFileMonitorEvent  event_type,
                  gpointer           user_data)
{
  BgPicturesSource *self = BG_PICTURES_SOURCE (user_data);
  char *uri;

  switch (event_type)
    {
      case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
        file_added (file, self);
        break;

      case G_FILE_MONITOR_EVENT_DELETED:
        uri = g_file_get_uri (file);
        bg_pictures_source_remove (self, uri);
        g_free (uri);
        break;

      default:
        return;
    }
}
static void
picture_opened_for_read (GObject *source_object,
                         GAsyncResult *res,
                         gpointer user_data)
{
  BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data);
  CcBackgroundItem *item;
  GFileInputStream *stream;
  GError *error = NULL;

  item = g_object_get_data (source_object, "item");
  stream = g_file_read_finish (G_FILE (source_object), res, &error);
  if (stream == NULL)
    {
      char *filename;

      filename = g_file_get_path (G_FILE (source_object));
      g_warning ("Failed to load picture '%s': %s", filename, error->message);
      g_free (filename);
      g_error_free (error);
      g_object_unref (item);
      return;
    }

  g_object_set_data (G_OBJECT (stream), "item", item);

  gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream),
                                             THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
                                             TRUE,
                                             NULL,
                                             picture_scaled, bg_source);
  g_object_unref (stream);
}
static void
file_info_ready (GObject      *object,
                 GAsyncResult *res,
                 gpointer      user_data)
{
  GFileInfo *info;
  GError *error = NULL;
  GFile *file = G_FILE (object);

  info = g_file_query_info_finish (file, res, &error);

  if (!info)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Problem looking up file info: %s", error->message);
      g_clear_error (&error);
      return;
    }

  /* Up the ref count so we can re-use the add_single_item code path which
   * reduces the ref count.
   */
  g_object_ref (file);
  add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info, NULL);
}
static void
dir_enum_async_ready (GObject      *source,
                      GAsyncResult *res,
                      gpointer      user_data)
{
  BgPicturesSourcePrivate *priv;
  GFileEnumerator *enumerator;
  GError *err = NULL;

  enumerator = g_file_enumerate_children_finish (G_FILE (source), res, &err);

  if (err)
    {
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Could not fill pictures source: %s", err->message);
      g_error_free (err);
      return;
    }

  priv = BG_PICTURES_SOURCE (user_data)->priv;

  /* get the files */
  g_file_enumerator_next_files_async (enumerator,
                                      G_MAXINT,
                                      G_PRIORITY_LOW,
                                      priv->cancellable,
                                      file_info_async_ready,
                                      user_data);
  g_object_unref (enumerator);
}
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  const char *software;
  const char *uri;
  GtkTreeIter iter;
  GtkListStore *store;

  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Failed to load image: %s", error->message);

      g_error_free (error);
      return;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  item = g_object_get_data (source_object, "item");
  uri = cc_background_item_get_uri (item);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot",
               cc_background_item_get_uri (item));
      g_object_unref (pixbuf);
      g_object_unref (item);
      return;
    }

  cc_background_item_load (item, NULL);

  /* insert the item into the liststore */
  gtk_list_store_insert_with_values (store, &iter, -1,
                                     0, pixbuf,
                                     1, item,
                                     -1);

  g_hash_table_insert (bg_source->priv->known_items,
                       bg_pictures_source_get_unique_filename (uri),
                       GINT_TO_POINTER (TRUE));


  g_object_unref (pixbuf);
}
static void
picture_opened_for_read (GObject *source_object,
                         GAsyncResult *res,
                         gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GFileInputStream *stream;
  GError *error = NULL;
  gint thumbnail_height;
  gint thumbnail_width;

  item = g_object_get_data (source_object, "item");
  stream = g_file_read_finish (G_FILE (source_object), res, &error);
  if (stream == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          char *filename = g_file_get_path (G_FILE (source_object));
          g_warning ("Failed to load picture '%s': %s", filename, error->message);
          remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
          g_free (filename);
        }

      g_error_free (error);
      return;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);

  thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (bg_source));
  thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (bg_source));
  g_object_set_data_full (G_OBJECT (stream), "item", g_object_ref (item), g_object_unref);
  gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream),
                                             thumbnail_width, thumbnail_height,
                                             TRUE,
                                             bg_source->priv->cancellable,
                                             picture_scaled, bg_source);
  g_object_unref (stream);
}
static void
bg_pictures_source_finalize (GObject *object)
{
  BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object);

  g_clear_object (&bg_source->priv->thumb_factory);

  g_clear_pointer (&bg_source->priv->known_items, g_hash_table_destroy);

  g_clear_object (&bg_source->priv->picture_dir_monitor);
  g_clear_object (&bg_source->priv->cache_dir_monitor);

  G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object);
}
static void
bg_pictures_source_dispose (GObject *object)
{
  BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (object)->priv;

  if (priv->cancellable)
    {
      g_cancellable_cancel (priv->cancellable);
      g_clear_object (&priv->cancellable);
    }

  g_clear_object (&priv->grl_miner);
  g_clear_object (&priv->thumb_factory);

  G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object);
}
static void
file_info_async_ready (GObject      *source,
                       GAsyncResult *res,
                       gpointer      user_data)
{
  BgPicturesSource *bg_source;
  GList *files, *l;
  GError *err = NULL;
  GFile *parent;

  files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source),
                                               res,
                                               &err);
  if (err)
    {
      if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Could not get pictures file information: %s", err->message);
      g_error_free (err);

      g_list_foreach (files, (GFunc) g_object_unref, NULL);
      g_list_free (files);
      return;
    }

  bg_source = BG_PICTURES_SOURCE (user_data);

  parent = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source));

  files = g_list_sort (files, file_sort_func);

  /* iterate over the available files */
  for (l = files; l; l = g_list_next (l))
    {
      GFileInfo *info = l->data;
      GFile *file;

      file = g_file_get_child (parent, g_file_info_get_name (info));

      add_single_file_from_info (bg_source, file, info, NULL);
    }

  g_list_foreach (files, (GFunc) g_object_unref, NULL);
  g_list_free (files);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
static void
bg_pictures_source_dispose (GObject *object)
{
  BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (object)->priv;

  if (priv->cancellable)
    {
      g_cancellable_cancel (priv->cancellable);
      g_object_unref (priv->cancellable);
      priv->cancellable = NULL;
    }

  if (priv->thumb_factory)
    {
      g_object_unref (priv->thumb_factory);
      priv->thumb_factory = NULL;
    }

  G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object);
}
static void
picture_copied_for_read (GObject *source_object,
                         GAsyncResult *res,
                         gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GFile *thumbnail_file = G_FILE (source_object);
  GFile *native_file;

  if (!g_file_copy_finish (thumbnail_file, res, &error))
    {
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        goto out;
      else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
        {
          gchar *uri;

          uri = g_file_get_uri (thumbnail_file);
          g_warning ("Failed to download '%s': %s", uri, error->message);
          g_free (uri);
          goto out;
        }
    }

  bg_source = BG_PICTURES_SOURCE (user_data);

  native_file = g_object_get_data (G_OBJECT (thumbnail_file), "native-file");
  item = g_object_get_data (G_OBJECT (thumbnail_file), "item");
  g_object_set_data_full (G_OBJECT (native_file), "item", g_object_ref (item), g_object_unref);
  g_file_read_async (native_file,
                     G_PRIORITY_DEFAULT,
                     bg_source->priv->cancellable,
                     picture_opened_for_read,
                     bg_source);

 out:
  g_clear_error (&error);
}
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf = NULL;
  const char *software;
  const char *uri;
  GtkTreeIter iter;
  GtkTreePath *path;
  GtkTreeRowReference *row_ref;
  GtkListStore *store;
  cairo_surface_t *surface = NULL;
  int scale_factor;

  item = g_object_get_data (source_object, "item");
  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_warning ("Failed to load image: %s", error->message);
          remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
        }

      g_error_free (error);
      goto out;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  uri = cc_background_item_get_uri (item);
  if (uri == NULL)
    uri = cc_background_item_get_source_url (item);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", uri);
      remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
      goto out;
    }

  scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source));
  surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
  cc_background_item_load (item, NULL);

  row_ref = g_object_get_data (G_OBJECT (item), "row-ref");
  if (row_ref == NULL)
    {
      /* insert the item into the liststore if it did not exist */
      gtk_list_store_insert_with_values (store, NULL, -1,
                                         0, surface,
                                         1, item,
                                         -1);
    }
  else
    {
      path = gtk_tree_row_reference_get_path (row_ref);
      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
        {
          /* otherwise update the thumbnail */
          gtk_list_store_set (store, &iter,
                              0, surface,
                              -1);
        }
    }

  g_hash_table_insert (bg_source->priv->known_items,
                       bg_pictures_source_get_unique_filename (uri),
                       GINT_TO_POINTER (TRUE));


 out:
  g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
  g_clear_object (&pixbuf);
}
Ejemplo n.º 14
0
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  const char *source_url;
  const char *software;
  GtkTreeIter iter;
  GtkListStore *store;

  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Failed to load image: %s", error->message);

      g_error_free (error);
      return;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  item = g_object_get_data (source_object, "item");

  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
                                   1,
                                   (GtkTreeIterCompareFunc)sort_func,
                                   bg_source,
                                   NULL);

  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
                                        1,
                                        GTK_SORT_ASCENDING);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot",
               cc_background_item_get_uri (item));
      g_object_unref (pixbuf);
      g_object_unref (item);
      return;
    }

  cc_background_item_load (item, NULL);

  /* insert the item into the liststore */
  gtk_list_store_insert_with_values (store, &iter, 0,
                                     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);
}
Ejemplo n.º 15
0
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data);
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  const char *source_url;

  GtkTreeIter iter;
  GtkListStore *store;

  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  item = g_object_get_data (source_object, "item");

  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      g_warning ("Failed to load image: %s", error->message);
      g_error_free (error);
      g_object_unref (item);
      return;
    }

  /* insert the item into the liststore */
  gtk_list_store_insert_with_values (store, &iter, 0,
                                     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);
}