[Goodies-commits] r3472 - ristretto/trunk/src

Stephan Arts stephan at xfce.org
Mon Oct 29 10:41:56 CET 2007


Author: stephan
Date: 2007-10-29 09:41:56 +0000 (Mon, 29 Oct 2007)
New Revision: 3472

Modified:
   ristretto/trunk/src/Makefile.am
   ristretto/trunk/src/main.c
   ristretto/trunk/src/main_window.c
   ristretto/trunk/src/navigator.c
   ristretto/trunk/src/navigator.h
   ristretto/trunk/src/picture_viewer.c
Log:
Add cache to ristretto... (it now saves up to 5 images in memory after rendering them)



Modified: ristretto/trunk/src/Makefile.am
===================================================================
--- ristretto/trunk/src/Makefile.am	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/Makefile.am	2007-10-29 09:41:56 UTC (rev 3472)
@@ -3,9 +3,9 @@
 ristretto_SOURCES = \
 	main.c \
     main_window.c main_window.h \
+	navigator.c navigator.h \
 	picture_viewer.c picture_viewer.h \
-	thumbnail_viewer.c thumbnail_viewer.h \
-	navigator.c navigator.h
+	thumbnail_viewer.c thumbnail_viewer.h
 
 ristretto_CFLAGS = \
 	$(GTK_CFLAGS) \

Modified: ristretto/trunk/src/main.c
===================================================================
--- ristretto/trunk/src/main.c	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/main.c	2007-10-29 09:41:56 UTC (rev 3472)
@@ -132,7 +132,6 @@
                     const gchar *filename = g_dir_read_name(dir);
                     while (filename)
                     {
-                        rstto_navigator_set_is_album(navigator, FALSE);
                         gchar *path_name = g_strconcat(path_string,  "/", filename, NULL);
                         ThunarVfsPath *file_path = thunar_vfs_path_new(path_name, NULL);
                         if (file_path)
@@ -141,7 +140,7 @@
                             gchar *file_media = thunar_vfs_mime_info_get_media(file_info->mime_info);
                             if(!strcmp(file_media, "image"))
                             {
-                                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(file_info);
+                                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(navigator, file_info);
                                 gint i = rstto_navigator_add (navigator, entry);
                                 if (!strcmp(path_name, argv[n]))
                                 {
@@ -161,7 +160,6 @@
                 {
                     GDir *dir = g_dir_open(argv[n], 0, NULL);
                     const gchar *filename = g_dir_read_name(dir);
-                    rstto_navigator_set_is_album(navigator, TRUE);
                     while (filename)
                     {
                         gchar *path_name = g_strconcat(argv[n],  "/", filename, NULL);
@@ -172,7 +170,7 @@
                             gchar *file_media = thunar_vfs_mime_info_get_media(file_info->mime_info);
                             if(!strcmp(file_media, "image"))
                             {
-                                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(file_info);
+                                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(navigator, file_info);
                                 rstto_navigator_add (navigator, entry);
                             }
                             g_free(file_media);

Modified: ristretto/trunk/src/main_window.c
===================================================================
--- ristretto/trunk/src/main_window.c	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/main_window.c	2007-10-29 09:41:56 UTC (rev 3472)
@@ -947,7 +947,6 @@
     gtk_menu_shell_insert(GTK_MENU_SHELL(window->priv->menus.go.menu), window->priv->menus.go.menu_item_pause, 5);
     gtk_widget_show_all(window->priv->menus.go.menu_item_pause);
     rstto_navigator_set_running(RSTTO_NAVIGATOR(window->priv->navigator), TRUE);
-    rstto_picture_viewer_set_timeout(RSTTO_PICTURE_VIEWER(window->priv->picture_viewer), FALSE);
 }
 
 static void
@@ -958,7 +957,6 @@
     gtk_menu_shell_insert(GTK_MENU_SHELL(window->priv->menus.go.menu), window->priv->menus.go.menu_item_play, 5);
     gtk_widget_show_all(window->priv->menus.go.menu_item_play);
     rstto_navigator_set_running(RSTTO_NAVIGATOR(window->priv->navigator), FALSE);
-    rstto_picture_viewer_set_timeout(RSTTO_PICTURE_VIEWER(window->priv->picture_viewer), TRUE);
 }
 
 static void
@@ -1022,12 +1020,7 @@
             gchar *file_media = thunar_vfs_mime_info_get_media(info->mime_info);
             if(!strcmp(file_media, "image"))
             {
-                if(rstto_navigator_get_is_album(window->priv->navigator) == TRUE)
-                {
-                    rstto_navigator_clear(window->priv->navigator);
-                }
-                rstto_navigator_set_is_album(window->priv->navigator, FALSE);
-                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(info);
+                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(window->priv->navigator, info);
                 rstto_navigator_add (window->priv->navigator, entry);
                 gchar *uri = thunar_vfs_path_dup_uri(info->path);
                 gtk_recent_manager_add_item(window->priv->manager, uri);
@@ -1064,7 +1057,6 @@
     if(response == GTK_RESPONSE_OK)
     {
         rstto_navigator_clear(window->priv->navigator);
-        rstto_navigator_set_is_album(window->priv->navigator, TRUE);
         const gchar *dir_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
         GDir *dir = g_dir_open(dir_name, 0, NULL);
         if (dir)
@@ -1080,7 +1072,7 @@
                     gchar *file_media = thunar_vfs_mime_info_get_media(info->mime_info);
                     if(!strcmp(file_media, "image"))
                     {
-                        RsttoNavigatorEntry *entry = rstto_navigator_entry_new(info);
+                        RsttoNavigatorEntry *entry = rstto_navigator_entry_new(window->priv->navigator, info);
                         rstto_navigator_add (window->priv->navigator, entry);
                     }
                     g_free(file_media);
@@ -1111,18 +1103,12 @@
         {
             if(strcmp(thunar_vfs_mime_info_get_name(info->mime_info), "inode/directory"))
             {
-                if(rstto_navigator_get_is_album(window->priv->navigator) == TRUE)
-                {
-                    rstto_navigator_clear(window->priv->navigator);
-                }
-                rstto_navigator_set_is_album(window->priv->navigator, FALSE);
-                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(info);
+                RsttoNavigatorEntry *entry = rstto_navigator_entry_new(window->priv->navigator, info);
                 rstto_navigator_add (window->priv->navigator, entry);
             }
             else
             {
                 rstto_navigator_clear(window->priv->navigator);
-                rstto_navigator_set_is_album(window->priv->navigator, TRUE);
                 gchar *dir_path = thunar_vfs_path_dup_string(info->path);
                 GDir *dir = g_dir_open(dir_path, 0, NULL);
                 const gchar *filename = g_dir_read_name(dir);
@@ -1136,7 +1122,7 @@
                         gchar *file_media = thunar_vfs_mime_info_get_media(file_info->mime_info);
                         if(!strcmp(file_media, "image"))
                         {
-                            RsttoNavigatorEntry *entry = rstto_navigator_entry_new(file_info);
+                            RsttoNavigatorEntry *entry = rstto_navigator_entry_new(window->priv->navigator, file_info);
                             rstto_navigator_add (window->priv->navigator, entry);
                         }
                         g_free(file_media);

Modified: ristretto/trunk/src/navigator.c
===================================================================
--- ristretto/trunk/src/navigator.c	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/navigator.c	2007-10-29 09:41:56 UTC (rev 3472)
@@ -39,6 +39,25 @@
 static gint
 rstto_navigator_entry_name_compare_func(RsttoNavigatorEntry *a, RsttoNavigatorEntry *b);
 
+static void
+cb_rstto_navigator_entry_area_prepared (GdkPixbufLoader *loader, RsttoNavigatorEntry *entry);
+static void
+cb_rstto_navigator_entry_closed (GdkPixbufLoader *loader, RsttoNavigatorEntry *entry);
+static gboolean
+cb_rstto_navigator_entry_read_file(GIOChannel *io_channel, GIOCondition cond, RsttoNavigatorEntry *entry);
+
+static gboolean
+cb_rstto_navigator_entry_update_image (RsttoNavigatorEntry *entry);
+
+static void
+cb_rstto_navigator_entry_fs_event (ThunarVfsMonitor *,
+                                   ThunarVfsMonitorHandle *,
+                                   ThunarVfsMonitorEvent,
+                                   ThunarVfsPath *,
+                                   ThunarVfsPath *,
+                                   RsttoNavigatorEntry *);
+
+
 enum
 {
     RSTTO_NAVIGATOR_SIGNAL_ENTRY_MODIFIED = 0,
@@ -51,10 +70,25 @@
 struct _RsttoNavigatorEntry
 {
     ThunarVfsInfo       *info;
+    GdkPixbufLoader     *loader;
+    ExifData            *exif_data;
+    ThunarVfsMonitorHandle *monitor_handle;
+
     GdkPixbuf           *thumb;
+
+    GdkPixbufAnimation  *animation;
+    GdkPixbufAnimationIter *iter;
+    GdkPixbuf           *src_pixbuf;
+
+    GIOChannel          *io_channel;
+    gint                 io_source_id;
+    gint                 timeout_id;
+
+    RsttoNavigator      *navigator;
+
+
     gdouble              scale;
     gboolean             fit_to_screen;
-    ExifData            *exif_data;
     GdkPixbufRotation    rotation;
     gboolean             h_flipped;
     gboolean             v_flipped;
@@ -96,7 +130,7 @@
     navigator->compare_func = (GCompareFunc)rstto_navigator_entry_name_compare_func;
     navigator->old_position = -1;
     navigator->timeout = 5000;
-    navigator->album = FALSE;
+    navigator->monitor = thunar_vfs_monitor_get_default();
 
     navigator->factory = thunar_vfs_thumb_factory_new(THUNAR_VFS_THUMB_SIZE_NORMAL);
 }
@@ -126,10 +160,9 @@
             0,
             NULL,
             NULL,
-            g_cclosure_marshal_VOID__UINT_POINTER,
+            g_cclosure_marshal_VOID__POINTER,
             G_TYPE_NONE,
-            2,
-            G_TYPE_UINT,
+            1,
             G_TYPE_POINTER,
             NULL);
     rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_ITER_CHANGED] = g_signal_new("iter-changed",
@@ -178,11 +211,18 @@
 
     navigator = g_object_new(RSTTO_TYPE_NAVIGATOR, NULL);
 
-    navigator->icon_theme = gtk_icon_theme_new();
-
     return navigator;
 }
 
+/*
+ * static gint
+ * rstto_navigator_entry_name_compare_func:
+ *
+ * @a: RsttoNavigatorEntry 
+ * @b: RsttoNavigatorEntry
+ *
+ * Return value: see g_strcasecmp
+ */
 static gint
 rstto_navigator_entry_name_compare_func(RsttoNavigatorEntry *a, RsttoNavigatorEntry *b)
 {
@@ -190,10 +230,88 @@
 }
 
 void
+rstto_navigator_guard_history(RsttoNavigator *navigator, RsttoNavigatorEntry *entry)
+{
+    /* check if the image is still loading, if so... don't cache the image */
+    if(entry->io_channel)
+    {
+        g_source_remove(entry->io_source_id);
+        entry->io_channel = NULL;
+        entry->io_source_id = 0;
+        if(entry->loader)
+        {
+            g_signal_handlers_disconnect_by_func(entry->loader , cb_rstto_navigator_entry_area_prepared, entry);
+            gdk_pixbuf_loader_close(entry->loader, NULL);
+            g_object_unref(entry->loader);
+            entry->loader = NULL;
+        }
+
+        if(entry->animation)
+        {
+            g_object_unref(entry->animation);
+            entry->animation = NULL;
+        }
+
+        if(entry->src_pixbuf)
+        {
+            gdk_pixbuf_unref(entry->src_pixbuf);
+            entry->src_pixbuf = NULL;
+        }
+    }
+
+    /* add image to the cache-history */
+    navigator->history = g_list_prepend(navigator->history, entry);
+
+    if (g_list_length(navigator->history) > 5)
+    {
+        GList *last_entry = g_list_last(navigator->history);
+        RsttoNavigatorEntry *nav_entry = last_entry->data;
+
+        if (nav_entry)
+        {
+
+            if(nav_entry->thumb)
+            {
+                gdk_pixbuf_unref(nav_entry->thumb);
+                nav_entry->thumb = NULL;
+            }
+
+            if(nav_entry->io_channel)
+            {
+                g_source_remove(nav_entry->io_source_id);
+                nav_entry->io_channel = NULL;
+                nav_entry->io_source_id = 0;
+            }
+
+            if(nav_entry->loader)
+            {
+                g_signal_handlers_disconnect_by_func(nav_entry->loader , cb_rstto_navigator_entry_area_prepared, nav_entry);
+                gdk_pixbuf_loader_close(nav_entry->loader, NULL);
+                g_object_unref(nav_entry->loader);
+                nav_entry->loader = NULL;
+            }
+            if(nav_entry->animation)
+            {
+                g_object_unref(nav_entry->animation);
+                nav_entry->animation = NULL;
+            }
+            if(nav_entry->src_pixbuf)
+            {
+                gdk_pixbuf_unref(nav_entry->src_pixbuf);
+                nav_entry->src_pixbuf = NULL;
+            }
+        }
+
+        navigator->history = g_list_remove(navigator->history, nav_entry);
+    }
+}
+
+void
 rstto_navigator_jump_first (RsttoNavigator *navigator)
 {
     if(navigator->file_iter)
     {
+        rstto_navigator_guard_history(navigator, navigator->file_iter->data);
         navigator->old_position = rstto_navigator_get_position(navigator);
     }
     navigator->file_iter = g_list_first(navigator->file_list);
@@ -208,6 +326,7 @@
 {
     if(navigator->file_iter)
     {
+        rstto_navigator_guard_history(navigator, navigator->file_iter->data);
         navigator->old_position = rstto_navigator_get_position(navigator);
         navigator->file_iter = g_list_next(navigator->file_iter);
     }
@@ -240,6 +359,7 @@
 {
     if(navigator->file_iter)
     {
+        rstto_navigator_guard_history(navigator, navigator->file_iter->data);
         navigator->old_position = rstto_navigator_get_position(navigator);
         navigator->file_iter = g_list_previous(navigator->file_iter);
     }
@@ -262,6 +382,7 @@
 {
     if(navigator->file_iter)
     {
+        rstto_navigator_guard_history(navigator, navigator->file_iter->data);
         navigator->old_position = rstto_navigator_get_position(navigator);
     }
     navigator->file_iter = g_list_last(navigator->file_list);
@@ -332,6 +453,8 @@
 gint
 rstto_navigator_add (RsttoNavigator *navigator, RsttoNavigatorEntry *entry)
 {
+    g_return_val_if_fail(navigator == entry->navigator, -1);
+
     navigator->file_list = g_list_insert_sorted(navigator->file_list, entry, navigator->compare_func);
     if (!navigator->file_iter)
     {
@@ -343,6 +466,9 @@
                       entry,
                       NULL);
     }
+
+    entry->monitor_handle = thunar_vfs_monitor_add_file(navigator->monitor, entry->info->path, (ThunarVfsMonitorCallback)cb_rstto_navigator_entry_fs_event, entry);
+
     g_signal_emit(G_OBJECT(navigator), rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_NEW_ENTRY], 0, g_list_index(navigator->file_list, entry), entry, NULL);
     return g_list_index(navigator->file_list, entry);
 }
@@ -387,8 +513,16 @@
             }
             return;
         }
+        if (g_list_find(navigator->history, entry))
+        {
+            navigator->history = g_list_remove(navigator->history, entry);
+        }
     }
     navigator->file_list = g_list_remove(navigator->file_list, entry);
+    if (entry->monitor_handle)
+    {
+        thunar_vfs_monitor_remove(navigator->monitor, entry->monitor_handle);
+    }
     if(g_list_length(navigator->file_list) == 0)
     {
         navigator->file_iter = NULL;
@@ -430,18 +564,6 @@
     }
 }
 
-void
-rstto_navigator_set_is_album (RsttoNavigator *navigator, gboolean album)
-{
-    navigator->album = album;
-}
-
-gboolean
-rstto_navigator_get_is_album (RsttoNavigator *navigator)
-{
-    return navigator->album;
-}
-
 /* Callbacks */
 
 static gboolean
@@ -477,7 +599,7 @@
 
 
 RsttoNavigatorEntry *
-rstto_navigator_entry_new (ThunarVfsInfo *info)
+rstto_navigator_entry_new (RsttoNavigator *navigator, ThunarVfsInfo *info)
 {
     RsttoNavigatorEntry *entry = NULL;
     gchar *filename = thunar_vfs_path_dup_string(info->path);
@@ -487,6 +609,7 @@
 
         entry->info = info;
         entry->exif_data = exif_data_new_from_file(filename);
+        entry->navigator = navigator;
         
         ExifEntry *exifentry = exif_data_get_entry(entry->exif_data, EXIF_TAG_ORIENTATION);
         if (exifentry)
@@ -583,6 +706,26 @@
         exif_data_free(nav_entry->exif_data);
         nav_entry->exif_data = NULL;
     }
+    
+    if(nav_entry->io_channel)
+    {
+        g_source_remove(nav_entry->io_source_id);
+    }
+
+    if(nav_entry->loader)
+    {
+        g_signal_handlers_disconnect_by_func(nav_entry->loader , cb_rstto_navigator_entry_area_prepared, nav_entry);
+        gdk_pixbuf_loader_close(nav_entry->loader, NULL);
+        g_object_unref(nav_entry->loader);
+    }
+    if(nav_entry->animation)
+    {
+        g_object_unref(nav_entry->animation);
+    }
+    if(nav_entry->src_pixbuf)
+    {
+        gdk_pixbuf_unref(nav_entry->src_pixbuf);
+    }
     thunar_vfs_info_unref(nav_entry->info);
     g_free(nav_entry);
 }
@@ -669,3 +812,242 @@
     return entry->exif_data;
 }
 
+
+GdkPixbufLoader *
+rstto_navigator_entry_get_pixbuf_loader (RsttoNavigatorEntry *entry)
+{
+    if (!entry->loader)
+    {
+        entry->loader = gdk_pixbuf_loader_new();
+    }
+    return entry->loader;
+}
+
+GdkPixbuf *
+rstto_navigator_entry_get_pixbuf (RsttoNavigatorEntry *entry)
+{
+    return entry->src_pixbuf;
+}
+
+gboolean
+rstto_navigator_entry_load_image (RsttoNavigatorEntry *entry)
+{
+    gchar *path = NULL;
+
+    if (entry->io_channel)
+    {
+        return FALSE;
+    }
+    if (entry->loader == NULL)
+    {
+        entry->loader = gdk_pixbuf_loader_new();
+
+        g_signal_connect(entry->loader, "area-prepared", G_CALLBACK(cb_rstto_navigator_entry_area_prepared), entry);
+        /*g_signal_connect(entry->loader, "area-updated", G_CALLBACK(cb_rstto_navigator_entry_area_updated), viewer);*/
+        g_signal_connect(entry->loader, "closed", G_CALLBACK(cb_rstto_navigator_entry_closed), entry);
+
+        path = thunar_vfs_path_dup_string(entry->info->path);
+        entry->io_channel = g_io_channel_new_file(path, "r", NULL);
+
+        g_io_channel_set_encoding(entry->io_channel, NULL, NULL);
+        entry->io_source_id = g_io_add_watch(entry->io_channel, G_IO_IN | G_IO_PRI, (GIOFunc)cb_rstto_navigator_entry_read_file, entry);
+    }
+    else
+    {
+        if (entry->src_pixbuf)
+        {
+            g_signal_emit(G_OBJECT(entry->navigator), rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_ENTRY_MODIFIED], 0, entry, NULL);
+        }
+    }
+
+    return TRUE;
+}
+
+
+static gboolean
+cb_rstto_navigator_entry_read_file(GIOChannel *io_channel, GIOCondition cond, RsttoNavigatorEntry *entry)
+{
+    gchar buffer[1024];
+    gsize bytes_read = 0;
+    GError *error = NULL;
+    GIOStatus status;
+
+    g_return_val_if_fail(io_channel == entry->io_channel, FALSE);
+
+    if (entry->loader)
+    {
+
+        status = g_io_channel_read_chars(io_channel, buffer, 1024, &bytes_read,  &error);
+
+        switch (status)
+        {
+            case G_IO_STATUS_NORMAL:
+                if(gdk_pixbuf_loader_write(entry->loader, (const guchar *)buffer, bytes_read, NULL) == FALSE)
+                {
+                    gdk_pixbuf_loader_close(entry->loader, NULL);
+                    entry->io_channel = NULL;
+                    return FALSE;
+                }
+                return TRUE;
+                break;
+            case G_IO_STATUS_EOF:
+                gdk_pixbuf_loader_write(entry->loader, (const guchar *)buffer, bytes_read, NULL);
+                gdk_pixbuf_loader_close(entry->loader, NULL);
+                entry->io_channel = NULL;
+                return FALSE;
+                break;
+            case G_IO_STATUS_ERROR:
+                gdk_pixbuf_loader_close(entry->loader, NULL);
+                g_io_channel_shutdown(io_channel, FALSE, NULL);
+                entry->io_channel = NULL;
+                return FALSE;
+                break;
+            case G_IO_STATUS_AGAIN:
+                return TRUE;
+                break;
+        }
+        g_io_channel_shutdown(io_channel, FALSE, NULL);
+    }
+    g_io_channel_shutdown(io_channel, FALSE, NULL);
+    return FALSE;
+}
+
+static void
+cb_rstto_navigator_entry_area_prepared (GdkPixbufLoader *loader, RsttoNavigatorEntry *entry)
+{
+    entry->animation = gdk_pixbuf_loader_get_animation(loader);
+    entry->iter = gdk_pixbuf_animation_get_iter(entry->animation, NULL);
+    if (entry->src_pixbuf)
+    {
+        gdk_pixbuf_unref(entry->src_pixbuf);
+        entry->src_pixbuf = NULL;
+    }
+
+    gint time = gdk_pixbuf_animation_iter_get_delay_time(entry->iter);
+
+    if (time != -1)
+    {
+        entry->timeout_id = g_timeout_add(time, (GSourceFunc)cb_rstto_navigator_entry_update_image, entry);
+    }   
+    else
+    {
+        entry->iter = NULL;
+    }
+    g_signal_emit(G_OBJECT(entry->navigator), rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_ENTRY_MODIFIED], 0, entry, NULL);
+}
+
+static void
+cb_rstto_navigator_entry_closed (GdkPixbufLoader *loader, RsttoNavigatorEntry *entry)
+{
+    if (entry->src_pixbuf)
+    {
+        gdk_pixbuf_unref(entry->src_pixbuf);
+        entry->src_pixbuf = NULL;
+    }
+
+    GdkPixbuf *pixbuf = NULL;
+
+    if (entry->iter)
+    {
+        pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(entry->iter);
+    }
+    else
+    {
+        if (entry->loader)
+        {
+            pixbuf = gdk_pixbuf_loader_get_pixbuf(entry->loader);
+        }
+    }
+
+   
+    if (pixbuf != NULL)
+    {
+        entry->src_pixbuf = gdk_pixbuf_rotate_simple(pixbuf, rstto_navigator_entry_get_rotation(entry));
+        if (rstto_navigator_entry_get_flip(entry, FALSE))
+        {
+            pixbuf = entry->src_pixbuf;
+            entry->src_pixbuf = gdk_pixbuf_flip(pixbuf, FALSE);
+            gdk_pixbuf_unref(pixbuf);
+        }
+
+        if (rstto_navigator_entry_get_flip(entry, TRUE))
+        {
+            pixbuf = entry->src_pixbuf;
+            entry->src_pixbuf = gdk_pixbuf_flip(pixbuf, TRUE);
+            gdk_pixbuf_unref(pixbuf);
+        }
+        g_signal_emit(G_OBJECT(entry->navigator), rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_ENTRY_MODIFIED], 0, entry, NULL);
+    }
+}
+
+static gboolean
+cb_rstto_navigator_entry_update_image (RsttoNavigatorEntry *entry)
+{
+    GdkPixbuf *src_pixbuf = NULL;
+
+    if (entry->iter)
+    {
+        if(gdk_pixbuf_animation_iter_advance(entry->iter, NULL))
+        {
+            /* Cleanup old image */
+            if (entry->src_pixbuf)
+            {
+                gdk_pixbuf_unref(entry->src_pixbuf);
+                entry->src_pixbuf = NULL;
+            }
+            entry->src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(entry->iter);
+            src_pixbuf = entry->src_pixbuf;
+
+            if (src_pixbuf)
+            {
+                entry->src_pixbuf = gdk_pixbuf_rotate_simple(src_pixbuf, rstto_navigator_entry_get_rotation(entry));
+                if (rstto_navigator_entry_get_flip(entry, FALSE))
+                {
+                    src_pixbuf = entry->src_pixbuf;
+                    entry->src_pixbuf = gdk_pixbuf_flip(src_pixbuf, FALSE);
+                    gdk_pixbuf_unref(src_pixbuf);
+                }
+
+                if (rstto_navigator_entry_get_flip(entry, TRUE))
+                {
+                    src_pixbuf = entry->src_pixbuf;
+                    entry->src_pixbuf = gdk_pixbuf_flip(src_pixbuf, TRUE);
+                    gdk_pixbuf_unref(src_pixbuf);
+                }
+            }
+        }
+
+        gint time = gdk_pixbuf_animation_iter_get_delay_time(entry->iter);
+        if (time != -1)
+        {
+            entry->timeout_id = g_timeout_add(time, (GSourceFunc)cb_rstto_navigator_entry_update_image, entry);
+        }
+        g_signal_emit(G_OBJECT(entry->navigator), rstto_navigator_signals[RSTTO_NAVIGATOR_SIGNAL_ENTRY_MODIFIED], 0, entry, NULL);
+
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static void
+cb_rstto_navigator_entry_fs_event (ThunarVfsMonitor *monitor,
+                                   ThunarVfsMonitorHandle *handl,
+                                   ThunarVfsMonitorEvent event,
+                                   ThunarVfsPath *handle_path,
+                                   ThunarVfsPath *event_path,
+                                   RsttoNavigatorEntry *entry)
+{
+    switch (event)
+    {
+        case THUNAR_VFS_MONITOR_EVENT_CHANGED:
+            break;
+        case THUNAR_VFS_MONITOR_EVENT_CREATED:
+            break;
+        case THUNAR_VFS_MONITOR_EVENT_DELETED:
+            rstto_navigator_remove(entry->navigator, entry);
+            rstto_navigator_entry_free(entry);
+            break;
+        default:
+            break;
+    }
+}

Modified: ristretto/trunk/src/navigator.h
===================================================================
--- ristretto/trunk/src/navigator.h	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/navigator.h	2007-10-29 09:41:56 UTC (rev 3472)
@@ -45,18 +45,20 @@
 
 struct _RsttoNavigator
 {
-    GObject             parent;
-    GtkIconTheme       *icon_theme;
-    ThunarVfsPath      *path;
-    GList              *file_list;
-    GList              *file_iter;
-    gboolean            album;
-    gint                old_position;
-    gboolean            running;
-    gint                timeout;
-    gint                id;
-    GCompareFunc        compare_func;
+    GObject                parent;
+    ThunarVfsMonitor      *monitor;
     ThunarVfsThumbFactory *factory;
+
+    ThunarVfsPath         *path;
+    GCompareFunc           compare_func;
+    GList                 *file_list;
+    GList                 *file_iter;
+    GList                 *history;
+
+    gint                   old_position;
+    gboolean               running;
+    gint                   timeout;
+    gint                   id;
 };
 
 typedef struct _RsttoNavigatorClass RsttoNavigatorClass;
@@ -102,14 +104,10 @@
 void
 rstto_navigator_clear (RsttoNavigator *navigator);
 void
-rstto_navigator_set_is_album (RsttoNavigator *navigator, gboolean album);
-gboolean
-rstto_navigator_get_is_album (RsttoNavigator *navigator);
-void
 rstto_navigator_set_entry_rotation (RsttoNavigator *navigator, RsttoNavigatorEntry *entry, GdkPixbufRotation rotation);
 
 RsttoNavigatorEntry *
-rstto_navigator_entry_new (ThunarVfsInfo *info);
+rstto_navigator_entry_new (RsttoNavigator *, ThunarVfsInfo *info);
 void
 rstto_navigator_entry_free(RsttoNavigatorEntry *nav_entry);
 ThunarVfsInfo *
@@ -134,6 +132,13 @@
 ExifData *
 rstto_navigator_entry_get_exif_data (RsttoNavigatorEntry *entry);
 
+GdkPixbufLoader *
+rstto_navigator_entry_get_pixbuf_loader (RsttoNavigatorEntry *entry);
+GdkPixbuf *
+rstto_navigator_entry_get_pixbuf (RsttoNavigatorEntry *entry);
+gboolean
+rstto_navigator_entry_load_image (RsttoNavigatorEntry *entry);
+
 G_END_DECLS
 
 #endif /* __RISTRETTO_NAVIGATOR_H__ */

Modified: ristretto/trunk/src/picture_viewer.c
===================================================================
--- ristretto/trunk/src/picture_viewer.c	2007-10-29 09:17:36 UTC (rev 3471)
+++ ristretto/trunk/src/picture_viewer.c	2007-10-29 09:41:56 UTC (rev 3472)
@@ -30,18 +30,13 @@
 
 struct _RsttoPictureViewerPriv
 {
-    GdkPixbufLoader  *loader;
-    GdkPixbufAnimation *animation;
-    GdkPixbufAnimationIter *iter;
-    GIOChannel       *io_channel;
+    RsttoNavigator   *navigator;
+    RsttoNavigatorEntry *entry;
+
     GdkPixbuf        *src_pixbuf;
     GdkPixbuf        *dst_pixbuf; /* The pixbuf which ends up on screen */
-    RsttoNavigator   *navigator;
     void             (*cb_value_changed)(GtkAdjustment *, RsttoPictureViewer *);
     gboolean          show_border;
-    GTimer           *timer;
-    gint              timeout_id;
-    gboolean          timeout;
     struct
     {
         gdouble x;
@@ -90,6 +85,9 @@
 static void
 cb_rstto_picture_viewer_nav_iter_changed(RsttoNavigator *, gint , RsttoNavigatorEntry *, RsttoPictureViewer *);
 static void
+cb_rstto_picture_viewer_nav_entry_modified(RsttoNavigator *, RsttoNavigatorEntry *, RsttoPictureViewer *);
+
+static void
 cb_rstto_picture_viewer_value_changed(GtkAdjustment *, RsttoPictureViewer *);
 static void
 cb_rstto_picture_viewer_scroll_event (RsttoPictureViewer *, GdkEventScroll *);
@@ -104,20 +102,6 @@
 static void
 cb_rstto_picture_viewer_popup_menu (RsttoPictureViewer *viewer, gboolean user_data);
 
-static gboolean
-cb_rstto_picture_viewer_update_image(RsttoPictureViewer *viewer);
-
-static gboolean
-cb_rstto_picture_viewer_read_file(GIOChannel *io_channel, GIOCondition cond, RsttoPictureViewer *viewer);
-
-static void
-cb_rstto_picture_viewer_area_prepared(GdkPixbufLoader *loader, RsttoPictureViewer *viewer);
-static void
-cb_rstto_picture_viewer_area_updated(GdkPixbufLoader *loader, gint x, gint y, gint width, gint height, RsttoPictureViewer *viewer);
-static void
-cb_rstto_picture_viewer_closed(GdkPixbufLoader *loader, RsttoPictureViewer *viewer);
-
-
 static GtkWidgetClass *parent_class = NULL;
 
 GType
@@ -161,8 +145,6 @@
                            GDK_BUTTON1_MOTION_MASK);
 
     viewer->priv->show_border = TRUE;
-    viewer->priv->timer = g_timer_new();
-    viewer->priv->timeout = TRUE;
 
     g_signal_connect(G_OBJECT(viewer), "scroll_event", G_CALLBACK(cb_rstto_picture_viewer_scroll_event), NULL);
     g_signal_connect(G_OBJECT(viewer), "button_press_event", G_CALLBACK(cb_rstto_picture_viewer_button_press_event), NULL);
@@ -491,6 +473,7 @@
     widget = g_object_new(RSTTO_TYPE_PICTURE_VIEWER, NULL);
     RSTTO_PICTURE_VIEWER(widget)->priv->navigator = navigator;
     g_signal_connect(G_OBJECT(navigator), "iter-changed", G_CALLBACK(cb_rstto_picture_viewer_nav_iter_changed), widget);
+    g_signal_connect(G_OBJECT(navigator), "entry-modified", G_CALLBACK(cb_rstto_picture_viewer_nav_entry_modified), widget);
 
     return widget;
 }
@@ -743,119 +726,29 @@
     return changed;
 }
 
-static gboolean
-cb_rstto_picture_viewer_update_image(RsttoPictureViewer *viewer)
+static void
+cb_rstto_picture_viewer_nav_iter_changed(RsttoNavigator *nav, gint nr, RsttoNavigatorEntry *entry, RsttoPictureViewer *viewer)
 {
-    if (viewer->priv->iter)
-    {
-        if(gdk_pixbuf_animation_iter_advance(viewer->priv->iter, NULL))
-        {
-            /* Cleanup old image */
-            if (viewer->priv->src_pixbuf)
-            {
-                gdk_pixbuf_unref(viewer->priv->src_pixbuf);
-                viewer->priv->src_pixbuf = NULL;
-            }
-            RsttoNavigatorEntry *entry = rstto_navigator_get_file(viewer->priv->navigator);
-
-            if (entry)
-            {
-                GdkPixbuf *src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(viewer->priv->iter);
-                if (src_pixbuf)
-                {
-                    viewer->priv->src_pixbuf = gdk_pixbuf_rotate_simple(src_pixbuf, rstto_navigator_entry_get_rotation(entry));
-                    if (rstto_navigator_entry_get_flip(entry, FALSE))
-                    {
-                        src_pixbuf = viewer->priv->src_pixbuf;
-                        viewer->priv->src_pixbuf = gdk_pixbuf_flip(src_pixbuf, FALSE);
-                        gdk_pixbuf_unref(src_pixbuf);
-                    }
-
-                    if (rstto_navigator_entry_get_flip(entry, TRUE))
-                    {
-                        src_pixbuf = viewer->priv->src_pixbuf;
-                        viewer->priv->src_pixbuf = gdk_pixbuf_flip(src_pixbuf, TRUE);
-                        gdk_pixbuf_unref(src_pixbuf);
-                    }
-                }
-            }
-
-            rstto_picture_viewer_refresh(viewer);
-            rstto_picture_viewer_paint(GTK_WIDGET(viewer));
-
-            gint time = gdk_pixbuf_animation_iter_get_delay_time(viewer->priv->iter);
-            if (time != -1)
-            {
-                viewer->priv->timeout_id = g_timeout_add(time, (GSourceFunc)cb_rstto_picture_viewer_update_image, viewer);
-            }
-
-            return FALSE;
-        }
-    }
-    return TRUE;
+    viewer->priv->entry = entry;
+    rstto_navigator_entry_load_image(entry);
 }
 
 static void
-cb_rstto_picture_viewer_nav_iter_changed(RsttoNavigator *nav, gint nr, RsttoNavigatorEntry *entry, RsttoPictureViewer *viewer)
+cb_rstto_picture_viewer_nav_entry_modified(RsttoNavigator *nav, RsttoNavigatorEntry *entry, RsttoPictureViewer *viewer)
 {
-    GtkWidget *widget = GTK_WIDGET(viewer);
-    if(entry)
-    { 
-        if (GTK_WIDGET_REALIZED(widget))
+    if (entry == viewer->priv->entry)
+    {
+        if(viewer->priv->src_pixbuf)
         {
-            GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-            gdk_window_set_cursor(widget->window, cursor);
-            gdk_cursor_unref(cursor);
+            gdk_pixbuf_unref(viewer->priv->src_pixbuf);
         }
-        if (viewer->priv->loader)
-        {
-            g_signal_handlers_disconnect_by_func(viewer->priv->loader , cb_rstto_picture_viewer_area_prepared, viewer);
-            g_signal_handlers_disconnect_by_func(viewer->priv->loader , cb_rstto_picture_viewer_area_updated, viewer);
-            gdk_pixbuf_loader_close(viewer->priv->loader, NULL);
-            g_object_unref(viewer->priv->loader);
-            if (viewer->priv->iter)
-            {
-                viewer->priv->iter = NULL;
-            }
-            if(viewer->priv->animation)
-            {
-                g_object_unref(viewer->priv->animation);
-                viewer->priv->animation = NULL;
-            }
-            if(viewer->priv->src_pixbuf)
-            {
-                gdk_pixbuf_unref(viewer->priv->src_pixbuf);
-                viewer->priv->src_pixbuf = NULL;
-            }
-        }
-        viewer->priv->loader = gdk_pixbuf_loader_new();
-
-        g_signal_connect(viewer->priv->loader, "area-prepared", G_CALLBACK(cb_rstto_picture_viewer_area_prepared), viewer);
-        g_signal_connect(viewer->priv->loader, "area-updated", G_CALLBACK(cb_rstto_picture_viewer_area_updated), viewer);
-        g_signal_connect(viewer->priv->loader, "closed", G_CALLBACK(cb_rstto_picture_viewer_closed), viewer);
-        ThunarVfsInfo *info = rstto_navigator_entry_get_info(entry);
-        gchar *path = thunar_vfs_path_dup_string(info->path);
-
-        viewer->priv->io_channel = g_io_channel_new_file(path, "r", NULL);
-        g_io_channel_set_encoding(viewer->priv->io_channel, NULL, NULL);
-        g_io_add_watch(viewer->priv->io_channel, G_IO_IN | G_IO_PRI, (GIOFunc)cb_rstto_picture_viewer_read_file, viewer);
-    }
-    else
-    {
+        viewer->priv->src_pixbuf = rstto_navigator_entry_get_pixbuf(entry);
         if (viewer->priv->src_pixbuf)
         {
-            g_object_unref(viewer->priv->src_pixbuf);
-            viewer->priv->src_pixbuf = NULL;
+            gdk_pixbuf_ref(viewer->priv->src_pixbuf);
         }
-        if (viewer->priv->dst_pixbuf)
-        {
-            g_object_unref(viewer->priv->dst_pixbuf);
-            viewer->priv->dst_pixbuf = NULL;
-        }
-        if (GTK_WIDGET_REALIZED(widget))
-        {
-            rstto_picture_viewer_paint(GTK_WIDGET(viewer));
-        }
+        rstto_picture_viewer_refresh(viewer);
+        rstto_picture_viewer_paint(GTK_WIDGET(viewer));
     }
 }
 
@@ -887,169 +780,6 @@
     }
 }
 
-void
-rstto_picture_viewer_set_timeout(RsttoPictureViewer *viewer, gboolean timeout)
-{
-    viewer->priv->timeout = timeout;
-}
-
-static gboolean
-cb_rstto_picture_viewer_read_file(GIOChannel *io_channel, GIOCondition cond, RsttoPictureViewer *viewer)
-{
-    gchar buffer[1024];
-    gsize bytes_read = 0;
-    GError *error = NULL;
-
-
-    GIOStatus status;
-    if (viewer->priv->io_channel == io_channel)
-    {
-        status = g_io_channel_read_chars(io_channel, buffer, 1024, &bytes_read,  &error);
-
-        switch (status)
-        {
-            case G_IO_STATUS_NORMAL:
-                if(gdk_pixbuf_loader_write(viewer->priv->loader, (const guchar *)buffer, bytes_read, NULL) == FALSE)
-                {
-                    gdk_pixbuf_loader_close(viewer->priv->loader, NULL);
-                    viewer->priv->io_channel = NULL;
-                    return FALSE;
-                }
-                return TRUE;
-                break;
-            case G_IO_STATUS_EOF:
-                gdk_pixbuf_loader_write(viewer->priv->loader, (const guchar *)buffer, bytes_read, NULL);
-                gdk_pixbuf_loader_close(viewer->priv->loader, NULL);
-                viewer->priv->io_channel = NULL;
-                return FALSE;
-                break;
-            case G_IO_STATUS_ERROR:
-                gdk_pixbuf_loader_close(viewer->priv->loader, NULL);
-                viewer->priv->io_channel = NULL;
-                return FALSE;
-                break;
-            case G_IO_STATUS_AGAIN:
-                return TRUE;
-                break;
-        }
-    }
-    g_io_channel_shutdown(io_channel, FALSE, NULL);
-    return FALSE;
-}
-
-static void
-cb_rstto_picture_viewer_area_prepared(GdkPixbufLoader *loader, RsttoPictureViewer *viewer)
-{
-    viewer->priv->animation = gdk_pixbuf_loader_get_animation(loader);
-    viewer->priv->iter = gdk_pixbuf_animation_get_iter(viewer->priv->animation, NULL);
-    if (viewer->priv->src_pixbuf)
-    {
-        gdk_pixbuf_unref(viewer->priv->src_pixbuf);
-        viewer->priv->src_pixbuf = NULL;
-    }
-
-    gint time = gdk_pixbuf_animation_iter_get_delay_time(viewer->priv->iter);
-
-    rstto_picture_viewer_refresh(viewer);
-    rstto_picture_viewer_paint(GTK_WIDGET(viewer));
-
-    if (time != -1)
-    {
-        /* update frame */
-        viewer->priv->timeout_id = g_timeout_add(time, (GSourceFunc)cb_rstto_picture_viewer_update_image, viewer);
-    }   
-    else
-    {
-        viewer->priv->iter = NULL;
-    }
-}
-
-static void
-cb_rstto_picture_viewer_area_updated(GdkPixbufLoader *loader, gint x, gint y, gint width, gint height, RsttoPictureViewer *viewer)
-{
-    if (viewer->priv->iter)
-    {
-        /* Current Frame being updated?! */
-        if (gdk_pixbuf_animation_iter_on_currently_loading_frame(viewer->priv->iter) == TRUE)
-        {
-            /* Is it inside the viewport? */
-            RsttoNavigatorEntry *entry = rstto_navigator_get_file(viewer->priv->navigator);
-            gdouble scale = rstto_navigator_entry_get_scale(entry);
-            if (((viewer->vadjustment->value > (y * scale)) && (viewer->vadjustment->value < ((y+height) * scale))) &&
-                ((viewer->hadjustment->value > (x * scale)) && (viewer->hadjustment->value < ((x+width) * scale))))
-            {
-            
-            /* Update */
-            /*
-            gdk_pixbuf_unref(viewer->priv->src_pixbuf);
-            viewer->priv->src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(viewer->priv->iter);
-            gdk_pixbuf_ref(viewer->priv->src_pixbuf);
-            rstto_picture_viewer_refresh(viewer);
-            rstto_picture_viewer_paint(viewer);
-            */
-            }
-        }
-    }
-}
-
-static void
-cb_rstto_picture_viewer_closed(GdkPixbufLoader *loader, RsttoPictureViewer *viewer)
-{
-    GtkWidget *widget = GTK_WIDGET(viewer);
-
-    RsttoNavigatorEntry *entry = rstto_navigator_get_file(viewer->priv->navigator);
-
-    if (viewer->priv->src_pixbuf)
-    {
-        gdk_pixbuf_unref(viewer->priv->src_pixbuf);
-        viewer->priv->src_pixbuf = NULL;
-    }
-
-    if (entry)
-    {
-        GdkPixbuf *pixbuf = NULL;
-
-        if (viewer->priv->iter)
-        {
-            pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(viewer->priv->iter);
-        }
-        else
-        {
-            if (viewer->priv->loader)
-            {
-                pixbuf = gdk_pixbuf_loader_get_pixbuf(viewer->priv->loader);
-            }
-        }
-
-       
-        if (pixbuf != NULL)
-        {
-            viewer->priv->src_pixbuf = gdk_pixbuf_rotate_simple(pixbuf, rstto_navigator_entry_get_rotation(entry));
-            if (rstto_navigator_entry_get_flip(entry, FALSE))
-            {
-                pixbuf = viewer->priv->src_pixbuf;
-                viewer->priv->src_pixbuf = gdk_pixbuf_flip(pixbuf, FALSE);
-                gdk_pixbuf_unref(pixbuf);
-            }
-
-            if (rstto_navigator_entry_get_flip(entry, TRUE))
-            {
-                pixbuf = viewer->priv->src_pixbuf;
-                viewer->priv->src_pixbuf = gdk_pixbuf_flip(pixbuf, TRUE);
-                gdk_pixbuf_unref(pixbuf);
-            }
-        }
-        
-    }
-
-    rstto_picture_viewer_refresh(viewer);
-    rstto_picture_viewer_paint(GTK_WIDGET(viewer));
-    if (GTK_WIDGET_REALIZED(widget))
-    {
-        gdk_window_set_cursor(widget->window, NULL);
-    }
-}
-
 static gboolean 
 cb_rstto_picture_viewer_motion_notify_event (RsttoPictureViewer *viewer,
                                              GdkEventMotion *event,




More information about the Goodies-commits mailing list