Index: AUTHORS =================================================================== RCS file: /cvs/gnome/eog/AUTHORS,v retrieving revision 1.7 diff -u -r1.7 AUTHORS --- AUTHORS 29 Aug 2004 19:05:27 -0000 1.7 +++ AUTHORS 22 Jun 2005 10:35:13 -0000 @@ -3,3 +3,4 @@ Arik Devens (arik@gnome.org) Michael Meeks (michael@ximian.com) Martin Baulig (baulig@suse.de) +Philip Van Hoof (pvanhoof@gnome.org) Index: ChangeLog =================================================================== RCS file: /cvs/gnome/eog/ChangeLog,v retrieving revision 1.625 diff -u -r1.625 ChangeLog --- ChangeLog 17 Jun 2005 21:31:02 -0000 1.625 +++ ChangeLog 22 Jun 2005 10:35:13 -0000 @@ -1,3 +1,8 @@ +2005-06-22 Philip Van Hoof + + * libeog/eog-collection-item.c, libeog/eog-image-list.c: + notification of filesystem changes (rename, delete, create) + 2005-06-18 Tor Lillqvist * shell/main.c (get_installation_subdir, eog_get_datadir, Index: TODO =================================================================== RCS file: /cvs/gnome/eog/TODO,v retrieving revision 1.8 diff -u -r1.8 TODO --- TODO 29 May 2005 16:41:56 -0000 1.8 +++ TODO 22 Jun 2005 10:35:13 -0000 @@ -8,11 +8,6 @@ This is more or less an up-to-date (2005-05-29) list of things need to be done on the code in the HEAD branch: -* libeog/eog-image-list.c, libeog/eog-wrap-list.c: Allow deletion of -images through the user interface. - -* libeog/eog-image-list.c: React on changes in the file system, -eg. image changed or deleted (available through gnome-vfs wrapper) * Check for outdated thumbnails in .thumbnails directory (according to freedesktop.org thumbnail specification). Index: libeog/eog-collection-item.c =================================================================== RCS file: /cvs/gnome/eog/libeog/eog-collection-item.c,v retrieving revision 1.6 diff -u -r1.6 eog-collection-item.c --- libeog/eog-collection-item.c 5 Apr 2005 19:24:29 -0000 1.6 +++ libeog/eog-collection-item.c 22 Jun 2005 10:35:14 -0000 @@ -273,7 +273,10 @@ gboolean show_frame = FALSE; priv = EOG_COLLECTION_ITEM (data)->priv; - + + if (!priv) + return; + if (eog_job_get_success (job)) { /* success */ pixbuf = eog_image_get_pixbuf_thumbnail (priv->image); Index: libeog/eog-image-list.c =================================================================== RCS file: /cvs/gnome/eog/libeog/eog-image-list.c,v retrieving revision 1.10 diff -u -r1.10 eog-image-list.c --- libeog/eog-image-list.c 14 Mar 2005 20:35:13 -0000 1.10 +++ libeog/eog-image-list.c 22 Jun 2005 10:35:15 -0000 @@ -21,6 +21,11 @@ GList *node; }; +typedef struct { + GnomeVFSMonitorHandle *handle; + const gchar *text_uri; +} MonitorHandleContext; + struct _EogImageListPrivate { /* The age is incremented everytime the list is altered. Iterators are only valid if they have the same age */ @@ -35,6 +40,9 @@ /* the largest common part of all image uris */ GnomeVFSURI *base_uri; gboolean no_common_base; + + GList *monitors; + }; typedef struct { @@ -101,6 +109,16 @@ } static void +foreach_monitors_free (gpointer data, gpointer user_data) +{ + MonitorHandleContext *hctx = data; + + gnome_vfs_monitor_cancel (hctx->handle); + + g_free (data); +} + +static void eog_image_list_dispose (GObject *object) { EogImageList *list; @@ -126,6 +144,10 @@ gnome_vfs_uri_unref (priv->base_uri); priv->base_uri = NULL; } + + g_list_foreach (priv->monitors, + foreach_monitors_free, NULL); + g_list_free (priv->monitors); } static void @@ -142,6 +164,8 @@ priv->n_images = 0; priv->base_uri = NULL; priv->no_common_base = FALSE; + + priv->monitors = NULL; } static void @@ -361,6 +385,96 @@ /* ================== Directory Loading stuff ===================*/ + +static void +cleanup_dead_files (EogImageList *list) +{ + gint position = 0; + GList *node = NULL, *remove = NULL; + gboolean found = FALSE; + + if (list && list->priv) + node = list->priv->store; + + while (node != NULL && !found) { + GnomeVFSURI *uri = eog_image_get_uri(node->data); + if (!gnome_vfs_uri_exists (uri)) { + remove = g_list_append (remove, (gpointer)position); + } + node = node->next; + position++; + } + + while (remove) { + gint pos = (gint)remove->data; + EogIter *iter = eog_image_list_get_iter_by_pos (list, pos); + + if (iter) { + remove_image_private (list, iter); + g_signal_emit (list, eog_image_list_signals[IMAGE_REMOVED], 0, pos); + } + + remove = g_list_next (remove); + } + + g_list_free (remove); +} + +static void +vfs_monitor_dir_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + EogImageList *list = user_data; + GnomeVFSURI *uri = NULL; + EogImage *image = NULL; + GList *node=NULL; + gboolean found = FALSE; + + cleanup_dead_files (list); + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: + case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: + break; + + case GNOME_VFS_MONITOR_EVENT_CREATED: + + if (list && list->priv) { + node = list->priv->store; + + while (node != NULL && !found) { + + uri = eog_image_get_uri(node->data); + gchar *str = gnome_vfs_uri_to_string + (uri, GNOME_VFS_URI_HIDE_NONE); + found = (strcmp (str, info_uri)==0)?TRUE:FALSE; + g_free (str); + node = node->next; + } + } + + if (!found) { + uri = gnome_vfs_uri_new (info_uri); + image = eog_image_new_uri (uri); + + if (image) { + eog_image_list_add_image (list, image); + /* Q: g_object_unref (image) ? */ + } + } + gnome_vfs_uri_unref (uri); + break; + } + + return; +} + /* Called for each file in a directory. Checks if the file is some * sort of image. If so, it creates an image object and adds it to the * list. @@ -390,12 +504,10 @@ } if (load_uri) { - uri = gnome_vfs_uri_append_file_name (ctx->uri, rel_uri); - + uri = gnome_vfs_uri_append_file_name (ctx->uri, rel_uri); image = eog_image_new_uri (uri); gnome_vfs_uri_unref (uri); - - if (image != NULL) { + if (image != NULL) { add_image_private (list, image, FALSE); g_object_unref (image); } @@ -408,20 +520,30 @@ add_directory (EogImageList *list, GnomeVFSURI *uri, GnomeVFSFileInfo *info) { DirLoadingContext ctx; - + MonitorHandleContext *hctx = g_new0(MonitorHandleContext, 1); + + hctx->text_uri = gnome_vfs_uri_get_path (uri); + g_return_if_fail (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY); ctx.uri = uri; ctx.list = list; ctx.info = info; + gnome_vfs_monitor_add (&hctx->handle, hctx->text_uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfs_monitor_dir_cb, + list); + + list->priv->monitors = g_list_append (list->priv->monitors, hctx); + gnome_vfs_directory_visit_uri (uri, GNOME_VFS_FILE_INFO_DEFAULT | GNOME_VFS_FILE_INFO_FOLLOW_LINKS | GNOME_VFS_FILE_INFO_GET_MIME_TYPE, GNOME_VFS_DIRECTORY_VISIT_DEFAULT, directory_visit_cb, - &ctx); + &ctx); } static void @@ -591,10 +713,17 @@ void eog_image_list_add_image (EogImageList *list, EogImage *image) { + int pos; + g_return_if_fail (EOG_IS_IMAGE_LIST (list)); g_return_if_fail (EOG_IS_IMAGE (image)); - add_image_private (list, image, TRUE); + + pos = add_image_private (list, image, TRUE); + + if (pos >= 0) { + g_signal_emit (list, eog_image_list_signals[IMAGE_ADDED], 0, image, pos); + } } void @@ -602,15 +731,16 @@ { EogIter* iter; int pos; - + g_return_if_fail (EOG_IS_IMAGE_LIST (list)); g_return_if_fail (EOG_IS_IMAGE (image)); - + iter = eog_image_list_get_iter_by_img (list, image); if (iter == NULL) return; pos = remove_image_private (list, iter); + g_free (iter); if (pos >= 0) {