[gnome-keyring/ui-widgets: 47/49] [gcr] Rework the architecture of viewers.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/ui-widgets: 47/49] [gcr] Rework the architecture of viewers.
- Date: Wed, 8 Sep 2010 02:24:14 +0000 (UTC)
commit 22f5fee4f2da40eecf296038b5edf2b420e20b37
Author: Stef Walter <stef memberwebs com>
Date: Mon Aug 30 13:45:41 2010 +0000
[gcr] Rework the architecture of viewers.
* GcrRenderer renders data like a certificate.
* GcrViewer is what the renderers render to.
* GcrXxxWidget are helper classes for quick instatiation.
gcr/Makefile.am | 12 +-
gcr/gcr-certificate-renderer.c | 540 +++++++++++++++++++++++++++++++++
gcr/gcr-certificate-renderer.h | 67 ++++
gcr/gcr-certificate-widget.c | 395 +++----------------------
gcr/gcr-certificate-widget.h | 9 +-
gcr/gcr-display-view.c | 585 ++++++++++++++++++++++++++----------
gcr/gcr-display-view.h | 13 +-
gcr/gcr-key-renderer.c | 342 +++++++++++++++++++++
gcr/gcr-key-renderer.h | 62 ++++
gcr/gcr-key-widget.c | 239 +++------------
gcr/gcr-key-widget.h | 6 +-
gcr/{gcr-view.c => gcr-renderer.c} | 87 ++++--
gcr/gcr-renderer.h | 73 +++++
gcr/gcr-view.h | 53 ----
gcr/gcr-viewer.c | 99 ++++++
gcr/gcr-viewer.h | 73 +++++
gcr/tests/ui-test-certificate.c | 1 -
gcr/tests/ui-test-key.c | 3 +-
18 files changed, 1849 insertions(+), 810 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index e9b55eb..86b0891 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -17,13 +17,16 @@ incdir = $(includedir)/gcr
inc_HEADERS = \
gcr.h \
gcr-certificate.h \
+ gcr-certificate-renderer.h \
gcr-certificate-widget.h \
+ gcr-key-renderer.h \
gcr-key-widget.h \
gcr-importer.h \
gcr-parser.h \
+ gcr-renderer.h \
gcr-types.h \
gcr-unlock-options-widget.h \
- gcr-view.h
+ gcr-viewer.h
# ------------------------------------------------------------------
# LIBRARY
@@ -44,19 +47,22 @@ lib_LTLIBRARIES = libgcr.la
libgcr_la_SOURCES = \
gcr-certificate.c gcr-certificate.h \
+ gcr-certificate-renderer.c gcr-certificate-renderer.h \
gcr-certificate-widget.c gcr-certificate-widget.h \
- gcr-key-widget.c gcr-key-widget.h \
gcr-display-view.c gcr-display-view.h \
gcr-icons.c gcr-icons.h \
gcr-import-dialog.c gcr-import-dialog.h \
gcr-importer.c gcr-importer.h \
gcr-internal.h \
+ gcr-key-renderer.c gcr-key-renderer.h \
+ gcr-key-widget.c gcr-key-widget.h \
gcr-library.c \
gcr-parser.c gcr-parser.h \
+ gcr-renderer.c gcr-renderer.h \
gcr-simple-certificate.c gcr-simple-certificate.h \
gcr-types.h \
gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
- gcr-view.c gcr-view.h \
+ gcr-viewer.c gcr-viewer.h \
$(BUILT_SOURCES)
libgcr_la_CFLAGS = \
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
new file mode 100644
index 0000000..a0432ae
--- /dev/null
+++ b/gcr/gcr-certificate-renderer.c
@@ -0,0 +1,540 @@
+/*
+ * 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-certificate.h"
+#include "gcr-certificate-renderer.h"
+#include "gcr-display-view.h"
+#include "gcr-icons.h"
+#include "gcr-simple-certificate.h"
+#include "gcr-renderer.h"
+
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-dn.h"
+#include "egg/egg-oid.h"
+#include "egg/egg-hex.h"
+
+#include "gck/gck.h"
+
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+ PROP_0,
+ PROP_CERTIFICATE,
+ PROP_LABEL,
+ PROP_ATTRIBUTES
+};
+
+struct _GcrCertificateRendererPrivate {
+ GcrCertificate *certificate;
+ GckAttributes *attributes;
+ guint key_size;
+ gchar *label;
+};
+
+static void gcr_renderer_iface_init (GcrRendererIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init));
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gchar*
+calculate_label (GcrCertificateRenderer *self, GNode *asn)
+{
+ gchar *label;
+
+ if (self->pv->label)
+ return g_strdup (self->pv->label);
+
+ if (self->pv->attributes) {
+ if (gck_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
+ return label;
+ }
+
+ if (asn != NULL) {
+ label = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+ if (label != NULL)
+ return label;
+ }
+
+ return g_strdup (_("Certificate"));
+}
+
+static gboolean
+append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
+ GNode *asn, const guchar *data, gsize n_data, gint index)
+{
+ GcrRenderer *renderer = GCR_RENDERER (self);
+ GNode *node;
+ GQuark oid;
+ gchar *display;
+ gsize n_value;
+ const guchar *value;
+ const gchar *text;
+ gboolean critical;
+
+ /* Make sure it is present */
+ node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
+ if (node == NULL)
+ return FALSE;
+
+ /* Dig out the OID */
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
+ g_return_val_if_fail (oid, FALSE);
+
+ _gcr_display_view_append_heading (view, renderer, _("Extension"));
+
+
+ /* Extension type */
+ text = egg_oid_get_description (oid);
+ _gcr_display_view_append_value (view, renderer, _("Identifier"), text, FALSE);
+
+
+ /* Extension value */
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
+
+ /* TODO: Parsing of extensions that we understand */
+ display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Value"), display, TRUE);
+ g_free (display);
+
+
+ /* Critical */
+ if (egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical))
+ _gcr_display_view_append_value (view, renderer, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
+
+ return TRUE;
+}
+
+typedef struct _on_parsed_dn_args {
+ GcrCertificateRenderer *renderer;
+ GcrDisplayView *view;
+} on_parsed_dn_args;
+
+static void
+on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
+ gsize n_value, gpointer user_data)
+{
+ GcrCertificateRenderer *self = ((on_parsed_dn_args*)user_data)->renderer;
+ GcrDisplayView *view = ((on_parsed_dn_args*)user_data)->view;
+ const gchar *attr;
+ const gchar *desc;
+ gchar *field;
+ gchar *display;
+
+ g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
+
+ attr = egg_oid_get_name (oid);
+ desc = egg_oid_get_description (oid);
+
+ /* Combine them into something sane */
+ if (attr && desc) {
+ if (strcmp (attr, desc) == 0)
+ field = g_strdup (attr);
+ else
+ field = g_strdup_printf ("%s (%s)", attr, desc);
+ } else if (!attr && !desc) {
+ field = g_strdup ("");
+ } else if (attr) {
+ field = g_strdup (attr);
+ } else if (desc) {
+ field = g_strdup (desc);
+ } else {
+ g_assert_not_reached ();
+ }
+
+ display = egg_dn_print_value (oid, value, n_value);
+ if (display == NULL)
+ display = g_strdup ("");
+
+ _gcr_display_view_append_value (view, GCR_RENDERER (self), field, display, FALSE);
+ g_free (field);
+ g_free (display);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+gcr_certificate_renderer_init (GcrCertificateRenderer *self)
+{
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
+}
+
+static void
+gcr_certificate_renderer_dispose (GObject *obj)
+{
+ GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
+
+ if (self->pv->certificate)
+ g_object_unref (self->pv->certificate);
+ self->pv->certificate = NULL;
+
+ G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->dispose (obj);
+}
+
+static void
+gcr_certificate_renderer_finalize (GObject *obj)
+{
+ GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
+
+ g_assert (!self->pv->certificate);
+
+ if (self->pv->attributes)
+ gck_attributes_unref (self->pv->attributes);
+ self->pv->attributes = NULL;
+
+ g_free (self->pv->label);
+ self->pv->label = NULL;
+
+ G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
+}
+
+static void
+gcr_certificate_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
+
+ switch (prop_id) {
+ case PROP_CERTIFICATE:
+ gcr_certificate_renderer_set_certificate (self, g_value_get_object (value));
+ break;
+ 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:
+ gcr_certificate_renderer_set_attributes (self, g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
+
+ switch (prop_id) {
+ case PROP_CERTIFICATE:
+ g_value_set_object (value, self->pv->certificate);
+ break;
+ case PROP_LABEL:
+ g_value_take_string (value, calculate_label (self, NULL));
+ break;
+ case PROP_ATTRIBUTES:
+ g_value_set_boxed (value, self->pv->attributes);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GckAttributes *registered;
+
+ gcr_certificate_renderer_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GcrCertificateRendererPrivate));
+
+ gobject_class->dispose = gcr_certificate_renderer_dispose;
+ gobject_class->finalize = gcr_certificate_renderer_finalize;
+ gobject_class->set_property = gcr_certificate_renderer_set_property;
+ gobject_class->get_property = gcr_certificate_renderer_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
+ g_param_spec_object("certificate", "Certificate", "Certificate to display.",
+ GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
+
+ g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+ g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+
+ _gcr_icons_register ();
+
+ /* Register this as a renderer which can be loaded */
+ registered = gck_attributes_new ();
+ gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
+ gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, registered);
+ gck_attributes_unref (registered);
+}
+
+static void
+gcr_certificate_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
+{
+ GcrCertificateRenderer *self;
+ const guchar *data, *value;
+ gsize n_data, n_value, n_raw;
+ GcrDisplayView *view;
+ on_parsed_dn_args args;
+ const gchar *text;
+ gpointer raw;
+ gulong version;
+ guint bits, index;
+ gchar *display;
+ GNode *asn;
+ GQuark oid;
+ GDate date;
+
+ self = GCR_CERTIFICATE_RENDERER (renderer);
+
+ if (GCR_IS_DISPLAY_VIEW (viewer)) {
+ view = GCR_DISPLAY_VIEW (viewer);
+
+ } else {
+ g_warning ("GcrCertificateRenderer only works with internal specific "
+ "GcrViewer returned by gcr_viewer_new().");
+ return;
+ }
+
+ _gcr_display_view_clear (view, renderer);
+
+ if (!self->pv->certificate)
+ return;
+
+ _gcr_display_view_set_stock_image (view, GCR_RENDERER (self), GCR_ICON_CERTIFICATE);
+
+ data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
+ g_return_if_fail (data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
+ g_return_if_fail (asn);
+
+ display = calculate_label (self, asn);
+ _gcr_display_view_append_title (view, renderer, display);
+ g_free (display);
+
+ display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+ _gcr_display_view_append_content (view, renderer, _("Identity"), display);
+ g_free (display);
+
+ display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
+ _gcr_display_view_append_content (view, renderer, _("Verified by"), display);
+ g_free (display);
+
+ if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
+ display = g_malloc0 (128);
+ if (!g_date_strftime (display, 128, "%x", &date))
+ g_return_if_reached ();
+ _gcr_display_view_append_content (view, renderer, _("Expires"), display);
+ g_free (display);
+ }
+
+ _gcr_display_view_start_details (view, renderer);
+
+ args.renderer = self;
+ args.view = view;
+
+ /* The subject */
+ _gcr_display_view_append_heading (view, renderer, _("Subject Name"));
+ egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, &args);
+
+ /* The Issuer */
+ _gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
+ egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, &args);
+
+ /* The Issued Parameters */
+ _gcr_display_view_append_heading (view, renderer, _("Issued Certificate"));
+
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
+ g_return_if_reached ();
+ display = g_strdup_printf ("%lu", version + 1);
+ _gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
+ g_free (display);
+
+ raw = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), NULL, &n_raw);
+ g_return_if_fail (raw);
+ display = egg_hex_encode_full (raw, n_raw, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Serial Number"), display, TRUE);
+ g_free (display);
+ g_free (raw);
+
+ display = g_malloc0 (128);
+ if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
+ if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
+ g_return_if_reached ();
+ _gcr_display_view_append_value (view, renderer, _("Not Valid Before"), display, FALSE);
+ }
+ if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
+ if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
+ g_return_if_reached ();
+ _gcr_display_view_append_value (view, renderer, _("Not Valid After"), display, FALSE);
+ }
+ g_free (display);
+
+ /* Signature */
+ _gcr_display_view_append_heading (view, renderer, ("Signature"));
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
+ text = egg_oid_get_description (oid);
+ _gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
+
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
+ if (value && n_value) {
+ display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Signature Parameters"), display, TRUE);
+ g_free (display);
+ }
+
+ raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
+ g_return_if_fail (raw);
+ display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Signature"), display, TRUE);
+ g_free (display);
+ g_free (raw);
+
+ /* Public Key Info */
+ _gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+ "algorithm", "algorithm", NULL));
+ text = egg_oid_get_description (oid);
+ _gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
+
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+ "algorithm", "parameters", NULL), &n_value);
+ if (value && n_value) {
+ display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Key Parameters"), display, TRUE);
+ g_free (display);
+ }
+
+ bits = gcr_certificate_get_key_size (self->pv->certificate);
+ if (bits > 0) {
+ display = g_strdup_printf ("%u", bits);
+ _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
+ g_free (display);
+ }
+
+ raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+ "subjectPublicKey", NULL), NULL, &bits);
+ g_return_if_fail (raw);
+ display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
+ _gcr_display_view_append_value (view, renderer, _("Public Key"), display, TRUE);
+ g_free (display);
+ g_free (raw);
+
+ /* Fingerprints */
+ _gcr_display_view_append_heading (view, renderer, _("Fingerprints"));
+
+ _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
+ _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
+
+ /* Extensions */
+ for (index = 1; TRUE; ++index) {
+ if (!append_extension (self, view, asn, data, n_data, index))
+ break;
+ }
+
+ egg_asn1x_destroy (asn);
+}
+
+static void
+gcr_renderer_iface_init (GcrRendererIface *iface)
+{
+ iface->render = gcr_certificate_renderer_real_render;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrCertificateRenderer*
+gcr_certificate_renderer_new (GcrCertificate *certificate)
+{
+ return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "certificate", certificate, NULL);
+}
+
+GcrCertificate*
+gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self)
+{
+ g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
+ return self->pv->certificate;
+}
+
+void
+gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self, GcrCertificate *cert)
+{
+ g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
+
+ if (self->pv->certificate)
+ g_object_unref (self->pv->certificate);
+ self->pv->certificate = cert;
+ if (self->pv->certificate)
+ g_object_ref (self->pv->certificate);
+
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ g_object_notify (G_OBJECT (self), "certificate");
+}
+
+GckAttributes*
+gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self)
+{
+ g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
+ return self->pv->attributes;
+}
+
+void
+gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttributes *attrs)
+{
+ GcrCertificate *cert;
+ GckAttribute *attr;
+ gboolean emit = TRUE;
+
+ g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
+
+ gck_attributes_unref (self->pv->attributes);
+ self->pv->attributes = attrs;\
+
+ if (self->pv->attributes) {
+ gck_attributes_ref (self->pv->attributes);
+ attr = gck_attributes_find (self->pv->attributes, CKA_VALUE);
+ if (attr) {
+ /* Create a new certificate object refferring to same memory */
+ cert = gcr_simple_certificate_new_static (attr->value, attr->length);
+ g_object_set_data_full (G_OBJECT (cert), "attributes",
+ gck_attributes_ref (self->pv->attributes),
+ (GDestroyNotify)gck_attributes_unref);
+ gcr_certificate_renderer_set_certificate (self, cert);
+ g_object_unref (cert);
+ emit = FALSE;
+ } else {
+ gcr_certificate_renderer_set_certificate (self, NULL);
+ }
+ }
+
+ if (emit)
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+
+}
diff --git a/gcr/gcr-certificate-renderer.h b/gcr/gcr-certificate-renderer.h
new file mode 100644
index 0000000..685c04e
--- /dev/null
+++ b/gcr/gcr-certificate-renderer.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef __GCR_CERTIFICATE_RENDERER_H__
+#define __GCR_CERTIFICATE_RENDERER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-certificate.h"
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_CERTIFICATE_RENDERER (gcr_certificate_renderer_get_type ())
+#define GCR_CERTIFICATE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRenderer))
+#define GCR_CERTIFICATE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererClass))
+#define GCR_IS_CERTIFICATE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_RENDERER))
+#define GCR_IS_CERTIFICATE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_RENDERER))
+#define GCR_CERTIFICATE_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererClass))
+
+typedef struct _GcrCertificateRenderer GcrCertificateRenderer;
+typedef struct _GcrCertificateRendererClass GcrCertificateRendererClass;
+typedef struct _GcrCertificateRendererPrivate GcrCertificateRendererPrivate;
+
+struct _GcrCertificateRenderer {
+ GObject parent;
+ GcrCertificateRendererPrivate *pv;
+};
+
+struct _GcrCertificateRendererClass {
+ GObjectClass parent_class;
+};
+
+GType gcr_certificate_renderer_get_type (void);
+
+GcrCertificateRenderer* gcr_certificate_renderer_new (GcrCertificate *cert);
+
+GcrCertificate* gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self);
+
+void gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self,
+ GcrCertificate *cert);
+
+struct _GckAttributes* gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self);
+
+void gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self,
+ struct _GckAttributes *attrs);
+
+G_END_DECLS
+
+#endif /* __GCR_CERTIFICATE_RENDERER_H__ */
diff --git a/gcr/gcr-certificate-widget.c b/gcr/gcr-certificate-widget.c
index f1ee235..8e61063 100644
--- a/gcr/gcr-certificate-widget.c
+++ b/gcr/gcr-certificate-widget.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Stefan Walter
+ * 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
@@ -20,17 +20,10 @@
#include "config.h"
#include "gcr-certificate.h"
+#include "gcr-certificate-renderer.h"
#include "gcr-certificate-widget.h"
-#include "gcr-display-view.h"
-#include "gcr-icons.h"
-#include "gcr-simple-certificate.h"
-#include "gcr-view.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-dn.h"
-#include "egg/egg-oid.h"
-#include "egg/egg-hex.h"
+#include "gcr-renderer.h"
+#include "gcr-viewer.h"
#include "gck/gck.h"
@@ -40,287 +33,15 @@
enum {
PROP_0,
PROP_CERTIFICATE,
- PROP_LABEL,
PROP_ATTRIBUTES
};
struct _GcrCertificateWidgetPrivate {
- GcrCertificate *certificate;
- GcrDisplayView *view;
- guint key_size;
- gchar *label;
- GckAttributes *attributes;
+ GcrViewer *viewer;
+ GcrCertificateRenderer *renderer;
};
-static void gcr_view_iface_init (GcrViewIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrCertificateWidget, gcr_certificate_widget, GTK_TYPE_ALIGNMENT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEW, gcr_view_iface_init));
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gchar*
-calculate_label (GcrCertificateWidget *self, GNode *asn)
-{
- gchar *label;
-
- if (self->pv->label)
- return g_strdup (self->pv->label);
-
- if (self->pv->attributes) {
- if (gck_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
- return label;
- }
-
- if (asn != NULL) {
- label = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
- if (label != NULL)
- return label;
- }
-
- return g_strdup (_("Certificate"));
-}
-
-static gboolean
-append_extension (GcrCertificateWidget *self, GNode *asn,
- const guchar *data, gsize n_data, gint index)
-{
- GNode *node;
- GQuark oid;
- gchar *display;
- gsize n_value;
- const guchar *value;
- const gchar *text;
- gboolean critical;
-
- /* Make sure it is present */
- node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
- if (node == NULL)
- return FALSE;
-
- /* Dig out the OID */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
- g_return_val_if_fail (oid, FALSE);
-
- _gcr_display_view_append_heading (self->pv->view, _("Extension"));
-
-
- /* Extension type */
- text = egg_oid_get_description (oid);
- _gcr_display_view_append_value (self->pv->view, _("Identifier"), text, FALSE);
-
-
- /* Extension value */
- value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
-
- /* TODO: Parsing of extensions that we understand */
- display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Value"), display, TRUE);
- g_free (display);
-
-
- /* Critical */
- if (egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical))
- _gcr_display_view_append_value (self->pv->view, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
-
- return TRUE;
-}
-
-static void
-on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
- gsize n_value, gpointer user_data)
-{
- GcrCertificateWidget *self = user_data;
- const gchar *attr;
- const gchar *desc;
- gchar *field;
- gchar *display;
-
- g_return_if_fail (GCR_IS_CERTIFICATE_WIDGET (self));
-
- attr = egg_oid_get_name (oid);
- desc = egg_oid_get_description (oid);
-
- /* Combine them into something sane */
- if (attr && desc) {
- if (strcmp (attr, desc) == 0)
- field = g_strdup (attr);
- else
- field = g_strdup_printf ("%s (%s)", attr, desc);
- } else if (!attr && !desc) {
- field = g_strdup ("");
- } else if (attr) {
- field = g_strdup (attr);
- } else if (desc) {
- field = g_strdup (desc);
- } else {
- g_assert_not_reached ();
- }
-
- display = egg_dn_print_value (oid, value, n_value);
- if (display == NULL)
- display = g_strdup ("");
-
- _gcr_display_view_append_value (self->pv->view, field, display, FALSE);
- g_free (field);
- g_free (display);
-}
-
-static void
-refresh_display (GcrCertificateWidget *self)
-{
- const guchar *data, *value;
- gsize n_data, n_value, n_raw;
- const gchar *text;
- gpointer raw;
- gulong version;
- guint bits, index;
- gchar *display;
- GNode *asn;
- GQuark oid;
- GDate date;
-
- if (!self->pv->view)
- return;
-
- _gcr_display_view_clear (self->pv->view);
-
- if (!self->pv->certificate)
- return;
-
- data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
- g_return_if_fail (data);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- g_return_if_fail (asn);
-
- display = calculate_label (self, asn);
- _gcr_display_view_append_title (self->pv->view, display);
- g_free (display);
-
- display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
- _gcr_display_view_append_content (self->pv->view, _("Identity"), display);
- g_free (display);
-
- display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
- _gcr_display_view_append_content (self->pv->view, _("Verified by"), display);
- g_free (display);
-
- if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
- display = g_malloc0 (128);
- if (!g_date_strftime (display, 128, "%x", &date))
- g_return_if_reached ();
- _gcr_display_view_append_content (self->pv->view, _("Expires"), display);
- g_free (display);
- }
-
- _gcr_display_view_start_details (self->pv->view);
-
- /* The subject */
- _gcr_display_view_append_heading (self->pv->view, _("Subject Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, self);
-
- /* The Issuer */
- _gcr_display_view_append_heading (self->pv->view, _("Issuer Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, self);
-
- /* The Issued Parameters */
- _gcr_display_view_append_heading (self->pv->view, _("Issued Certificate"));
-
- if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
- g_return_if_reached ();
- display = g_strdup_printf ("%lu", version + 1);
- _gcr_display_view_append_value (self->pv->view, _("Version"), display, FALSE);
- g_free (display);
-
- raw = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), NULL, &n_raw);
- g_return_if_fail (raw);
- display = egg_hex_encode_full (raw, n_raw, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Serial Number"), display, TRUE);
- g_free (display);
- g_free (raw);
-
- display = g_malloc0 (128);
- if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
- if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
- g_return_if_reached ();
- _gcr_display_view_append_value (self->pv->view, _("Not Valid Before"), display, FALSE);
- }
- if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
- if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
- g_return_if_reached ();
- _gcr_display_view_append_value (self->pv->view, _("Not Valid After"), display, FALSE);
- }
- g_free (display);
-
- /* Signature */
- _gcr_display_view_append_heading (self->pv->view, _("Signature"));
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
- text = egg_oid_get_description (oid);
- _gcr_display_view_append_value (self->pv->view, _("Signature Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
- if (value && n_value) {
- display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Signature Parameters"), display, TRUE);
- g_free (display);
- }
-
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
- g_return_if_fail (raw);
- display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Signature"), display, TRUE);
- g_free (display);
- g_free (raw);
-
- /* Public Key Info */
- _gcr_display_view_append_heading (self->pv->view, _("Public Key Info"));
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "algorithm", "algorithm", NULL));
- text = egg_oid_get_description (oid);
- _gcr_display_view_append_value (self->pv->view, _("Key Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "algorithm", "parameters", NULL), &n_value);
- if (value && n_value) {
- display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Key Parameters"), display, TRUE);
- g_free (display);
- }
-
- bits = gcr_certificate_get_key_size (self->pv->certificate);
- if (bits > 0) {
- display = g_strdup_printf ("%u", bits);
- _gcr_display_view_append_value (self->pv->view, _("Key Size"), display, FALSE);
- g_free (display);
- }
-
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "subjectPublicKey", NULL), NULL, &bits);
- g_return_if_fail (raw);
- display = egg_hex_encode_full (raw, bits / 8, TRUE, ' ', 1);
- _gcr_display_view_append_value (self->pv->view, _("Public Key"), display, TRUE);
- g_free (display);
- g_free (raw);
-
- /* Fingerprints */
- _gcr_display_view_append_heading (self->pv->view, _("Fingerprints"));
-
- _gcr_display_view_append_fingerprint (self->pv->view, data, n_data, "SHA1", G_CHECKSUM_SHA1);
- _gcr_display_view_append_fingerprint (self->pv->view, data, n_data, "MD5", G_CHECKSUM_MD5);
-
- /* Extensions */
- for (index = 1; TRUE; ++index) {
- if (!append_extension (self, asn, data, n_data, index))
- break;
- }
-
- egg_asn1x_destroy (asn);
-}
+G_DEFINE_TYPE (GcrCertificateWidget, gcr_certificate_widget, GTK_TYPE_ALIGNMENT);
/* -----------------------------------------------------------------------------
* OBJECT
@@ -337,17 +58,17 @@ gcr_certificate_widget_constructor (GType type, guint n_props, GObjectConstructP
self = GCR_CERTIFICATE_WIDGET (obj);
- self->pv->view = _gcr_display_view_new ();
- _gcr_display_view_set_stock_image (self->pv->view, GCR_ICON_CERTIFICATE);
+ self->pv->viewer = gcr_viewer_new ();
scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->view));
+ gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->viewer));
gtk_container_add (GTK_CONTAINER (self), scroll);
gtk_widget_show_all (scroll);
+ gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (self->pv->renderer));
return obj;
}
@@ -355,18 +76,7 @@ static void
gcr_certificate_widget_init (GcrCertificateWidget *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_WIDGET, GcrCertificateWidgetPrivate));
-}
-
-static void
-gcr_certificate_widget_dispose (GObject *obj)
-{
- GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
-
- if (self->pv->certificate)
- g_object_unref (self->pv->certificate);
- self->pv->certificate = NULL;
-
- G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->dispose (obj);
+ self->pv->renderer = gcr_certificate_renderer_new (NULL);
}
static void
@@ -374,14 +84,12 @@ gcr_certificate_widget_finalize (GObject *obj)
{
GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
- g_assert (!self->pv->certificate);
+ g_assert (self->pv->renderer);
+ g_object_unref (self->pv->renderer);
+ self->pv->renderer = NULL;
- if (self->pv->attributes)
- gck_attributes_unref (self->pv->attributes);
- self->pv->attributes = NULL;
-
- g_free (self->pv->label);
- self->pv->label = NULL;
+ g_assert (self->pv->viewer);
+ self->pv->viewer = NULL;
G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->finalize (obj);
}
@@ -391,35 +99,13 @@ gcr_certificate_widget_set_property (GObject *obj, guint prop_id, const GValue *
GParamSpec *pspec)
{
GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
- GcrCertificate *cert;
- GckAttribute *attr;
switch (prop_id) {
case PROP_CERTIFICATE:
gcr_certificate_widget_set_certificate (self, g_value_get_object (value));
break;
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- refresh_display (self);
- break;
case PROP_ATTRIBUTES:
- g_return_if_fail (!self->pv->attributes);
- self->pv->attributes = g_value_dup_boxed (value);
- if (self->pv->attributes) {
- attr = gck_attributes_find (self->pv->attributes, CKA_VALUE);
- if (attr) {
- /* Create a new certificate object refferring to same memory */
- cert = gcr_simple_certificate_new_static (attr->value, attr->length);
- g_object_set_data_full (G_OBJECT (cert), "attributes",
- gck_attributes_ref (self->pv->attributes),
- (GDestroyNotify)gck_attributes_unref);
- gcr_certificate_widget_set_certificate (self, cert);
- g_object_unref (cert);
- refresh_display (self);
- }
- }
+ gcr_certificate_widget_set_attributes (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -435,13 +121,10 @@ gcr_certificate_widget_get_property (GObject *obj, guint prop_id, GValue *value,
switch (prop_id) {
case PROP_CERTIFICATE:
- g_value_set_object (value, self->pv->certificate);
- break;
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self, NULL));
+ g_value_set_object (value, gcr_certificate_widget_get_certificate (self));
break;
case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->attributes);
+ g_value_set_boxed (value, gcr_certificate_widget_get_attributes (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -459,7 +142,6 @@ gcr_certificate_widget_class_init (GcrCertificateWidgetClass *klass)
g_type_class_add_private (klass, sizeof (GcrCertificateWidgetPrivate));
gobject_class->constructor = gcr_certificate_widget_constructor;
- gobject_class->dispose = gcr_certificate_widget_dispose;
gobject_class->finalize = gcr_certificate_widget_finalize;
gobject_class->set_property = gcr_certificate_widget_set_property;
gobject_class->get_property = gcr_certificate_widget_get_property;
@@ -468,24 +150,17 @@ gcr_certificate_widget_class_init (GcrCertificateWidgetClass *klass)
g_param_spec_object("certificate", "Certificate", "Certificate to display.",
GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
- g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+ g_param_spec_boxed ("attributes", "Attributes", "Attributes which contain the certificate",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
- _gcr_icons_register ();
-
- /* Register this as a view which can be loaded */
+ /* Register this as a renderer which can be loaded */
registered = gck_attributes_new ();
gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
- gcr_view_register (GCR_TYPE_CERTIFICATE_WIDGET, registered);
+ gcr_renderer_register (GCR_TYPE_CERTIFICATE_WIDGET, registered);
gck_attributes_unref (registered);
}
-static void
-gcr_view_iface_init (GcrViewIface *iface)
-{
- /* Nothing to do */
-}
-
/* -----------------------------------------------------------------------------
* PUBLIC
*/
@@ -500,20 +175,26 @@ GcrCertificate*
gcr_certificate_widget_get_certificate (GcrCertificateWidget *self)
{
g_return_val_if_fail (GCR_IS_CERTIFICATE_WIDGET (self), NULL);
- return self->pv->certificate;
+ return gcr_certificate_renderer_get_certificate (self->pv->renderer);
}
void
gcr_certificate_widget_set_certificate (GcrCertificateWidget *self, GcrCertificate *cert)
{
g_return_if_fail (GCR_IS_CERTIFICATE_WIDGET (self));
+ gcr_certificate_renderer_set_certificate (self->pv->renderer, cert);
+}
- if (self->pv->certificate)
- g_object_unref (self->pv->certificate);
- self->pv->certificate = cert;
- if (self->pv->certificate)
- g_object_ref (self->pv->certificate);
+GckAttributes*
+gcr_certificate_widget_get_attributes (GcrCertificateWidget *self)
+{
+ g_return_val_if_fail (GCR_IS_CERTIFICATE_WIDGET (self), NULL);
+ return gcr_certificate_renderer_get_attributes (self->pv->renderer);
+}
- refresh_display (self);
- g_object_notify (G_OBJECT (self), "certificate");
+void
+gcr_certificate_widget_set_attributes (GcrCertificateWidget *self, GckAttributes* attrs)
+{
+ g_return_if_fail (GCR_IS_CERTIFICATE_WIDGET (self));
+ gcr_certificate_renderer_set_attributes (self->pv->renderer, attrs);
}
diff --git a/gcr/gcr-certificate-widget.h b/gcr/gcr-certificate-widget.h
index e363e59..c88284e 100644
--- a/gcr/gcr-certificate-widget.h
+++ b/gcr/gcr-certificate-widget.h
@@ -52,11 +52,16 @@ GType gcr_certificate_widget_get_type (void);
GcrCertificateWidget* gcr_certificate_widget_new (GcrCertificate *cert);
-GcrCertificate* gcr_certificate_widget_get_certificate (GcrCertificateWidget *details);
+GcrCertificate* gcr_certificate_widget_get_certificate (GcrCertificateWidget *self);
-void gcr_certificate_widget_set_certificate (GcrCertificateWidget *details,
+void gcr_certificate_widget_set_certificate (GcrCertificateWidget *self,
GcrCertificate *cert);
+struct _GckAttributes* gcr_certificate_widget_get_attributes (GcrCertificateWidget *self);
+
+void gcr_certificate_widget_set_attributes (GcrCertificateWidget *self,
+ struct _GckAttributes* attrs);
+
G_END_DECLS
#endif /* __GCR_CERTIFICATE_WIDGET_H__ */
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
index a733fe6..23f5db1 100644
--- a/gcr/gcr-display-view.c
+++ b/gcr/gcr-display-view.c
@@ -20,28 +20,45 @@
#include "config.h"
#include "gcr-display-view.h"
+#include "gcr-renderer.h"
+#include "gcr-viewer.h"
#include "egg/egg-oid.h"
#include "egg/egg-hex.h"
#include <gdk/gdk.h>
-G_DEFINE_TYPE (GcrDisplayView, _gcr_display_view, GTK_TYPE_TEXT_VIEW);
+static void _gcr_display_view_viewer_iface (GcrViewerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrDisplayView, _gcr_display_view, GTK_TYPE_TEXT_VIEW,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEWER, _gcr_display_view_viewer_iface));
#define NORMAL_MARGIN 10
#define FIELD_MARGIN 17
#define COLUMN_MARGIN 6
#define ICON_MARGIN 8
-struct _GcrDisplayViewPrivate {
- GtkTextBuffer *buffer;
- GtkTextTag *field_tag;
- GtkTextTag *details_tag;
+typedef struct _GcrDisplayItem {
+ GcrDisplayView *display_view;
+ GtkTextMark *beginning;
+ GtkTextMark *ending;
GtkWidget *details_widget;
- GtkTextChildAnchor *details_anchor;
- const gchar *extra_tag;
+ GtkTextTag *extra_tag;
gint field_width;
GdkPixbuf *pixbuf;
+ GtkTextTag *field_tag;
+ GtkTextTag *details_tag;
+ gulong data_changed_id;
+} GcrDisplayItem;
+
+struct _GcrDisplayViewPrivate {
+ GtkTextBuffer *buffer;
+ GPtrArray *renderers;
+ GHashTable *items;
+ GtkTextTag *title_tag;
+ GtkTextTag *content_tag;
+ GtkTextTag *heading_tag;
+ GtkTextTag *monospace_tag;
};
/* -----------------------------------------------------------------------------
@@ -52,7 +69,6 @@ static GtkTextTagTable*
create_tag_table (GcrDisplayView *self)
{
GtkTextTagTable *tags;
- GtkTextTag *tag;
gint width, height;
g_assert (GCR_IS_DISPLAY_VIEW (self));
@@ -62,63 +78,41 @@ create_tag_table (GcrDisplayView *self)
if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &width, &height))
width = 48;
- tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "title",
- "scale", PANGO_SCALE_LARGE,
- "right-margin", (ICON_MARGIN * 2) + width,
- "pixels-above-lines", 9,
- "pixels-below-lines", 6,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- gtk_text_tag_table_add (tags, tag);
- g_object_unref (tag);
-
- tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "content",
- "right-margin", (ICON_MARGIN * 2) + width,
- "left-margin", FIELD_MARGIN,
- "pixels-below-lines", 3,
- NULL);
- gtk_text_tag_table_add (tags, tag);
- g_object_unref (tag);
-
- tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "heading",
- "pixels-above-lines", 9,
- "pixels-below-lines", 3,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- gtk_text_tag_table_add (tags, tag);
- g_object_unref (tag);
-
- tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "monospace",
- "family", "monospace",
- NULL);
- gtk_text_tag_table_add (tags, tag);
- g_object_unref (tag);
-
- g_assert (!self->pv->field_tag);
- self->pv->field_width = 0;
- self->pv->field_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "field",
- "left-margin", self->pv->field_width + FIELD_MARGIN,
- "indent", self->pv->field_width,
- "pixels-below-lines", 3,
- "wrap-mode", GTK_WRAP_WORD_CHAR,
+ self->pv->title_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "title",
+ "scale", PANGO_SCALE_LARGE,
+ "right-margin", (ICON_MARGIN * 2) + width,
+ "pixels-above-lines", 9,
+ "pixels-below-lines", 6,
+ "weight", PANGO_WEIGHT_BOLD,
NULL);
- gtk_text_tag_table_add (tags, self->pv->field_tag);
+ gtk_text_tag_table_add (tags, self->pv->title_tag);
+
+ self->pv->content_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "content",
+ "right-margin", (ICON_MARGIN * 2) + width,
+ "left-margin", FIELD_MARGIN,
+ "pixels-below-lines", 3,
+ NULL);
+ gtk_text_tag_table_add (tags, self->pv->content_tag);
- g_assert (!self->pv->details_tag);
- self->pv->details_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "details",
+ self->pv->heading_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "heading",
+ "pixels-above-lines", 9,
+ "pixels-below-lines", 3,
+ "weight", PANGO_WEIGHT_BOLD,
NULL);
- gtk_text_tag_table_add (tags, self->pv->details_tag);
+ gtk_text_tag_table_add (tags, self->pv->heading_tag);
+
+ self->pv->monospace_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "monospace",
+ "family", "monospace",
+ NULL);
+ gtk_text_tag_table_add (tags, self->pv->monospace_tag);
return tags;
}
-
static void
on_expander_realize (GtkWidget *widget, gpointer user_data)
{
@@ -131,12 +125,137 @@ static void
on_expander_expanded (GObject *object, GParamSpec *param_spec, gpointer user_data)
{
GtkExpander *expander = GTK_EXPANDER (object);
- GcrDisplayView *self = GCR_DISPLAY_VIEW (user_data);
- g_object_set (self->pv->details_tag,
+ GcrDisplayItem *item = user_data;
+ g_object_set (item->details_tag,
"invisible", gtk_expander_get_expanded (expander) ? FALSE : TRUE,
NULL);
}
+static void
+style_display_item (GtkWidget *widget, GcrDisplayItem *item)
+{
+ GtkStyle *style = gtk_widget_get_style (widget);
+ gtk_widget_modify_bg (item->details_widget, GTK_STATE_NORMAL, &style->base[GTK_STATE_NORMAL]);
+}
+
+static GcrDisplayItem*
+create_display_item (GcrDisplayView *self)
+{
+ GcrDisplayItem *item;
+ GtkTextTagTable *tags;
+ GtkTextIter iter;
+ GtkWidget *widget;
+ GtkWidget *label;
+ GtkWidget *alignment;
+
+ item = g_new0 (GcrDisplayItem, 1);
+ item->display_view = self;
+
+ tags = gtk_text_buffer_get_tag_table (self->pv->buffer);
+
+ g_assert (!item->field_tag);
+ item->field_width = 0;
+ item->field_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "left-margin", item->field_width + FIELD_MARGIN,
+ "indent", item->field_width,
+ "pixels-below-lines", 3,
+ "wrap-mode", GTK_WRAP_WORD_CHAR,
+ NULL);
+ gtk_text_tag_table_add (tags, item->field_tag);
+
+ g_assert (!item->details_tag);
+ item->details_tag = g_object_new (GTK_TYPE_TEXT_TAG, NULL);
+ gtk_text_tag_table_add (tags, item->details_tag);
+
+ /* The mark that determines the beginning of this item, with left gravity. */
+ gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
+ item->beginning = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, TRUE);
+ g_object_ref (item->beginning);
+
+ /* The mark that determines the end of this item, with right gravity. */
+ gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
+ item->ending = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, FALSE);
+ g_object_ref (item->ending);
+
+ widget = gtk_expander_new_with_mnemonic ("");
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), "<b>_Details</b>");
+ g_signal_connect (widget, "notify::expanded", G_CALLBACK (on_expander_expanded), item);
+ g_signal_connect (widget, "realize", G_CALLBACK (on_expander_realize), NULL);
+ on_expander_expanded (G_OBJECT (widget), NULL, item);
+
+ alignment = gtk_alignment_new (0.5, 0.5, 0.5, 0.5);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 9, 0, 0);
+ gtk_container_add (GTK_CONTAINER (alignment), widget);
+ gtk_widget_show_all (alignment);
+
+ item->details_widget = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (item->details_widget), alignment);
+ g_signal_connect (item->details_widget, "realize", G_CALLBACK (on_expander_realize), NULL);
+ g_object_ref (item->details_widget);
+
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ style_display_item (GTK_WIDGET (self), item);
+
+ /* TODO: Initialize the rest of the fields */
+
+ return item;
+}
+
+static void
+destroy_display_item (gpointer data)
+{
+ GcrDisplayItem *item = data;
+ GtkTextTagTable *tags;
+ GcrDisplayView *self;
+
+ g_assert (item);
+
+ g_assert (GCR_IS_DISPLAY_VIEW (item->display_view));
+ self = item->display_view;
+
+ tags = gtk_text_buffer_get_tag_table (self->pv->buffer);
+ gtk_text_tag_table_remove (tags, item->field_tag);
+ gtk_text_tag_table_remove (tags, item->details_tag);
+
+ g_object_unref (item->field_tag);
+ g_object_unref (item->details_tag);
+
+ if (item->pixbuf)
+ g_object_unref (item->pixbuf);
+ item->pixbuf = NULL;
+
+ g_assert (item->details_widget);
+ g_object_unref (item->details_widget);
+ item->details_widget = NULL;
+
+ g_return_if_fail (!gtk_text_mark_get_deleted (item->beginning));
+ gtk_text_buffer_delete_mark (self->pv->buffer, item->beginning);
+ g_object_unref (item->beginning);
+
+ g_return_if_fail (!gtk_text_mark_get_deleted (item->ending));
+ gtk_text_buffer_delete_mark (self->pv->buffer, item->ending);
+ g_object_unref (item->ending);
+
+ g_free (item);
+}
+
+static GcrDisplayItem*
+lookup_display_item (GcrDisplayView *self, GcrRenderer *renderer)
+{
+ GcrDisplayItem *item = g_hash_table_lookup (self->pv->items, renderer);
+ g_return_val_if_fail (item, NULL);
+ g_assert (item->display_view == self);
+ return item;
+}
+
+static void
+on_renderer_data_changed (GcrRenderer *renderer, GcrViewer *self)
+{
+ /* Just ask the renderer to render itself on us */
+ gcr_renderer_render (renderer, self);
+}
+
/* -----------------------------------------------------------------------------
* OBJECT
*/
@@ -148,7 +267,6 @@ _gcr_display_view_constructor (GType type, guint n_props, GObjectConstructParam
GcrDisplayView *self = NULL;
GtkTextView *view = NULL;
GtkTextTagTable *tags;
- GtkWidget *widget, *alignment, *label;
g_return_val_if_fail (obj, NULL);
@@ -165,26 +283,6 @@ _gcr_display_view_constructor (GType type, guint n_props, GObjectConstructParam
gtk_text_view_set_right_margin (view, NORMAL_MARGIN);
gtk_text_view_set_cursor_visible (view, FALSE);
- widget = gtk_expander_new_with_mnemonic ("");
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), "<b>_Details</b>");
- g_signal_connect_object (widget, "notify::expanded",
- G_CALLBACK (on_expander_expanded), self, 0);
- g_signal_connect_object (widget, "realize",
- G_CALLBACK (on_expander_realize), self, 0);
- on_expander_expanded (G_OBJECT (widget), NULL, self);
-
- alignment = gtk_alignment_new (0.5, 0.5, 0.5, 0.5);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 9, 0, 0);
- gtk_container_add (GTK_CONTAINER (alignment), widget);
- gtk_widget_show_all (alignment);
-
- self->pv->details_widget = gtk_event_box_new ();
- gtk_container_add (GTK_CONTAINER (self->pv->details_widget), alignment);
- g_signal_connect_object (self->pv->details_widget, "realize",
- G_CALLBACK (on_expander_realize), self, 0);
- g_object_ref (self->pv->details_widget);
-
return obj;
}
@@ -192,6 +290,34 @@ static void
_gcr_display_view_init (GcrDisplayView *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_DISPLAY_VIEW, GcrDisplayViewPrivate));
+ self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, destroy_display_item);
+ self->pv->renderers = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+static void
+_gcr_display_view_dispose (GObject *obj)
+{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (obj);
+ GcrRenderer *renderer;
+ GcrDisplayItem *item;
+
+ if (self->pv->buffer)
+ g_object_unref (self->pv->buffer);
+ self->pv->buffer = NULL;
+
+ while (self->pv->renderers->len) {
+ renderer = g_ptr_array_index (self->pv->renderers, 0);
+ item = g_hash_table_lookup (self->pv->items, renderer);
+ g_return_if_fail (item);
+ g_signal_handler_disconnect (renderer, item->data_changed_id);
+ if (!g_hash_table_remove (self->pv->items, renderer))
+ g_return_if_reached ();
+ g_ptr_array_remove_index_fast (self->pv->renderers, 0);
+ }
+
+ g_assert (g_hash_table_size (self->pv->items) == 0);
+
+ G_OBJECT_CLASS (_gcr_display_view_parent_class)->finalize (obj);
}
static void
@@ -203,17 +329,30 @@ _gcr_display_view_finalize (GObject *obj)
g_object_unref (self->pv->buffer);
self->pv->buffer = NULL;
- if (self->pv->field_tag)
- g_object_unref (self->pv->field_tag);
- self->pv->field_tag = NULL;
+ g_assert (g_hash_table_size (self->pv->items) == 0);
+ g_hash_table_destroy (self->pv->items);
+ self->pv->items = NULL;
+
+ g_assert (self->pv->renderers);
+ g_assert (self->pv->renderers->len == 0);
+ g_ptr_array_free (self->pv->renderers, TRUE);
+ self->pv->renderers = NULL;
+
+ g_assert (self->pv->content_tag);
+ g_object_unref (self->pv->content_tag);
+ self->pv->content_tag = NULL;
- if (self->pv->pixbuf)
- g_object_unref (self->pv->pixbuf);
- self->pv->pixbuf = NULL;
+ g_assert (self->pv->heading_tag);
+ g_object_unref (self->pv->heading_tag);
+ self->pv->heading_tag = NULL;
- if (self->pv->details_widget)
- g_object_unref (self->pv->details_widget);
- self->pv->details_widget = NULL;
+ g_assert (self->pv->monospace_tag);
+ g_object_unref (self->pv->monospace_tag);
+ self->pv->monospace_tag = NULL;
+
+ g_assert (self->pv->title_tag);
+ g_object_unref (self->pv->title_tag);
+ self->pv->title_tag = NULL;
G_OBJECT_CLASS (_gcr_display_view_parent_class)->finalize (obj);
}
@@ -222,13 +361,16 @@ static void
_gcr_display_view_realize (GtkWidget *widget)
{
GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
- GtkStyle *style;
+ GHashTableIter iter;
+ gpointer value;
if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->realize)
GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->realize (widget);
- style = gtk_widget_get_style (widget);
- gtk_widget_modify_bg (self->pv->details_widget, GTK_STATE_NORMAL, &style->base[GTK_STATE_NORMAL]);
+ /* Set style on all the items */
+ g_hash_table_iter_init (&iter, self->pv->items);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ style_display_item (widget, value);
}
static gboolean
@@ -238,33 +380,49 @@ _gcr_display_view_expose_event (GtkWidget *widget, GdkEventExpose *event)
GtkTextView *view = GTK_TEXT_VIEW (widget);
gboolean handled = FALSE;
GdkRectangle visible;
- GdkRectangle position;
+ GdkRectangle location;
+ GHashTableIter hit;
+ GcrDisplayItem *item;
+ gpointer value;
+ GtkTextIter iter;
cairo_t *cr;
/* Have GtkTextView draw the text first. */
if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->expose_event)
handled = GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->expose_event (widget, event);
- if (self->pv->pixbuf == NULL)
- return handled;
-
/* Render the pixbuf if it's available */
if (event->window == gtk_text_view_get_window (view, GTK_TEXT_WINDOW_TEXT)) {
- position.height = gdk_pixbuf_get_height (self->pv->pixbuf);
- position.width = gdk_pixbuf_get_width (self->pv->pixbuf);
-
gtk_text_view_get_visible_rect (view, &visible);
- gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
- visible.width - position.width - ICON_MARGIN, ICON_MARGIN,
- &position.x, &position.y);
+ g_hash_table_iter_init (&hit, self->pv->items);
+ while (g_hash_table_iter_next (&hit, NULL, &value)) {
- cr = gdk_cairo_create (event->window);
- gdk_cairo_set_source_pixbuf (cr, self->pv->pixbuf, 0, 0);
- cairo_rectangle (cr, position.x, position.y, position.width, position.height);
- cairo_fill (cr);
- cairo_destroy (cr);
+ item = value;
+ if (item->pixbuf == NULL)
+ continue;
+
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
+ gtk_text_view_get_iter_location (view, &iter, &location);
+
+ location.height = gdk_pixbuf_get_height (item->pixbuf);
+ location.width = gdk_pixbuf_get_width (item->pixbuf);
+ location.x = visible.width - location.width - ICON_MARGIN;
+
+ if (!gdk_rectangle_intersect (&visible, &location, NULL))
+ continue;
+
+ gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
+ location.x, location.y,
+ &location.x, &location.y);
+
+ cr = gdk_cairo_create (event->window);
+ gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y);
+ cairo_rectangle (cr, location.x, location.y, location.width, location.height);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ }
}
return handled;
@@ -280,12 +438,73 @@ _gcr_display_view_class_init (GcrDisplayViewClass *klass)
g_type_class_add_private (klass, sizeof (GcrDisplayViewPrivate));
gobject_class->constructor = _gcr_display_view_constructor;
+ gobject_class->dispose = _gcr_display_view_dispose;
gobject_class->finalize = _gcr_display_view_finalize;
widget_class->realize = _gcr_display_view_realize;
widget_class->expose_event = _gcr_display_view_expose_event;
}
+static void
+_gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
+ GcrDisplayItem *item;
+
+ item = create_display_item (self);
+ g_ptr_array_add (self->pv->renderers, g_object_ref (renderer));
+ g_hash_table_insert (self->pv->items, renderer, item);
+
+ gcr_renderer_render (renderer, viewer);
+ item->data_changed_id = g_signal_connect (renderer, "data-changed",
+ G_CALLBACK (on_renderer_data_changed), self);
+}
+
+static void
+_gcr_display_view_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
+ GcrDisplayItem *item;
+
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ /* Unhook the callback */
+ g_signal_handler_disconnect (renderer, item->data_changed_id);
+
+ /* Destroys the display item */
+ g_assert (item->display_view == self);
+ g_hash_table_remove (self->pv->items, renderer);
+
+ /* Unrefs the renderer */
+ if (!g_ptr_array_remove (self->pv->renderers, renderer))
+ g_return_if_reached ();
+}
+
+static guint
+_gcr_display_view_real_count_renderers (GcrViewer *viewer)
+{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
+ return self->pv->renderers->len;
+}
+
+static GcrRenderer*
+_gcr_display_view_real_get_renderer (GcrViewer *viewer, guint index_)
+{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
+ g_return_val_if_fail (index_ < self->pv->renderers->len, NULL);
+ return g_ptr_array_index (self->pv->renderers, index_);
+}
+
+static void
+_gcr_display_view_viewer_iface (GcrViewerIface *iface)
+{
+ iface->add_renderer = (gpointer)_gcr_display_view_real_add_renderer;
+ iface->remove_renderer = (gpointer)_gcr_display_view_real_remove_renderer;
+ iface->count_renderers = (gpointer)_gcr_display_view_real_count_renderers;
+ iface->get_renderer = (gpointer)_gcr_display_view_real_get_renderer;
+}
+
/* -----------------------------------------------------------------------------
* PUBLIC
*/
@@ -297,64 +516,87 @@ _gcr_display_view_new (void)
}
void
-_gcr_display_view_clear (GcrDisplayView *self)
+_gcr_display_view_clear (GcrDisplayView *self, GcrRenderer *renderer)
{
GtkTextIter start, iter;
- if (gtk_widget_get_parent (self->pv->details_widget))
- gtk_container_remove (GTK_CONTAINER (self), self->pv->details_widget);
+ GcrDisplayItem *item;
+
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ if (gtk_widget_get_parent (item->details_widget))
+ gtk_container_remove (GTK_CONTAINER (self), item->details_widget);
gtk_text_buffer_get_start_iter (self->pv->buffer, &start);
gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
- self->pv->extra_tag = NULL;
- self->pv->field_width = 0;
+ item->extra_tag = NULL;
+ item->field_width = 0;
}
void
-_gcr_display_view_start_details (GcrDisplayView *self)
+_gcr_display_view_start_details (GcrDisplayView *self, GcrRenderer *renderer)
{
GtkTextChildAnchor *anchor;
+ GcrDisplayItem *item;
GtkTextIter iter;
- self->pv->extra_tag = "details";
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ item->extra_tag = item->details_tag;
gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
anchor = gtk_text_buffer_create_child_anchor (self->pv->buffer, &iter);
- gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), self->pv->details_widget, anchor);
- gtk_widget_show_all (self->pv->details_widget);
+ gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), item->details_widget, anchor);
+ gtk_widget_show_all (item->details_widget);
gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1);
}
void
-_gcr_display_view_append_content (GcrDisplayView *self, const gchar *content, const gchar *details)
+_gcr_display_view_append_content (GcrDisplayView *self, GcrRenderer *renderer,
+ const gchar *content, const gchar *details)
{
+ GcrDisplayItem *item;
GtkTextIter iter;
gchar *memory = NULL;
g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
g_return_if_fail (content);
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
if (details)
content = memory = g_strdup_printf ("%s: %s", content, details);
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, content, -1,
- "content", self->pv->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, "\n", 1,
- self->pv->extra_tag, NULL);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, content, -1,
+ self->pv->content_tag, item->extra_tag, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
+ item->extra_tag, NULL);
g_free (memory);
}
void
-_gcr_display_view_append_value (GcrDisplayView *self, const gchar *field,
+_gcr_display_view_append_value (GcrDisplayView *self, GcrRenderer *renderer, const gchar *field,
const gchar *value, gboolean monospace)
{
+ GcrDisplayItem *item;
PangoRectangle extents;
PangoTabArray *tabs;
PangoLayout *layout;
GtkTextIter iter;
gchar *text;
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ g_return_if_fail (field);
+
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
text = g_strdup_printf ("%s:", field);
if (value == NULL)
value = "";
@@ -366,58 +608,75 @@ _gcr_display_view_append_value (GcrDisplayView *self, const gchar *field,
g_object_unref (layout);
/* Make the tab wide enough to accomodate */
- if (extents.width > self->pv->field_width) {
- self->pv->field_width = extents.width + COLUMN_MARGIN;
+ if (extents.width > item->field_width) {
+ item->field_width = extents.width + COLUMN_MARGIN;
tabs = pango_tab_array_new (1, TRUE);
- pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, self->pv->field_width);
- g_object_set (self->pv->field_tag,
+ pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, item->field_width);
+ g_object_set (item->field_tag,
"left-margin", FIELD_MARGIN,
- "indent", 0 - self->pv->field_width,
+ "indent", 0 - item->field_width,
"tabs", tabs,
NULL);
pango_tab_array_free (tabs);
}
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, text, -1,
- "field", self->pv->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, "\t", 1,
- self->pv->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, value, -1, "field",
- monospace ? "monospace" : self->pv->extra_tag,
- monospace ? self->pv->extra_tag : NULL, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, "\n", 1,
- self->pv->extra_tag, NULL);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, text, -1,
+ item->field_tag, item->extra_tag, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\t", 1,
+ item->extra_tag, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, value, -1, item->field_tag,
+ monospace ? self->pv->monospace_tag : item->extra_tag,
+ monospace ? item->extra_tag : NULL, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
+ item->extra_tag, NULL);
g_free (text);
}
void
-_gcr_display_view_append_title (GcrDisplayView *self, const gchar *title)
+_gcr_display_view_append_title (GcrDisplayView *self, GcrRenderer *renderer, const gchar *title)
{
+ GcrDisplayItem *item;
GtkTextIter iter;
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, title, -1,
- "title", self->pv->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, "\n", 1,
- self->pv->extra_tag, NULL);
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ g_return_if_fail (title);
+
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ g_return_if_fail (item && item->display_view == self);
+
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, title, -1,
+ self->pv->title_tag, item->extra_tag, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
+ item->extra_tag, NULL);
}
void
-_gcr_display_view_append_heading (GcrDisplayView *self, const gchar *heading)
+_gcr_display_view_append_heading (GcrDisplayView *self, GcrRenderer *renderer, const gchar *heading)
{
+ GcrDisplayItem *item;
GtkTextIter iter;
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, heading, -1,
- "heading", self->pv->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, "\n", 1,
- self->pv->extra_tag, NULL);
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ g_return_if_fail (heading);
+
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, heading, -1,
+ self->pv->heading_tag, item->extra_tag, NULL);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
+ item->extra_tag, NULL);
}
void
-_gcr_display_view_append_fingerprint (GcrDisplayView *self, const guchar *data,
+_gcr_display_view_append_fingerprint (GcrDisplayView *self, GcrRenderer *renderer, const guchar *data,
gsize n_data, const gchar *name, GChecksumType type)
{
GChecksum *checksum;
@@ -425,6 +684,8 @@ _gcr_display_view_append_fingerprint (GcrDisplayView *self, const guchar *data,
gsize n_buffer;
gchar *display;
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+
checksum = g_checksum_new (type);
g_return_if_fail (checksum);
g_checksum_update (checksum, data, n_data);
@@ -437,16 +698,26 @@ _gcr_display_view_append_fingerprint (GcrDisplayView *self, const guchar *data,
g_checksum_free (checksum);
display = egg_hex_encode_full (buffer, n_buffer, TRUE, ' ', 1);
- _gcr_display_view_append_value (self, name, display, TRUE);
+ _gcr_display_view_append_value (self, renderer, name, display, TRUE);
g_free (display);
g_free (buffer);
}
void
-_gcr_display_view_set_stock_image (GcrDisplayView *self, const gchar *stock_id)
+_gcr_display_view_set_stock_image (GcrDisplayView *self, GcrRenderer *renderer,
+ const gchar *stock_id)
{
- if (self->pv->pixbuf)
- g_object_unref (self->pv->pixbuf);
- self->pv->pixbuf = gtk_widget_render_icon (GTK_WIDGET (self), stock_id, GTK_ICON_SIZE_DIALOG, NULL);
+ GcrDisplayItem *item;
+
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ if (item->pixbuf)
+ g_object_unref (item->pixbuf);
+ if (stock_id)
+ item->pixbuf = gtk_widget_render_icon (GTK_WIDGET (self), stock_id, GTK_ICON_SIZE_DIALOG, NULL);
+ else
+ item->pixbuf = NULL;
}
diff --git a/gcr/gcr-display-view.h b/gcr/gcr-display-view.h
index f47aecf..c5f83a6 100644
--- a/gcr/gcr-display-view.h
+++ b/gcr/gcr-display-view.h
@@ -25,6 +25,7 @@
#include "gcr-certificate.h"
#include "gcr-types.h"
+#include "gcr-viewer.h"
G_BEGIN_DECLS
@@ -52,32 +53,40 @@ GType _gcr_display_view_get_type (void);
GcrDisplayView* _gcr_display_view_new (void);
-void _gcr_display_view_clear (GcrDisplayView *self);
+void _gcr_display_view_clear (GcrDisplayView *self,
+ GcrRenderer *renderer);
void _gcr_display_view_append_value (GcrDisplayView *self,
+ GcrRenderer *renderer,
const gchar *field,
const gchar *value,
gboolean monospace);
void _gcr_display_view_append_title (GcrDisplayView *self,
+ GcrRenderer *renderer,
const gchar *title);
void _gcr_display_view_append_content (GcrDisplayView *self,
+ GcrRenderer *renderer,
const gchar *content,
const gchar *details);
-void _gcr_display_view_start_details (GcrDisplayView *self);
+void _gcr_display_view_start_details (GcrDisplayView *self,
+ GcrRenderer *renderer);
void _gcr_display_view_append_heading (GcrDisplayView *self,
+ GcrRenderer *renderer,
const gchar *heading);
void _gcr_display_view_append_fingerprint (GcrDisplayView *self,
+ GcrRenderer *renderer,
const guchar *data,
gsize n_data,
const gchar *name,
GChecksumType type);
void _gcr_display_view_set_stock_image (GcrDisplayView *self,
+ GcrRenderer *renderer,
const gchar *stock_id);
G_END_DECLS
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
new file mode 100644
index 0000000..262dde3
--- /dev/null
+++ b/gcr/gcr-key-renderer.c
@@ -0,0 +1,342 @@
+/*
+ * 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-key-renderer.h"
+#include "gcr-display-view.h"
+#include "gcr-icons.h"
+#include "gcr-renderer.h"
+#include "gcr-viewer.h"
+
+#include "egg/egg-hex.h"
+
+#include "gck/gck.h"
+
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+ PROP_0,
+ PROP_LABEL,
+ PROP_ATTRIBUTES
+};
+
+struct _GcrKeyRendererPrivate {
+ guint key_size;
+ gchar *label;
+ GckAttributes *attributes;
+};
+
+static void gcr_key_renderer_renderer_iface (GcrRendererIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrKeyRenderer, gcr_key_renderer, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_key_renderer_renderer_iface));
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gchar*
+calculate_label (GcrKeyRenderer *self)
+{
+ gchar *label;
+
+ if (self->pv->label)
+ return g_strdup (self->pv->label);
+
+ if (self->pv->attributes) {
+ if (gck_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
+ return label;
+ }
+
+ return g_strdup (_("Key"));
+}
+
+static gint
+calculate_rsa_key_size (GckAttributes *attrs)
+{
+ GckAttribute *attr;
+ gulong bits;
+
+ attr = gck_attributes_find (attrs, CKA_MODULUS);
+
+ /* Calculate the bit length, and remove the complement */
+ if (attr != NULL)
+ return (attr->length / 2) * 2 * 8;
+
+ if (gck_attributes_find_ulong (attrs, CKA_MODULUS_BITS, &bits))
+ return (gint)bits;
+
+ return -1;
+}
+
+static guint
+calculate_dsa_key_size (GckAttributes *attrs)
+{
+ GckAttribute *attr;
+ gulong bits;
+
+ attr = gck_attributes_find (attrs, CKA_PRIME);
+
+ /* Calculate the bit length, and remove the complement */
+ if (attr != NULL)
+ return (attr->length / 2) * 2 * 8;
+
+ if (gck_attributes_find_ulong (attrs, CKA_PRIME_BITS, &bits))
+ return (gint)bits;
+
+ return -1;
+}
+
+static gint
+calculate_key_size (GckAttributes *attrs, gulong key_type)
+{
+ if (key_type == CKK_RSA)
+ return calculate_rsa_key_size (attrs);
+ else if (key_type == CKK_DSA)
+ return calculate_dsa_key_size (attrs);
+ else
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+gcr_key_renderer_init (GcrKeyRenderer *self)
+{
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_RENDERER, GcrKeyRendererPrivate));
+}
+
+static void
+gcr_key_renderer_dispose (GObject *obj)
+{
+ G_OBJECT_CLASS (gcr_key_renderer_parent_class)->dispose (obj);
+}
+
+static void
+gcr_key_renderer_finalize (GObject *obj)
+{
+ GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
+
+ if (self->pv->attributes)
+ gck_attributes_unref (self->pv->attributes);
+ self->pv->attributes = NULL;
+
+ g_free (self->pv->label);
+ self->pv->label = NULL;
+
+ G_OBJECT_CLASS (gcr_key_renderer_parent_class)->finalize (obj);
+}
+
+static void
+gcr_key_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrKeyRenderer *self = GCR_KEY_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:
+ g_return_if_fail (!self->pv->attributes);
+ self->pv->attributes = g_value_dup_boxed (value);
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_key_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_take_string (value, calculate_label (self));
+ break;
+ case PROP_ATTRIBUTES:
+ g_value_set_boxed (value, self->pv->attributes);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_key_renderer_class_init (GcrKeyRendererClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GckAttributes *registered;
+
+ gcr_key_renderer_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GcrKeyRendererPrivate));
+
+ gobject_class->dispose = gcr_key_renderer_dispose;
+ gobject_class->finalize = gcr_key_renderer_finalize;
+ gobject_class->set_property = gcr_key_renderer_set_property;
+ gobject_class->get_property = gcr_key_renderer_get_property;
+
+ g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+ g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+
+ _gcr_icons_register ();
+
+ /* Register this as a view which can be loaded */
+ registered = gck_attributes_new ();
+ gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
+ gcr_renderer_register (GCR_TYPE_KEY_RENDERER, registered);
+ gck_attributes_unref (registered);
+}
+
+static void
+gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
+{
+ GcrKeyRenderer *self;
+ GcrDisplayView *view;
+ const gchar *text;
+ gchar *display;
+ gulong klass;
+ gulong key_type;
+ gint size;
+
+ self = GCR_KEY_RENDERER (renderer);
+
+ if (GCR_IS_DISPLAY_VIEW (viewer)) {
+ view = GCR_DISPLAY_VIEW (viewer);
+
+ } else {
+ g_warning ("GcrKeyRenderer only works with internal specific "
+ "GcrViewer returned by gcr_viewer_new().");
+ return;
+ }
+
+ _gcr_display_view_clear (view, renderer);
+
+ if (!self->pv->attributes)
+ return;
+
+ _gcr_display_view_set_stock_image (view, renderer, GTK_STOCK_DIALOG_AUTHENTICATION);
+
+ if (!gck_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
+ !gck_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
+ g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
+ return;
+ }
+
+ display = calculate_label (self);
+ _gcr_display_view_append_title (view, renderer, display);
+ g_free (display);
+
+ if (klass == CKO_PRIVATE_KEY) {
+ if (key_type == CKK_RSA)
+ text = _("Private RSA Key");
+ else if (key_type == CKK_DSA)
+ text = _("Private DSA Key");
+ else
+ text = _("Private Key");
+ } else if (klass == CKO_PUBLIC_KEY) {
+ if (key_type == CKK_RSA)
+ text = _("Public DSA Key");
+ else if (key_type == CKK_DSA)
+ text = _("Public DSA Key");
+ else
+ text = _("Public Key");
+ }
+
+ _gcr_display_view_append_content (view, renderer, text, NULL);
+
+ size = calculate_key_size (self->pv->attributes, key_type);
+ if (size >= 0) {
+ display = g_strdup_printf (_("%d bits"), size);
+ _gcr_display_view_append_content (view, renderer, _("Strength"), display);
+ g_free (display);
+ }
+
+ _gcr_display_view_start_details (view, renderer);
+
+
+ if (key_type == CKK_RSA)
+ text = _("RSA");
+ else if (key_type == CKK_DSA)
+ text = _("DSA");
+ else
+ text = _("Unknown");
+ _gcr_display_view_append_value (view, renderer, _("Algorithm"), text, FALSE);
+
+ size = calculate_key_size (self->pv->attributes, key_type);
+ if (size < 0)
+ display = g_strdup (_("Unknown"));
+ else
+ display = g_strdup_printf ("%d", size);
+ _gcr_display_view_append_value (view, renderer, _("Size"), display, FALSE);
+ g_free (display);
+
+ /* TODO: We need to have consistent key fingerprints. */
+ _gcr_display_view_append_value (view, renderer, _("Fingerprint"), "XX XX XX XX XX XX XX XX XX XX", TRUE);
+}
+
+static void
+gcr_key_renderer_renderer_iface (GcrRendererIface *iface)
+{
+ iface->render = gcr_key_renderer_real_render;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrKeyRenderer*
+gcr_key_renderer_new (const gchar *label, GckAttributes *attrs)
+{
+ return g_object_new (GCR_TYPE_KEY_RENDERER, "label", label, "attributes", attrs, NULL);
+}
+
+void
+gcr_key_renderer_set_attributes (GcrKeyRenderer *self, GckAttributes *attrs)
+{
+ g_return_if_fail (GCR_IS_KEY_RENDERER (self));
+
+ if (self->pv->attributes)
+ gck_attributes_unref (self->pv->attributes);
+ self->pv->attributes = attrs;
+ if (self->pv->attributes)
+ gck_attributes_ref (self->pv->attributes);
+
+ g_object_notify (G_OBJECT (self), "attributes");
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+}
+
+GckAttributes*
+gcr_key_renderer_get_attributes (GcrKeyRenderer *self)
+{
+ g_return_val_if_fail (GCR_IS_KEY_RENDERER (self), NULL);
+ return self->pv->attributes;
+}
diff --git a/gcr/gcr-key-renderer.h b/gcr/gcr-key-renderer.h
new file mode 100644
index 0000000..1d25528
--- /dev/null
+++ b/gcr/gcr-key-renderer.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef __GCR_KEY_RENDERER_H__
+#define __GCR_KEY_RENDERER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_KEY_RENDERER (gcr_key_renderer_get_type ())
+#define GCR_KEY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_KEY_RENDERER, GcrKeyRenderer))
+#define GCR_KEY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_KEY_RENDERER, GcrKeyRendererClass))
+#define GCR_IS_KEY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_KEY_RENDERER))
+#define GCR_IS_KEY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_KEY_RENDERER))
+#define GCR_KEY_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_KEY_RENDERER, GcrKeyRendererClass))
+
+typedef struct _GcrKeyRenderer GcrKeyRenderer;
+typedef struct _GcrKeyRendererClass GcrKeyRendererClass;
+typedef struct _GcrKeyRendererPrivate GcrKeyRendererPrivate;
+
+struct _GcrKeyRenderer {
+ GObject parent;
+ GcrKeyRendererPrivate *pv;
+};
+
+struct _GcrKeyRendererClass {
+ GObjectClass parent_class;
+};
+
+GType gcr_key_renderer_get_type (void);
+
+GcrKeyRenderer* gcr_key_renderer_new (const gchar *label,
+ struct _GckAttributes *attrs);
+
+void gcr_key_renderer_set_attributes (GcrKeyRenderer *self,
+ struct _GckAttributes *attrs);
+
+struct _GckAttributes* gcr_key_renderer_get_attributes (GcrKeyRenderer *self);
+
+G_END_DECLS
+
+#endif /* __GCR_KEY_RENDERER_H__ */
diff --git a/gcr/gcr-key-widget.c b/gcr/gcr-key-widget.c
index 8f7a7b5..53fdde9 100644
--- a/gcr/gcr-key-widget.c
+++ b/gcr/gcr-key-widget.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Stefan Walter
+ * 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
@@ -19,14 +19,10 @@
#include "config.h"
+#include "gcr-key-renderer.h"
#include "gcr-key-widget.h"
-#include "gcr-display-view.h"
-#include "gcr-icons.h"
-#include "gcr-view.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-oid.h"
-#include "egg/egg-hex.h"
+#include "gcr-renderer.h"
+#include "gcr-viewer.h"
#include "gck/gck.h"
@@ -35,163 +31,15 @@
enum {
PROP_0,
- PROP_LABEL,
PROP_ATTRIBUTES
};
struct _GcrKeyWidgetPrivate {
- GcrDisplayView *view;
- guint key_size;
- gchar *label;
- GckAttributes *attributes;
+ GcrViewer *viewer;
+ GcrKeyRenderer *renderer;
};
-static void gcr_view_iface_init (GcrViewIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrKeyWidget, gcr_key_widget, GTK_TYPE_ALIGNMENT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEW, gcr_view_iface_init));
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gchar*
-calculate_label (GcrKeyWidget *self)
-{
- gchar *label;
-
- if (self->pv->label)
- return g_strdup (self->pv->label);
-
- if (self->pv->attributes) {
- if (gck_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
- return label;
- }
-
- return g_strdup (_("Key"));
-}
-
-static gint
-calculate_rsa_key_size (GckAttributes *attrs)
-{
- GckAttribute *attr;
- gulong bits;
-
- attr = gck_attributes_find (attrs, CKA_MODULUS);
-
- /* Calculate the bit length, and remove the complement */
- if (attr != NULL)
- return (attr->length / 2) * 2 * 8;
-
- if (gck_attributes_find_ulong (attrs, CKA_MODULUS_BITS, &bits))
- return (gint)bits;
-
- return -1;
-}
-
-static guint
-calculate_dsa_key_size (GckAttributes *attrs)
-{
- GckAttribute *attr;
- gulong bits;
-
- attr = gck_attributes_find (attrs, CKA_PRIME);
-
- /* Calculate the bit length, and remove the complement */
- if (attr != NULL)
- return (attr->length / 2) * 2 * 8;
-
- if (gck_attributes_find_ulong (attrs, CKA_PRIME_BITS, &bits))
- return (gint)bits;
-
- return -1;
-}
-
-static gint
-calculate_key_size (GckAttributes *attrs, gulong key_type)
-{
- if (key_type == CKK_RSA)
- return calculate_rsa_key_size (attrs);
- else if (key_type == CKK_DSA)
- return calculate_dsa_key_size (attrs);
- else
- return -1;
-}
-
-static void
-refresh_display (GcrKeyWidget *self)
-{
- const gchar *text;
- gchar *display;
- gulong klass;
- gulong key_type;
- gint size;
-
- if (!self->pv->view)
- return;
-
- _gcr_display_view_clear (self->pv->view);
-
- if (!self->pv->attributes)
- return;
-
- if (!gck_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
- !gck_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
- g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
- return;
- }
-
- display = calculate_label (self);
- _gcr_display_view_append_title (self->pv->view, display);
- g_free (display);
-
- if (klass == CKO_PRIVATE_KEY) {
- if (key_type == CKK_RSA)
- text = _("Private RSA Key");
- else if (key_type == CKK_DSA)
- text = _("Private DSA Key");
- else
- text = _("Private Key");
- } else if (klass == CKO_PUBLIC_KEY) {
- if (key_type == CKK_RSA)
- text = _("Public DSA Key");
- else if (key_type == CKK_DSA)
- text = _("Public DSA Key");
- else
- text = _("Public Key");
- }
-
- _gcr_display_view_append_content (self->pv->view, text, NULL);
-
- size = calculate_key_size (self->pv->attributes, key_type);
- if (size >= 0) {
- display = g_strdup_printf (_("%d bits"), size);
- _gcr_display_view_append_content (self->pv->view, _("Strength"), display);
- g_free (display);
- }
-
- _gcr_display_view_start_details (self->pv->view);
-
-
- if (key_type == CKK_RSA)
- text = _("RSA");
- else if (key_type == CKK_DSA)
- text = _("DSA");
- else
- text = _("Unknown");
- _gcr_display_view_append_value (self->pv->view, _("Algorithm"), text, FALSE);
-
- size = calculate_key_size (self->pv->attributes, key_type);
- if (size < 0)
- display = g_strdup (_("Unknown"));
- else
- display = g_strdup_printf ("%d", size);
- _gcr_display_view_append_value (self->pv->view, _("Size"), display, FALSE);
- g_free (display);
-
- /* TODO: We need to have consistent key fingerprints. */
- _gcr_display_view_append_value (self->pv->view, _("Fingerprint"), "XX XX XX XX XX XX XX XX XX XX", TRUE);
-}
+G_DEFINE_TYPE (GcrKeyWidget, gcr_key_widget, GTK_TYPE_ALIGNMENT);
/* -----------------------------------------------------------------------------
* OBJECT
@@ -208,19 +56,17 @@ gcr_key_widget_constructor (GType type, guint n_props, GObjectConstructParam *pr
self = GCR_KEY_WIDGET (obj);
- self->pv->view = _gcr_display_view_new ();
- _gcr_display_view_set_stock_image (self->pv->view, GTK_STOCK_DIALOG_AUTHENTICATION);
+ self->pv->viewer = gcr_viewer_new ();
scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
- gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->view));
+ gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->viewer));
gtk_container_add (GTK_CONTAINER (self), scroll);
gtk_widget_show_all (scroll);
- refresh_display (self);
-
+ gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (self->pv->renderer));
return obj;
}
@@ -228,12 +74,7 @@ static void
gcr_key_widget_init (GcrKeyWidget *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_WIDGET, GcrKeyWidgetPrivate));
-}
-
-static void
-gcr_key_widget_dispose (GObject *obj)
-{
- G_OBJECT_CLASS (gcr_key_widget_parent_class)->dispose (obj);
+ self->pv->renderer = gcr_key_renderer_new (NULL, NULL);
}
static void
@@ -241,12 +82,12 @@ gcr_key_widget_finalize (GObject *obj)
{
GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
- if (self->pv->attributes)
- gck_attributes_unref (self->pv->attributes);
- self->pv->attributes = NULL;
+ g_assert (self->pv->renderer);
+ g_object_unref (self->pv->renderer);
+ self->pv->renderer = NULL;
- g_free (self->pv->label);
- self->pv->label = NULL;
+ g_assert (self->pv->viewer);
+ self->pv->viewer = NULL;
G_OBJECT_CLASS (gcr_key_widget_parent_class)->finalize (obj);
}
@@ -258,15 +99,8 @@ gcr_key_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
GcrKeyWidget *self = GCR_KEY_WIDGET (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");
- refresh_display (self);
- break;
case PROP_ATTRIBUTES:
- g_return_if_fail (!self->pv->attributes);
- self->pv->attributes = g_value_dup_boxed (value);
+ gcr_key_widget_set_attributes (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -281,11 +115,8 @@ gcr_key_widget_get_property (GObject *obj, guint prop_id, GValue *value,
GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->attributes);
+ g_value_set_boxed (value, gcr_key_widget_get_attributes (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -303,35 +134,41 @@ gcr_key_widget_class_init (GcrKeyWidgetClass *klass)
g_type_class_add_private (klass, sizeof (GcrKeyWidgetPrivate));
gobject_class->constructor = gcr_key_widget_constructor;
- gobject_class->dispose = gcr_key_widget_dispose;
gobject_class->finalize = gcr_key_widget_finalize;
gobject_class->set_property = gcr_key_widget_set_property;
gobject_class->get_property = gcr_key_widget_get_property;
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
- g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
-
- _gcr_icons_register ();
+ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+ g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the widget",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
/* Register this as a view which can be loaded */
registered = gck_attributes_new ();
gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
- gcr_view_register (GCR_TYPE_KEY_WIDGET, registered);
+ gcr_renderer_register (GCR_TYPE_KEY_WIDGET, registered);
gck_attributes_unref (registered);
}
-static void
-gcr_view_iface_init (GcrViewIface *iface)
-{
- /* Nothing to do */
-}
-
/* -----------------------------------------------------------------------------
* PUBLIC
*/
GcrKeyWidget*
-gcr_key_widget_new (const gchar *label, GckAttributes *attrs)
+gcr_key_widget_new (GckAttributes *attrs)
+{
+ return g_object_new (GCR_TYPE_KEY_WIDGET, "attributes", attrs, NULL);
+}
+
+void
+gcr_key_widget_set_attributes (GcrKeyWidget *self, GckAttributes *attrs)
+{
+ g_return_if_fail (GCR_IS_KEY_WIDGET (self));
+ gcr_key_renderer_set_attributes (self->pv->renderer, attrs);
+}
+
+GckAttributes*
+gcr_key_widget_get_attributes (GcrKeyWidget *self)
{
- return g_object_new (GCR_TYPE_KEY_WIDGET, "label", label, "attributes", attrs, NULL);
+ g_return_val_if_fail (GCR_IS_KEY_WIDGET (self), NULL);
+ return gcr_key_renderer_get_attributes (self->pv->renderer);
}
diff --git a/gcr/gcr-key-widget.h b/gcr/gcr-key-widget.h
index 34aefa0..5393e02 100644
--- a/gcr/gcr-key-widget.h
+++ b/gcr/gcr-key-widget.h
@@ -49,9 +49,13 @@ struct _GcrKeyWidgetClass {
GType gcr_key_widget_get_type (void);
-GcrKeyWidget* gcr_key_widget_new (const gchar *label,
+GcrKeyWidget* gcr_key_widget_new (struct _GckAttributes *attrs);
+
+void gcr_key_widget_set_attributes (GcrKeyWidget *self,
struct _GckAttributes *attrs);
+struct _GckAttributes* gcr_key_widget_get_attributes (GcrKeyWidget *self);
+
G_END_DECLS
#endif /* __GCR_KEY_WIDGET_H__ */
diff --git a/gcr/gcr-view.c b/gcr/gcr-renderer.c
similarity index 53%
rename from gcr/gcr-view.c
rename to gcr/gcr-renderer.c
index 9df6606..59ca30a 100644
--- a/gcr/gcr-view.c
+++ b/gcr/gcr-renderer.c
@@ -21,60 +21,85 @@
#include "config.h"
-#include "gcr-view.h"
+#include "gcr-renderer.h"
#include "gck/gck.h"
#include <gtk/gtk.h>
-typedef struct _GcrRegisteredView {
+enum {
+ DATA_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct _GcrRegistered {
GckAttributes *attrs;
- GType view_type;
-} GcrRegisteredView;
+ GType renderer_type;
+} GcrRegistered;
-static GArray *registered_views = NULL;
+static GArray *registered_renderers = NULL;
static gboolean registered_sorted = FALSE;
static void
-gcr_view_base_init (gpointer gobject_iface)
+gcr_renderer_base_init (gpointer gobject_iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
g_object_interface_install_property (gobject_iface,
- g_param_spec_string ("label", "Label", "The label for the view",
+ g_param_spec_string ("label", "Label", "The label for the renderer",
"", G_PARAM_READWRITE));
g_object_interface_install_property (gobject_iface,
- g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the view",
- GCK_TYPE_ATTRIBUTES, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the renderer",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+
+ signals[DATA_CHANGED] = g_signal_new ("data-changed", GCR_TYPE_RENDERER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrRendererIface, data_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
initialized = TRUE;
}
}
GType
-gcr_view_get_type (void)
+gcr_renderer_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
- sizeof (GcrViewIface),
- gcr_view_base_init, /* base init */
- NULL, /* base finalize */
+ sizeof (GcrRendererIface),
+ gcr_renderer_base_init, /* base init */
+ NULL, /* base finalize */
};
- type = g_type_register_static (G_TYPE_INTERFACE, "GcrViewIface", &info, 0);
- g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET);
+ type = g_type_register_static (G_TYPE_INTERFACE, "GcrRendererIface", &info, 0);
}
return type;
}
+void
+gcr_renderer_render (GcrRenderer *self, GcrViewer *viewer)
+{
+ g_return_if_fail (GCR_IS_RENDERER (self));
+ g_return_if_fail (GCR_RENDERER_GET_INTERFACE (self)->render);
+ GCR_RENDERER_GET_INTERFACE (self)->render (self, viewer);
+}
+
+void
+gcr_renderer_emit_data_changed (GcrRenderer *self)
+{
+ g_return_if_fail (GCR_IS_RENDERER (self));
+ g_signal_emit (self, signals[DATA_CHANGED], 0);
+}
+
static gint
sort_registered_by_n_attrs (gconstpointer a, gconstpointer b)
{
- const GcrRegisteredView *ra = a;
- const GcrRegisteredView *rb = b;
+ const GcrRegistered *ra = a;
+ const GcrRegistered *rb = b;
gulong na, nb;
g_assert (a);
@@ -89,10 +114,10 @@ sort_registered_by_n_attrs (gconstpointer a, gconstpointer b)
return (na == nb) ? 0 : -1;
}
-GcrView*
-gcr_view_create (const gchar *label, GckAttributes *attrs)
+GcrRenderer*
+gcr_renderer_create (const gchar *label, GckAttributes *attrs)
{
- GcrRegisteredView *registered;
+ GcrRegistered *registered;
gboolean matched;
gulong n_attrs;
gulong j;
@@ -100,16 +125,16 @@ gcr_view_create (const gchar *label, GckAttributes *attrs)
g_return_val_if_fail (attrs, NULL);
- if (!registered_views)
+ if (!registered_renderers)
return NULL;
if (!registered_sorted) {
- g_array_sort (registered_views, sort_registered_by_n_attrs);
+ g_array_sort (registered_renderers, sort_registered_by_n_attrs);
registered_sorted = TRUE;
}
- for (i = 0; i < registered_views->len; ++i) {
- registered = &(g_array_index (registered_views, GcrRegisteredView, i));
+ for (i = 0; i < registered_renderers->len; ++i) {
+ registered = &(g_array_index (registered_renderers, GcrRegistered, i));
n_attrs = gck_attributes_count (registered->attrs);
matched = TRUE;
@@ -122,7 +147,7 @@ gcr_view_create (const gchar *label, GckAttributes *attrs)
}
if (matched)
- return g_object_new (registered->view_type, "label", label,
+ return g_object_new (registered->renderer_type, "label", label,
"attributes", attrs, NULL);
}
@@ -130,15 +155,15 @@ gcr_view_create (const gchar *label, GckAttributes *attrs)
}
void
-gcr_view_register (GType view_type, GckAttributes *attrs)
+gcr_renderer_register (GType renderer_type, GckAttributes *attrs)
{
- GcrRegisteredView registered;
+ GcrRegistered registered;
- if (!registered_views)
- registered_views = g_array_new (FALSE, FALSE, sizeof (GcrRegisteredView));
+ if (!registered_renderers)
+ registered_renderers = g_array_new (FALSE, FALSE, sizeof (GcrRegistered));
- registered.view_type = view_type;
+ registered.renderer_type = renderer_type;
registered.attrs = gck_attributes_ref (attrs);
- g_array_append_val (registered_views, registered);
+ g_array_append_val (registered_renderers, registered);
registered_sorted = FALSE;
}
diff --git a/gcr/gcr-renderer.h b/gcr/gcr-renderer.h
new file mode 100644
index 0000000..9c4800a
--- /dev/null
+++ b/gcr/gcr-renderer.h
@@ -0,0 +1,73 @@
+/*
+ * gnome-keyring
+ *
+ * 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.
+ */
+
+#ifndef __GCR_RENDERER_H__
+#define __GCR_RENDERER_H__
+
+#include <glib-object.h>
+
+#include "gcr-types.h"
+#include "gcr-viewer.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_RENDERER (gcr_renderer_get_type())
+#define GCR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_RENDERER, GcrRenderer))
+#define GCR_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_RENDERER))
+#define GCR_RENDERER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_RENDERER, GcrRendererIface))
+
+typedef struct _GcrRendererIface GcrRendererIface;
+
+struct _GcrRendererIface {
+ GTypeInterface parent;
+
+ /* signals */
+ void (*data_changed) (GcrRenderer *self);
+
+ /* virtual */
+ void (*render) (GcrRenderer *self, GcrViewer *viewer);
+
+ gpointer dummy1;
+ gpointer dummy2;
+ gpointer dummy3;
+ gpointer dummy4;
+ gpointer dummy5;
+ gpointer dummy6;
+ gpointer dummy7;
+
+};
+
+GType gcr_renderer_get_type (void) G_GNUC_CONST;
+
+void gcr_renderer_render (GcrRenderer *self,
+ GcrViewer *viewer);
+
+void gcr_renderer_emit_data_changed (GcrRenderer *self);
+
+GcrRenderer* gcr_renderer_create (const gchar *label,
+ struct _GckAttributes *attrs);
+
+void gcr_renderer_register (GType renderer_type,
+ struct _GckAttributes *attrs);
+
+G_END_DECLS
+
+#endif /* __GCR_RENDERER_H__ */
diff --git a/gcr/gcr-viewer.c b/gcr/gcr-viewer.c
new file mode 100644
index 0000000..03a5a4b
--- /dev/null
+++ b/gcr/gcr-viewer.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 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-renderer.h"
+#include "gcr-viewer.h"
+
+/* -----------------------------------------------------------------------------
+ * INTERFACE
+ */
+
+static void
+gcr_viewer_base_init (gpointer gobject_iface)
+{
+ static gboolean initialized = FALSE;
+ if (!initialized) {
+
+ initialized = TRUE;
+ }
+}
+
+GType
+gcr_viewer_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GcrViewerIface),
+ gcr_viewer_base_init, /* base init */
+ NULL, /* base finalize */
+ };
+ type = g_type_register_static (G_TYPE_INTERFACE, "GcrViewerIface", &info, 0);
+ g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET);
+ }
+
+ return type;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrViewer*
+gcr_viewer_new (void)
+{
+ return GCR_VIEWER (_gcr_display_view_new ());
+}
+
+void
+gcr_viewer_add_renderer (GcrViewer *self, GcrRenderer *renderer)
+{
+ g_return_if_fail (GCR_IS_VIEWER (self));
+ g_return_if_fail (GCR_IS_RENDERER (renderer));
+ g_return_if_fail (GCR_VIEWER_GET_INTERFACE (self)->add_renderer);
+ GCR_VIEWER_GET_INTERFACE (self)->add_renderer (self, renderer);
+}
+
+void
+gcr_viewer_remove_renderer (GcrViewer *self, GcrRenderer *renderer)
+{
+ g_return_if_fail (GCR_IS_VIEWER (self));
+ g_return_if_fail (GCR_IS_RENDERER (renderer));
+ g_return_if_fail (GCR_VIEWER_GET_INTERFACE (self)->remove_renderer);
+ GCR_VIEWER_GET_INTERFACE (self)->remove_renderer (self, renderer);
+}
+
+guint
+gcr_viewer_count_renderers (GcrViewer *self)
+{
+ g_return_val_if_fail (GCR_IS_VIEWER (self), 0);
+ g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (self)->count_renderers, 0);
+ return GCR_VIEWER_GET_INTERFACE (self)->count_renderers (self);
+}
+
+GcrRenderer*
+gcr_viewer_get_renderer (GcrViewer *self, guint index_)
+{
+ g_return_val_if_fail (GCR_IS_VIEWER (self), NULL);
+ g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (self)->get_renderer, NULL);
+ return GCR_VIEWER_GET_INTERFACE (self)->get_renderer (self, index_);
+}
diff --git a/gcr/gcr-viewer.h b/gcr/gcr-viewer.h
new file mode 100644
index 0000000..6f53bdb
--- /dev/null
+++ b/gcr/gcr-viewer.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef __GCR_VIEWER_H__
+#define __GCR_VIEWER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_VIEWER (gcr_viewer_get_type())
+#define GCR_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER, GcrViewer))
+#define GCR_IS_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER))
+#define GCR_VIEWER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_VIEWER, GcrViewerIface))
+
+typedef struct _GcrRenderer GcrRenderer;
+typedef struct _GcrViewer GcrViewer;
+typedef struct _GcrViewerIface GcrViewerIface;
+
+struct _GcrViewerIface {
+ GTypeInterface parent;
+
+ void (*add_renderer) (GcrViewer *self, GcrRenderer *viewer);
+
+ void (*remove_renderer) (GcrViewer *self, GcrRenderer *viewer);
+
+ guint (*count_renderers) (GcrViewer *self);
+
+ GcrRenderer* (*get_renderer) (GcrViewer *self, guint index_);
+
+ gpointer dummy1;
+ gpointer dummy2;
+ gpointer dummy3;
+ gpointer dummy4;
+};
+
+GType gcr_viewer_get_type (void);
+
+GcrViewer* gcr_viewer_new (void);
+
+void gcr_viewer_add_renderer (GcrViewer *self,
+ GcrRenderer *renderer);
+
+void gcr_viewer_remove_renderer (GcrViewer *self,
+ GcrRenderer *renderer);
+
+guint gcr_viewer_count_renderers (GcrViewer *self);
+
+GcrRenderer* gcr_viewer_get_renderer (GcrViewer *self,
+ guint at);
+
+G_END_DECLS
+
+#endif /* __GCR_VIEWER_H__ */
diff --git a/gcr/tests/ui-test-certificate.c b/gcr/tests/ui-test-certificate.c
index fdec278..bf12e72 100644
--- a/gcr/tests/ui-test-certificate.c
+++ b/gcr/tests/ui-test-certificate.c
@@ -41,7 +41,6 @@ on_parser_parsed (GcrParser *parser, gpointer unused)
g_object_ref_sink (dialog);
details = g_object_new (GCR_TYPE_CERTIFICATE_WIDGET,
- "label", "Google's Certificate",
"attributes", gcr_parser_get_parsed_attributes (parser),
NULL);
diff --git a/gcr/tests/ui-test-key.c b/gcr/tests/ui-test-key.c
index e54c7b4..4ccba3e 100644
--- a/gcr/tests/ui-test-key.c
+++ b/gcr/tests/ui-test-key.c
@@ -40,8 +40,7 @@ on_parser_parsed (GcrParser *parser, gpointer unused)
dialog = GTK_DIALOG (gtk_dialog_new ());
g_object_ref_sink (dialog);
- details = gcr_key_widget_new ("My Private Key",
- gcr_parser_get_parsed_attributes (parser));
+ details = gcr_key_widget_new (gcr_parser_get_parsed_attributes (parser));
gtk_widget_show (GTK_WIDGET (details));
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]