[Xfce4-commits] <ristretto:master> Implement error-reporting

Stephan Arts noreply at xfce.org
Tue Feb 28 19:10:03 CET 2012


Updating branch refs/heads/master
         to 1625574874fecc2bcf887a3252f4da21559bb83c (commit)
       from b7521ce80512e4b44c1eb21e95c716925caf85f4 (commit)

commit 1625574874fecc2bcf887a3252f4da21559bb83c
Author: Stephan Arts <stephan at xfce.org>
Date:   Tue Feb 28 18:59:19 2012 +0100

    Implement error-reporting

 src/image_viewer.c |  164 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/image_viewer.h |    3 +
 src/main_window.c  |   81 +++++++++++++++-----------
 src/settings.c     |   29 +++++++++
 4 files changed, 233 insertions(+), 44 deletions(-)

diff --git a/src/image_viewer.c b/src/image_viewer.c
index 2627a6e..65fc28e 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -21,6 +21,7 @@
 #include <gtk/gtkmarshal.h>
 #include <string.h>
 #include <gio/gio.h>
+#include <libxfce4ui/libxfce4ui.h>
 #include <libexif/exif-data.h>
 
 #include <math.h>
@@ -68,10 +69,14 @@ struct _RsttoImageViewerPriv
     GdkColormap                 *colormap;
 
     GtkIconTheme                *icon_theme;
+    GdkPixbuf                   *missing_icon;
     GdkPixbuf                   *bg_icon;
     GdkColor                    *bg_color;
     GdkColor                    *bg_color_fs;
 
+    GError                      *error;
+    gboolean                     show_broken_image_error;
+
     RsttoImageViewerTransaction *transaction;
     GdkPixbuf                   *pixbuf;
     RsttoImageOrientation        orientation;
@@ -124,6 +129,8 @@ struct _RsttoImageViewerTransaction
     GCancellable     *cancellable;
     GdkPixbufLoader  *loader;
 
+    GError           *error;
+
     gint              image_width;
     gint              image_height;
     gdouble           image_scale;
@@ -282,6 +289,11 @@ rstto_image_viewer_init ( GObject *object )
     viewer->priv->visual = gdk_rgb_get_visual();
     viewer->priv->colormap = gdk_colormap_new (viewer->priv->visual, TRUE);
 
+    viewer->priv->show_broken_image_error =
+            rstto_settings_get_boolean_property (
+                    viewer->priv->settings,
+                    "show-error-broken-image");
+
     viewer->priv->icon_theme = gtk_icon_theme_get_default ();
     viewer->priv->bg_icon = gtk_icon_theme_load_icon (
             viewer->priv->icon_theme,
@@ -289,6 +301,12 @@ rstto_image_viewer_init ( GObject *object )
             BACKGROUND_ICON_SIZE,
             0,
             NULL);
+    viewer->priv->missing_icon = gtk_icon_theme_load_icon (
+            viewer->priv->icon_theme,
+            "image-missing",
+            BACKGROUND_ICON_SIZE,
+            0,
+            NULL);
     gdk_pixbuf_saturate_and_pixelate (
             viewer->priv->bg_icon,
             viewer->priv->bg_icon,
@@ -573,6 +591,11 @@ rstto_image_viewer_destroy(GtkObject *object)
             g_object_unref (viewer->priv->bg_icon);
             viewer->priv->bg_icon = NULL;
         }
+        if (viewer->priv->missing_icon)
+        {
+            g_object_unref (viewer->priv->missing_icon);
+            viewer->priv->missing_icon = NULL;
+        }
         if (viewer->priv->pixbuf)
         {
             g_object_unref (viewer->priv->pixbuf);
@@ -957,6 +980,7 @@ paint_image (
     gdouble y_offset;
     gint block_width = 10;
     gint block_height = 10;
+    gdouble bg_scale = 1.0;
 
     if (viewer->priv->pixbuf)
     {
@@ -1137,6 +1161,53 @@ paint_image (
                 0.0);
         cairo_paint (ctx);
     }
+    else
+    {
+        if (viewer->priv->error)
+        {
+            /* Calculate the icon-size */
+            /***************************/
+            if (widget->allocation.width < widget->allocation.height)
+            {
+                bg_scale = (gdouble)BACKGROUND_ICON_SIZE /
+                    (gdouble)widget->allocation.width * 1.2;
+            }
+            else
+            {
+                bg_scale = (gdouble)BACKGROUND_ICON_SIZE /
+                    (gdouble)widget->allocation.height * 1.2;
+            }
+
+            /* Move the cairo context in position so the
+             * background-image is painted in the center
+             * of the widget.
+             */
+            cairo_translate (
+                    ctx,
+                    (gdouble)(widget->allocation.width-BACKGROUND_ICON_SIZE/bg_scale)/2.0,
+                    (gdouble)(widget->allocation.height-BACKGROUND_ICON_SIZE/bg_scale)/2.0);
+
+            /* Scale the context so the image
+             * fills the same part of the cairo-context
+             */
+            cairo_scale (
+                    ctx,
+                    1.0 / bg_scale,
+                    1.0 / bg_scale);
+
+            /* Draw the pixbuf on the cairo-context */
+            /****************************************/
+            if(viewer->priv->missing_icon != NULL)
+            {
+                gdk_cairo_set_source_pixbuf (
+                        ctx,
+                        viewer->priv->missing_icon,
+                        0.0,
+                        0.0);
+                cairo_paint_with_alpha (ctx, 1.0);
+            }
+        }
+    }
 
 }
 
@@ -1357,6 +1428,14 @@ rstto_image_viewer_set_file (
                 g_object_unref (viewer->priv->file);
 
                 viewer->priv->file = file;
+                if (viewer->priv->error)
+                {
+                    g_error_free (viewer->priv->error);
+                    viewer->priv->error = NULL;
+                }
+                viewer->priv->image_scale = 0;
+                viewer->priv->image_width = 0;
+                viewer->priv->image_height = 0;
 
                 rstto_image_viewer_load_image (
                         viewer,
@@ -1481,6 +1560,10 @@ rstto_image_viewer_transaction_free (RsttoImageViewerTransaction *tr)
     {
         tr->viewer->priv->transaction = NULL;
     }
+    if (tr->error)
+    {
+        g_error_free (tr->error);
+    }
     g_object_unref (tr->cancellable);
     g_object_unref (tr->loader);
     g_free (tr->buffer);
@@ -1695,9 +1778,8 @@ cb_rstto_image_viewer_read_input_stream_ready (
         GAsyncResult *result,
         gpointer user_data )
 {
-    GError *error = NULL;
     RsttoImageViewerTransaction *transaction = (RsttoImageViewerTransaction *)user_data;
-    gssize read_bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), result, &error);
+    gssize read_bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), result, &transaction->error);
 
     if (read_bytes == -1)
     {
@@ -1707,7 +1789,7 @@ cb_rstto_image_viewer_read_input_stream_ready (
 
     if (read_bytes > 0)
     {
-        if(gdk_pixbuf_loader_write (transaction->loader, (const guchar *)transaction->buffer, read_bytes, &error) == FALSE)
+        if(gdk_pixbuf_loader_write (transaction->loader, (const guchar *)transaction->buffer, read_bytes, &transaction->error) == FALSE)
         {
             /* Clean up the input-stream */
             g_input_stream_close (G_INPUT_STREAM (source_object), NULL, NULL);
@@ -1726,7 +1808,7 @@ cb_rstto_image_viewer_read_input_stream_ready (
     }
     else {
         /* Loading complete, transaction should not be free-ed */
-        gdk_pixbuf_loader_close (transaction->loader, NULL);
+        gdk_pixbuf_loader_close (transaction->loader, &transaction->error);
 
         /* Clean up the input-stream */
         g_input_stream_close (G_INPUT_STREAM (source_object), NULL, NULL);
@@ -1841,17 +1923,71 @@ cb_rstto_image_loader_closed (GdkPixbufLoader *loader, RsttoImageViewerTransacti
 {
     RsttoImageViewer *viewer = transaction->viewer;
     GtkWidget *widget = GTK_WIDGET(viewer);
+    GtkWidget *error_dialog = NULL;
+    GtkWidget *vbox, *do_not_show_checkbox;
 
     if (viewer->priv->transaction == transaction)
     {
         
-        viewer->priv->image_scale = transaction->image_scale;
-        viewer->priv->image_width = transaction->image_width;
-        viewer->priv->image_height = transaction->image_height;
-        viewer->priv->orientation = transaction->orientation;
+        if (NULL == transaction->error)
+        {
+            gtk_widget_set_tooltip_text (GTK_WIDGET (viewer), NULL);
+            viewer->priv->image_scale = transaction->image_scale;
+            viewer->priv->image_width = transaction->image_width;
+            viewer->priv->image_height = transaction->image_height;
+            viewer->priv->orientation = transaction->orientation;
+            set_scale (viewer, transaction->scale);
+        }
+        else
+        {
+            if (viewer->priv->pixbuf)
+            {
+                g_object_unref (viewer->priv->pixbuf);
+                viewer->priv->pixbuf = NULL;
+            }
+
+            gtk_widget_set_tooltip_text (GTK_WIDGET (viewer), transaction->error->message);
+            if (viewer->priv->show_broken_image_error)
+            {
+                GDK_THREADS_ENTER();
+                error_dialog = gtk_message_dialog_new_with_markup (
+                        NULL,
+                        0,
+                        GTK_MESSAGE_WARNING,
+                        GTK_BUTTONS_OK,
+                        transaction->error->message
+                        );
+                vbox = gtk_message_dialog_get_message_area (
+                       GTK_MESSAGE_DIALOG (error_dialog));
+
+                do_not_show_checkbox = gtk_check_button_new_with_mnemonic (
+                        _("Do _not show this message again"));
+                gtk_box_pack_end (
+                        GTK_BOX (vbox),
+                        do_not_show_checkbox,
+                        TRUE,
+                        FALSE,
+                        0);
+                gtk_widget_show (do_not_show_checkbox);
+                gtk_dialog_run (GTK_DIALOG(error_dialog));
+
+                if (TRUE == gtk_toggle_button_get_active (
+                        GTK_TOGGLE_BUTTON (do_not_show_checkbox)))
+                {
+                    viewer->priv->show_broken_image_error = FALSE;
+                    rstto_settings_set_boolean_property (
+                        viewer->priv->settings,
+                        "show-error-broken-image",
+                        FALSE);
+                }
+                gtk_widget_destroy (error_dialog);
+                GDK_THREADS_LEAVE();
+            }
+        }
 
-        set_scale (viewer, transaction->scale);
 
+        viewer->priv->error = transaction->error;
+        transaction->error = NULL;
         viewer->priv->transaction = NULL;
 
         gdk_window_invalidate_rect (
@@ -2530,3 +2666,13 @@ cb_rstto_image_viewer_dnd (GtkWidget *widget, GdkDragContext *context, gint x, g
         gtk_drag_finish (context, FALSE, FALSE, time_);
     }
 }
+
+GError *
+rstto_image_viewer_get_error ( RsttoImageViewer *viewer )
+{
+    if (viewer->priv->error)
+    {
+        return g_error_copy (viewer->priv->error);
+    }
+    return NULL;
+}
diff --git a/src/image_viewer.h b/src/image_viewer.h
index dd2a465..2d30e18 100644
--- a/src/image_viewer.h
+++ b/src/image_viewer.h
@@ -107,6 +107,9 @@ rstto_image_viewer_set_menu (
     RsttoImageViewer *viewer,
     GtkMenu *menu);
 
+GError *
+rstto_image_viewer_get_error ( RsttoImageViewer *viewer );
+
 G_END_DECLS
 
 #endif /* __RISTRETTO_IMAGE_VIEWER_H__ */
diff --git a/src/main_window.c b/src/main_window.c
index 909bec4..8a5bd78 100644
--- a/src/main_window.c
+++ b/src/main_window.c
@@ -1110,6 +1110,7 @@ rstto_main_window_update_statusbar (RsttoMainWindow *window)
     RsttoImageViewer *viewer = RSTTO_IMAGE_VIEWER(window->priv->image_viewer);
     ExifEntry *exif_entry = NULL;
     gchar exif_data[20];
+    GError *error = NULL;
 
     if (window->priv->image_list)
     {
@@ -1120,49 +1121,59 @@ rstto_main_window_update_statusbar (RsttoMainWindow *window)
 
             status = g_strdup(file_basename);
 
-            if (TRUE == rstto_file_has_exif (cur_file))
+            error = rstto_image_viewer_get_error (RSTTO_IMAGE_VIEWER (window->priv->image_viewer));
+            if (NULL != error)
+            {
+                tmp_status = g_strdup_printf ("%s\t- %s", status, error->message);
+                g_free (status);
+                status = tmp_status;
+            }
+            else
             {
-                /* Extend the status-message with exif-info */
-                /********************************************/
-                exif_entry = rstto_file_get_exif (
-                        cur_file,
-                        EXIF_TAG_FNUMBER);
-                if (exif_entry)
+                if (TRUE == rstto_file_has_exif (cur_file))
                 {
-                    exif_entry_get_value (exif_entry, exif_data, 20);
+                    /* Extend the status-message with exif-info */
+                    /********************************************/
+                    exif_entry = rstto_file_get_exif (
+                            cur_file,
+                            EXIF_TAG_FNUMBER);
+                    if (exif_entry)
+                    {
+                        exif_entry_get_value (exif_entry, exif_data, 20);
 
-                    tmp_status = g_strdup_printf ("%s\t%s", status, exif_data);
+                        tmp_status = g_strdup_printf ("%s\t%s", status, exif_data);
 
-                    g_free (status);
-                    status = tmp_status;
+                        g_free (status);
+                        status = tmp_status;
 
-                    /*exif_entry_free (exif_entry);*/
-                }
-                exif_entry = rstto_file_get_exif (
-                        cur_file,
-                        EXIF_TAG_EXPOSURE_TIME);
-                if (exif_entry)
-                {
-                    exif_entry_get_value (exif_entry, exif_data, 20);
+                        /*exif_entry_free (exif_entry);*/
+                    }
+                    exif_entry = rstto_file_get_exif (
+                            cur_file,
+                            EXIF_TAG_EXPOSURE_TIME);
+                    if (exif_entry)
+                    {
+                        exif_entry_get_value (exif_entry, exif_data, 20);
 
-                    tmp_status = g_strdup_printf ("%s\t%s", status, exif_data);
+                        tmp_status = g_strdup_printf ("%s\t%s", status, exif_data);
 
-                    g_free (status);
-                    status = tmp_status;
+                        g_free (status);
+                        status = tmp_status;
 
-                    /*exif_entry_free (exif_entry);*/
+                        /*exif_entry_free (exif_entry);*/
+                    }
                 }
-            }
 
-            if(rstto_image_viewer_get_width(viewer) != 0 && rstto_image_viewer_get_height(viewer) != 0)
-            {
-                tmp_status = g_strdup_printf ("%s\t%d x %d\t%.1f%%", status,
-                                            rstto_image_viewer_get_width(viewer),
-                                            rstto_image_viewer_get_height(viewer),
-                                            (100 * rstto_image_viewer_get_scale(viewer)));
+                if(rstto_image_viewer_get_width(viewer) != 0 && rstto_image_viewer_get_height(viewer) != 0)
+                {
+                    tmp_status = g_strdup_printf ("%s\t%d x %d\t%.1f%%", status,
+                                                rstto_image_viewer_get_width(viewer),
+                                                rstto_image_viewer_get_height(viewer),
+                                                (100 * rstto_image_viewer_get_scale(viewer)));
 
-                g_free (status);
-                status = tmp_status;
+                    g_free (status);
+                    status = tmp_status;
+                }
             }
         }
         else
diff --git a/src/settings.c b/src/settings.c
index 0fc04fa..6d11c8e 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -74,6 +74,7 @@ enum
     PROP_MAXIMIZE_ON_STARTUP,
     PROP_MERGE_TOOLBARS,
     PROP_ERROR_MISSING_THUMBNAILER,
+    PROP_ERROR_BROKEN_IMAGE,
     PROP_SORT_TYPE,
     PROP_THUMBNAIL_SIZE,
 };
@@ -133,6 +134,7 @@ struct _RsttoSettingsPriv
 
     struct {
         gboolean missing_thumbnailer;
+        gboolean broken_image;
     } errors;
 };
 
@@ -170,6 +172,7 @@ rstto_settings_init (GObject *object)
     settings->priv->maximize_on_startup = TRUE;
     settings->priv->hide_thumbnailbar_fullscreen = TRUE;
     settings->priv->errors.missing_thumbnailer = TRUE;
+    settings->priv->errors.broken_image = TRUE;
     settings->priv->thumbnail_size = THUMBNAIL_SIZE_NORMAL;
 
     xfconf_g_property_bind (
@@ -317,6 +320,13 @@ rstto_settings_init (GObject *object)
 
     xfconf_g_property_bind (
             settings->priv->channel,
+            "/errors/broken-image",
+            G_TYPE_BOOLEAN,
+            settings,
+            "show-error-broken-image");
+
+    xfconf_g_property_bind (
+            settings->priv->channel,
             "/desktop/type",
             G_TYPE_STRING,
             settings,
@@ -566,6 +576,17 @@ rstto_settings_class_init (GObjectClass *object_class)
             PROP_ERROR_MISSING_THUMBNAILER,
             pspec);
 
+    pspec = g_param_spec_boolean (
+            "show-error-broken-image",
+            "",
+            "",
+            TRUE,
+            G_PARAM_READWRITE);
+    g_object_class_install_property (
+            object_class,
+            PROP_ERROR_BROKEN_IMAGE,
+            pspec);
+
     pspec = g_param_spec_uint (
             "sort-type",
             "",
@@ -753,6 +774,9 @@ rstto_settings_set_property    (GObject      *object,
         case PROP_ERROR_MISSING_THUMBNAILER:
             settings->priv->errors.missing_thumbnailer = g_value_get_boolean (value);
             break;
+        case PROP_ERROR_BROKEN_IMAGE:
+            settings->priv->errors.broken_image = g_value_get_boolean (value);
+            break;
         case PROP_SORT_TYPE:
             settings->priv->sort_type = g_value_get_uint ( value );
             break;
@@ -837,6 +861,11 @@ rstto_settings_get_property    (GObject    *object,
                     value,
                     settings->priv->errors.missing_thumbnailer);
             break;
+        case PROP_ERROR_BROKEN_IMAGE:
+            g_value_set_boolean (
+                    value,
+                    settings->priv->errors.broken_image);
+            break;
         case PROP_SORT_TYPE:
             g_value_set_uint (
                     value,


More information about the Xfce4-commits mailing list