[gnome-keyring] [gcr] Add functionality for renderers to populate tree models.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [gcr] Add functionality for renderers to populate tree models.
- Date: Tue, 5 Apr 2011 13:12:04 +0000 (UTC)
commit 66d822848be5117eccd4cf338b304759342ebd3a
Author: Stef Walter <stef memberwebs com>
Date: Fri Oct 15 03:17:29 2010 +0000
[gcr] Add functionality for renderers to populate tree models.
* Add markup, icon and description properties to renderers.
* Add GcrSimpleCollection which implements collections.
* Use GIcon instead of stock ids.
* Rough example test certificate selector.
gcr/Makefile.am | 2 +
gcr/gcr-certificate-renderer.c | 69 +++++++++++++++----
gcr/gcr-collection-model.c | 4 +-
gcr/gcr-display-view.c | 42 +++++++++---
gcr/gcr-display-view.h | 4 +-
gcr/gcr-key-renderer.c | 12 +++-
gcr/gcr-library.c | 8 ++-
gcr/gcr-renderer.c | 18 ++++-
gcr/gcr-renderer.h | 21 +++++-
gcr/gcr-simple-collection.c | 143 ++++++++++++++++++++++++++++++++++++++++
gcr/gcr-simple-collection.h | 67 +++++++++++++++++++
gcr/gcr.h | 3 +
gcr/tests/.gitignore | 1 +
gcr/tests/Makefile.am | 43 ++----------
gcr/tests/test-ui-selector.c | 129 ++++++++++++++++++++++++++++++++++++
15 files changed, 492 insertions(+), 74 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 5f4aad1..26b71c7 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -43,6 +43,7 @@ inc_HEADERS = \
gcr-pkcs11-certificate.h \
gcr-renderer.h \
gcr-simple-certificate.h \
+ gcr-simple-collection.h \
gcr-trust.h \
gcr-types.h \
gcr-unlock-options.h \
@@ -87,6 +88,7 @@ libgcr GCR_VERSION_SUFFIX@_la_SOURCES = \
gcr-pkcs11-certificate.c gcr-pkcs11-certificate.h \
gcr-renderer.c gcr-renderer.h \
gcr-simple-certificate.c gcr-simple-certificate.h \
+ gcr-simple-collection.c gcr-simple-collection.h \
gcr-trust.c gcr-trust.h \
gcr-types.h \
gcr-unlock-options.h \
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
index f6710e4..592b69b 100644
--- a/gcr/gcr-certificate-renderer.c
+++ b/gcr/gcr-certificate-renderer.c
@@ -42,7 +42,10 @@ enum {
PROP_0,
PROP_CERTIFICATE,
PROP_LABEL,
- PROP_ATTRIBUTES
+ PROP_ATTRIBUTES,
+ PROP_DESCRIPTION,
+ PROP_ICON,
+ PROP_MARKUP
};
struct _GcrCertificateRendererPrivate {
@@ -50,6 +53,7 @@ struct _GcrCertificateRendererPrivate {
GckAttributes *opt_attrs;
guint key_size;
gchar *label;
+ GIcon *icon;
};
static void gcr_renderer_iface_init (GcrRendererIface *iface);
@@ -64,7 +68,7 @@ G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYP
*/
static gchar*
-calculate_label (GcrCertificateRenderer *self, GNode *asn)
+calculate_label (GcrCertificateRenderer *self)
{
gchar *label;
@@ -76,15 +80,33 @@ calculate_label (GcrCertificateRenderer *self, GNode *asn)
return label;
}
- if (asn != NULL) {
- label = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
- if (label != NULL)
- return label;
- }
+ label = gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self));
+ if (label != NULL)
+ return label;
return g_strdup (_("Certificate"));
}
+static gchar*
+calculate_markup (GcrCertificateRenderer *self)
+{
+ gchar *label;
+ gchar *issuer;
+ gchar *markup;
+
+ label = calculate_label (self);
+ issuer = gcr_certificate_get_issuer_cn (GCR_CERTIFICATE (self));
+
+ if (issuer)
+ markup = g_markup_printf_escaped ("%s\n<small>Issued by: %s</small>", label, issuer);
+ else
+ markup = g_markup_printf_escaped ("%s\n<small>Issued by: <i>No name</i></small>", label);
+
+ g_free (label);
+ g_free (issuer);
+ return markup;
+}
+
static gboolean
append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
GNode *asn, const guchar *data, gsize n_data, gint index)
@@ -218,13 +240,13 @@ on_certificate_export (GtkMenuItem *menuitem, gpointer user_data)
gchar *label;
GtkWidget *parent;
- label = calculate_label (self, NULL);
+ label = calculate_label (self);
parent = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
if (parent && !GTK_IS_WINDOW (parent))
parent = NULL;
- exporter = _gcr_certificate_exporter_new (self->pv->certificate, label,
+ exporter = _gcr_certificate_exporter_new (GCR_CERTIFICATE (self), label,
GTK_WINDOW (parent));
g_free (label);
@@ -241,6 +263,7 @@ static void
gcr_certificate_renderer_init (GcrCertificateRenderer *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
+ self->pv->icon = g_themed_icon_new (GCR_ICON_CERTIFICATE);
}
static void
@@ -269,6 +292,10 @@ gcr_certificate_renderer_finalize (GObject *obj)
g_free (self->pv->label);
self->pv->label = NULL;
+ if (self->pv->icon)
+ g_object_unref (self->pv->icon);
+ self->pv->icon = NULL;
+
G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
}
@@ -308,11 +335,20 @@ gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *valu
g_value_set_object (value, self->pv->opt_cert);
break;
case PROP_LABEL:
- g_value_take_string (value, calculate_label (self, NULL));
+ g_value_take_string (value, calculate_label (self));
break;
case PROP_ATTRIBUTES:
g_value_set_boxed (value, self->pv->opt_attrs);
break;
+ case PROP_ICON:
+ g_value_set_object (value, self->pv->icon);
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, _("Certificate"));
+ break;
+ case PROP_MARKUP:
+ g_value_take_string (value, calculate_markup (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -339,6 +375,9 @@ gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+ g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_ICON, "icon");
+ g_object_class_override_property (gobject_class, PROP_MARKUP, "markup");
_gcr_icons_register ();
@@ -381,16 +420,16 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_clear (view, renderer);
cert = GCR_CERTIFICATE (self);
- _gcr_display_view_set_stock_image (view, GCR_RENDERER (self), GCR_ICON_CERTIFICATE);
-
data = gcr_certificate_get_der_data (cert, &n_data);
if (!data)
return;
+ _gcr_display_view_set_icon (view, GCR_RENDERER (self), self->pv->icon);
+
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
g_return_if_fail (asn);
- display = calculate_label (self, asn);
+ display = calculate_label (self);
_gcr_display_view_append_title (view, renderer, display);
g_free (display);
@@ -539,12 +578,12 @@ gcr_certificate_renderer_populate_popup (GcrRenderer *self, GcrViewer *viewer,
static void
gcr_renderer_iface_init (GcrRendererIface *iface)
{
- iface->render = gcr_certificate_renderer_render;
iface->populate_popup = gcr_certificate_renderer_populate_popup;
+ iface->render_view = gcr_certificate_renderer_render;
}
-static const guchar*
+static gconstpointer
gcr_certificate_renderer_real_get_der_data (GcrCertificate *cert, gsize *n_data)
{
GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
diff --git a/gcr/gcr-collection-model.c b/gcr/gcr-collection-model.c
index 4be857c..1eac064 100644
--- a/gcr/gcr-collection-model.c
+++ b/gcr/gcr-collection-model.c
@@ -64,7 +64,7 @@ index_for_iter (GcrCollectionModel *self, const GtkTreeIter *iter)
g_return_val_if_fail (G_IS_OBJECT (iter->user_data), -1);
index = GPOINTER_TO_INT (iter->user_data2);
- g_assert (index > 0 && index < self->pv->objects->len);
+ g_assert (index >= 0 && index < self->pv->objects->len);
return index;
}
@@ -588,7 +588,7 @@ gcr_collection_model_new (GcrCollection *collection, ...)
GcrCollectionModel*
gcr_collection_model_new_full (GcrCollection *collection, const GcrCollectionModelColumn *columns, guint n_columns)
{
- GcrCollectionModel *self = g_object_new (GCR_TYPE_COLLECTION, "collection", collection, NULL);
+ GcrCollectionModel *self = g_object_new (GCR_TYPE_COLLECTION_MODEL, "collection", collection, NULL);
gcr_collection_model_set_columns (self, columns, n_columns);
return self;
}
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
index ddf54b6..d93c268 100644
--- a/gcr/gcr-display-view.c
+++ b/gcr/gcr-display-view.c
@@ -211,7 +211,7 @@ on_expander_expanded (GObject *object, GParamSpec *param_spec, gpointer user_dat
GtkExpander *expander = GTK_EXPANDER (object);
GcrDisplayItem *item = user_data;
item->expanded = gtk_expander_get_expanded (expander);
- gcr_renderer_render (item->renderer, GCR_VIEWER (item->display_view));
+ gcr_renderer_render_view (item->renderer, GCR_VIEWER (item->display_view));
recalculate_and_resize (item->display_view);
}
@@ -379,7 +379,7 @@ static void
on_renderer_data_changed (GcrRenderer *renderer, GcrViewer *self)
{
/* Just ask the renderer to render itself on us */
- gcr_renderer_render (renderer, self);
+ gcr_renderer_render_view (renderer, self);
}
static void
@@ -691,7 +691,7 @@ _gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
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);
+ gcr_renderer_render_view (renderer, viewer);
item->data_changed_id = g_signal_connect (renderer, "data-changed",
G_CALLBACK (on_renderer_data_changed), self);
}
@@ -962,10 +962,14 @@ _gcr_display_view_append_fingerprint (GcrDisplayView *self, GcrRenderer *rendere
}
void
-_gcr_display_view_set_stock_image (GcrDisplayView *self, GcrRenderer *renderer,
- const gchar *stock_id)
+_gcr_display_view_set_icon (GcrDisplayView *self, GcrRenderer *renderer, GIcon *icon)
{
GcrDisplayItem *item;
+ GdkScreen *screen;
+ GtkIconTheme *icon_theme;
+ GtkSettings *settings;
+ gint width, height;
+ GtkIconInfo *info;
g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
item = lookup_display_item (self, renderer);
@@ -973,12 +977,28 @@ _gcr_display_view_set_stock_image (GcrDisplayView *self, GcrRenderer *renderer,
if (item->pixbuf)
g_object_unref (item->pixbuf);
- if (stock_id)
-#if GTK_CHECK_VERSION (2,91,7)
- item->pixbuf = gtk_widget_render_icon_pixbuf (GTK_WIDGET (self), stock_id, GTK_ICON_SIZE_DIALOG);
+ item->pixbuf = NULL;
+
+ if (!icon)
+ return;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+ settings = gtk_settings_get_for_screen (screen);
+
+ if (!gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_DIALOG, &width, &height))
+ g_return_if_reached ();
+
+ info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+
+ if (info) {
+#if GTK_CHECK_VERSION (2,91,0)
+ GtkStyleContext *style = gtk_widget_get_style_context (GTK_WIDGET (self));
+ item->pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, FALSE, NULL);
#else
- item->pixbuf = gtk_widget_render_icon (GTK_WIDGET (self), stock_id, GTK_ICON_SIZE_DIALOG, NULL);
+ item->pixbuf = gtk_icon_info_load_icon (info, NULL);
#endif
- else
- item->pixbuf = NULL;
+ gtk_icon_info_free (info);
+ }
}
diff --git a/gcr/gcr-display-view.h b/gcr/gcr-display-view.h
index c5f83a6..be237bb 100644
--- a/gcr/gcr-display-view.h
+++ b/gcr/gcr-display-view.h
@@ -85,9 +85,9 @@ void _gcr_display_view_append_fingerprint (GcrDisplayView *
const gchar *name,
GChecksumType type);
-void _gcr_display_view_set_stock_image (GcrDisplayView *self,
+void _gcr_display_view_set_icon (GcrDisplayView *self,
GcrRenderer *renderer,
- const gchar *stock_id);
+ GIcon *icon);
G_END_DECLS
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
index 7f2fb4c..0b018d5 100644
--- a/gcr/gcr-key-renderer.c
+++ b/gcr/gcr-key-renderer.c
@@ -42,6 +42,7 @@ struct _GcrKeyRendererPrivate {
guint key_size;
gchar *label;
GckAttributes *attributes;
+ GIcon *icon;
};
static void gcr_key_renderer_renderer_iface (GcrRendererIface *iface);
@@ -124,6 +125,7 @@ static void
gcr_key_renderer_init (GcrKeyRenderer *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_RENDERER, GcrKeyRendererPrivate));
+ self->pv->icon = g_themed_icon_new (GCR_ICON_FOLDER);
}
static void
@@ -144,6 +146,10 @@ gcr_key_renderer_finalize (GObject *obj)
g_free (self->pv->label);
self->pv->label = NULL;
+ if (self->pv->icon)
+ g_object_unref (self->pv->icon);
+ self->pv->icon = NULL;
+
G_OBJECT_CLASS (gcr_key_renderer_parent_class)->finalize (obj);
}
@@ -243,14 +249,14 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
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;
}
+ _gcr_display_view_set_icon (view, renderer, self->pv->icon);
+
display = calculate_label (self);
_gcr_display_view_append_title (view, renderer, display);
g_free (display);
@@ -306,7 +312,7 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
static void
gcr_key_renderer_renderer_iface (GcrRendererIface *iface)
{
- iface->render = gcr_key_renderer_real_render;
+ iface->render_view = gcr_key_renderer_real_render;
}
/* -----------------------------------------------------------------------------
diff --git a/gcr/gcr-library.c b/gcr/gcr-library.c
index d7e5f4c..0e65f31 100644
--- a/gcr/gcr-library.c
+++ b/gcr/gcr-library.c
@@ -21,9 +21,12 @@
#include "config.h"
-#include "gcr-types.h"
+#include "gcr.h"
+#include "gcr-certificate-renderer.h"
#include "gcr-internal.h"
#include "gcr-library.h"
+#include "gcr-key-renderer.h"
+#include "gcr-types.h"
#include "egg/egg-error.h"
#include "egg/egg-libgcrypt.h"
@@ -176,6 +179,9 @@ _gcr_initialize (void)
trust_lookup_uris[1] = g_strdup ("pkcs11:library-manufacturer=GNOME%20Keyring;serial=1:XDG:DEFAULT");
trust_lookup_uris[2] = NULL;
+ g_type_class_unref (g_type_class_ref (GCR_TYPE_CERTIFICATE_RENDERER));
+ g_type_class_unref (g_type_class_ref (GCR_TYPE_KEY_RENDERER));
+
g_once_init_leave (&gcr_initialized, 1);
}
}
diff --git a/gcr/gcr-renderer.c b/gcr/gcr-renderer.c
index 28bc905..cbc8bbc 100644
--- a/gcr/gcr-renderer.c
+++ b/gcr/gcr-renderer.c
@@ -56,6 +56,18 @@ gcr_renderer_base_init (gpointer gobject_iface)
g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the renderer",
GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("description", "Description", "Description of object being rendered",
+ "", G_PARAM_READABLE));
+
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("markup", "Markup", "Markup which describes object being rendered",
+ "", G_PARAM_READABLE));
+
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_object ("icon", "Icon", "Icon for the object being rendered",
+ G_TYPE_ICON, G_PARAM_READABLE));
+
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);
@@ -81,11 +93,11 @@ gcr_renderer_get_type (void)
}
void
-gcr_renderer_render (GcrRenderer *self, GcrViewer *viewer)
+gcr_renderer_render_view (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);
+ g_return_if_fail (GCR_RENDERER_GET_INTERFACE (self)->render_view);
+ GCR_RENDERER_GET_INTERFACE (self)->render_view (self, viewer);
}
void
diff --git a/gcr/gcr-renderer.h b/gcr/gcr-renderer.h
index bf7e04a..e2e9234 100644
--- a/gcr/gcr-renderer.h
+++ b/gcr/gcr-renderer.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
#define GCR_RENDERER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_RENDERER, GcrRendererIface))
typedef struct _GcrRendererIface GcrRendererIface;
+typedef struct _GcrRendererColumn GcrRendererColumn;
struct _GcrRendererIface {
GTypeInterface parent;
@@ -43,7 +44,11 @@ struct _GcrRendererIface {
void (*data_changed) (GcrRenderer *self);
/* virtual */
- void (*render) (GcrRenderer *self, GcrViewer *viewer);
+ void (*render_view) (GcrRenderer *self, GcrViewer *viewer);
+
+ const GcrRendererColumn* (*get_column_info) (GcrRenderer *self, gint *n_columns);
+
+ const void (*get_column_value) (GcrRenderer *self, GQuark column, GValue *value);
void (*populate_popup) (GcrRenderer *self, GcrViewer *viewer, GtkMenu *menu);
@@ -57,15 +62,27 @@ struct _GcrRendererIface {
};
+struct _GcrRendererColumn {
+ GQuark column;
+ GType type;
+ const gchar *description;
+};
+
GType gcr_renderer_get_type (void) G_GNUC_CONST;
-void gcr_renderer_render (GcrRenderer *self,
+void gcr_renderer_render_view (GcrRenderer *self,
GcrViewer *viewer);
void gcr_renderer_popuplate_popup (GcrRenderer *self,
GcrViewer *viewer,
GtkMenu *menu);
+gchar* gcr_renderer_get_markup (GcrRenderer *self);
+
+gchar* gcr_renderer_get_description (GcrRenderer *self);
+
+gchar* gcr_renderer_get_stock_icon (GcrRenderer *self);
+
void gcr_renderer_emit_data_changed (GcrRenderer *self);
GcrRenderer* gcr_renderer_create (const gchar *label,
diff --git a/gcr/gcr-simple-collection.c b/gcr/gcr-simple-collection.c
new file mode 100644
index 0000000..b88467a
--- /dev/null
+++ b/gcr/gcr-simple-collection.c
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#include "gcr-collection.h"
+#include "gcr-internal.h"
+#include "gcr-simple-collection.h"
+
+#include <string.h>
+
+struct _GcrSimpleCollectionPrivate {
+ GHashTable *items;
+};
+
+static void gcr_collection_iface (GcrCollectionIface *iface);
+G_DEFINE_TYPE_WITH_CODE (GcrSimpleCollection, gcr_simple_collection, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, gcr_collection_iface));
+
+#define UNUSED_VALUE GUINT_TO_POINTER (1)
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+gcr_simple_collection_init (GcrSimpleCollection *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_SIMPLE_COLLECTION, GcrSimpleCollectionPrivate);
+ self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
+}
+
+static void
+gcr_simple_collection_dispose (GObject *obj)
+{
+ GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (obj);
+
+ g_hash_table_remove_all (self->pv->items);
+
+ G_OBJECT_CLASS (gcr_simple_collection_parent_class)->dispose (obj);
+}
+
+static void
+gcr_simple_collection_finalize (GObject *obj)
+{
+ GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (obj);
+
+ g_assert (self->pv->items);
+ g_assert (g_hash_table_size (self->pv->items) == 0);
+ g_hash_table_destroy (self->pv->items);
+ self->pv->items = NULL;
+
+ G_OBJECT_CLASS (gcr_simple_collection_parent_class)->finalize (obj);
+}
+
+static void
+gcr_simple_collection_class_init (GcrSimpleCollectionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = gcr_simple_collection_dispose;
+ gobject_class->finalize = gcr_simple_collection_finalize;
+ g_type_class_add_private (gobject_class, sizeof (GcrSimpleCollectionPrivate));
+ _gcr_initialize ();
+}
+
+static guint
+gcr_simple_collection_real_get_length (GcrCollection *coll)
+{
+ GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (coll);
+ return g_hash_table_size (self->pv->items);
+}
+
+static GList*
+gcr_simple_collection_real_get_objects (GcrCollection *coll)
+{
+ GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (coll);
+ return g_hash_table_get_keys (self->pv->items);
+}
+
+static void
+gcr_collection_iface (GcrCollectionIface *iface)
+{
+ iface->get_length = gcr_simple_collection_real_get_length;
+ iface->get_objects = gcr_simple_collection_real_get_objects;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrCollection*
+gcr_simple_collection_new (void)
+{
+ return g_object_new (GCR_TYPE_SIMPLE_COLLECTION, NULL);
+}
+
+void
+gcr_simple_collection_add (GcrSimpleCollection *self, GObject *object)
+{
+ g_return_if_fail (GCR_IS_SIMPLE_COLLECTION (self));
+ g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (!g_hash_table_lookup (self->pv->items, object));
+ g_hash_table_insert (self->pv->items, g_object_ref (object), UNUSED_VALUE);
+ gcr_collection_emit_added (GCR_COLLECTION (self), object);
+}
+
+void
+gcr_simple_collection_remove (GcrSimpleCollection *self, GObject *object)
+{
+ g_return_if_fail (GCR_IS_SIMPLE_COLLECTION (self));
+ g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (g_hash_table_lookup (self->pv->items, object));
+ g_object_ref (object);
+ g_hash_table_remove (self->pv->items, object);
+ gcr_collection_emit_removed (GCR_COLLECTION (self), object);
+ g_object_unref (object);
+}
+
+gboolean
+gcr_simple_collection_contains (GcrSimpleCollection *self, GObject *object)
+{
+ g_return_val_if_fail (GCR_IS_SIMPLE_COLLECTION (self), FALSE);
+ g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+ return g_hash_table_lookup (self->pv->items, object) ? TRUE : FALSE;
+}
diff --git a/gcr/gcr-simple-collection.h b/gcr/gcr-simple-collection.h
new file mode 100644
index 0000000..beccb0b
--- /dev/null
+++ b/gcr/gcr-simple-collection.h
@@ -0,0 +1,67 @@
+/*
+ * 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_SIMPLE_COLLECTION_H__
+#define __GCR_SIMPLE_COLLECTION_H__
+
+#include "gcr.h"
+#include "gcr-collection.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_SIMPLE_COLLECTION (gcr_simple_collection_get_type ())
+#define GCR_SIMPLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrSimpleCollection))
+#define GCR_SIMPLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION, GcrSimpleCollectionClass))
+#define GCR_IS_SIMPLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
+#define GCR_IS_SIMPLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION))
+#define GCR_SIMPLE_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION, GcrSimpleCollectionClass))
+
+typedef struct _GcrSimpleCollection GcrSimpleCollection;
+typedef struct _GcrSimpleCollectionClass GcrSimpleCollectionClass;
+typedef struct _GcrSimpleCollectionPrivate GcrSimpleCollectionPrivate;
+
+struct _GcrSimpleCollection {
+ GObject parent;
+ GcrSimpleCollectionPrivate *pv;
+};
+
+struct _GcrSimpleCollectionClass {
+ GObjectClass parent_class;
+};
+
+GType gcr_simple_collection_get_type (void);
+
+GcrCollection* gcr_simple_collection_new (void);
+
+void gcr_simple_collection_add (GcrSimpleCollection *self,
+ GObject *object);
+
+void gcr_simple_collection_remove (GcrSimpleCollection *self,
+ GObject *object);
+
+gboolean gcr_simple_collection_contains (GcrSimpleCollection *self,
+ GObject *object);
+
+G_END_DECLS
+
+#endif /* __GCR_SIMPLE_COLLECTION_H__ */
diff --git a/gcr/gcr.h b/gcr/gcr.h
index e0aa175..8ac536b 100644
--- a/gcr/gcr.h
+++ b/gcr/gcr.h
@@ -38,13 +38,16 @@
#include "gcr-certificate-chain.h"
#include "gcr-certificate-renderer.h"
#include "gcr-certificate-widget.h"
+#include "gcr-collection-model.h"
#include "gcr-key-renderer.h"
#include "gcr-key-widget.h"
#include "gcr-importer.h"
#include "gcr-library.h"
#include "gcr-parser.h"
+#include "gcr-renderer.h"
#include "gcr-pkcs11-certificate.h"
#include "gcr-simple-certificate.h"
+#include "gcr-simple-collection.h"
#include "gcr-trust.h"
#include "gcr-unlock-options.h"
#include "gcr-unlock-options-widget.h"
diff --git a/gcr/tests/.gitignore b/gcr/tests/.gitignore
index 652f4c0..f30fd7b 100644
--- a/gcr/tests/.gitignore
+++ b/gcr/tests/.gitignore
@@ -2,3 +2,4 @@
/ui-test-details
/ui-test-key
/ui-test-unlock-options
+/test-ui-selector
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index fab95d8..7aa06c3 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -25,46 +25,19 @@ EXTRA_DIST += \
# ------------------------------------------------------------------
-noinst_PROGRAMS += \
- ui-test-certificate \
- ui-test-key \
- ui-test-unlock-options
-
-ui_test_certificate_SOURCES = \
- ui-test-certificate.c
-
-ui_test_certificate_CFLAGS = \
+INCLUDES += \
-DGCR_API_SUBJECT_TO_CHANGE \
+ -DGCK_API_SUBJECT_TO_CHANGE \
$(GTK_CFLAGS)
-ui_test_certificate_LDADD = \
+LIBS += \
$(top_builddir)/gcr/libgcr GCR_VERSION_SUFFIX@.la \
$(top_builddir)/gck/libgck.la \
$(GTK_LIBS) \
$(LIBGCRYPT_LIBS)
-ui_test_unlock_options_SOURCES = \
- ui-test-unlock-options.c
-
-ui_test_unlock_options_CFLAGS = \
- -DGCR_API_SUBJECT_TO_CHANGE \
- $(GTK_CFLAGS)
-
-ui_test_unlock_options_LDADD = \
- $(top_builddir)/gcr/libgcr GCR_VERSION_SUFFIX@.la \
- $(top_builddir)/gck/libgck.la \
- $(GTK_LIBS) \
- $(LIBGCRYPT_LIBS)
-
-ui_test_key_SOURCES = \
- ui-test-key.c
-
-ui_test_key_CFLAGS = \
- -DGCR_API_SUBJECT_TO_CHANGE \
- $(GTK_CFLAGS)
-
-ui_test_key_LDADD = \
- $(top_builddir)/gcr/libgcr GCR_VERSION_SUFFIX@.la \
- $(top_builddir)/gck/libgck.la \
- $(GTK_LIBS) \
- $(LIBGCRYPT_LIBS)
+noinst_PROGRAMS += \
+ test-ui-selector \
+ ui-test-certificate \
+ ui-test-key \
+ ui-test-unlock-options
diff --git a/gcr/tests/test-ui-selector.c b/gcr/tests/test-ui-selector.c
new file mode 100644
index 0000000..d6933d5
--- /dev/null
+++ b/gcr/tests/test-ui-selector.c
@@ -0,0 +1,129 @@
+
+#include "config.h"
+
+#include "gcr.h"
+
+#include <gtk/gtk.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static void
+chdir_base_dir (char* argv0)
+{
+ gchar *dir, *base;
+
+ dir = g_path_get_dirname (argv0);
+ if (chdir (dir) < 0)
+ g_warning ("couldn't change directory to: %s: %s",
+ dir, g_strerror (errno));
+
+ base = g_path_get_basename (dir);
+ if (strcmp (base, ".libs") == 0) {
+ if (chdir ("..") < 0)
+ g_warning ("couldn't change directory to ..: %s",
+ g_strerror (errno));
+ }
+
+ g_free (base);
+ g_free (dir);
+}
+
+static void
+on_parser_parsed (GcrParser *parser, gpointer user_data)
+{
+ GcrSimpleCollection *collection = user_data;
+ GcrRenderer *renderer;
+
+ renderer = gcr_renderer_create (gcr_parser_get_parsed_label (parser),
+ gcr_parser_get_parsed_attributes (parser));
+
+ if (renderer) {
+ gcr_simple_collection_add (collection, G_OBJECT (renderer));
+ g_object_unref (renderer);
+ }
+}
+
+static void
+add_to_selector (GcrParser *parser, const gchar *path)
+{
+ GError *err = NULL;
+ guchar *data;
+ gsize n_data;
+
+ if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
+ g_error ("couldn't read file: %s", path);
+
+ if (!gcr_parser_parse_data (parser, data, n_data, &err))
+ g_error ("couldn't parse data: %s", err->message);
+
+ g_free (data);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GcrCollectionModel *model;
+ GcrCollection *collection;
+ GtkDialog *dialog;
+ GtkWidget *combo;
+ GtkCellRenderer *cell;
+ GcrParser *parser;
+ int i;
+
+ gtk_init (&argc, &argv);
+
+ dialog = GTK_DIALOG (gtk_dialog_new ());
+ g_object_ref_sink (dialog);
+
+ collection = gcr_simple_collection_new ();
+ model = gcr_collection_model_new (collection,
+ "icon", G_TYPE_ICON,
+ "markup", G_TYPE_STRING,
+ NULL);
+
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
+ cell = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (cell, "stock-size", GTK_ICON_SIZE_DND, NULL);
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), cell, "gicon", 0);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), cell, "markup", 1);
+
+ gtk_widget_show (GTK_WIDGET (combo));
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), combo);
+
+#if 0
+ {
+ GtkWidget *widget = gtk_file_chooser_button_new ("Tester", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_widget_show (widget);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), widget);
+ }
+#endif
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
+
+ parser = gcr_parser_new ();
+ g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), collection);
+
+ if (argc == 1) {
+ chdir_base_dir (argv[0]);
+ add_to_selector (parser, "test-data/ca-certificates.crt");
+ } else {
+ for (i = 1; i < argc; ++i)
+ add_to_selector (parser, argv[i]);
+ }
+
+ g_object_unref (parser);
+
+ gtk_dialog_run (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ g_object_unref (dialog);
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]