[gnome-keyring] gcr: Display errors in the gcr-viewer



commit 08aa3f057147d345b8e8e14affbec01750e7c4cf
Author: Stef Walter <stefw collabora co uk>
Date:   Wed Aug 31 15:57:02 2011 +0200

    gcr: Display errors in the gcr-viewer
    
     * Add GcrFailureRenderer which shows errors with reason and icon

 gcr/Makefile.am            |    1 +
 gcr/gcr-failure-renderer.c |  209 ++++++++++++++++++++++++++++++++++++++++++++
 gcr/gcr-failure-renderer.h |   68 ++++++++++++++
 gcr/gcr-viewer-window.c    |   32 ++++---
 4 files changed, 297 insertions(+), 13 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index c6e626e..e84c536 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -98,6 +98,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
 	gcr-display-view.c gcr-display-view.h \
 	gcr-gnupg-collection.c gcr-gnupg-collection.h \
 	gcr-gnupg-key.c gcr-gnupg-key.h \
+	gcr-failure-renderer.c gcr-failure-renderer.h \
 	gcr-fingerprint.c gcr-fingerprint.h \
 	gcr-gnupg-process.c gcr-gnupg-process.h \
 	gcr-gnupg-util.c gcr-gnupg-util.h \
diff --git a/gcr/gcr-failure-renderer.c b/gcr/gcr-failure-renderer.c
new file mode 100644
index 0000000..8f75956
--- /dev/null
+++ b/gcr/gcr-failure-renderer.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gcr-display-view.h"
+#include "gcr-icons.h"
+#include "gcr-parser.h"
+#include "gcr-failure-renderer.h"
+
+#include "egg/egg-entry-buffer.h"
+
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+	PROP_0,
+	PROP_LABEL,
+	PROP_ATTRIBUTES
+};
+
+struct _GcrFailureRendererPrivate {
+	gchar *label;
+	GError *error;
+};
+
+static void gcr_renderer_iface_init (GcrRendererIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrFailureRenderer, _gcr_failure_renderer, G_TYPE_OBJECT,
+	G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
+);
+
+static void
+_gcr_failure_renderer_init (GcrFailureRenderer *self)
+{
+	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_FAILURE_RENDERER,
+	                                         GcrFailureRendererPrivate));
+}
+
+static void
+_gcr_failure_renderer_finalize (GObject *obj)
+{
+	GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
+
+	g_error_free (self->pv->error);
+	g_free (self->pv->label);
+
+	G_OBJECT_CLASS (_gcr_failure_renderer_parent_class)->finalize (obj);
+}
+
+static void
+_gcr_failure_renderer_set_property (GObject *obj,
+                                   guint prop_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+	GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
+
+	switch (prop_id) {
+	case PROP_LABEL:
+		g_free (self->pv->label);
+		self->pv->label = g_value_dup_string (value);
+		g_object_notify (obj, "label");
+		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+		break;
+	case PROP_ATTRIBUTES:
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+_gcr_failure_renderer_get_property (GObject *obj,
+                                   guint prop_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+	GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
+
+	switch (prop_id) {
+	case PROP_LABEL:
+		g_value_take_string (value, self->pv->label);
+		break;
+	case PROP_ATTRIBUTES:
+		g_value_set_boxed (value, NULL);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+_gcr_failure_renderer_class_init (GcrFailureRendererClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GcrFailureRendererPrivate));
+
+	gobject_class->finalize = _gcr_failure_renderer_finalize;
+	gobject_class->set_property = _gcr_failure_renderer_set_property;
+	gobject_class->get_property = _gcr_failure_renderer_get_property;
+
+	g_object_class_install_property (gobject_class, PROP_LABEL,
+	           g_param_spec_string ("label", "Label", "Failure Label",
+	                                "", G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+	           g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
+	                               GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+
+	_gcr_icons_register ();
+}
+
+static void
+gcr_failure_renderer_render (GcrRenderer *renderer,
+                            GcrViewer *viewer)
+{
+	GcrFailureRenderer *self = GCR_FAILURE_RENDERER (renderer);
+	GcrDisplayView *view;
+	gchar *display;
+	GIcon *icon;
+
+	if (GCR_IS_DISPLAY_VIEW (viewer)) {
+		view = GCR_DISPLAY_VIEW (viewer);
+
+	} else {
+		g_warning ("GcrFailureRenderer only works with internal specific "
+		           "GcrViewer returned by gcr_viewer_new().");
+		return;
+	}
+
+	_gcr_display_view_begin (view, renderer);
+
+	if (g_error_matches (self->pv->error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED))
+		icon = g_themed_icon_new ("dialog-warning");
+	else
+		icon = g_themed_icon_new ("dialog-error");
+	_gcr_display_view_set_icon (view, renderer, icon);
+	g_object_unref (icon);
+
+	_gcr_display_view_append_title (view, renderer, self->pv->label);
+
+	if (self->pv->label)
+		display = g_strdup_printf (_("Could not display '%s'"), self->pv->label);
+	else
+		display = g_strdup (_("Could not display file"));
+	_gcr_display_view_append_content (view, renderer, display, NULL);
+	g_free (display);
+
+	if (self->pv->error->message)
+		_gcr_display_view_append_value (view, renderer, _("Reason"),
+		                                self->pv->error->message, FALSE);
+
+	_gcr_display_view_end (view, renderer);
+}
+
+static void
+gcr_renderer_iface_init (GcrRendererIface *iface)
+{
+	iface->render_view = gcr_failure_renderer_render;
+}
+
+GcrRenderer *
+_gcr_failure_renderer_new (const gchar *label,
+                           GError *error)
+{
+	GcrFailureRenderer *renderer;
+
+	renderer = g_object_new (GCR_TYPE_FAILURE_RENDERER,
+	                         "label", label,
+	                         NULL);
+
+	renderer->pv->error = g_error_copy (error);
+	return GCR_RENDERER (renderer);
+}
+
+GcrRenderer *
+_gcr_failure_renderer_new_unsupported (const gchar *label)
+{
+	GcrRenderer *renderer;
+	GError *error;
+
+	error = g_error_new (GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
+	                     _("Cannot display a file of this type."));
+
+	renderer = _gcr_failure_renderer_new (label, error);
+
+	g_error_free (error);
+	return renderer;
+}
diff --git a/gcr/gcr-failure-renderer.h b/gcr/gcr-failure-renderer.h
new file mode 100644
index 0000000..5ea2f09
--- /dev/null
+++ b/gcr/gcr-failure-renderer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
+#error "Only <gcr/gcr.h> can be included directly."
+#endif
+
+#ifndef __GCR_FAILURE_RENDERER_H__
+#define __GCR_FAILURE_RENDERER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-renderer.h"
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_FAILURE_RENDERER               (_gcr_failure_renderer_get_type ())
+#define GCR_FAILURE_RENDERER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_FAILURE_RENDERER, GcrFailureRenderer))
+#define GCR_FAILURE_RENDERER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_FAILURE_RENDERER, GcrFailureRendererClass))
+#define GCR_IS_FAILURE_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_FAILURE_RENDERER))
+#define GCR_IS_FAILURE_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_FAILURE_RENDERER))
+#define GCR_FAILURE_RENDERER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_FAILURE_RENDERER, GcrFailureRendererClass))
+
+typedef struct _GcrFailureRenderer GcrFailureRenderer;
+typedef struct _GcrFailureRendererClass GcrFailureRendererClass;
+typedef struct _GcrFailureRendererPrivate GcrFailureRendererPrivate;
+
+struct _GcrFailureRenderer {
+	/*< private >*/
+	GObject parent;
+	GcrFailureRendererPrivate *pv;
+};
+
+struct _GcrFailureRendererClass {
+	/*< private >*/
+	GObjectClass parent_class;
+};
+
+GType                  _gcr_failure_renderer_get_type          (void);
+
+GcrRenderer *          _gcr_failure_renderer_new              (const gchar *label,
+                                                               GError *error);
+
+GcrRenderer *          _gcr_failure_renderer_new_unsupported  (const gchar *label);
+
+G_END_DECLS
+
+#endif /* __GCR_FAILURE_RENDERER_H__ */
diff --git a/gcr/gcr-viewer-window.c b/gcr/gcr-viewer-window.c
index cb6140c..44e2f30 100644
--- a/gcr/gcr-viewer-window.c
+++ b/gcr/gcr-viewer-window.c
@@ -23,6 +23,7 @@
 
 #include "config.h"
 
+#include "gcr-failure-renderer.h"
 #include "gcr-parser.h"
 #include "gcr-renderer.h"
 #include "gcr-unlock-renderer.h"
@@ -96,10 +97,11 @@ on_parser_parsed (GcrParser *parser, gpointer user_data)
 	renderer = gcr_renderer_create (get_parsed_label_or_display_name (self, parser),
 	                                gcr_parser_get_parsed_attributes (parser));
 
-	if (renderer) {
-		gcr_viewer_add_renderer (self->pv->viewer, renderer);
-		g_object_unref (renderer);
-	}
+	if (renderer == NULL)
+		renderer = _gcr_failure_renderer_new_unsupported (get_parsed_label_or_display_name (self, parser));
+
+	gcr_viewer_add_renderer (self->pv->viewer, renderer);
+	g_object_unref (renderer);
 }
 
 static gboolean
@@ -252,26 +254,25 @@ on_parser_parse_stream_returned (GObject *source, GAsyncResult *result,
 {
 	GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
 	GError *error = NULL;
+	GcrRenderer *renderer;
 
 	gcr_parser_parse_stream_finish (self->pv->parser, result, &error);
 
 	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
 	    g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_CANCELLED)) {
+		viewer_stop_loading_files (self);
 
 	} else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)) {
-		viewer_load_next_file (self);
-		return;
+		/* Just skip this one, an unlock renderer was added */
 
 	} else if (error) {
-		g_warning ("failed to load: %s", error->message);
+		renderer = _gcr_failure_renderer_new (self->pv->display_name, error);
+		gcr_viewer_add_renderer (self->pv->viewer, renderer);
+		g_object_unref (renderer);
 		g_error_free (error);
-
-	} else {
-		viewer_load_next_file (self);
-		return;
 	}
 
-	viewer_stop_loading_files (self);
+	viewer_load_next_file (self);
 }
 
 static void
@@ -295,6 +296,7 @@ on_file_read_returned (GObject *source, GAsyncResult *result, gpointer user_data
 	GFile *file = G_FILE (source);
 	GError *error = NULL;
 	GFileInputStream *fis;
+	GcrRenderer *renderer;
 
 	fis = g_file_read_finish (file, result, &error);
 	update_display_name (self, file);
@@ -303,7 +305,11 @@ on_file_read_returned (GObject *source, GAsyncResult *result, gpointer user_data
 		viewer_stop_loading_files (self);
 
 	} else if (error) {
-		g_assert_not_reached (); /* TODO: */
+		renderer = _gcr_failure_renderer_new (self->pv->display_name, error);
+		gcr_viewer_add_renderer (self->pv->viewer, renderer);
+		g_object_unref (renderer);
+		g_error_free (error);
+
 		viewer_load_next_file (self);
 
 	} else {



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