* Add a certificate base class to augment interface with default props.
* All properties come from certificate rather than renderer.
* Certificates are comparable.
gcr_certificate_get_key_size
gcr_certificate_get_fingerprint
gcr_certificate_get_fingerprint_hex
+gcr_certificate_mixin_class_init
+gcr_certificate_mixin_get_property
+GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE
+gcr_certificate_mixin_comparable_init
<SUBSECTION Standard>
GCR_CERTIFICATE
GCR_IS_CERTIFICATE
gcr-certificate-widget.h \
gcr-collection.h \
gcr-collection-model.h \
+ gcr-column.h \
+ gcr-comparable.h \
gcr-key-renderer.h \
gcr-key-widget.h \
gcr-importer.h \
gcr-parser.h \
gcr-pkcs11-certificate.h \
gcr-renderer.h \
+ gcr-selector.h \
gcr-simple-certificate.h \
gcr-simple-collection.h \
gcr-trust.h \
gcr-collection.c gcr-collection.h \
gcr-collection-model.c gcr-collection-model.h \
gcr-display-scrolled.c gcr-display-scrolled.h \
+ gcr-comparable.c gcr-comparable.h \
gcr-display-view.c gcr-display-view.h \
gcr-icons.c gcr-icons.h \
gcr-import-dialog.c gcr-import-dialog.h \
gcr-parser.c gcr-parser.h \
gcr-pkcs11-certificate.c gcr-pkcs11-certificate.h \
gcr-renderer.c gcr-renderer.h \
+ gcr-selector.c gcr-selector.h \
gcr-simple-certificate.c gcr-simple-certificate.h \
gcr-simple-collection.c gcr-simple-collection.h \
gcr-trust.c gcr-trust.h \
PROP_0,
PROP_CERTIFICATE,
PROP_LABEL,
- PROP_ATTRIBUTES,
- PROP_DESCRIPTION,
- PROP_ICON,
- PROP_MARKUP,
- PROP_SUBJECT,
- PROP_ISSUER,
- PROP_EXPIRY
+ PROP_ATTRIBUTES
};
struct _GcrCertificateRendererPrivate {
GckAttributes *opt_attrs;
guint key_size;
gchar *label;
- GIcon *icon;
};
static void gcr_renderer_iface_init (GcrRendererIface *iface);
-static void gcr_certificate_iface_init (GcrCertificateIface *iface);
+static void gcr_renderer_certificate_iface_init (GcrCertificateIface *iface);
G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init)
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface_init));
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
+ GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_renderer_certificate_iface_init);
+);
/* -----------------------------------------------------------------------------
* INTERNAL
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)
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
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);
}
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;
- case PROP_SUBJECT:
- g_value_take_string (value, gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self)));
- break;
- case PROP_ISSUER:
- g_value_take_string (value, gcr_certificate_get_issuer_cn (GCR_CERTIFICATE (self)));
- break;
- case PROP_EXPIRY:
- g_value_take_boxed (value, gcr_certificate_get_expiry_date (GCR_CERTIFICATE (self)));
- break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
break;
}
}
g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
- GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
+ GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_string ("subject", "Subject", "Common name of subject",
- "", G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+ g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_string ("issuer", "Issuer", "Common name of issuer",
- "", G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_boxed ("expiry", "Expiry", "Certificate expiry",
- G_TYPE_DATE, G_PARAM_READABLE));
-
- 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");
+ g_object_class_install_property (gobject_class, PROP_LABEL,
+ g_param_spec_string ("label", "Label", "Certificate Label",
+ "", G_PARAM_READWRITE));
_gcr_icons_register ();
+ gcr_certificate_mixin_class_init (gobject_class);
/* Register this as a renderer which can be loaded */
registered = gck_attributes_new ();
GNode *asn;
GQuark oid;
GDate date;
+ GIcon *icon;
self = GCR_CERTIFICATE_RENDERER (renderer);
if (!data)
return;
- _gcr_display_view_set_icon (view, GCR_RENDERER (self), self->pv->icon);
+ icon = gcr_certificate_get_icon (cert);
+ _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
+ g_object_unref (icon);
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
g_return_if_fail (asn);
static void
gcr_renderer_iface_init (GcrRendererIface *iface)
{
- static GcrModelColumn columns[] = {
- { "expiry", /* Below */ 0, N_("Expires"), 0 },
- { "label", G_TYPE_STRING, N_("Name"), 0 },
- { "description", G_TYPE_STRING, N_("Type"), 0 },
- { "subject", G_TYPE_STRING, N_("Subject"), 0 },
- { "issuer", G_TYPE_STRING, N_("Issued By"), 0 },
- { NULL }
- };
-
- /* Not constant so fill it in here */
- columns[0].type = G_TYPE_DATE;
-
iface->populate_popup = gcr_certificate_renderer_populate_popup;
iface->render_view = gcr_certificate_renderer_render;
- iface->column_info = columns;
}
static gconstpointer
-gcr_certificate_renderer_real_get_der_data (GcrCertificate *cert, gsize *n_data)
+gcr_certificate_renderer_get_der_data (GcrCertificate *cert, gsize *n_data)
{
GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
GckAttribute *attr;
}
static void
-gcr_certificate_iface_init (GcrCertificateIface *iface)
+gcr_renderer_certificate_iface_init (GcrCertificateIface *iface)
{
- iface->get_der_data = gcr_certificate_renderer_real_get_der_data;
+ iface->get_der_data = gcr_certificate_renderer_get_der_data;
}
/* -----------------------------------------------------------------------------
GType gcr_certificate_renderer_get_type (void);
-const GcrModelColumn* gcr_certificate_renderer_get_columns (void);
-
GcrCertificateRenderer* gcr_certificate_renderer_new (GcrCertificate *cert);
GcrCertificateRenderer* gcr_certificate_renderer_new_for_attributes (const gchar *label,
#include "config.h"
-#include "gcr-internal.h"
#include "gcr-certificate.h"
+#include "gcr-comparable.h"
+#include "gcr-icons.h"
+#include "gcr-internal.h"
#include "egg/egg-asn1x.h"
#include "egg/egg-asn1-defs.h"
#include "egg/egg-hex.h"
#include <string.h>
+#include <glib/gi18n-lib.h>
/**
* SECTION:gcr-certificate
*
* You can use #GcrSimpleCertificate to simply load a certificate for which
* you already have the raw certificate data.
+ *
+ * The #GcrCertificate interface has several properties that must be implemented.
+ * You can use a mixin to implement these properties if desired. See the
+ * gcr_certificate_mixin_class_init() and gcr_certificate_mixin_get_property()
+ * functions.
+ *
+ * All certificates are comparable. If implementing a #GcrCertificate, you can
+ * use GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE() to implement the #GcrComparable
+ * interface.
*/
/*
static gconstpointer _gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data);
static gconstpointer _gcr_certificate_get_issuer_const (GcrCertificate *self, gsize *n_data);
+enum {
+ PROP_FIRST = 0x0007000,
+ PROP_LABEL,
+ PROP_MARKUP,
+ PROP_DESCRIPTION,
+ PROP_ICON,
+ PROP_SUBJECT,
+ PROP_ISSUER,
+ PROP_EXPIRY
+};
+
/* -----------------------------------------------------------------------------
* INTERNAL
*/
return digest;
}
+static gchar*
+calculate_markup (GcrCertificate *self)
+{
+ gchar *label = NULL;
+ gchar *issuer;
+ gchar *markup;
+
+ g_object_get (self, "label", &label, NULL);
+ issuer = gcr_certificate_get_issuer_cn (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 gchar*
+calculate_expiry (GcrCertificate *self)
+{
+ GDate *date;
+ gchar *result;
+
+ date = gcr_certificate_get_expiry_date (self);
+ result = g_malloc0 (256);
+ if (!g_date_strftime (result, 256, "%s", date)) {
+ g_free (result);
+ result = NULL;
+ }
+ g_date_free (date);
+ return result;
+}
+
/* ---------------------------------------------------------------------------------
* INTERFACE
*/
static void
-gcr_certificate_base_init (gpointer g_class)
+gcr_certificate_iface_init (gpointer gobject_iface)
{
static volatile gsize initialized = 0;
OID_RSA_KEY = g_quark_from_static_string ("1.2.840.113549.1.1.1");
OID_DSA_KEY = g_quark_from_static_string ("1.2.840.10040.4.1");
- /* Add properties and signals to the interface */
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("label", "Label", "Certificate label",
+ "", G_PARAM_READABLE));
+
+ 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));
+
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("subject", "Subject", "Common name of subject",
+ "", G_PARAM_READABLE));
+
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("issuer", "Issuer", "Common name of issuer",
+ "", G_PARAM_READABLE));
+
+ g_object_interface_install_property (gobject_iface,
+ g_param_spec_string ("expiry", "Expiry", "Certificate expiry",
+ "", G_PARAM_READABLE));
g_once_init_leave (&initialized, 1);
}
if (!type) {
static const GTypeInfo info = {
sizeof (GcrCertificateIface),
- gcr_certificate_base_init, /* base init */
+ gcr_certificate_iface_init, /* base init */
NULL, /* base finalize */
NULL, /* class_init */
NULL, /* class finalize */
NULL, /* instance init */
};
type = g_type_register_static (G_TYPE_INTERFACE, "GcrCertificateIface", &info, 0);
- g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ g_type_interface_add_prerequisite (type, GCR_TYPE_COMPARABLE);
}
return type;
}
-
/* -----------------------------------------------------------------------------
* PUBLIC
*/
+const GcrColumn*
+gcr_certificate_get_columns (void)
+{
+ static GcrColumn columns[] = {
+ { "icon", 0, NULL, 0 },
+ { "label", G_TYPE_STRING, N_("Name"), 0 },
+ { "description", G_TYPE_STRING, N_("Type"), 0 },
+ { "subject", G_TYPE_STRING, N_("Subject"), 0 },
+ { "issuer", G_TYPE_STRING, N_("Issued By"), 0 },
+ { "expiry", G_TYPE_STRING, N_("Expires"), 0 },
+ { NULL }
+ };
+
+ columns[0].type = G_TYPE_ICON;
+ return columns;
+}
+
+gint
+gcr_certificate_compare (GcrComparable *first, GcrComparable *other)
+{
+ gconstpointer data1, data2;
+ gsize size1, size2;
+
+ if (!GCR_IS_CERTIFICATE (first))
+ first = NULL;
+ if (!GCR_IS_CERTIFICATE (other))
+ other = NULL;
+
+ if (first == other)
+ return TRUE;
+ if (!first)
+ return 1;
+ if (!other)
+ return -1;
+
+ data1 = gcr_certificate_get_der_data (GCR_CERTIFICATE (first), &size1);
+ data2 = gcr_certificate_get_der_data (GCR_CERTIFICATE (other), &size2);
+
+ return gcr_comparable_memcmp (data1, size1, data2, size2);
+}
+
+
/**
* gcr_certificate_get_der_data:
* @self: a #GcrCertificate
g_free (serial);
return hex;
}
+
+GIcon*
+gcr_certificate_get_icon (GcrCertificate *self)
+{
+ g_return_val_if_fail (GCR_IS_CERTIFICATE (self), FALSE);
+ return g_themed_icon_new (GCR_ICON_CERTIFICATE);
+}
+
+/* -----------------------------------------------------------------------------
+ * MIXIN
+ */
+
+/**
+ * GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE:
+ *
+ * Implement the GcrComparable interface. Use this macro like this:
+ *
+ * <informalexample><programlisting>
+ * G_DEFINE_TYPE_WITH_CODE (MyCertificate, my_certificate, G_TYPE_OBJECT,
+ * GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
+ * G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, my_certificate_iface_init);
+ * );
+ * </programlisting></informalexample>
+ */
+
+/**
+ * gcr_certificate_mixin_comparable_init:
+ * @iface: The interface
+ *
+ * Initialize a #GcrComparableIface to compare the current certificate.
+ * In general it's easier to use the GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE()
+ * macro instead of this function.
+ */
+void
+gcr_certificate_mixin_comparable_init (GcrComparableIface *iface)
+{
+ iface->compare = gcr_certificate_compare;
+}
+
+/**
+ * gcr_certificate_mixin_class_init:
+ * @object_class: The GObjectClass for this class
+ *
+ * Initialize the certificate mixin for the class. This mixin implements the
+ * various required properties for the certificate.
+ *
+ * Call this function near the end of your derived class_init() function. The
+ * derived class must implement the #GcrCertificate interface.
+ */
+void
+gcr_certificate_mixin_class_init (GObjectClass *object_class)
+{
+ if (!g_object_class_find_property (object_class, "description"))
+ g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
+ if (!g_object_class_find_property (object_class, "markup"))
+ g_object_class_override_property (object_class, PROP_MARKUP, "markup");
+ if (!g_object_class_find_property (object_class, "label"))
+ g_object_class_override_property (object_class, PROP_LABEL, "label");
+ if (!g_object_class_find_property (object_class, "icon"))
+ g_object_class_override_property (object_class, PROP_ICON, "icon");
+ if (!g_object_class_find_property (object_class, "subject"))
+ g_object_class_override_property (object_class, PROP_SUBJECT, "subject");
+ if (!g_object_class_find_property (object_class, "issuer"))
+ g_object_class_override_property (object_class, PROP_ISSUER, "issuer");
+ if (!g_object_class_find_property (object_class, "expiry"))
+ g_object_class_override_property (object_class, PROP_EXPIRY, "expiry");
+
+ _gcr_initialize ();
+}
+
+/**
+ * gcr_certificate_mixin_get_property:
+ * @obj: The object
+ * @prop_id: The property id
+ * @value: The value to fill in.
+ * @pspec: The param specification.
+ *
+ * Implementation to get various required certificate properties. This should
+ * be called from your derived class get_property function, or used as a
+ * get_property virtual function.
+ *
+ * Example of use as called from derived class get_property function:
+ *
+ * <informalexample><programlisting>
+ * static void
+ * my_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec)
+ * {
+ * switch (prop_id) {
+ *
+ * ...
+ *
+ * default:
+ * gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
+ * break;
+ * }
+ *}
+ * </programlisting></informalexample>
+ *
+ * Example of use as get_property function:
+ *
+ * <informalexample><programlisting>
+ * static void
+ * my_class_init (MyClass *klass)
+ * {
+ * GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ * gobject_class->get_property = gcr_certificate_mixin_get_property;
+ *
+ * ...
+ * }
+ * </programlisting></informalexample>
+
+ */
+void
+gcr_certificate_mixin_get_property (GObject *obj, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GcrCertificate *cert = GCR_CERTIFICATE (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_take_string (value, gcr_certificate_get_subject_cn (cert));
+ break;
+ case PROP_SUBJECT:
+ g_value_take_string (value, gcr_certificate_get_subject_cn (cert));
+ break;
+ case PROP_ICON:
+ g_value_set_object (value, gcr_certificate_get_icon (cert));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, _("Certificate"));
+ break;
+ case PROP_MARKUP:
+ g_value_take_string (value, calculate_markup (cert));
+ break;
+ case PROP_ISSUER:
+ g_value_take_string (value, gcr_certificate_get_issuer_cn (cert));
+ break;
+ case PROP_EXPIRY:
+ g_value_take_string (value, calculate_expiry (cert));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
#define __GCR_CERTIFICATE_H__
#include "gcr-types.h"
+#include "gcr-column.h"
+#include "gcr-comparable.h"
#include <glib-object.h>
+#include <gio/gio.h>
G_BEGIN_DECLS
-#define GCR_TYPE_CERTIFICATE (gcr_certificate_get_type())
-#define GCR_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE, GcrCertificate))
-#define GCR_IS_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE))
-#define GCR_CERTIFICATE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_CERTIFICATE, GcrCertificateIface))
+#define GCR_CERTIFICATE_COLUMNS (gcr_certificate_get_columns ())
+#define GCR_TYPE_CERTIFICATE (gcr_certificate_get_type ())
+#define GCR_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE, GcrCertificate))
+#define GCR_IS_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE))
+#define GCR_CERTIFICATE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_CERTIFICATE, GcrCertificateIface))
-typedef struct _GcrCertificate GcrCertificate;
-typedef struct _GcrCertificateIface GcrCertificateIface;
+typedef struct _GcrCertificate GcrCertificate;
+typedef struct _GcrCertificateIface GcrCertificateIface;
struct _GcrCertificateIface {
GTypeInterface parent;
- gconstpointer (*get_der_data) (GcrCertificate *self, gsize *n_data);
+ gconstpointer (*get_der_data) (GcrCertificate *self, gsize *n_data);
gpointer dummy1;
gpointer dummy2;
gconstpointer gcr_certificate_get_der_data (GcrCertificate *self,
gsize *n_data);
+const GcrColumn* gcr_certificate_get_columns (void);
+
+gint gcr_certificate_compare (GcrComparable *self,
+ GcrComparable *other);
+
gchar* gcr_certificate_get_issuer_cn (GcrCertificate *self);
gchar* gcr_certificate_get_issuer_dn (GcrCertificate *self);
gchar* gcr_certificate_get_fingerprint_hex (GcrCertificate *self,
GChecksumType type);
+GIcon* gcr_certificate_get_icon (GcrCertificate *self);
+
+#define GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE() \
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_COMPARABLE, gcr_certificate_mixin_comparable_init)
+
+void gcr_certificate_mixin_comparable_init (GcrComparableIface *iface);
+
+void gcr_certificate_mixin_class_init (GObjectClass *object_class);
+
+void gcr_certificate_mixin_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
G_END_DECLS
#endif /* __GCR_CERTIFICATE_H__ */
struct _GcrCollectionModelPrivate {
GcrCollection *collection;
GHashTable *object_to_index;
+ GHashTable *toggled_active;
gint cache_stamp;
gint last_stamp;
G_DEFINE_TYPE_EXTENDED (GcrCollectionModel, gcr_collection_model, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, gcr_collection_model_tree_model));
+#define UNUSED_VALUE GUINT_TO_POINTER (1)
+
/* -----------------------------------------------------------------------------
* INTERNAL
*/
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (column >= 0 && column < self->pv->n_columns);
+ /* The selected column? */
+ if (column == self->pv->n_columns - 1) {
+ g_assert (!self->pv->column_names[column]);
+ g_assert (self->pv->column_types[column] == G_TYPE_BOOLEAN);
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, gcr_collection_model_get_selected (self, iter));
+ return;
+ }
+
/* Figure out which property */
type = self->pv->column_types[column];
property = self->pv->column_names[column];
/* Disconnect from all rows */
for (i = self->pv->objects->len; i > 0; --i) {
obj = g_ptr_array_index (self->pv->objects, i - 1);
- disconnect_object (self, object);
+ disconnect_object (self, obj);
}
/* Disconnect from the collection */
self->pv->collection = NULL;
}
+ if (self->pv->toggled_active)
+ g_hash_table_remove_all (self->pv->toggled_active);
+
G_OBJECT_CLASS (gcr_collection_model_parent_class)->dispose (object);
}
g_ptr_array_free (self->pv->objects, TRUE);
self->pv->objects = NULL;
+ if (self->pv->toggled_active)
+ g_hash_table_destroy (self->pv->toggled_active);
+ self->pv->toggled_active = NULL;
+
if (self->pv->column_names) {
g_strfreev (self->pv->column_names);
self->pv->column_names = NULL;
GcrCollectionModel*
gcr_collection_model_new (GcrCollection *collection, ...)
{
- GcrModelColumn column;
+ GcrColumn column;
GcrCollectionModel *self;
const gchar *arg;
GArray *array;
va_list va;
/* With a null terminator */
- array = g_array_new (TRUE, TRUE, sizeof (GcrModelColumn));
+ array = g_array_new (TRUE, TRUE, sizeof (GcrColumn));
va_start (va, collection);
while ((arg = va_arg (va, const gchar*)) != NULL) {
}
va_end (va);
- self = gcr_collection_model_new_full (collection, (GcrModelColumn*)array->data);
+ self = gcr_collection_model_new_full (collection, (GcrColumn*)array->data);
g_array_free (array, TRUE);
return self;
}
GcrCollectionModel*
-gcr_collection_model_new_full (GcrCollection *collection, const GcrModelColumn *columns)
+gcr_collection_model_new_full (GcrCollection *collection, const GcrColumn *columns)
{
GcrCollectionModel *self = g_object_new (GCR_TYPE_COLLECTION_MODEL, "collection", collection, NULL);
gcr_collection_model_set_columns (self, columns);
}
gint
-gcr_collection_model_set_columns (GcrCollectionModel *self, const GcrModelColumn *columns)
+gcr_collection_model_set_columns (GcrCollectionModel *self, const GcrColumn *columns)
{
- const GcrModelColumn *col;
+ const GcrColumn *col;
guint i, n_columns;
g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), -1);
g_return_val_if_fail (self->pv->n_columns == 0, -1);
- /* Count the number of columns */
- for (col = columns, n_columns = 0; col->property; ++col)
+ /* Count the number of columns, extra column for selected */
+ for (col = columns, n_columns = 1; col->property; ++col)
++n_columns;
self->pv->column_names = g_new0 (gchar*, n_columns + 1);
self->pv->column_types = g_new0 (GType, n_columns + 1);
self->pv->n_columns = n_columns;
- for (i = 0; i < n_columns; ++i) {
+ /* All the columns, except the selected column */
+ for (i = 0; i < n_columns - 1; ++i) {
self->pv->column_names[i] = g_strdup (columns[i].property);
self->pv->column_types[i] = columns[i].type;
}
+ /* The selected column */
+ self->pv->column_names[i] = NULL;
+ self->pv->column_types[i] = G_TYPE_BOOLEAN;
+
return n_columns - 1;
}
return iter_for_index (self, index, iter);
}
+
+guint
+gcr_collection_model_column_selected (GcrCollectionModel *self)
+{
+ g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), 0);
+ g_assert (self->pv->n_columns > 0);
+ return self->pv->n_columns - 1;
+}
+
+void
+gcr_collection_model_toggle_selected (GcrCollectionModel *self, GtkTreeIter *iter)
+{
+ GObject *object;
+
+ g_return_if_fail (GCR_IS_COLLECTION_MODEL (self));
+
+ object = gcr_collection_model_object_for_iter (self, iter);
+ g_return_if_fail (G_IS_OBJECT (object));
+
+ if (!self->pv->toggled_active)
+ self->pv->toggled_active = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ if (g_hash_table_lookup (self->pv->toggled_active, object))
+ g_hash_table_remove (self->pv->toggled_active, object);
+ else
+ g_hash_table_insert (self->pv->toggled_active, object, UNUSED_VALUE);
+}
+
+void
+gcr_collection_model_set_selected (GcrCollectionModel *self, GtkTreeIter *iter, gboolean selected)
+{
+ GObject *object;
+
+ g_return_if_fail (GCR_IS_COLLECTION_MODEL (self));
+
+ object = gcr_collection_model_object_for_iter (self, iter);
+ g_return_if_fail (G_IS_OBJECT (object));
+
+ if (!self->pv->toggled_active)
+ self->pv->toggled_active = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ if (selected)
+ g_hash_table_insert (self->pv->toggled_active, object, UNUSED_VALUE);
+ else
+ g_hash_table_remove (self->pv->toggled_active, object);
+}
+
+gboolean
+gcr_collection_model_get_selected (GcrCollectionModel *self, GtkTreeIter *iter)
+{
+ GObject *object;
+
+ g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), FALSE);
+
+ object = gcr_collection_model_object_for_iter (self, iter);
+ g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+
+ if (!self->pv->toggled_active)
+ return FALSE;
+
+ return g_hash_table_lookup (self->pv->toggled_active, object) ? TRUE : FALSE;
+}
...) G_GNUC_NULL_TERMINATED;
GcrCollectionModel* gcr_collection_model_new_full (GcrCollection *collection,
- const GcrModelColumn *columns);
+ const GcrColumn *columns);
gint gcr_collection_model_set_columns (GcrCollectionModel *self,
- const GcrModelColumn *columns);
+ const GcrColumn *columns);
GObject* gcr_collection_model_object_for_iter (GcrCollectionModel *self,
const GtkTreeIter *iter);
GObject *object,
GtkTreeIter *iter);
+guint gcr_collection_model_column_selected (GcrCollectionModel *self);
+
+void gcr_collection_model_toggle_selected (GcrCollectionModel *self,
+ GtkTreeIter *iter);
+
+void gcr_collection_model_set_selected (GcrCollectionModel *self,
+ GtkTreeIter *iter,
+ gboolean selected);
+
+gboolean gcr_collection_model_get_selected (GcrCollectionModel *self,
+ GtkTreeIter *iter);
+
#endif /* __GCR_COLLECTION_MODEL_H__ */
G_BEGIN_DECLS
-typedef struct _GcrModelColumn {
+typedef struct _GcrColumn {
const gchar *property;
GType type;
const gchar *label;
+ gpointer user_data;
gpointer reserved;
-} GcrModelColumn;
+} GcrColumn;
G_END_DECLS
--- /dev/null
+/*
+ * 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-comparable.h"
+
+#include <string.h>
+
+/* ---------------------------------------------------------------------------------
+ * INTERFACE
+ */
+
+static void
+gcr_comparable_base_init (gpointer g_class)
+{
+ static volatile gsize initialized = 0;
+
+ if (g_once_init_enter (&initialized)) {
+ /* Add properties and signals to the interface */
+ g_once_init_leave (&initialized, 1);
+ }
+}
+
+GType
+gcr_comparable_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GcrComparableIface),
+ gcr_comparable_base_init, /* base init */
+ NULL, /* base finalize */
+ NULL, /* class_init */
+ NULL, /* class finalize */
+ NULL, /* class data */
+ 0,
+ 0, /* n_preallocs */
+ NULL, /* instance init */
+ };
+ type = g_type_register_static (G_TYPE_INTERFACE, "GcrComparableIface", &info, 0);
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+gint
+gcr_comparable_compare (GcrComparable *self, GcrComparable *other)
+{
+ g_return_val_if_fail (GCR_IS_COMPARABLE (self), -1);
+ g_return_val_if_fail (GCR_COMPARABLE_GET_INTERFACE (self)->compare, -1);
+ g_return_val_if_fail (G_IS_OBJECT (self), -1);
+ return GCR_COMPARABLE_GET_INTERFACE (self)->compare (self, other);
+}
+
+gint
+gcr_comparable_memcmp (gconstpointer mem1, gsize size1,
+ gconstpointer mem2, gsize size2)
+{
+ gint result;
+
+ if (mem1 == mem2 && size1 == size2)
+ return 0;
+
+ if (!mem1)
+ return 1;
+ if (!mem2)
+ return -1;
+
+ result = memcmp (mem1, mem2, MIN (size1, size2));
+ if (result != 0)
+ return result;
+
+ if (size1 == size2)
+ return 0;
+ if (size1 < size2)
+ return -1;
+ return 1;
+}
--- /dev/null
+/*
+ * 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_COMPARABLE_H__
+#define __GCR_COMPARABLE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_COMPARABLE (gcr_comparable_get_type())
+#define GCR_COMPARABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COMPARABLE, GcrComparable))
+#define GCR_IS_COMPARABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COMPARABLE))
+#define GCR_COMPARABLE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_COMPARABLE, GcrComparableIface))
+
+typedef struct _GcrComparable GcrComparable;
+typedef struct _GcrComparableIface GcrComparableIface;
+
+struct _GcrComparableIface {
+ GTypeInterface parent;
+ gint (*compare) (GcrComparable *self, GcrComparable *other);
+};
+
+GType gcr_comparable_get_type (void);
+
+gint gcr_comparable_compare (GcrComparable *self,
+ GcrComparable *other);
+
+gint gcr_comparable_memcmp (gconstpointer mem1,
+ gsize size1,
+ gconstpointer mem2,
+ gsize size2);
+
+G_END_DECLS
+
+#endif /* __GCR_COMPARABLE_H__ */
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);
}
+
+ g_type_class_unref (g_type_class_ref (GCR_TYPE_CERTIFICATE_RENDERER));
+ g_type_class_unref (g_type_class_ref (GCR_TYPE_KEY_RENDERER));
}
/**
static void gcr_certificate_iface (GcrCertificateIface *iface);
G_DEFINE_TYPE_WITH_CODE (GcrPkcs11Certificate, gcr_pkcs11_certificate, GCK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface));
+ GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface);
+);
/* ----------------------------------------------------------------------------
* INTERAL
g_value_set_boxed (value, gcr_pkcs11_certificate_get_attributes (self));
break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
break;
}
}
g_type_class_add_private (gobject_class, sizeof (GcrPkcs11CertificatePrivate));
+ gcr_certificate_mixin_class_init (gobject_class);
_gcr_initialize ();
}
static gconstpointer
-gcr_pkcs11_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
+gcr_pkcs11_certificate_get_der_data (GcrCertificate *cert, gsize *n_data)
{
- GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (base);
+ GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (cert);
GckAttribute *attr;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
static void
gcr_certificate_iface (GcrCertificateIface *iface)
{
- iface->get_der_data = (gpointer)gcr_pkcs11_certificate_real_get_der_data;
+ iface->get_der_data = gcr_pkcs11_certificate_get_der_data;
}
/* -----------------------------------------------------------------------------
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);
g_array_append_val (registered_renderers, registered);
registered_sorted = FALSE;
}
-
-const GcrModelColumn*
-gcr_renderer_columns (GType renderer_type)
-{
- const GcrModelColumn *columns;
- GcrRendererIface *renderer;
- GTypeClass *klass;
-
- klass = g_type_class_ref (renderer_type);
- g_return_val_if_fail (klass, NULL);
-
- renderer = g_type_interface_peek (klass, GCR_TYPE_RENDERER);
- g_return_val_if_fail (renderer, NULL);
-
- columns = renderer->column_info;
- g_return_val_if_fail (columns, NULL);
-
- g_type_class_unref (klass);
-
- return columns;
-}
struct _GcrRendererIface {
GTypeInterface parent;
- /* data */
- const GcrModelColumn *column_info;
-
/* signals */
void (*data_changed) (GcrRenderer *self);
GcrRenderer* gcr_renderer_create (const gchar *label,
GckAttributes *attrs);
-const GcrModelColumn* gcr_renderer_columns (GType renderer_type);
-
void gcr_renderer_register (GType renderer_type,
GckAttributes *attrs);
--- /dev/null
+/*
+ * 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-model.h"
+#include "gcr-internal.h"
+#include "gcr-selector.h"
+
+enum {
+ PROP_0,
+ PROP_COLLECTION,
+ PROP_COLUMNS,
+ PROP_MODE
+};
+
+#if 0
+enum {
+ XXXX,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+#endif
+
+struct _GcrSelectorPrivate {
+ GtkComboBox *combo;
+ GtkTreeView *tree;
+ GcrCollection *collection;
+ const GcrColumn *columns;
+ GcrCollectionModel *model;
+ GcrSelectorMode mode;
+};
+
+G_DEFINE_TYPE (GcrSelector, gcr_selector, GTK_TYPE_ALIGNMENT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static void
+on_check_column_toggled (GtkCellRendererToggle *cell, gchar *path, GcrCollectionModel *model)
+{
+ GtkTreeIter iter;
+
+ g_assert (path != NULL);
+
+ if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
+ gcr_collection_model_toggle_selected (model, &iter);
+}
+
+static void
+add_string_column (GcrSelector *self, const GcrColumn *column, guint index)
+{
+ GtkCellRenderer *cell;
+ GtkTreeViewColumn *col;
+
+ g_assert (column->type == G_TYPE_STRING);
+
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (G_OBJECT (cell), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ col = gtk_tree_view_column_new_with_attributes (column->label, cell, "text", index, NULL);
+ gtk_tree_view_column_set_resizable (col, TRUE);
+ gtk_tree_view_append_column (self->pv->tree, col);
+}
+
+static void
+add_icon_column (GcrSelector *self, const GcrColumn *column, guint index)
+{
+ GtkCellRenderer *cell;
+ GtkTreeViewColumn *col;
+
+ g_assert (column->type == G_TYPE_ICON);
+
+ cell = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (cell, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
+ col = gtk_tree_view_column_new_with_attributes (column->label, cell, "gicon", index, NULL);
+ gtk_tree_view_column_set_resizable (col, TRUE);
+ gtk_tree_view_append_column (self->pv->tree, col);
+}
+
+static void
+add_check_column (GcrSelector *self, guint index)
+{
+ GtkCellRenderer *cell;
+ GtkTreeViewColumn *col;
+
+ cell = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (cell, "toggled", G_CALLBACK (on_check_column_toggled), self->pv->model);
+
+ col = gtk_tree_view_column_new_with_attributes ("", cell, "active", index, NULL);
+ gtk_tree_view_column_set_resizable (col, FALSE);
+ gtk_tree_view_append_column (self->pv->tree, col);
+}
+
+static void
+construct_single_selector (GcrSelector *self)
+{
+ GtkCellRenderer *cell;
+ GtkWidget *widget;
+
+ self->pv->model = gcr_collection_model_new (self->pv->collection,
+ "icon", G_TYPE_ICON,
+ "markup", G_TYPE_STRING,
+ NULL);
+
+ widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (self->pv->model));
+ self->pv->combo = GTK_COMBO_BOX (widget);
+
+ /* The icon */
+ 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 (widget), cell, FALSE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), cell, "gicon", 0);
+
+ /* The markup */
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), cell, "markup", 1);
+
+ gtk_widget_show (widget);
+ gtk_container_add (GTK_CONTAINER (self), widget);
+}
+
+static void
+construct_multiple_selector (GcrSelector *self)
+{
+ const GcrColumn *column;
+ GtkWidget *widget, *scroll;
+ guint i;
+
+ self->pv->model = gcr_collection_model_new_full (self->pv->collection,
+ self->pv->columns);
+
+ widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->pv->model));
+ self->pv->tree = GTK_TREE_VIEW (widget);
+
+ /* First add the check mark column */
+ add_check_column (self, gcr_collection_model_column_selected (self->pv->model));
+
+ for (column = self->pv->columns, i = 0; column->property; ++column, ++i) {
+ if (column->type == G_TYPE_STRING)
+ add_string_column (self, column, i);
+ else if (column->type == G_TYPE_ICON)
+ add_icon_column (self, column, i);
+ else {
+ g_warning ("skipping unsupported column '%s' of type: %s",
+ column->label, g_type_name (column->type));
+ }
+ }
+
+ 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_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (scroll), widget);
+ gtk_container_add (GTK_CONTAINER (self), scroll);
+
+ gtk_widget_show_all (scroll);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+GType
+gcr_selector_mode_get_type (void)
+{
+ static GType type = 0;
+ static GEnumValue values[] = {
+ { GCR_SELECTOR_MODE_SINGLE, "single", "Single"},
+ { GCR_SELECTOR_MODE_MULTIPLE, "multiple", "Multiple"},
+ { 0, NULL, NULL }
+ };
+ if (!type)
+ type = g_enum_register_static ("GcrSelectorMode", values);
+ return type;
+}
+
+static GObject*
+gcr_selector_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GcrSelector *self = GCR_SELECTOR (G_OBJECT_CLASS (gcr_selector_parent_class)->constructor(type, n_props, props));
+ g_return_val_if_fail (self, NULL);
+
+ g_return_val_if_fail (self->pv->columns, NULL);
+
+ switch (self->pv->mode) {
+ case GCR_SELECTOR_MODE_SINGLE:
+ construct_single_selector (self);
+ break;
+ case GCR_SELECTOR_MODE_MULTIPLE:
+ construct_multiple_selector (self);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return G_OBJECT (self);
+}
+
+static void
+gcr_selector_init (GcrSelector *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_SELECTOR, GcrSelectorPrivate);
+}
+
+static void
+gcr_selector_dispose (GObject *obj)
+{
+ GcrSelector *self = GCR_SELECTOR (obj);
+
+ if (self->pv->model)
+ g_object_unref (self->pv->model);
+ self->pv->model = NULL;
+
+ if (self->pv->collection)
+ g_object_unref (self->pv->collection);
+ self->pv->collection = NULL;
+
+ G_OBJECT_CLASS (gcr_selector_parent_class)->dispose (obj);
+}
+
+static void
+gcr_selector_finalize (GObject *obj)
+{
+ GcrSelector *self = GCR_SELECTOR (obj);
+
+ g_assert (!self->pv->collection);
+ g_assert (!self->pv->model);
+ self->pv->combo = NULL;
+ self->pv->tree = NULL;
+
+ G_OBJECT_CLASS (gcr_selector_parent_class)->finalize (obj);
+}
+
+static void
+gcr_selector_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrSelector *self = GCR_SELECTOR (obj);
+ switch (prop_id) {
+ case PROP_COLLECTION:
+ g_return_if_fail (!self->pv->collection);
+ self->pv->collection = g_value_dup_object (value);
+ g_return_if_fail (self->pv->collection);
+ break;
+ case PROP_COLUMNS:
+ g_return_if_fail (!self->pv->columns);
+ self->pv->columns = g_value_get_pointer (value);
+ g_return_if_fail (self->pv->columns);
+ break;
+ case PROP_MODE:
+ self->pv->mode = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_selector_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrSelector *self = GCR_SELECTOR (obj);
+
+ switch (prop_id) {
+ case PROP_COLLECTION:
+ g_value_set_object (value, gcr_selector_get_collection (self));
+ break;
+ case PROP_COLUMNS:
+ g_value_set_pointer (value, (gpointer)gcr_selector_get_columns (self));
+ break;
+ case PROP_MODE:
+ g_value_set_enum (value, gcr_selector_get_mode (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_selector_class_init (GcrSelectorClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructor = gcr_selector_constructor;
+ gobject_class->dispose = gcr_selector_dispose;
+ gobject_class->finalize = gcr_selector_finalize;
+ gobject_class->set_property = gcr_selector_set_property;
+ gobject_class->get_property = gcr_selector_get_property;
+
+ g_type_class_add_private (gobject_class, sizeof (GcrSelectorPrivate));
+
+ g_object_class_install_property (gobject_class, PROP_COLLECTION,
+ g_param_spec_object ("collection", "Collection", "Collection to select from",
+ GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_COLUMNS,
+ g_param_spec_pointer ("columns", "Columns", "Columns to display in multiple selector",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_MODE,
+ g_param_spec_enum ("mode", "Mode", "The mode of the selector",
+ GCR_TYPE_SELECTOR_MODE, GCR_SELECTOR_MODE_SINGLE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ _gcr_initialize ();
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrSelector*
+gcr_selector_new (GcrCollection *collection, const GcrColumn *columns, GcrSelectorMode mode)
+{
+ return g_object_new (GCR_TYPE_SELECTOR,
+ "collection", collection,
+ "columns", columns,
+ "mode", mode,
+ NULL);
+}
+
+GcrCollection*
+gcr_selector_get_collection (GcrSelector *self)
+{
+ g_return_val_if_fail (GCR_IS_SELECTOR (self), NULL);
+ return self->pv->collection;
+}
+
+const GcrColumn*
+gcr_selector_get_columns (GcrSelector *self)
+{
+ g_return_val_if_fail (GCR_IS_SELECTOR (self), NULL);
+ return self->pv->columns;
+}
+
+GcrSelectorMode
+gcr_selector_get_mode (GcrSelector *self)
+{
+ g_return_val_if_fail (GCR_IS_SELECTOR (self), 0);
+ return self->pv->mode;
+}
--- /dev/null
+/*
+ * 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_SELECTOR_H__
+#define __GCR_SELECTOR_H__
+
+#include "gcr-types.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_SELECTOR (gcr_selector_get_type ())
+#define GCR_TYPE_SELECTOR_MODE (gcr_selector_mode_get_type ())
+#define GCR_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_SELECTOR, GcrSelector))
+#define GCR_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_SELECTOR, GcrSelectorClass))
+#define GCR_IS_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_SELECTOR))
+#define GCR_IS_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_SELECTOR))
+#define GCR_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_SELECTOR, GcrSelectorClass))
+
+typedef struct _GcrSelector GcrSelector;
+typedef struct _GcrSelectorClass GcrSelectorClass;
+typedef struct _GcrSelectorPrivate GcrSelectorPrivate;
+
+typedef enum _GcrSelectorMode {
+ GCR_SELECTOR_MODE_SINGLE = 1,
+ GCR_SELECTOR_MODE_MULTIPLE
+} GcrSelectorMode;
+
+struct _GcrSelector {
+ GtkAlignment parent;
+ GcrSelectorPrivate *pv;
+};
+
+struct _GcrSelectorClass {
+ GtkAlignmentClass parent_class;
+
+#if 0
+ /* signals --------------------------------------------------------- */
+
+ /* A callback for each password needed */
+ gboolean (*authenticate) (GcrSelector *self, gint count);
+
+ void (*parsed) (GcrSelector *self);
+#endif
+};
+
+GType gcr_selector_get_type (void);
+
+GType gcr_selector_mode_get_type (void);
+
+GcrSelector* gcr_selector_new (GcrCollection *collection,
+ const GcrColumn *columns,
+ GcrSelectorMode mode);
+
+GcrCollection* gcr_selector_get_collection (GcrSelector *self);
+
+const GcrColumn* gcr_selector_get_columns (GcrSelector *self);
+
+GcrSelectorMode gcr_selector_get_mode (GcrSelector *self);
+
+G_END_DECLS
+
+#endif /* __GCR_SELECTOR_H__ */
#include "config.h"
#include "gcr-certificate.h"
+#include "gcr-comparable.h"
#include "gcr-internal.h"
#include "gcr-simple-certificate.h"
guchar *owned;
};
-static void gcr_certificate_iface (GcrCertificateIface *iface);
+/* Forward declarations */
+static void gcr_simple_certificate_iface_init (GcrCertificateIface *iface);
+
G_DEFINE_TYPE_WITH_CODE (GcrSimpleCertificate, gcr_simple_certificate, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface));
+ GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_simple_certificate_iface_init);
+);
/* -----------------------------------------------------------------------------
* OBJECT
}
static void
-gcr_simple_certificate_finalize (GObject *obj)
+gcr_simple_certificate_real_finalize (GObject *obj)
{
GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (obj);
gcr_simple_certificate_class_init (GcrSimpleCertificateClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = gcr_simple_certificate_finalize;
+
+ gobject_class->finalize = gcr_simple_certificate_real_finalize;
+ gobject_class->get_property = gcr_certificate_mixin_get_property;
+
g_type_class_add_private (gobject_class, sizeof (GcrSimpleCertificatePrivate));
+
+ gcr_certificate_mixin_class_init (gobject_class);
_gcr_initialize ();
}
static gconstpointer
-gcr_simple_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
+gcr_simple_certificate_get_der_data (GcrCertificate *cert, gsize *n_data)
{
- GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (base);
+ GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (cert);
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (n_data, NULL);
}
static void
-gcr_certificate_iface (GcrCertificateIface *iface)
+gcr_simple_certificate_iface_init (GcrCertificateIface *iface)
{
- iface->get_der_data = (gpointer)gcr_simple_certificate_real_get_der_data;
+ iface->get_der_data = gcr_simple_certificate_get_der_data;
}
/* -----------------------------------------------------------------------------
#include "gcr-parser.h"
#include "gcr-renderer.h"
#include "gcr-pkcs11-certificate.h"
+#include "gcr-selector.h"
#include "gcr-simple-certificate.h"
#include "gcr-simple-collection.h"
#include "gcr-trust.h"
g_free (data);
}
-#if 1
-static void
-build_selector (GtkDialog *dialog, GcrCollection *collection)
-{
- GcrCollectionModel *model;
- GtkWidget *combo;
- GtkCellRenderer *cell;
-
- 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);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-
- g_object_unref (model);
-}
-#endif
-
-#if 0
-static void
-build_selector (GtkDialog *dialog, GcrCollection *collection)
-{
- GcrCollectionModel *model;
- const GcrModelColumn *columns;
- GtkWidget *combo;
- GtkCellRenderer *cell;
-
- columns = gcr_renderer_columns (GCR_TYPE_CERTIFICATE_RENDERER);
- model = gcr_collection_model_new_full (collection, columns);
-
- gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
-
- 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);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-
- g_object_unref (model);
-}
-#endif
-
int
main (int argc, char *argv[])
{
GcrCollection *collection;
+ GcrSelector *selector;
GtkDialog *dialog;
GcrParser *parser;
int i;
g_object_ref_sink (dialog);
collection = gcr_simple_collection_new ();
- build_selector (dialog, collection);
+ selector = gcr_selector_new (collection, GCR_CERTIFICATE_COLUMNS, GCR_SELECTOR_MODE_MULTIPLE);
-#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_widget_show (GTK_WIDGET (selector));
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (selector));
+
+ 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);