[gthumb] image viewer: adapt to the preloader changes



commit 6bf68a6ed1a9ecf17a235dfb0758c435f4e180b5
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Sep 14 18:19:58 2013 +0200

    image viewer: adapt to the preloader changes
    
    store the requested size in the image history to keep track when
    a better quality is needed by the viewer

 extensions/file_tools/gth-file-tool-resize.c    |    1 +
 extensions/image_viewer/gth-image-viewer-page.c |  346 ++++++++++++++++-------
 gthumb/cairo-utils.c                            |   26 ++
 gthumb/cairo-utils.h                            |    3 +
 gthumb/gth-image-history.c                      |   16 +-
 gthumb/gth-image-history.h                      |    3 +
 gthumb/gth-image-viewer.c                       |   35 +++-
 gthumb/gth-image-viewer.h                       |    3 +
 8 files changed, 322 insertions(+), 111 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-resize.c b/extensions/file_tools/gth-file-tool-resize.c
index ada52d2..e063fc7 100644
--- a/extensions/file_tools/gth-file-tool-resize.c
+++ b/extensions/file_tools/gth-file-tool-resize.c
@@ -178,6 +178,7 @@ resize_task_completed_cb (GthTask  *task,
        if (self->priv->final_resize) {
                gth_image_history_add_image (gth_image_viewer_page_get_history (GTH_IMAGE_VIEWER_PAGE 
(viewer_page)),
                                             self->priv->new_image,
+                                            -1,
                                             TRUE);
                gth_viewer_page_focus (GTH_VIEWER_PAGE (viewer_page));
                gth_file_tool_hide_options (GTH_FILE_TOOL (self));
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 0b2b542..11a7477 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -48,8 +48,6 @@ struct _GthImageViewerPagePrivate {
        guint              browser_merge_id;
        GthImageHistory   *history;
        GthFileData       *file_data;
-       gulong             requested_ready_id;
-       gulong             original_size_ready_id;
        guint              hide_mouse_timeout;
        guint              motion_signal;
        gboolean           image_changed;
@@ -228,6 +226,121 @@ gth_image_viewer_page_file_loaded (GthImageViewerPage *self,
 }
 
 
+static int
+_gth_image_preloader_get_requested_size (GthImageViewerPage *self)
+{
+       int window_width;
+       int window_height;
+
+       gtk_window_get_size (GTK_WINDOW (self->priv->browser),
+                            &window_width,
+                            &window_height);
+
+       return MAX (window_width, window_height);
+}
+
+
+static void
+different_quality_ready_cb (GObject            *source_object,
+                           GAsyncResult        *result,
+                           gpointer             user_data)
+{
+       GthImageViewerPage *self = user_data;
+       GthFileData        *requested;
+       GthImage           *image;
+       int                 requested_size;
+       int                 original_width;
+       int                 original_height;
+       GError             *error = NULL;
+
+       if (! gth_image_preloader_load_finish (GTH_IMAGE_PRELOADER (source_object),
+                                              result,
+                                              &requested,
+                                              &image,
+                                              &requested_size,
+                                              &original_width,
+                                              &original_height,
+                                              &error))
+       {
+               g_clear_error (&error);
+               return;
+       }
+
+       if (! _g_file_equal (requested->file, self->priv->file_data->file))
+               goto clear_data;
+
+       if (image == NULL)
+               goto clear_data;
+
+       gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
+
+       gth_image_viewer_set_better_quality (GTH_IMAGE_VIEWER (self->priv->viewer),
+                                            image,
+                                            original_width,
+                                            original_height);
+       gth_image_viewer_set_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer), requested_size);
+       gtk_widget_queue_draw (self->priv->viewer);
+
+clear_data:
+
+       _g_object_unref (requested);
+       _g_object_unref (image);
+       g_clear_error (&error);
+
+       return;
+}
+
+
+static void
+update_image_quality_if_required (GthImageViewerPage *self)
+{
+       double zoom;
+
+       if (self->priv->image_changed)
+               return;
+
+       zoom = gth_image_viewer_get_zoom (GTH_IMAGE_VIEWER (self->priv->viewer));
+       if (zoom >= 1.0) {
+               int requested_size;
+               int original_width;
+               int original_height;
+
+               requested_size = gth_image_viewer_get_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer));
+               gth_image_viewer_get_original_size (GTH_IMAGE_VIEWER (self->priv->viewer),
+                                                   &original_width,
+                                                   &original_height);
+               if ((requested_size > 0) && (MAX (original_width, original_height) > requested_size)) {
+                       /*g_print ("request size %d\n", GTH_ORIGINAL_SIZE);*/
+                       gth_image_preloader_load (self->priv->preloader,
+                                                 self->priv->file_data,
+                                                 GTH_ORIGINAL_SIZE,
+                                                 NULL,
+                                                 different_quality_ready_cb,
+                                                 self,
+                                                 GTH_NO_PRELOADERS,
+                                                 NULL);
+               }
+       }
+       else {
+               int requested_size;
+
+               requested_size = gth_image_viewer_get_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer));
+               if (requested_size == -1) {
+                       requested_size = _gth_image_preloader_get_requested_size (self);
+                       /*g_print ("request size %d\n", requested_size);*/
+                       gth_image_preloader_load (self->priv->preloader,
+                                                 self->priv->file_data,
+                                                 requested_size,
+                                                 NULL,
+                                                 different_quality_ready_cb,
+                                                 self,
+                                                 GTH_NO_PRELOADERS,
+                                                 NULL);
+               }
+       }
+}
+
+
 static gboolean
 viewer_zoom_changed_cb (GtkWidget          *widget,
                        GthImageViewerPage *self)
@@ -236,6 +349,7 @@ viewer_zoom_changed_cb (GtkWidget          *widget,
        char   *text;
 
        gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
+       update_image_quality_if_required (self);
 
        zoom = gth_image_viewer_get_zoom (GTH_IMAGE_VIEWER (self->priv->viewer));
        text = g_strdup_printf ("  %d%%  ", (int) (zoom * 100));
@@ -381,78 +495,6 @@ viewer_unrealize_cb (GtkWidget *widget,
 
 
 static void
-image_preloader_requested_ready_cb (GthImagePreloader  *preloader,
-                                   GthFileData        *requested,
-                                   GthImage           *image,
-                                   int                 original_width,
-                                   int                 original_height,
-                                   GError             *error,
-                                   GthImageViewerPage *self)
-{
-       if (! _g_file_equal (requested->file, self->priv->file_data->file))
-               return;
-
-       if ((error != NULL) || (image == NULL)) {
-               gth_image_viewer_page_file_loaded (self, FALSE);
-               return;
-       }
-
-       gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
-
-       gth_image_viewer_set_image (GTH_IMAGE_VIEWER (self->priv->viewer),
-                                   image,
-                                   original_width,
-                                   original_height);
-
-       gth_image_history_clear (self->priv->history);
-       gth_image_history_add_image (self->priv->history,
-                                    gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER 
(self->priv->viewer)),
-                                    FALSE);
-
-       if ((original_width == -1) || (original_height == -1))
-               /* In this case the image was loaded at its original size,
-                * so we get the original size from the image surface size. */
-               gth_image_viewer_get_original_size (GTH_IMAGE_VIEWER (self->priv->viewer),
-                                                   &original_width,
-                                                   &original_height);
-       g_file_info_set_attribute_int32 (self->priv->file_data->info,
-                                        "frame::width",
-                                        original_width);
-       g_file_info_set_attribute_int32 (self->priv->file_data->info,
-                                        "frame::height",
-                                        original_height);
-
-       gth_image_viewer_page_file_loaded (self, TRUE);
-}
-
-
-static void
-image_preloader_original_size_ready_cb (GthImagePreloader  *preloader,
-                                       GthFileData        *requested,
-                                       GthImage           *image,
-                                       int                 original_width,
-                                       int                 original_height,
-                                       GError             *error,
-                                       GthImageViewerPage *self)
-{
-       if (! _g_file_equal (requested->file, self->priv->file_data->file))
-               return;
-
-       if (error != NULL)
-               return;
-
-       gth_image_viewer_set_better_quality (GTH_IMAGE_VIEWER (self->priv->viewer),
-                                            image,
-                                            original_width,
-                                            original_height);
-       gth_image_history_clear (self->priv->history);
-       gth_image_history_add_image (self->priv->history,
-                                    gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER 
(self->priv->viewer)),
-                                    FALSE);
-}
-
-
-static void
 pref_zoom_quality_changed (GSettings *settings,
                           char      *key,
                           gpointer   user_data)
@@ -694,14 +736,6 @@ gth_image_viewer_page_real_activate (GthViewerPage *base,
        gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), self->priv->actions, 0);
 
        self->priv->preloader = gth_browser_get_image_preloader (browser);
-       self->priv->requested_ready_id = g_signal_connect (G_OBJECT (self->priv->preloader),
-                                                          "requested_ready",
-                                                          G_CALLBACK (image_preloader_requested_ready_cb),
-                                                          self);
-       self->priv->original_size_ready_id = g_signal_connect (G_OBJECT (self->priv->preloader),
-                                                              "original_size_ready",
-                                                              G_CALLBACK 
(image_preloader_original_size_ready_cb),
-                                                              self);
 
        self->priv->viewer = gth_image_viewer_new ();
        gth_image_viewer_set_zoom_quality (GTH_IMAGE_VIEWER (self->priv->viewer),
@@ -803,11 +837,6 @@ gth_image_viewer_page_real_deactivate (GthViewerPage *base)
        g_object_unref (self->priv->actions);
        self->priv->actions = NULL;
 
-       g_signal_handler_disconnect (self->priv->preloader, self->priv->requested_ready_id);
-       g_signal_handler_disconnect (self->priv->preloader, self->priv->original_size_ready_id);
-       self->priv->requested_ready_id = 0;
-       self->priv->original_size_ready_id = 0;
-
        g_object_unref (self->priv->preloader);
        self->priv->preloader = NULL;
 
@@ -860,6 +889,81 @@ gth_image_viewer_page_real_can_view (GthViewerPage *base,
 }
 
 
+
+static void
+preloader_load_ready_cb (GObject       *source_object,
+                        GAsyncResult   *result,
+                        gpointer        user_data)
+{
+       GthImageViewerPage *self = user_data;
+       GthFileData        *requested;
+       GthImage           *image;
+       int                 requested_size;
+       int                 original_width;
+       int                 original_height;
+       GError             *error = NULL;
+
+       if (! gth_image_preloader_load_finish (GTH_IMAGE_PRELOADER (source_object),
+                                              result,
+                                              &requested,
+                                              &image,
+                                              &requested_size,
+                                              &original_width,
+                                              &original_height,
+                                              &error))
+       {
+               g_clear_error (&error);
+               return;
+       }
+
+       if (! _g_file_equal (requested->file, self->priv->file_data->file))
+               goto clear_data;
+
+       if (image == NULL) {
+               gth_image_viewer_page_file_loaded (self, FALSE);
+               goto clear_data;
+       }
+
+       gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
+
+       gth_image_viewer_set_image (GTH_IMAGE_VIEWER (self->priv->viewer),
+                                   image,
+                                   original_width,
+                                   original_height);
+       gth_image_viewer_set_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer), requested_size);
+       gtk_widget_queue_draw (self->priv->viewer);
+
+       gth_image_history_clear (self->priv->history);
+       gth_image_history_add_image (self->priv->history,
+                                    gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER 
(self->priv->viewer)),
+                                    requested_size,
+                                    FALSE);
+
+       if ((original_width == -1) || (original_height == -1))
+               /* In this case the image was loaded at its original size,
+                * so we get the original size from the image surface size. */
+               gth_image_viewer_get_original_size (GTH_IMAGE_VIEWER (self->priv->viewer),
+                                                   &original_width,
+                                                   &original_height);
+       g_file_info_set_attribute_int32 (self->priv->file_data->info,
+                                        "frame::width",
+                                        original_width);
+       g_file_info_set_attribute_int32 (self->priv->file_data->info,
+                                        "frame::height",
+                                        original_height);
+
+       gth_image_viewer_page_file_loaded (self, TRUE);
+
+clear_data:
+
+       _g_object_unref (requested);
+       _g_object_unref (image);
+       g_clear_error (&error);
+
+       return;
+}
+
+
 #define N_PRELOADERS 4
 
 
@@ -873,8 +977,6 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
        int                 i;
        GthFileData        *next_file_data[N_PRELOADERS];
        GthFileData        *prev_file_data[N_PRELOADERS];
-       int                 window_width;
-       int                 window_height;
 
        self = (GthImageViewerPage*) base;
        g_return_if_fail (file_data != NULL);
@@ -903,7 +1005,9 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
 
        file_store = gth_browser_get_file_store (self->priv->browser);
        if (gth_file_store_find_visible (file_store, self->priv->file_data->file, &iter)) {
-               GtkTreeIter next_iter;
+               GtkTreeIter      next_iter;
+               gboolean         thumbnail_available;
+               cairo_surface_t *thumbnail;
 
                next_iter = iter;
                for (i = 0; i < N_PRELOADERS; i++) {
@@ -918,15 +1022,45 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
                                break;
                        prev_file_data[i] = gth_file_store_get_file (file_store, &next_iter);
                }
-       }
 
-       gtk_window_get_size (GTK_WINDOW (self->priv->browser),
-                            &window_width,
-                            &window_height);
+               thumbnail_available = FALSE;
+               gtk_tree_model_get (GTK_TREE_MODEL (file_store),
+                                   &iter,
+                                   GTH_FILE_STORE_THUMBNAIL_COLUMN,
+                                   &thumbnail,
+                                   -1);
+
+               if (thumbnail != NULL) {
+                       cairo_surface_metadata_t *metadata;
+                       int                       original_width;
+                       int                       original_height;
+
+                       metadata = _cairo_image_surface_get_metadata (thumbnail);
+                       original_width = metadata->thumbnail.image_width;
+                       original_height = metadata->thumbnail.image_height;
+
+                       if ((thumbnail != NULL) && (original_width > 0) && (original_height > 0)) {
+                               gth_image_viewer_set_surface (GTH_IMAGE_VIEWER (self->priv->viewer),
+                                                             thumbnail,
+                                                             original_width,
+                                                             original_height);
+                               thumbnail_available = TRUE;
+                       }
+
+                       cairo_surface_destroy (thumbnail);
+               }
+
+               if (! thumbnail_available)
+                       gth_image_viewer_set_void (GTH_IMAGE_VIEWER (self->priv->viewer));
+       }
 
        gth_image_preloader_load (self->priv->preloader,
                                  self->priv->file_data,
-                                 (gth_image_prelaoder_get_load_policy (self->priv->preloader) == 
GTH_LOAD_POLICY_TWO_STEPS) ? MAX (window_width, window_height) : -1,
+                                 _gth_image_preloader_get_requested_size (self),
+                                 NULL,
+                                 preloader_load_ready_cb,
+                                 self,
+                                 N_PRELOADERS * 2,
                                  next_file_data[0],
                                  next_file_data[1],
                                  next_file_data[2],
@@ -934,8 +1068,7 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
                                  prev_file_data[0],
                                  prev_file_data[1],
                                  prev_file_data[2],
-                                 prev_file_data[3],
-                                 NULL);
+                                 prev_file_data[3]);
 }
 
 
@@ -1246,6 +1379,7 @@ gth_image_viewer_page_real_save_as (GthViewerPage *base,
 static void
 _gth_image_viewer_page_set_image (GthImageViewerPage *self,
                                  cairo_surface_t    *image,
+                                 int                 requested_size,
                                  gboolean            modified)
 {
        GthFileData *file_data;
@@ -1257,9 +1391,11 @@ _gth_image_viewer_page_set_image (GthImageViewerPage *self,
                return;
 
        gth_image_viewer_set_surface (GTH_IMAGE_VIEWER (self->priv->viewer), image, -1, -1);
+       gth_image_viewer_set_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer), requested_size);
 
        file_data = gth_browser_get_current_file (GTH_BROWSER (self->priv->browser));
 
+       self->priv->image_changed = modified;
        g_file_info_set_attribute_boolean (file_data->info, "gth::file::is-modified", modified);
 
        width = cairo_image_surface_get_width (image);
@@ -1269,10 +1405,11 @@ _gth_image_viewer_page_set_image (GthImageViewerPage *self,
 
        size = g_strdup_printf (_("%d × %d"), width, height);
        g_file_info_set_attribute_string (file_data->info, "general::dimensions", size);
+       g_free (size);
 
        gth_monitor_metadata_changed (gth_main_get_default_monitor (), file_data);
 
-       g_free (size);
+       update_image_quality_if_required (self);
 }
 
 
@@ -1284,7 +1421,7 @@ gth_image_viewer_page_real_revert (GthViewerPage *base)
 
        idata = gth_image_history_revert (self->priv->history);
        if (idata != NULL) {
-               _gth_image_viewer_page_set_image (self, idata->image, idata->unsaved);
+               _gth_image_viewer_page_set_image (self, idata->image, idata->requested_size, idata->unsaved);
                gth_image_data_unref (idata);
        }
 }
@@ -1441,10 +1578,9 @@ gth_image_viewer_page_set_image (GthImageViewerPage *self,
                return;
 
        if (add_to_history)
-               gth_image_history_add_image (self->priv->history, image, TRUE);
+               gth_image_history_add_image (self->priv->history, image, -1, TRUE);
 
-       _gth_image_viewer_page_set_image (self, image, TRUE);
-       self->priv->image_changed = TRUE;
+       _gth_image_viewer_page_set_image (self, image, -1, TRUE);
 
        if (add_to_history)
                gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
@@ -1458,7 +1594,7 @@ gth_image_viewer_page_undo (GthImageViewerPage *self)
 
        idata = gth_image_history_undo (self->priv->history);
        if (idata != NULL)
-               _gth_image_viewer_page_set_image (self, idata->image, idata->unsaved);
+               _gth_image_viewer_page_set_image (self, idata->image, idata->requested_size, idata->unsaved);
 }
 
 
@@ -1469,7 +1605,7 @@ gth_image_viewer_page_redo (GthImageViewerPage *self)
 
        idata = gth_image_history_redo (self->priv->history);
        if (idata != NULL)
-               _gth_image_viewer_page_set_image (self, idata->image, idata->unsaved);
+               _gth_image_viewer_page_set_image (self, idata->image, idata->requested_size, idata->unsaved);
 }
 
 
@@ -1489,7 +1625,7 @@ gth_image_viewer_page_reset (GthImageViewerPage *self)
        if (last_image == NULL)
                return;
 
-       _gth_image_viewer_page_set_image (self, last_image->image, last_image->unsaved);
+       _gth_image_viewer_page_set_image (self, last_image->image, last_image->requested_size, 
last_image->unsaved);
 }
 
 
diff --git a/gthumb/cairo-utils.c b/gthumb/cairo-utils.c
index b183faa..807d659 100644
--- a/gthumb/cairo-utils.c
+++ b/gthumb/cairo-utils.c
@@ -175,6 +175,32 @@ _cairo_image_surface_get_has_alpha (cairo_surface_t *surface)
 }
 
 
+gboolean
+_cairo_image_surface_get_original_size (cairo_surface_t *surface,
+                                       int             *original_width,
+                                       int             *original_height)
+{
+       cairo_surface_metadata_t *metadata;
+
+       if (surface == NULL)
+               return FALSE;
+
+       metadata = cairo_surface_get_user_data (surface, &surface_metadata_key);
+       if (metadata == NULL)
+               return FALSE;
+
+       if ((metadata->original_width <= 0) || (metadata->original_height <= 0))
+               return FALSE;
+
+       if (original_width)
+               *original_width = metadata->original_width;
+       if (original_height)
+               *original_height = metadata->original_height;
+
+       return TRUE;
+}
+
+
 cairo_surface_t *
 _cairo_image_surface_create (cairo_format_t format,
                             int            width,
diff --git a/gthumb/cairo-utils.h b/gthumb/cairo-utils.h
index 4f2d03d..521f310 100644
--- a/gthumb/cairo-utils.h
+++ b/gthumb/cairo-utils.h
@@ -170,6 +170,9 @@ cairo_surface_metadata_t *
 void               _cairo_image_surface_copy_metadata       (cairo_surface_t      *src,
                                                             cairo_surface_t       *dest);
 gboolean           _cairo_image_surface_get_has_alpha       (cairo_surface_t       *surface);
+gboolean           _cairo_image_surface_get_original_size   (cairo_surface_t       *surface,
+                                                            int                   *original_width,
+                                                            int                   *original_height);
 cairo_surface_t *  _cairo_image_surface_create              (cairo_format_t         format,
                                                             int                    width,
                                                             int                    height);
diff --git a/gthumb/gth-image-history.c b/gthumb/gth-image-history.c
index 875b4d4..d58c66d 100644
--- a/gthumb/gth-image-history.c
+++ b/gthumb/gth-image-history.c
@@ -34,6 +34,7 @@ G_DEFINE_TYPE (GthImageHistory, gth_image_history, G_TYPE_OBJECT)
 
 GthImageData *
 gth_image_data_new (cairo_surface_t *image,
+                   int              requested_size,
                    gboolean         unsaved)
 {
        GthImageData *idata;
@@ -44,6 +45,7 @@ gth_image_data_new (cairo_surface_t *image,
 
        idata->ref = 1;
        idata->image = cairo_surface_reference (image);
+       idata->requested_size = requested_size;
        idata->unsaved = unsaved;
 
        return idata;
@@ -172,6 +174,7 @@ remove_first_image (GList **list)
 static GList*
 add_image_to_list (GList           *list,
                   cairo_surface_t *image,
+                  int              requested_size,
                   gboolean         unsaved)
 {
        if (g_list_length (list) > MAX_UNDO_HISTORY_LEN) {
@@ -187,17 +190,19 @@ add_image_to_list (GList           *list,
        if (image == NULL)
                return list;
 
-       return g_list_prepend (list, gth_image_data_new (image, unsaved));
+       return g_list_prepend (list, gth_image_data_new (image, requested_size, unsaved));
 }
 
 
 static void
 add_image_to_undo_history (GthImageHistory *history,
                           cairo_surface_t *image,
+                          int              requested_size,
                           gboolean         unsaved)
 {
        history->priv->undo_history = add_image_to_list (history->priv->undo_history,
                                                         image,
+                                                        requested_size,
                                                         unsaved);
 }
 
@@ -205,10 +210,12 @@ add_image_to_undo_history (GthImageHistory *history,
 static void
 add_image_to_redo_history (GthImageHistory *history,
                           cairo_surface_t *image,
+                          int              requested_size,
                           gboolean         unsaved)
 {
        history->priv->redo_history = add_image_to_list (history->priv->redo_history,
                                                         image,
+                                                        requested_size,
                                                         unsaved);
 }
 
@@ -216,9 +223,10 @@ add_image_to_redo_history (GthImageHistory *history,
 void
 gth_image_history_add_image (GthImageHistory *history,
                             cairo_surface_t *image,
+                            int              requested_size,
                             gboolean         unsaved)
 {
-       add_image_to_undo_history (history, image, unsaved);
+       add_image_to_undo_history (history, image, requested_size, unsaved);
        gth_image_data_list_free (history->priv->redo_history);
        history->priv->redo_history = NULL;
 
@@ -237,7 +245,7 @@ gth_image_history_undo (GthImageHistory *history)
                return NULL;
 
        idata = remove_first_image (&(history->priv->undo_history));
-       add_image_to_redo_history (history, idata->image, idata->unsaved);
+       add_image_to_redo_history (history, idata->image, idata->requested_size, idata->unsaved);
        gth_image_data_unref (idata);
 
        g_signal_emit (G_OBJECT (history),
@@ -257,7 +265,7 @@ gth_image_history_redo (GthImageHistory *history)
                return NULL;
 
        idata = remove_first_image (&(history->priv->redo_history));
-       add_image_to_undo_history (history, idata->image, idata->unsaved);
+       add_image_to_undo_history (history, idata->image, idata->requested_size, idata->unsaved);
        gth_image_data_unref (idata);
 
        g_signal_emit (G_OBJECT (history),
diff --git a/gthumb/gth-image-history.h b/gthumb/gth-image-history.h
index e52e5a7..ffd686d 100644
--- a/gthumb/gth-image-history.h
+++ b/gthumb/gth-image-history.h
@@ -42,6 +42,7 @@ typedef struct _GthImageHistoryClass   GthImageHistoryClass;
 typedef struct {
        int              ref;
        cairo_surface_t *image;
+       int              requested_size;
        gboolean         unsaved;
 } GthImageData;
 
@@ -59,6 +60,7 @@ struct _GthImageHistoryClass {
 };
 
 GthImageData *    gth_image_data_new           (cairo_surface_t *image,
+                                               int              requested_size,
                                                gboolean         unsaved);
 GthImageData *    gth_image_data_ref           (GthImageData    *idata);
 void              gth_image_data_unref         (GthImageData    *idata);
@@ -68,6 +70,7 @@ GType             gth_image_history_get_type   (void);
 GthImageHistory * gth_image_history_new        (void);
 void              gth_image_history_add_image  (GthImageHistory *history,
                                                cairo_surface_t *image,
+                                               int              requested_size,
                                                gboolean         unsaved);
 GthImageData *    gth_image_history_undo       (GthImageHistory *history);
 GthImageData *    gth_image_history_redo       (GthImageHistory *history);
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index 6337ff5..00b7986 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -79,6 +79,7 @@ struct _GthImageViewerPrivate {
        GdkPixbufAnimation     *animation;
        int                     original_width;
        int                     original_height;
+       int                     requested_size;
 
        GdkPixbufAnimationIter *iter;
        GTimeVal                time;               /* Timer used to get the current frame. */
@@ -1595,18 +1596,33 @@ _gth_image_viewer_set_original_size (GthImageViewer *self,
                                     int             original_height)
 {
        cairo_surface_t *image;
+       int              image_width;
+       int              image_height;
 
        image = gth_image_viewer_get_current_image (self);
+       image_width = cairo_image_surface_get_width (image);
+       image_height = cairo_image_surface_get_height (image);
+
+       if (original_width <= 0 || original_height <= 0)
+               _cairo_image_surface_get_original_size (image, &original_width, &original_height);
 
        if (original_width > 0)
                self->priv->original_width = original_width;
        else
-               self->priv->original_width = (image != NULL) ? cairo_image_surface_get_width (image) : 0;
+               self->priv->original_width = (image != NULL) ? image_width : 0;
 
        if (original_height > 0)
                self->priv->original_height = original_height;
        else
-               self->priv->original_height = (image != NULL) ? cairo_image_surface_get_height (image) : 0;
+               self->priv->original_height = (image != NULL) ? image_height : 0;
+
+       if ((self->priv->original_width > image_width)
+           && (self->priv->original_height > image_height))
+       {
+               self->priv->requested_size = MAX (image_width, image_height);
+       }
+       else
+               self->priv->requested_size = -1;
 }
 
 
@@ -1935,6 +1951,21 @@ gth_image_viewer_get_original_size (GthImageViewer *self,
 }
 
 
+void
+gth_image_viewer_set_requested_size (GthImageViewer *self,
+                                    int             requested_size)
+{
+       self->priv->requested_size = requested_size;
+}
+
+
+int
+gth_image_viewer_get_requested_size (GthImageViewer *self)
+{
+       return self->priv->requested_size;
+}
+
+
 gboolean
 gth_image_viewer_get_has_alpha (GthImageViewer *self)
 {
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index 8100235..595ac30 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -194,6 +194,9 @@ cairo_surface_t *
 void           gth_image_viewer_get_original_size        (GthImageViewer        *viewer,
                                                          int                   *width,
                                                          int                   *height);
+void           gth_image_viewer_set_requested_size       (GthImageViewer        *viewer,
+                                                         int                    requested_size);
+int            gth_image_viewer_get_requested_size       (GthImageViewer        *viewer);
 
 /* animation. */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]