void
nautilus_update_thumbnail_file_copied (const char *source_file_uri,
				       const char *destination_file_uri)
{
	char *old_thumbnail_path;
	time_t mtime;
	GdkPixbuf *pixbuf;
	GnomeDesktopThumbnailFactory *factory;
	
	old_thumbnail_path = gnome_desktop_thumbnail_path_for_uri (source_file_uri, GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
	if (old_thumbnail_path != NULL &&
	    g_file_test (old_thumbnail_path, G_FILE_TEST_EXISTS)) {
		if (get_file_mtime (destination_file_uri, &mtime)) {
			pixbuf = gdk_pixbuf_new_from_file (old_thumbnail_path, NULL);
			
			if (pixbuf && gnome_desktop_thumbnail_has_uri (pixbuf, source_file_uri)) {
				factory = get_thumbnail_factory ();
				gnome_desktop_thumbnail_factory_save_thumbnail (factory,
										pixbuf,
										destination_file_uri,
										mtime);
			}
			
			if (pixbuf) {
				g_object_unref (pixbuf);
			}
		}
	}

	g_free (old_thumbnail_path);
}
Example #2
0
static gboolean
create_thumbnail (GIOSchedulerJob *job,
                  GCancellable *cancellable,
                  gpointer user_data)
{
  GSimpleAsyncResult *result = user_data;
  GFile *file = G_FILE (g_async_result_get_source_object (G_ASYNC_RESULT (result)));
  GnomeDesktopThumbnailFactory *factory;
  GFileInfo *info;
  gchar *uri;
  GdkPixbuf *pixbuf;
  guint64 mtime;

  uri = g_file_get_uri (file);
  info = g_file_query_info (file, ATTRIBUTES_FOR_THUMBNAIL,
                            G_FILE_QUERY_INFO_NONE,
                            NULL, NULL);

  /* we don't care about reporting errors here, just fail the
   * thumbnail.
   */
  if (info == NULL)
    {
      g_simple_async_result_set_op_res_gboolean (result, FALSE);
      goto out;
    }

  mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

  factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
  pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail
    (factory, 
     uri, g_file_info_get_content_type (info));

  if (pixbuf != NULL)
    {
      gnome_desktop_thumbnail_factory_save_thumbnail (factory, pixbuf,
                                                      uri, (time_t) mtime);
      g_simple_async_result_set_op_res_gboolean (result, TRUE);
    }
  else
    {
      g_simple_async_result_set_op_res_gboolean (result, FALSE);
    }

  g_object_unref (info);
  g_object_unref (file);
  g_object_unref (factory);
  g_clear_object (&pixbuf);

 out:
  g_simple_async_result_complete_in_idle (result);
  g_object_unref (result);

  return FALSE;
}
Example #3
0
/**
 * e_icon_factory_create_thumbnail
 * @filename: the file name to create the thumbnail for
 *
 * Creates system thumbnail for @filename.
 *
 * Returns: Path to system thumbnail of the file; %NULL if couldn't
 *          create it. Free it with g_free().
 **/
gchar *
e_icon_factory_create_thumbnail (const gchar *filename)
{
#ifdef HAVE_GNOME_DESKTOP
	static GnomeDesktopThumbnailFactory *thumbnail_factory = NULL;
	struct stat file_stat;
	gchar *thumbnail = NULL;

	g_return_val_if_fail (filename != NULL, NULL);

	if (thumbnail_factory == NULL) {
		thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
	}

	if (g_stat (filename, &file_stat) != -1 && S_ISREG (file_stat.st_mode)) {
		gchar *content_type, *mime = NULL;
		gboolean uncertain = FALSE;

		content_type = g_content_type_guess (filename, NULL, 0, &uncertain);
		if (content_type)
			mime = g_content_type_get_mime_type (content_type);

		if (mime) {
			gchar *uri = g_filename_to_uri (filename, NULL, NULL);

			g_return_val_if_fail (uri != NULL, NULL);

			thumbnail = gnome_desktop_thumbnail_factory_lookup (thumbnail_factory, uri, file_stat.st_mtime);
			if (!thumbnail && gnome_desktop_thumbnail_factory_can_thumbnail (thumbnail_factory, uri, mime, file_stat.st_mtime)) {
				GdkPixbuf *pixbuf;

				pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory, uri, mime);

				if (pixbuf) {
					gnome_desktop_thumbnail_factory_save_thumbnail (thumbnail_factory, pixbuf, uri, file_stat.st_mtime);
					g_object_unref (pixbuf);

					thumbnail = gnome_desktop_thumbnail_factory_lookup (thumbnail_factory, uri, file_stat.st_mtime);
				}
			}

			g_free (uri);
		}

		g_free (content_type);
		g_free (mime);
	}

	return thumbnail;
#else
	return NULL;
#endif /* HAVE_GNOME_DESKTOP */
}
static GdkPixbuf *
impl_load_thumbnail (StTextureCache    *cache,
                     const char        *uri,
                     const char        *mime_type,
                     guint              size,
                     GError           **error)
{
  GnomeDesktopThumbnailFactory *thumbnail_factory;
  GdkPixbuf *pixbuf = NULL;
  GFile *file;
  GFileInfo *file_info;
  GTimeVal mtime_g;
  time_t mtime = 0;
  char *existing_thumbnail;

  file = g_file_new_for_uri (uri);
  file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NONE, NULL, NULL);
  g_object_unref (file);
  if (file_info)
    {
      g_file_info_get_modification_time (file_info, &mtime_g);
      g_object_unref (file_info);
      mtime = (time_t) mtime_g.tv_sec;
    }

  thumbnail_factory = cache->priv->thumbnails;

  existing_thumbnail = gnome_desktop_thumbnail_factory_lookup (thumbnail_factory, uri, mtime);

  if (existing_thumbnail != NULL)
    {
      pixbuf = gdk_pixbuf_new_from_file_at_size (existing_thumbnail, size, size, error);
      g_free (existing_thumbnail);
    }
  else if (gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (thumbnail_factory, uri, mtime))
    g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Has failed thumbnail");
  else if (gnome_desktop_thumbnail_factory_can_thumbnail (thumbnail_factory, uri, mime_type, mtime))
    {
      pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory, uri, mime_type);
      if (pixbuf)
        {
          // we need to save the thumbnail so that we don't need to generate it again in the future
          gnome_desktop_thumbnail_factory_save_thumbnail (thumbnail_factory, pixbuf, uri, mtime);
        }
      else
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to generate thumbnail");
          gnome_desktop_thumbnail_factory_create_failed_thumbnail (thumbnail_factory, uri, mtime);
        }
     }
   return pixbuf;
}
Example #5
0
static void
create_thumbnail (GTask *task,
                  gpointer source_object,
                  gpointer task_data,
                  GCancellable *cancellable)
{
  GFile *file = G_FILE (source_object);
  GnomeDesktopThumbnailFactory *factory = NULL;
  GError *error = NULL;
  GFileInfo *info = NULL;
  gchar *uri = NULL;
  GdkPixbuf *pixbuf = NULL;
  guint64 mtime;

  uri = g_file_get_uri (file);

  info = g_file_query_info (file, ATTRIBUTES_FOR_THUMBNAIL,
                            G_FILE_QUERY_INFO_NONE,
                            NULL, &error);

  if (info == NULL)
    {
      g_task_return_error (task, error);
      goto out;
    }

  mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

  factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
  pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail
    (factory, 
     uri, g_file_info_get_content_type (info));

  if (pixbuf == NULL)
    {
      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "GnomeDesktopThumbnailFactory failed");
      goto out;
    }

  gnome_desktop_thumbnail_factory_save_thumbnail (factory, pixbuf, uri, (time_t) mtime);
  g_task_return_boolean (task, TRUE);

 out:
  g_clear_object (&info);
  g_clear_object (&factory);
  g_clear_object (&pixbuf);
  g_free (uri);
}
Example #6
0
static GdkPixbuf *
create_thumbnail (LoadThumbnailData *data)
{
    GFile *file = data->font_file;
    GnomeDesktopThumbnailFactory *factory;
    gchar *uri;
    guint64 mtime;

    GdkPixbuf *pixbuf = NULL;
    GFileInfo *info = NULL;

    uri = g_file_get_uri (file);
    info = g_file_query_info (file, ATTRIBUTES_FOR_CREATING_THUMBNAIL,
                              G_FILE_QUERY_INFO_NONE,
                              NULL, NULL);

    /* we don't care about reporting errors here, just fail the
     * thumbnail.
     */
    if (info == NULL)
        goto out;

    mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

    factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
    pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail
        (factory, 
         uri, g_file_info_get_content_type (info));

    if (pixbuf != NULL)
        gnome_desktop_thumbnail_factory_save_thumbnail (factory, pixbuf,
                                                        uri, (time_t) mtime);
    else
        gnome_desktop_thumbnail_factory_create_failed_thumbnail (factory,
                                                                 uri, (time_t) mtime);

  g_object_unref (factory);

 out:
  g_clear_object (&info);

  return pixbuf;
}
Example #7
0
gboolean
photos_utils_create_thumbnail (GFile *file, GCancellable *cancellable, GError **error)
{
  GnomeDesktopThumbnailFactory *factory = NULL;
  GFileInfo *info = NULL;
  const gchar *attributes = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","G_FILE_ATTRIBUTE_TIME_MODIFIED;
  gboolean ret_val = FALSE;
  gchar *uri = NULL;
  GdkPixbuf *pixbuf = NULL;
  guint64 mtime;

  uri = g_file_get_uri (file);
  info = g_file_query_info (file, attributes, G_FILE_QUERY_INFO_NONE, cancellable, error);
  if (info == NULL)
    goto out;

  mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

  factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
  pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (factory, uri, g_file_info_get_content_type (info));
  if (pixbuf == NULL)
    {
      /* FIXME: use proper #defines and enumerated types */
      g_set_error (error,
                   g_quark_from_static_string ("gnome-desktop-error"),
                   0,
                   "GnomeDesktopThumbnailFactory failed");
      goto out;
    }

  gnome_desktop_thumbnail_factory_save_thumbnail (factory, pixbuf, uri, (time_t) mtime);
  ret_val = TRUE;

 out:
  g_clear_object (&pixbuf);
  g_clear_object (&factory);
  g_clear_object (&info);
  g_free (uri);
  return ret_val;
}
/* thumbnail_thread is invoked as a separate thread to to make thumbnails. */
static gpointer
thumbnail_thread_start (gpointer data)
{
	NautilusThumbnailInfo *info = NULL;
	GdkPixbuf *pixbuf;
	time_t current_orig_mtime = 0;
	time_t current_time;
	GList *node;

	/* We loop until there are no more thumbails to make, at which point
	   we exit the thread. */
	for (;;) {
#ifdef DEBUG_THUMBNAILS
		g_message ("(Thumbnail Thread) Locking mutex\n");
#endif
		pthread_mutex_lock (&thumbnails_mutex);

		/*********************************
		 * MUTEX LOCKED
		 *********************************/

		/* Pop the last thumbnail we just made off the head of the
		   list and free it. I did this here so we only have to lock
		   the mutex once per thumbnail, rather than once before
		   creating it and once after.
		   Don't pop the thumbnail off the queue if the original file
		   mtime of the request changed. Then we need to redo the thumbnail.
		*/
		if (currently_thumbnailing &&
		    currently_thumbnailing->original_file_mtime == current_orig_mtime) {
			g_assert (info == currently_thumbnailing);
			node = g_hash_table_lookup (thumbnails_to_make_hash, info->image_uri);
			g_assert (node != NULL);
			g_hash_table_remove (thumbnails_to_make_hash, info->image_uri);
			free_thumbnail_info (info);
			g_queue_delete_link ((GQueue *)&thumbnails_to_make, node);
		}
		currently_thumbnailing = NULL;

		/* If there are no more thumbnails to make, reset the
		   thumbnail_thread_is_running flag, unlock the mutex, and
		   exit the thread. */
		if (g_queue_is_empty ((GQueue *)&thumbnails_to_make)) {
#ifdef DEBUG_THUMBNAILS
			g_message ("(Thumbnail Thread) Exiting\n");
#endif
			thumbnail_thread_is_running = FALSE;
			pthread_mutex_unlock (&thumbnails_mutex);
			pthread_exit (NULL);
		}

		/* Get the next one to make. We leave it on the list until it
		   is created so the main thread doesn't add it again while we
		   are creating it. */
		info = g_queue_peek_head ((GQueue *)&thumbnails_to_make);
		currently_thumbnailing = info;
		current_orig_mtime = info->original_file_mtime;
		/*********************************
		 * MUTEX UNLOCKED
		 *********************************/

#ifdef DEBUG_THUMBNAILS
		g_message ("(Thumbnail Thread) Unlocking mutex\n");
#endif
		pthread_mutex_unlock (&thumbnails_mutex);

		time (&current_time);

		/* Don't try to create a thumbnail if the file was modified recently.
		   This prevents constant re-thumbnailing of changing files. */ 
		if (current_time < current_orig_mtime + THUMBNAIL_CREATION_DELAY_SECS &&
		    current_time >= current_orig_mtime) {
#ifdef DEBUG_THUMBNAILS
			g_message ("(Thumbnail Thread) Skipping: %s\n",
				   info->image_uri);
#endif
			/* Reschedule thumbnailing via a change notification */
			g_timeout_add_seconds (1, thumbnail_thread_notify_file_changed,
				       g_strdup (info->image_uri));
 			continue;
		}

		/* Create the thumbnail. */
#ifdef DEBUG_THUMBNAILS
		g_message ("(Thumbnail Thread) Creating thumbnail: %s\n",
			   info->image_uri);
#endif

		pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory,
									     info->image_uri,
									     info->mime_type);

		if (pixbuf) {
			gnome_desktop_thumbnail_factory_save_thumbnail (thumbnail_factory,
									pixbuf,
									info->image_uri,
									current_orig_mtime);
			g_object_unref (pixbuf);
		} else {
			gnome_desktop_thumbnail_factory_create_failed_thumbnail (thumbnail_factory, 
										 info->image_uri,
										 current_orig_mtime);
		}
		/* We need to call nautilus_file_changed(), but I don't think that is
		   thread safe. So add an idle handler and do it from the main loop. */
		g_idle_add_full (G_PRIORITY_HIGH_IDLE,
				 thumbnail_thread_notify_file_changed,
				 g_strdup (info->image_uri), NULL);
	}
}
Example #9
0
static gboolean
cheese_thumb_view_idle_append_item (gpointer data)
{
  CheeseThumbViewIdleData *item = g_queue_peek_head (data);
  CheeseThumbView         *thumb_view;
  CheeseThumbViewPrivate  *priv;

  /* Disconnect the idle handler when the queue is empty. */
  if (item == NULL) return FALSE;

  thumb_view = item->thumb_view;
  priv = cheese_thumb_view_get_instance_private (thumb_view);


  GnomeDesktopThumbnailFactory *factory = priv->factory;
  GFile                        *file    = item->file;
  GtkTreeIter                   iter    = item->iter;
  GdkPixbuf                    *pixbuf  = NULL;
  GFileInfo                    *info;
  char                         *thumb_loc;
  GTimeVal                      mtime;
  char                         *mime_type;
  char                         *uri;
  char                         *filename;

  info = g_file_query_info (file, "standard::content-type,time::modified", 0, NULL, NULL);

  if (!info)
  {
    g_warning ("Invalid filename\n");
    return TRUE;
  }
  g_file_info_get_modification_time (info, &mtime);
  mime_type = g_strdup (g_file_info_get_content_type (info));

  uri      = g_file_get_uri (file);
  filename = g_file_get_path (file);

  thumb_loc = gnome_desktop_thumbnail_factory_lookup (factory, uri, mtime.tv_sec);

  if (!thumb_loc)
  {
    pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (factory, uri, mime_type);
    if (!pixbuf)
    {
      g_warning ("could not generate thumbnail for %s (%s)\n", filename, mime_type);
    }
    else
    {
      gnome_desktop_thumbnail_factory_save_thumbnail (factory, pixbuf, uri, mtime.tv_sec);
    }
  }
  else
  {
    pixbuf = gdk_pixbuf_new_from_file (thumb_loc, NULL);
    if (!pixbuf)
    {
      g_warning ("could not load thumbnail %s (%s)\n", filename, mime_type);
    }
  }
  g_object_unref (info);
  g_free (thumb_loc);
  g_free (uri);

  if (!pixbuf)
  {
    gchar  *escape = NULL;
    GError *error  = NULL;
    escape = g_strrstr (mime_type, "/");
    if (escape != NULL) *escape = '-';
    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
                                       mime_type,
                                       96,
                                       GTK_ICON_LOOKUP_GENERIC_FALLBACK,
                                       &error);
    if (error)
    {
      g_warning ("%s", error->message);
      return TRUE;
    }
  }
  else
  {
    cheese_thumbnail_add_frame (&pixbuf);
  }

  gtk_list_store_set (priv->store, &iter,
                      THUMBNAIL_PIXBUF_COLUMN, pixbuf, -1);

  g_free (mime_type);
  g_free (filename);
  g_object_unref (pixbuf);
  g_object_unref (file);
  g_slice_free (CheeseThumbViewIdleData, item);
  g_queue_pop_head (data);

  return TRUE;
}
Example #10
0
/**
 * eog_thumbnail_load:
 * @image: a #EogImage
 * @error: location to store the error ocurring or %NULL to ignore
 *
 * Loads the thumbnail for @image. In case of error, %NULL is returned
 * and @error is set.
 *
 * Returns: (transfer full): a new #GdkPixbuf with the thumbnail for
 * @image or %NULL in case of error.
 **/
GdkPixbuf*
eog_thumbnail_load (EogImage *image, GError **error)
{
	GdkPixbuf *thumb = NULL;
	GFile *file;
	EogThumbData *data;
	GdkPixbuf *pixbuf = NULL;

	g_return_val_if_fail (image != NULL, NULL);
	g_return_val_if_fail (error != NULL && *error == NULL, NULL);

	file = eog_image_get_file (image);
	data = eog_thumb_data_new (file, error);
	g_object_unref (file);

	if (data == NULL)
		return NULL;

	if (!data->can_read ||
	    (data->failed_thumb_exists && gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (factory, data->uri_str, data->mtime))) {
		eog_debug_message (DEBUG_THUMBNAIL, "%s: bad permissions or valid failed thumbnail present",data->uri_str);
		set_thumb_error (error, EOG_THUMB_ERROR_GENERIC, "Thumbnail creation failed");
		return NULL;
	}

	/* check if there is already a valid cached thumbnail */
	thumb = get_valid_thumbnail (data, error);

	if (thumb != NULL) {
		eog_debug_message (DEBUG_THUMBNAIL, "%s: loaded from cache",data->uri_str);
	} else if (gnome_desktop_thumbnail_factory_can_thumbnail (factory, data->uri_str, data->mime_type, data->mtime)) {
		/* Only use the image pixbuf when it is up to date. */
		if (!eog_image_is_file_changed (image))
			pixbuf = eog_image_get_pixbuf (image);

		if (pixbuf != NULL) {
			/* generate a thumbnail from the in-memory image,
			   if we have already loaded the image */
			eog_debug_message (DEBUG_THUMBNAIL, "%s: creating from pixbuf",data->uri_str);
			thumb = create_thumbnail_from_pixbuf (data, pixbuf, error);
			g_object_unref (pixbuf);
		} else {
			/* generate a thumbnail from the file */
			eog_debug_message (DEBUG_THUMBNAIL, "%s: creating from file",data->uri_str);
			thumb = gnome_desktop_thumbnail_factory_generate_thumbnail (factory, data->uri_str, data->mime_type);
		}

		if (thumb != NULL) {
			/* Save the new thumbnail */
			gnome_desktop_thumbnail_factory_save_thumbnail (factory, thumb, data->uri_str, data->mtime);
			eog_debug_message (DEBUG_THUMBNAIL, "%s: normal thumbnail saved",data->uri_str);
		} else {
			/* Save a failed thumbnail, to stop further thumbnail attempts */
			gnome_desktop_thumbnail_factory_create_failed_thumbnail (factory, data->uri_str, data->mtime);
			eog_debug_message (DEBUG_THUMBNAIL, "%s: failed thumbnail saved",data->uri_str);
			set_thumb_error (error, EOG_THUMB_ERROR_GENERIC, "Thumbnail creation failed");
		}
	}

	eog_thumb_data_free (data);

	return thumb;
}