Commit b15f2dbe authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson

Keep track of whether the file is being thumbnailed. If it is at

2003-03-12  Alexander Larsson  <alexl@redhat.com>

	* libnautilus-private/nautilus-file-private.h:
	* libnautilus-private/nautilus-file.c: (finalize),
	(nautilus_file_invalidate_attributes_internal),
	(nautilus_file_is_thumbnailing),
	(nautilus_file_set_is_thumbnailing):
	* libnautilus-private/nautilus-file.h:
	Keep track of whether the file is being thumbnailed.
	If it is at finalization, remove from the thumbnail queue.

	* libnautilus-private/nautilus-icon-container.h:
	* libnautilus-private/nautilus-icon-container.c:
	(redo_layout_internal), (realize),
	(nautilus_icon_container_instance_init),
	(nautilus_icon_container_prioritize_thumbnailing),
	(nautilus_icon_container_prioritize_thumbnailing_for_visible_icons)
	, (handle_vadjustment_changed):
	Prioritize thumbnailing for icons visibile on the screen.

	* libnautilus-private/nautilus-icon-factory.c:
	(show_thumbnails_changed_callback):
	Remove all thumbnails from queue when thumbnails are disabled.

	* libnautilus-private/nautilus-thumbnails.h:
	* libnautilus-private/nautilus-thumbnails.c: (free_thumbnail_info),
	(nautilus_thumbnail_remove_from_queue),
	(nautilus_thumbnail_remove_all_from_queue),
	(nautilus_thumbnail_prioritize),
	(thumbnail_thread_notify_file_changed),
	(nautilus_create_thumbnail), (thumbnail_thread_start):
	New functions to remove thumbnails from the queue and to prioritize them.

	* src/file-manager/fm-icon-container.c:
	(fm_icon_container_prioritize_thumbnailing),
	(fm_icon_container_class_init):
	Implement prioritize_thumbnailing.
parent 6043a430
2003-03-12 Alexander Larsson <alexl@redhat.com>
* libnautilus-private/nautilus-file-private.h:
* libnautilus-private/nautilus-file.c: (finalize),
(nautilus_file_invalidate_attributes_internal),
(nautilus_file_is_thumbnailing),
(nautilus_file_set_is_thumbnailing):
* libnautilus-private/nautilus-file.h:
Keep track of whether the file is being thumbnailed.
If it is at finalization, remove from the thumbnail queue.
* libnautilus-private/nautilus-icon-container.h:
* libnautilus-private/nautilus-icon-container.c:
(redo_layout_internal), (realize),
(nautilus_icon_container_instance_init),
(nautilus_icon_container_prioritize_thumbnailing),
(nautilus_icon_container_prioritize_thumbnailing_for_visible_icons)
, (handle_vadjustment_changed):
Prioritize thumbnailing for icons visibile on the screen.
* libnautilus-private/nautilus-icon-factory.c:
(show_thumbnails_changed_callback):
Remove all thumbnails from queue when thumbnails are disabled.
* libnautilus-private/nautilus-thumbnails.h:
* libnautilus-private/nautilus-thumbnails.c: (free_thumbnail_info),
(nautilus_thumbnail_remove_from_queue),
(nautilus_thumbnail_remove_all_from_queue),
(nautilus_thumbnail_prioritize),
(thumbnail_thread_notify_file_changed),
(nautilus_create_thumbnail), (thumbnail_thread_start):
New functions to remove thumbnails from the queue and to prioritize them.
* src/file-manager/fm-icon-container.c:
(fm_icon_container_prioritize_thumbnailing),
(fm_icon_container_class_init):
Implement prioritize_thumbnailing.
2003-03-11 Alexander Larsson <alexl@redhat.com>
* src/nautilus-window.c (nautilus_window_save_geometry):
......
......@@ -125,6 +125,8 @@ struct NautilusFileDetails
eel_boolean_bit got_link_info : 1;
eel_boolean_bit link_info_is_up_to_date : 1;
eel_boolean_bit is_thumbnailing : 1;
};
NautilusFile *nautilus_file_new_from_info (NautilusDirectory *directory,
......@@ -174,4 +176,9 @@ gboolean nautilus_file_rename_in_progress (NautilusFile
GnomeVFSFileInfo *nautilus_file_peek_vfs_file_info (NautilusFile *file);
/* Thumbnailing: */
void nautilus_file_set_is_thumbnailing (NautilusFile *file,
gboolean is_thumbnailing);
#endif
......@@ -36,6 +36,7 @@
#include "nautilus-link.h"
#include "nautilus-link-desktop-file.h"
#include "nautilus-metadata.h"
#include "nautilus-thumbnails.h"
#include "nautilus-trash-directory.h"
#include "nautilus-trash-file.h"
#include "nautilus-vfs-file.h"
......@@ -391,11 +392,18 @@ finalize (GObject *object)
{
NautilusDirectory *directory;
NautilusFile *file;
char *uri;
file = NAUTILUS_FILE (object);
g_assert (file->details->operations_in_progress == NULL);
if (file->details->is_thumbnailing) {
uri = nautilus_file_get_uri (file);
nautilus_thumbnail_remove_from_queue (uri);
g_free (uri);
}
if (file->details->monitor != NULL) {
nautilus_monitor_cancel (file->details->monitor);
}
......@@ -5057,6 +5065,23 @@ nautilus_file_invalidate_attributes_internal (NautilusFile *file,
/* FIXME bugzilla.gnome.org 45075: implement invalidating metadata */
}
gboolean
nautilus_file_is_thumbnailing (NautilusFile *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE);
return file->details->is_thumbnailing;
}
void
nautilus_file_set_is_thumbnailing (NautilusFile *file,
gboolean is_thumbnailing)
{
g_return_if_fail (NAUTILUS_IS_FILE (file));
file->details->is_thumbnailing = is_thumbnailing;
}
/**
* nautilus_file_invalidate_attributes
......
......@@ -298,6 +298,10 @@ char * nautilus_file_get_drop_target_uri (Nautilu
/* Get custom icon (if specified by metadata or link contents) */
char * nautilus_file_get_custom_icon (NautilusFile *file);
/* Thumbnailing handling */
gboolean nautilus_file_is_thumbnailing (NautilusFile *file);
/* Convenience functions for dealing with a list of NautilusFile objects that each have a ref.
* These are just convenient names for functions that work on lists of GtkObject *.
*/
......
......@@ -4,6 +4,7 @@
Copyright (C) 1999, 2000 Free Software Foundation
Copyright (C) 2000, 2001 Eazel, Inc.
Copyright (C) 2002, 2003 Red Hat, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
......@@ -166,6 +167,9 @@ static void nautilus_icon_container_stop_monitor_top_left (NautilusIco
static void nautilus_icon_container_start_monitor_top_left (NautilusIconContainer *container,
NautilusIconData *data,
gconstpointer client);
static void handle_vadjustment_changed (GtkAdjustment *adjustment,
NautilusIconContainer *container);
static void nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconContainer *container);
static int click_policy_auto_value;
......@@ -1302,6 +1306,7 @@ redo_layout_internal (NautilusIconContainer *container)
process_pending_icon_to_reveal (container);
process_pending_icon_to_rename (container);
nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (container);
}
static gboolean
......@@ -2490,6 +2495,7 @@ realize (GtkWidget *widget)
{
GtkWindow *window;
GdkBitmap *stipple;
GtkAdjustment *vadj;
GTK_WIDGET_CLASS (parent_class)->realize (widget);
......@@ -2507,6 +2513,11 @@ realize (GtkWidget *widget)
gdk_drawable_get_screen (GDK_DRAWABLE (widget->window)));
nautilus_icon_dnd_set_stipple (NAUTILUS_ICON_CONTAINER (widget), stipple);
vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (widget));
g_signal_connect (vadj, "value_changed",
G_CALLBACK (handle_vadjustment_changed), widget);
}
static void
......@@ -3633,7 +3644,7 @@ nautilus_icon_container_instance_init (NautilusIconContainer *container)
G_CALLBACK (handle_focus_out_event), NULL);
eel_background_set_use_base (background, TRUE);
/* read in theme-dependent data */
nautilus_icon_container_theme_changed (container);
eel_preferences_add_callback (NAUTILUS_PREFERENCES_THEME,
......@@ -4071,6 +4082,70 @@ nautilus_icon_container_stop_monitor_top_left (NautilusIconContainer *container,
}
static void
nautilus_icon_container_prioritize_thumbnailing (NautilusIconContainer *container,
NautilusIcon *icon)
{
NautilusIconContainerClass *klass;
klass = NAUTILUS_ICON_CONTAINER_GET_CLASS (container);
g_return_if_fail (klass->prioritize_thumbnailing != NULL);
klass->prioritize_thumbnailing (container, icon->data);
}
static void
nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconContainer *container)
{
GtkAdjustment *vadj;
double min_y, max_y;
double x0, y0, x1, y1;
GList *node;
NautilusIcon *icon;
vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (container));
min_y = vadj->value;
max_y = min_y + GTK_WIDGET (container)->allocation.height;
eel_canvas_c2w (EEL_CANVAS (container),
0, min_y, NULL, &min_y);
eel_canvas_c2w (EEL_CANVAS (container),
0, max_y, NULL, &max_y);
/* Do the iteration in reverse to get the render-order from top to bottom */
for (node = g_list_last (container->details->icons); node != NULL; node = node->prev) {
icon = node->data;
if (icon_is_positioned (icon)) {
eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon->item),
&x0,
&y0,
&x1,
&y1);
eel_canvas_item_i2w (EEL_CANVAS_ITEM (icon->item)->parent,
&x0,
&y0);
eel_canvas_item_i2w (EEL_CANVAS_ITEM (icon->item)->parent,
&x1,
&y1);
if (y1 >= min_y && y0 <= max_y) {
nautilus_icon_container_prioritize_thumbnailing (container,
icon);
}
}
}
}
static void
handle_vadjustment_changed (GtkAdjustment *adjustment,
NautilusIconContainer *container)
{
nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (container);
}
void
nautilus_icon_container_update_icon (NautilusIconContainer *container,
NautilusIcon *icon)
......
......@@ -126,6 +126,8 @@ typedef struct {
void (* stop_monitor_top_left) (NautilusIconContainer *container,
NautilusIconData *data,
gconstpointer client);
void (* prioritize_thumbnailing) (NautilusIconContainer *container,
NautilusIconData *data);
/* Queries on icons for subclass/client.
* These must be implemented => These are signals !
......
......@@ -650,6 +650,10 @@ show_thumbnails_changed_callback (gpointer user_data)
show_image_thumbs = eel_preferences_get_enum (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS);
nautilus_icon_factory_clear ();
/* If the user disabled thumbnailing, remove all outstanding thumbnails */
if (show_image_thumbs == NAUTILUS_SPEED_TRADEOFF_NEVER) {
nautilus_thumbnail_remove_all_from_queue ();
}
g_signal_emit (global_icon_factory,
signals[ICONS_CHANGED], 0);
}
......
......@@ -3,6 +3,7 @@
nautilus-thumbnails.h: Thumbnail code for icon factory.
Copyright (C) 2000, 2001 Eazel, Inc.
Copyright (C) 2002, 2003 Red Hat, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
......@@ -57,6 +58,15 @@
static gpointer thumbnail_thread_start (gpointer data);
/* structure used for making thumbnails, associating a uri with where the thumbnail is to be stored */
typedef struct {
char *image_uri;
char *mime_type;
time_t original_file_mtime;
} NautilusThumbnailInfo;
/*
* Thumbnail thread state.
*/
......@@ -77,6 +87,9 @@ static volatile gboolean thumbnail_thread_is_running = FALSE;
/* The list of NautilusThumbnailInfo structs containing information about the
thumbnails we are making. Lock thumbnails_mutex when accessing this. */
static volatile GList *thumbnails_to_make = NULL;
/* The currently thumbnailed icon. it also exists in the thumbnails_to_make list
* to avoid adding it again. Lock thumbnails_mutex when accessing this. */
static NautilusThumbnailInfo *currently_thumbnailing = NULL;
static GnomeThumbnailFactory *thumbnail_factory = NULL;
......@@ -99,15 +112,6 @@ get_file_mtime (const char *file_uri, time_t* mtime)
return TRUE;
}
/* structure used for making thumbnails, associating a uri with where the thumbnail is to be stored */
typedef struct {
char *image_uri;
char *mime_type;
time_t original_file_mtime;
} NautilusThumbnailInfo;
/* GCompareFunc-style function for comparing NautilusThumbnailInfos.
* Returns 0 if they refer to the same uri.
*/
......@@ -123,6 +127,14 @@ compare_thumbnail_info (gconstpointer a, gconstpointer b)
return strcmp (info_a->image_uri, info_b->image_uri) != 0;
}
static void
free_thumbnail_info (NautilusThumbnailInfo *info)
{
g_free (info->image_uri);
g_free (info->mime_type);
g_free (info);
}
/* This function is added as a very low priority idle function to start the
thread to create any needed thumbnails. It is added with a very low priority
so that it doesn't delay showing the directory in the icon/list views.
......@@ -263,6 +275,113 @@ nautilus_thumbnail_load_framed_image (const char *path)
}
void
nautilus_thumbnail_remove_from_queue (const char *file_uri)
{
NautilusThumbnailInfo info;
GList *node;
#ifdef DEBUG_THUMBNAILS
g_message ("(Remove from queue) Locking mutex\n");
#endif
pthread_mutex_lock (&thumbnails_mutex);
/*********************************
* MUTEX LOCKED
*********************************/
info.image_uri = (char *)file_uri;
info.mime_type = NULL;
node = g_list_find_custom ((GList*) thumbnails_to_make, &info,
compare_thumbnail_info);
if (node && node->data != currently_thumbnailing) {
free_thumbnail_info (node->data);
thumbnails_to_make = g_list_delete_link ((GList *)thumbnails_to_make, node);
}
/*********************************
* MUTEX UNLOCKED
*********************************/
#ifdef DEBUG_THUMBNAILS
g_message ("(Remove from queue) Unlocking mutex\n");
#endif
pthread_mutex_unlock (&thumbnails_mutex);
}
void
nautilus_thumbnail_remove_all_from_queue (void)
{
GList *l, *next;
#ifdef DEBUG_THUMBNAILS
g_message ("(Remove all from queue) Locking mutex\n");
#endif
pthread_mutex_lock (&thumbnails_mutex);
/*********************************
* MUTEX LOCKED
*********************************/
l = (GList *)thumbnails_to_make;
while (l != NULL) {
next = l->next;
if (l->data != currently_thumbnailing) {
free_thumbnail_info (l->data);
thumbnails_to_make = g_list_delete_link ((GList *)thumbnails_to_make, l);
}
l = next;
}
/*********************************
* MUTEX UNLOCKED
*********************************/
#ifdef DEBUG_THUMBNAILS
g_message ("(Remove all from queue) Unlocking mutex\n");
#endif
pthread_mutex_unlock (&thumbnails_mutex);
}
void
nautilus_thumbnail_prioritize (const char *file_uri)
{
NautilusThumbnailInfo info;
GList *node;
#ifdef DEBUG_THUMBNAILS
g_message ("(Prioritize) Locking mutex\n");
#endif
pthread_mutex_lock (&thumbnails_mutex);
/*********************************
* MUTEX LOCKED
*********************************/
info.image_uri = (char *)file_uri;
info.mime_type = NULL;
node = g_list_find_custom ((GList*) thumbnails_to_make, &info,
compare_thumbnail_info);
if (node && node->data != currently_thumbnailing) {
thumbnails_to_make = g_list_remove_link ((GList *)thumbnails_to_make, node);
thumbnails_to_make = g_list_concat (node, (GList *)thumbnails_to_make);
}
/*********************************
* MUTEX UNLOCKED
*********************************/
#ifdef DEBUG_THUMBNAILS
g_message ("(Prioritize) Unlocking mutex\n");
#endif
pthread_mutex_unlock (&thumbnails_mutex);
}
/***************************************************************************
* Thumbnail Thread Functions.
......@@ -286,6 +405,7 @@ thumbnail_thread_notify_file_changed (gpointer image_uri)
#endif
if (file != NULL) {
nautilus_file_set_is_thumbnailing (file, FALSE);
nautilus_file_changed (file);
nautilus_file_unref (file);
}
......@@ -302,6 +422,8 @@ nautilus_create_thumbnail (NautilusFile *file)
time_t file_mtime = 0;
NautilusThumbnailInfo *info;
nautilus_file_set_is_thumbnailing (file, TRUE);
info = g_new0 (NautilusThumbnailInfo, 1);
info->image_uri = nautilus_file_get_uri (file);
info->mime_type = nautilus_file_get_mime_type (file);
......@@ -347,9 +469,7 @@ nautilus_create_thumbnail (NautilusFile *file)
thumbnail_thread_starter_id = g_idle_add_full (G_PRIORITY_LOW, thumbnail_thread_starter_cb, NULL, NULL);
}
} else {
g_free (info->image_uri);
g_free (info->mime_type);
g_free (info);
free_thumbnail_info (info);
}
/*********************************
......@@ -385,11 +505,11 @@ thumbnail_thread_start (gpointer data)
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. */
if (thumbnails_to_make && info == thumbnails_to_make->data) {
thumbnails_to_make = g_list_remove ((GList*) thumbnails_to_make, info);
g_free (info->image_uri);
g_free (info->mime_type);
g_free (info);
if (currently_thumbnailing) {
g_assert (info == currently_thumbnailing);
free_thumbnail_info (currently_thumbnailing);
thumbnails_to_make = g_list_remove ((GList*) thumbnails_to_make, currently_thumbnailing);
currently_thumbnailing = NULL;
}
/* If there are no more thumbnails to make, reset the
......@@ -408,7 +528,7 @@ thumbnail_thread_start (gpointer data)
is created so the main thread doesn't add it again while we
are creating it. */
info = thumbnails_to_make->data;
currently_thumbnailing = info;
/*********************************
* MUTEX UNLOCKED
*********************************/
......
......@@ -35,4 +35,10 @@ void nautilus_update_thumbnail_file_renamed (const char *old_file_uri,
const char *new_file_uri);
void nautilus_remove_thumbnail_for_file (const char *old_file_uri);
/* Queue handling: */
void nautilus_thumbnail_remove_from_queue (const char *file_uri);
void nautilus_thumbnail_remove_all_from_queue (void);
void nautilus_thumbnail_prioritize (const char *file_uri);
#endif /* NAUTILUS_THUMBNAILS_H */
......@@ -30,6 +30,7 @@
#include <eel/eel-string.h>
#include <libnautilus-private/nautilus-global-preferences.h>
#include <libnautilus-private/nautilus-file-attributes.h>
#include <libnautilus-private/nautilus-thumbnails.h>
#include "fm-icon-container.h"
......@@ -114,6 +115,24 @@ fm_icon_container_stop_monitor_top_left (NautilusIconContainer *container,
nautilus_file_monitor_remove (file, client);
}
static void
fm_icon_container_prioritize_thumbnailing (NautilusIconContainer *container,
NautilusIconData *data)
{
NautilusFile *file;
char *uri;
file = (NautilusFile *) data;
g_assert (NAUTILUS_IS_FILE (file));
if (nautilus_file_is_thumbnailing (file)) {
uri = nautilus_file_get_uri (file);
nautilus_thumbnail_prioritize (uri);
g_free (uri);
}
}
/*
* Get the preference for which caption text should appear
......@@ -427,6 +446,7 @@ fm_icon_container_class_init (FMIconContainerClass *klass)
ic_class->get_icon_images = fm_icon_container_get_icon_images;
ic_class->start_monitor_top_left = fm_icon_container_start_monitor_top_left;
ic_class->stop_monitor_top_left = fm_icon_container_stop_monitor_top_left;
ic_class->prioritize_thumbnailing = fm_icon_container_prioritize_thumbnailing;
ic_class->compare_icons = fm_icon_container_compare_icons;
ic_class->compare_icons_by_name = fm_icon_container_compare_icons_by_name;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment