[gnome-keyring] gcr: Add support for unlocking files in gcr-viewer
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Add support for unlocking files in gcr-viewer
- Date: Thu, 1 Sep 2011 10:16:09 +0000 (UTC)
commit 02dd8275c8afa984c0389da1088abb680bdb9aa3
Author: Stef Walter <stefw collabora co uk>
Date: Wed Aug 31 15:30:58 2011 +0200
gcr: Add support for unlocking files in gcr-viewer
* Add a GcrRenderer which displays unlock widgets
* Add method to GcrViewer which allows insertion of renderer before another
* Functionality in GcrDisplayView for showing dialog like widgets in view
* Fixes for removing renderer from view
* Parser fixes for enabling all formats
* Parser fixes for PKCS#12 parsing with locked data
.gitignore | 1 +
gcr/Makefile.am | 1 +
gcr/gcr-display-scrolled.c | 10 ++
gcr/gcr-display-view.c | 141 ++++++++++++++---
gcr/gcr-display-view.h | 4 +
gcr/gcr-parser.c | 43 +++--
gcr/gcr-unlock-renderer.c | 368 ++++++++++++++++++++++++++++++++++++++++++++
gcr/gcr-unlock-renderer.h | 69 ++++++++
gcr/gcr-viewer-window.c | 125 ++++++++++++++-
gcr/gcr-viewer.c | 56 +++++---
gcr/gcr-viewer.h | 27 +++-
gcr/gcr.h | 1 +
gcr/tests/Makefile.am | 3 +-
gcr/tests/frob-unlock.c | 111 +++++++++++++
14 files changed, 885 insertions(+), 75 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 186ca98..d2fc41a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -121,6 +121,7 @@ run-tests
/gcr/tests/frob-tree-selector
/gcr/tests/frob-unlock-options
/gcr/tests/frob-parser
+/gcr/tests/frob-unlock
/gcr/tests/test-certificate
/gcr/tests/test-certificate-chain
/gcr/tests/test-colons
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 7d0404a..c6e626e 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -122,6 +122,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-types.h \
gcr-unlock-options.h \
gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
+ gcr-unlock-renderer.c gcr-unlock-renderer.h \
gcr-util.c gcr-util.h \
gcr-viewer.c gcr-viewer.h \
gcr-viewer-window.c gcr-viewer-window.h \
diff --git a/gcr/gcr-display-scrolled.c b/gcr/gcr-display-scrolled.c
index 3de3111..49d2dd9 100644
--- a/gcr/gcr-display-scrolled.c
+++ b/gcr/gcr-display-scrolled.c
@@ -126,6 +126,15 @@ _gcr_display_scrolled_real_add_renderer (GcrViewer *viewer, GcrRenderer *rendere
}
static void
+_gcr_display_scrolled_real_insert_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before)
+{
+ GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
+ gcr_viewer_insert_renderer (self->pv->internal, renderer, before);
+}
+
+static void
_gcr_display_scrolled_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
{
GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
@@ -150,6 +159,7 @@ static void
_gcr_display_scrolled_viewer_iface (GcrViewerIface *iface)
{
iface->add_renderer = _gcr_display_scrolled_real_add_renderer;
+ iface->insert_renderer = _gcr_display_scrolled_real_insert_renderer;
iface->remove_renderer = _gcr_display_scrolled_real_remove_renderer;
iface->count_renderers = _gcr_display_scrolled_real_count_renderers;
iface->get_renderer = _gcr_display_scrolled_real_get_renderer;
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
index b6cec63..035a3a7 100644
--- a/gcr/gcr-display-view.c
+++ b/gcr/gcr-display-view.c
@@ -34,6 +34,7 @@ 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 ZWSP "\342\200\213"
#define NORMAL_MARGIN 10
#define FIELD_MARGIN 17
#define COLUMN_MARGIN 6
@@ -47,6 +48,7 @@ typedef struct _GcrDisplayItem {
GtkTextMark *beginning;
GtkTextMark *ending;
GtkWidget *details_widget;
+ GtkTextChildAnchor *area_anchor;
GtkTextTag *extra_tag;
gint field_width;
GdkPixbuf *pixbuf;
@@ -63,6 +65,7 @@ struct _GcrDisplayViewPrivate {
GtkTextTag *content_tag;
GtkTextTag *heading_tag;
GtkTextTag *monospace_tag;
+ GtkTextTag *area_tag;
GcrDisplayItem *current_item;
gint text_height;
GdkCursor *cursor;
@@ -187,6 +190,7 @@ create_tag_table (GcrDisplayView *self)
"right-margin", (ICON_MARGIN * 2) + width,
"left-margin", FIELD_MARGIN,
"pixels-below-lines", 3,
+ "wrap-mode", GTK_WRAP_WORD,
NULL);
gtk_text_tag_table_add (tags, self->pv->content_tag);
@@ -204,6 +208,12 @@ create_tag_table (GcrDisplayView *self)
NULL);
gtk_text_tag_table_add (tags, self->pv->monospace_tag);
+ self->pv->area_tag = g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "area",
+ "justification", GTK_JUSTIFY_CENTER,
+ NULL);
+ gtk_text_tag_table_add (tags, self->pv->area_tag);
+
return tags;
}
@@ -277,7 +287,7 @@ create_display_item (GcrDisplayView *self, GcrRenderer *renderer)
gtk_text_tag_table_add (tags, item->details_tag);
/*
- * Add two zero width spaces that delimit this from later items. The
+ * Add two lines space that delimit this from later items. The
* item will live between the two zero width spaces.
*/
gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
@@ -316,8 +326,6 @@ create_display_item (GcrDisplayView *self, GcrRenderer *renderer)
if (gtk_widget_get_realized (GTK_WIDGET (self)))
style_display_item (GTK_WIDGET (self), item);
- /* TODO: Initialize the rest of the fields */
-
return item;
}
@@ -325,6 +333,7 @@ static void
destroy_display_item (gpointer data)
{
GcrDisplayItem *item = data;
+ GtkTextIter iter, end;
GtkTextTagTable *tags;
GcrDisplayView *self;
@@ -348,12 +357,22 @@ destroy_display_item (gpointer data)
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_clear_object (&item->area_anchor);
+ g_return_if_fail (!gtk_text_mark_get_deleted (item->beginning));
g_return_if_fail (!gtk_text_mark_get_deleted (item->ending));
+
+ /* Setup iters to encompass our delemiter characters see create_display_item() */
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
+ gtk_text_iter_backward_char (&iter);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &end, item->ending);
+ gtk_text_iter_forward_char (&end);
+ gtk_text_buffer_delete (self->pv->buffer, &iter, &end);
+
+ gtk_text_buffer_delete_mark (self->pv->buffer, item->beginning);
gtk_text_buffer_delete_mark (self->pv->buffer, item->ending);
+
+ g_object_unref (item->beginning);
g_object_unref (item->ending);
g_free (item);
@@ -392,10 +411,17 @@ find_item_at_iter (GcrDisplayView *self, GtkTextIter *iter)
}
static void
-on_renderer_data_changed (GcrRenderer *renderer, GcrViewer *self)
+on_renderer_data_changed (GcrRenderer *renderer,
+ gpointer user_data)
{
+ GcrDisplayView *self = GCR_DISPLAY_VIEW (user_data);
+
+ /* Item may be removed, but not yet destroyed */
+ if (!g_hash_table_lookup (self->pv->items, renderer))
+ return;
+
/* Just ask the renderer to render itself on us */
- gcr_renderer_render_view (renderer, self);
+ gcr_renderer_render_view (renderer, GCR_VIEWER (self));
}
static void
@@ -443,20 +469,26 @@ paint_item_border (GcrDisplayView *self,
{
GdkRGBA color;
GtkTextView *view;
- GtkTextIter iter;
+ GtkTextIter iter, end;
GdkRectangle location;
if (index == 0)
return;
+ view = GTK_TEXT_VIEW (self);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &end, item->ending);
+
+ /* Don't paint for non-visible items */
+ if (gtk_text_iter_compare (&iter, &end) == 0)
+ return;
+
ensure_text_height (self);
gtk_style_context_get_background_color (context,
GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED,
&color);
- view = GTK_TEXT_VIEW (self);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
gtk_text_view_get_iter_location (view, &iter, &location);
location.height = 2;
@@ -728,13 +760,39 @@ _gcr_display_view_class_init (GcrDisplayViewClass *klass)
}
static void
-_gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+_gcr_display_view_real_insert_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before)
{
GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
GcrDisplayItem *item;
+ guint i;
+
+ if (before != NULL)
+ g_return_if_fail (g_hash_table_lookup (self->pv->items, before) != NULL);
item = create_display_item (self, renderer);
- g_ptr_array_add (self->pv->renderers, g_object_ref (renderer));
+ g_object_ref (renderer);
+
+ /* Insert it at the right place */
+ if (before != NULL) {
+ g_ptr_array_add (self->pv->renderers, NULL);
+ for (i = self->pv->renderers->len; i > 0; i--) {
+ self->pv->renderers->pdata[i] = self->pv->renderers->pdata[i - 1];
+ if (self->pv->renderers->pdata[i] == before) {
+ self->pv->renderers->pdata[i - 1] = renderer;
+ break;
+ }
+ }
+
+ /* Must have been found */
+ g_assert (i > 0);
+
+ /* No before, just add to end */
+ } else {
+ g_ptr_array_add (self->pv->renderers, renderer);
+ }
+
g_hash_table_insert (self->pv->items, renderer, item);
gcr_renderer_render_view (renderer, viewer);
@@ -743,6 +801,12 @@ _gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
}
static void
+_gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+{
+ _gcr_display_view_real_insert_renderer (viewer, renderer, NULL);
+}
+
+static void
_gcr_display_view_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
{
GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
@@ -782,6 +846,7 @@ static void
_gcr_display_view_viewer_iface (GcrViewerIface *iface)
{
iface->add_renderer = (gpointer)_gcr_display_view_real_add_renderer;
+ iface->insert_renderer = (gpointer)_gcr_display_view_real_insert_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;
@@ -803,13 +868,27 @@ _gcr_display_view_begin (GcrDisplayView *self,
{
GtkTextIter start, iter;
GcrDisplayItem *item;
+ GList *widgets, *l;
g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
item = lookup_display_item (self, renderer);
g_return_if_fail (item);
+ /* Remove the details widget so it doesn't get destroyed */
if (gtk_widget_get_parent (item->details_widget))
gtk_container_remove (GTK_CONTAINER (self), item->details_widget);
+
+ /* Remove area widgets so they don't get destroyed unnecessarily */
+ if (item->area_anchor) {
+ g_assert (!gtk_text_child_anchor_get_deleted (item->area_anchor));
+ widgets = gtk_text_child_anchor_get_widgets (item->area_anchor);
+ for (l = widgets; l != NULL; l = g_list_next (l))
+ gtk_container_remove (GTK_CONTAINER (self), l->data);
+ g_list_free (widgets);
+ g_object_unref (item->area_anchor);
+ item->area_anchor = NULL;
+ }
+
gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->beginning);
gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
@@ -823,20 +902,11 @@ void
_gcr_display_view_end (GcrDisplayView *self,
GcrRenderer *renderer)
{
- GtkTextIter start, iter;
GcrDisplayItem *item;
g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
item = lookup_display_item (self, renderer);
g_return_if_fail (item);
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->beginning);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
-
-#if 0
- if (gtk_text_iter_compare (&start, &iter) != 0)
- gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1);
-#endif
}
void
@@ -1073,3 +1143,30 @@ _gcr_display_view_set_icon (GcrDisplayView *self, GcrRenderer *renderer, GIcon *
gtk_icon_info_free (info);
}
}
+
+void
+_gcr_display_view_add_widget_area (GcrDisplayView *self,
+ GcrRenderer *renderer,
+ GtkWidget *area)
+{
+ GtkTextIter iter, start;
+ GcrDisplayItem *item;
+
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ g_return_if_fail (GTK_IS_WIDGET (area));
+
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item != NULL);
+ g_return_if_fail (item->area_anchor == NULL);
+
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->ending);
+ iter = start;
+
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n" ZWSP, -1, self->pv->area_tag, NULL);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+
+ item->area_anchor = gtk_text_buffer_create_child_anchor (self->pv->buffer, &iter);
+ g_object_ref (item->area_anchor);
+ gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), area, item->area_anchor);
+ gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, ZWSP "\n", -1, self->pv->area_tag, NULL);
+}
diff --git a/gcr/gcr-display-view.h b/gcr/gcr-display-view.h
index f697e59..d1c84f7 100644
--- a/gcr/gcr-display-view.h
+++ b/gcr/gcr-display-view.h
@@ -100,6 +100,10 @@ void _gcr_display_view_set_icon (GcrDisplayView *
GcrRenderer *renderer,
GIcon *icon);
+void _gcr_display_view_add_widget_area (GcrDisplayView *self,
+ GcrRenderer *render,
+ GtkWidget *area);
+
G_END_DECLS
#endif /* __GCR_DISPLAY_VIEW_H__ */
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index 2ad68ab..00c7e39 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -1004,7 +1004,7 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
/* We assume unrecognized data is a bad encryption key */
}
-
+
done:
if (cih)
gcry_cipher_close (cih);
@@ -1077,8 +1077,10 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
r = GCR_ERROR_UNRECOGNIZED;
}
-
- if (r == GCR_ERROR_FAILURE || r == GCR_ERROR_CANCELLED) {
+
+ if (r == GCR_ERROR_FAILURE ||
+ r == GCR_ERROR_CANCELLED ||
+ r == GCR_ERROR_LOCKED) {
ret = r;
goto done;
}
@@ -1134,8 +1136,12 @@ parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
if (!content)
goto done;
+ parsing_begin (self, 0, data, n_data);
+
ret = handle_pkcs12_safe (self, content, n_content);
+ parsing_end (self);
+
done:
g_free (content);
egg_asn1x_destroy (asn_content);
@@ -1762,28 +1768,29 @@ gcr_parser_parse_data (GcrParser *self, gconstpointer data,
void
gcr_parser_format_enable (GcrParser *self, gint format_id)
{
- ParserFormat *format;
+ const ParserFormat *format;
+ guint i;
g_return_if_fail (GCR_IS_PARSER (self));
- if (format_id == -1) {
- if (self->pv->specific_formats)
- g_tree_destroy (self->pv->specific_formats);
- self->pv->specific_formats = NULL;
- self->pv->normal_formats = TRUE;
- return;
+ if (format_id != -1) {
+ format = parser_format_lookup (format_id);
+ g_return_if_fail (format);
}
- format = parser_format_lookup (format_id);
- g_return_if_fail (format);
-
- if (!self->pv->specific_formats) {
- if (self->pv->normal_formats)
- return;
+ if (!self->pv->specific_formats)
self->pv->specific_formats = g_tree_new (compare_pointers);
- }
- g_tree_insert (self->pv->specific_formats, format, format);
+ if (format_id != -1) {
+ g_tree_insert (self->pv->specific_formats,
+ (gpointer)format, (gpointer)format);
+ } else {
+ for (i = 0; i < G_N_ELEMENTS (parser_formats); i++) {
+ format = &parser_formats[i];
+ g_tree_insert (self->pv->specific_formats, (gpointer)format,
+ (gpointer)format);
+ }
+ }
}
/**
diff --git a/gcr/gcr-unlock-renderer.c b/gcr/gcr-unlock-renderer.c
new file mode 100644
index 0000000..b30d922
--- /dev/null
+++ b/gcr/gcr-unlock-renderer.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gcr-display-view.h"
+#include "gcr-icons.h"
+#include "gcr-parser.h"
+#include "gcr-unlock-renderer.h"
+
+#include "egg/egg-entry-buffer.h"
+
+#include <gdk/gdk.h>
+#include <glib/gi18n-lib.h>
+
+enum {
+ PROP_0,
+ PROP_LABEL,
+ PROP_ATTRIBUTES
+};
+
+struct _GcrUnlockRendererPrivate {
+ GtkEntry *entry;
+ GtkLabel *warning;
+
+ gpointer locked_data;
+ gsize n_locked_data;
+ gchar *label;
+ gboolean unlocked;
+ GList *renderers;
+ guint unlock_tries;
+
+ /* block widget destroys during render */
+ gint no_destroy;
+};
+
+static void gcr_renderer_iface_init (GcrRendererIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrUnlockRenderer, _gcr_unlock_renderer, GTK_TYPE_ALIGNMENT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
+);
+
+static gchar*
+calculate_label (GcrUnlockRenderer *self)
+{
+ if (self->pv->label)
+ return g_strdup_printf (_("Unlock: %s"), self->pv->label);
+
+ return g_strdup (_("Unlock"));
+}
+
+static gboolean
+on_parser_authenticate (GcrParser *parser,
+ gint count,
+ gpointer user_data)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (user_data);
+
+ /* On the first try, pass unlock password back to parser */
+ if (count == 0)
+ gcr_parser_add_password (parser, gtk_entry_get_text (self->pv->entry));
+
+ return TRUE;
+}
+
+static void
+on_parser_parsed (GcrParser *parser,
+ gpointer user_data)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (user_data);
+ GcrRenderer *renderer;
+
+ /* Create a new renderer for this piece of data */
+ renderer = gcr_renderer_create (gcr_parser_get_parsed_label (parser),
+ gcr_parser_get_parsed_attributes (parser));
+
+ /* And save this renderer for placing in viewer later */
+ if (renderer != NULL)
+ self->pv->renderers = g_list_prepend (self->pv->renderers, renderer);
+}
+
+static void
+show_warning (GcrUnlockRenderer *self,
+ const gchar *message)
+{
+ gchar *text;
+
+ text = g_strdup_printf ("<i>%s</i>", message);
+ gtk_label_set_markup (self->pv->warning, text);
+ g_free (text);
+
+ gtk_widget_show (GTK_WIDGET (self->pv->warning));
+}
+
+static void
+on_unlock_button_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (user_data);
+ GcrParser *parser;
+ GError *error = NULL;
+
+ /* Clear out any renderers somehow sitting around */
+ g_list_free_full (self->pv->renderers, g_object_unref);
+ self->pv->renderers = NULL;
+
+ parser = gcr_parser_new ();
+ gcr_parser_format_enable (parser, -1); /* all enabled */
+ g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), self);
+ g_signal_connect (parser, "authenticate", G_CALLBACK (on_parser_authenticate), self);
+ if (gcr_parser_parse_data (parser, self->pv->locked_data,
+ self->pv->n_locked_data, &error)) {
+
+ /* If we unlocked successfully, then hide ourselves, and add other renderers */
+ self->pv->unlocked = TRUE;
+
+ } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)){
+ self->pv->unlock_tries++;
+ show_warning (self, _("The password was incorrect"));
+ g_error_free (error);
+
+ } else {
+ show_warning (self, error->message);
+ g_error_free (error);
+ }
+
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+}
+
+static void
+on_entry_activated (GtkEntry *entry,
+ gpointer user_data)
+{
+ GtkButton *button = GTK_BUTTON (user_data);
+ gtk_button_clicked (button);
+}
+
+static void
+_gcr_unlock_renderer_init (GcrUnlockRenderer *self)
+{
+ GtkWidget *box, *vbox;
+ GtkWidget *button;
+ GtkEntryBuffer *buffer;
+
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_UNLOCK_RENDERER,
+ GcrUnlockRendererPrivate));
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+
+ buffer = egg_entry_buffer_new ();
+ self->pv->entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
+ gtk_entry_set_visibility (self->pv->entry, FALSE);
+ gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (self->pv->entry), TRUE, FALSE, 0);
+ gtk_widget_show (GTK_WIDGET (self->pv->entry));
+ g_object_unref (buffer);
+
+ button = gtk_button_new_with_label (_("Unlock"));
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "clicked", G_CALLBACK (on_unlock_button_clicked), self);
+ g_signal_connect (self->pv->entry, "activate", G_CALLBACK (on_entry_activated), button);
+ gtk_widget_show (button);
+
+ vbox = gtk_vbox_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
+ gtk_widget_show (box);
+
+ self->pv->warning = GTK_LABEL (gtk_label_new (""));
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (self->pv->warning), FALSE, FALSE, 0);
+ gtk_widget_hide (GTK_WIDGET (self->pv->warning));
+
+ gtk_container_add (GTK_CONTAINER (self), vbox);
+ gtk_widget_show (vbox);
+}
+
+static void
+_gcr_unlock_renderer_finalize (GObject *obj)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (obj);
+
+ g_free (self->pv->locked_data);
+ g_free (self->pv->label);
+ g_list_free_full (self->pv->renderers, g_object_unref);
+
+ G_OBJECT_CLASS (_gcr_unlock_renderer_parent_class)->finalize (obj);
+}
+
+static void
+_gcr_unlock_renderer_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_free (self->pv->label);
+ self->pv->label = g_value_dup_string (value);
+ g_object_notify (obj, "label");
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ break;
+ case PROP_ATTRIBUTES:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+_gcr_unlock_renderer_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_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, NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+_gcr_unlock_renderer_class_init (GcrUnlockRendererClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GcrUnlockRendererPrivate));
+
+ gobject_class->finalize = _gcr_unlock_renderer_finalize;
+ gobject_class->set_property = _gcr_unlock_renderer_set_property;
+ gobject_class->get_property = _gcr_unlock_renderer_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_LABEL,
+ g_param_spec_string ("label", "Label", "Unlock Label",
+ "", G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+ g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+
+ _gcr_icons_register ();
+}
+
+static void
+gcr_unlock_renderer_render (GcrRenderer *renderer,
+ GcrViewer *viewer)
+{
+ GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (renderer);
+ GcrDisplayView *view;
+ gchar *display;
+ GList *renderers;
+ GIcon *icon;
+ GList *l;
+
+ if (GCR_IS_DISPLAY_VIEW (viewer)) {
+ view = GCR_DISPLAY_VIEW (viewer);
+
+ } else {
+ g_warning ("GcrUnlockRenderer only works with internal specific "
+ "GcrViewer returned by gcr_viewer_new().");
+ return;
+ }
+
+ /*
+ * If we were successfully unlocked, then this will contain a list of
+ * renderers to add to the viewer.
+ */
+ if (self->pv->unlocked) {
+
+ /* We used prepend above, so list is backwards */
+ renderers = g_list_reverse (self->pv->renderers);
+ self->pv->renderers = NULL;
+
+ for (l = renderers; l != NULL; l = g_list_next (l))
+ gcr_viewer_insert_renderer (viewer, l->data, renderer);
+ g_list_free_full (renderers, g_object_unref);
+
+ /* And finally remove ourselves from the viewer */
+ gcr_viewer_remove_renderer (viewer, GCR_RENDERER (self));
+ /*
+ * Not yet unlocked, display the unlock dialog.
+ */
+ } else {
+
+ _gcr_display_view_begin (view, renderer);
+
+ icon = g_themed_icon_new ("emblem-readonly");
+ _gcr_display_view_set_icon (view, renderer, icon);
+ g_object_unref (icon);
+
+ display = calculate_label (self);
+ _gcr_display_view_append_title (view, renderer, display);
+ g_free (display);
+
+ if (self->pv->label)
+ display = g_strdup_printf (_("The contents of '%s' are locked. In order to view the contents, enter a the correct password."),
+ self->pv->label);
+ else
+ display = g_strdup (_("The contents are locked. In order to view the contents, enter a the correct password."));
+ _gcr_display_view_append_content (view, renderer, display, NULL);
+ g_free (display);
+
+ _gcr_display_view_add_widget_area (view, renderer, GTK_WIDGET (self));
+ gtk_widget_show (GTK_WIDGET (self));
+
+ _gcr_display_view_end (view, renderer);
+ }
+}
+
+static void
+gcr_renderer_iface_init (GcrRendererIface *iface)
+{
+ iface->render_view = gcr_unlock_renderer_render;
+}
+
+GcrUnlockRenderer*
+_gcr_unlock_renderer_new (const gchar *label,
+ gconstpointer locked_data,
+ gsize n_locked_data)
+{
+ GcrUnlockRenderer *renderer;
+
+ renderer = g_object_new (GCR_TYPE_UNLOCK_RENDERER,
+ "label", label,
+ NULL);
+ g_object_ref_sink (renderer);
+
+ renderer->pv->locked_data = g_memdup (locked_data, n_locked_data);
+ renderer->pv->n_locked_data = n_locked_data;
+
+ return renderer;
+}
+
+GcrUnlockRenderer *
+_gcr_unlock_renderer_new_for_parsed (GcrParser *parser)
+{
+ gconstpointer block;
+ gsize n_block;
+
+ block = gcr_parser_get_parsed_block (parser, &n_block);
+ return _gcr_unlock_renderer_new (gcr_parser_get_parsed_label (parser),
+ block, n_block);
+}
diff --git a/gcr/gcr-unlock-renderer.h b/gcr/gcr-unlock-renderer.h
new file mode 100644
index 0000000..54e0e46
--- /dev/null
+++ b/gcr/gcr-unlock-renderer.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
+#error "Only <gcr/gcr.h> can be included directly."
+#endif
+
+#ifndef __GCR_UNLOCK_RENDERER_H__
+#define __GCR_UNLOCK_RENDERER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-renderer.h"
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_UNLOCK_RENDERER (_gcr_unlock_renderer_get_type ())
+#define GCR_UNLOCK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRenderer))
+#define GCR_UNLOCK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRendererClass))
+#define GCR_IS_UNLOCK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_UNLOCK_RENDERER))
+#define GCR_IS_UNLOCK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_UNLOCK_RENDERER))
+#define GCR_UNLOCK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRendererClass))
+
+typedef struct _GcrUnlockRenderer GcrUnlockRenderer;
+typedef struct _GcrUnlockRendererClass GcrUnlockRendererClass;
+typedef struct _GcrUnlockRendererPrivate GcrUnlockRendererPrivate;
+
+struct _GcrUnlockRenderer {
+ /*< private >*/
+ GtkAlignment parent;
+ GcrUnlockRendererPrivate *pv;
+};
+
+struct _GcrUnlockRendererClass {
+ /*< private >*/
+ GtkAlignmentClass parent_class;
+};
+
+GType _gcr_unlock_renderer_get_type (void);
+
+GcrUnlockRenderer * _gcr_unlock_renderer_new (const gchar *label,
+ gconstpointer locked_data,
+ gsize n_locked_data);
+
+GcrUnlockRenderer * _gcr_unlock_renderer_new_for_parsed (GcrParser *parser);
+
+G_END_DECLS
+
+#endif /* __GCR_UNLOCK_RENDERER_H__ */
diff --git a/gcr/gcr-viewer-window.c b/gcr/gcr-viewer-window.c
index a85a757..cb6140c 100644
--- a/gcr/gcr-viewer-window.c
+++ b/gcr/gcr-viewer-window.c
@@ -25,6 +25,7 @@
#include "gcr-parser.h"
#include "gcr-renderer.h"
+#include "gcr-unlock-renderer.h"
#include "gcr-viewer-window.h"
#include "gcr-viewer.h"
@@ -61,12 +62,30 @@ struct _GcrViewerWindowPrivate {
GCancellable *cancellable;
GcrViewer *viewer;
gboolean loading;
+ gchar *display_name;
};
static void viewer_load_next_file (GcrViewerWindow *self);
static void viewer_stop_loading_files (GcrViewerWindow *self);
-G_DEFINE_TYPE (GcrViewerWindow, gcr_viewer_window, GTK_TYPE_WINDOW);
+static void gcr_viewer_iface_init (GcrViewerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrViewerWindow, gcr_viewer_window, GTK_TYPE_WINDOW,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEWER, gcr_viewer_iface_init);
+);
+
+static const gchar *
+get_parsed_label_or_display_name (GcrViewerWindow *self,
+ GcrParser *parser)
+{
+ const gchar *label;
+
+ label = gcr_parser_get_parsed_label (parser);
+ if (label == NULL)
+ label = self->pv->display_name;
+
+ return label;
+}
static void
on_parser_parsed (GcrParser *parser, gpointer user_data)
@@ -74,7 +93,7 @@ on_parser_parsed (GcrParser *parser, gpointer user_data)
GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
GcrRenderer *renderer;
- renderer = gcr_renderer_create (gcr_parser_get_parsed_label (parser),
+ renderer = gcr_renderer_create (get_parsed_label_or_display_name (self, parser),
gcr_parser_get_parsed_attributes (parser));
if (renderer) {
@@ -83,6 +102,24 @@ on_parser_parsed (GcrParser *parser, gpointer user_data)
}
}
+static gboolean
+on_parser_authenticate (GcrParser *parser,
+ guint count,
+ gpointer user_data)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
+ GcrUnlockRenderer *renderer;
+
+ renderer = _gcr_unlock_renderer_new_for_parsed (parser);
+ if (renderer) {
+ g_object_set (renderer, "label", get_parsed_label_or_display_name (self, parser), NULL);
+ gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (renderer));
+ g_object_unref (renderer);
+ }
+
+ return TRUE;
+}
+
static void
gcr_viewer_window_init (GcrViewerWindow *self)
{
@@ -94,6 +131,7 @@ gcr_viewer_window_init (GcrViewerWindow *self)
self->pv->cancellable = g_cancellable_new ();
g_signal_connect (self->pv->parser, "parsed", G_CALLBACK (on_parser_parsed), self);
+ g_signal_connect (self->pv->parser, "authenticate", G_CALLBACK (on_parser_authenticate), self);
}
static void
@@ -137,6 +175,7 @@ gcr_viewer_window_finalize (GObject *obj)
g_assert (g_queue_is_empty (self->pv->files_to_load));
g_queue_free (self->pv->files_to_load);
+ g_free (self->pv->display_name);
g_object_unref (self->pv->cancellable);
g_object_unref (self->pv->parser);
@@ -158,6 +197,56 @@ gcr_viewer_window_class_init (GcrViewerWindowClass *klass)
}
static void
+gcr_viewer_window_add_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (viewer);
+ gcr_viewer_add_renderer (self->pv->viewer, renderer);
+}
+
+static void
+gcr_viewer_window_insert_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (viewer);
+ gcr_viewer_insert_renderer (self->pv->viewer, renderer, before);
+}
+
+static void
+gcr_viewer_window_remove_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (viewer);
+ gcr_viewer_remove_renderer (self->pv->viewer, renderer);
+}
+
+static guint
+gcr_viewer_window_count_renderers (GcrViewer *viewer)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (viewer);
+ return gcr_viewer_count_renderers (self->pv->viewer);
+}
+
+static GcrRenderer *
+gcr_viewer_window_get_renderer (GcrViewer *viewer,
+ guint index_)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (viewer);
+ return gcr_viewer_get_renderer (self->pv->viewer, index_);
+}
+
+static void
+gcr_viewer_iface_init (GcrViewerIface *iface)
+{
+ iface->add_renderer = gcr_viewer_window_add_renderer;
+ iface->insert_renderer = gcr_viewer_window_insert_renderer;
+ iface->count_renderers = gcr_viewer_window_count_renderers;
+ iface->get_renderer = gcr_viewer_window_get_renderer;
+ iface->remove_renderer = gcr_viewer_window_remove_renderer;
+}
+
+static void
on_parser_parse_stream_returned (GObject *source, GAsyncResult *result,
gpointer user_data)
{
@@ -166,15 +255,37 @@ on_parser_parse_stream_returned (GObject *source, GAsyncResult *result,
gcr_parser_parse_stream_finish (self->pv->parser, result, &error);
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- viewer_stop_loading_files (self);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+ g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_CANCELLED)) {
+
+ } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)) {
+ viewer_load_next_file (self);
+ return;
} else if (error) {
- g_assert_not_reached (); /* TODO; */
+ g_warning ("failed to load: %s", error->message);
+ g_error_free (error);
} else {
viewer_load_next_file (self);
+ return;
}
+
+ viewer_stop_loading_files (self);
+}
+
+static void
+update_display_name (GcrViewerWindow *self,
+ GFile *file)
+{
+ gchar *basename;
+
+ basename = g_file_get_basename (file);
+
+ g_free (self->pv->display_name);
+ self->pv->display_name = g_filename_display_name (basename);
+
+ g_free (basename);
}
static void
@@ -186,7 +297,7 @@ on_file_read_returned (GObject *source, GAsyncResult *result, gpointer user_data
GFileInputStream *fis;
fis = g_file_read_finish (file, result, &error);
- g_object_unref (file);
+ update_display_name (self, file);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
viewer_stop_loading_files (self);
@@ -222,6 +333,8 @@ viewer_load_next_file (GcrViewerWindow *self)
g_file_read_async (file, G_PRIORITY_DEFAULT, self->pv->cancellable,
on_file_read_returned, self);
+
+ g_object_unref (file);
}
/**
diff --git a/gcr/gcr-viewer.c b/gcr/gcr-viewer.c
index e3b5c68..26b65df 100644
--- a/gcr/gcr-viewer.c
+++ b/gcr/gcr-viewer.c
@@ -49,6 +49,7 @@
* GcrViewerIface:
* @parent: The parent interface
* @add_renderer: Virtual method to add a renderer
+ * @insert_renderer: Virtual method to insert a renderer
* @remove_renderer: Virtual method to remove a renderer
* @count_renderers: Virtual method to count renderers
* @get_renderer: Virtual method to get a renderer
@@ -119,55 +120,69 @@ gcr_viewer_new_scrolled (void)
/**
* gcr_viewer_add_renderer:
- * @self: The viewer
+ * @viewer: The viewer
* @renderer: The renderer to add
*
* Add a renderer to this viewer.
*/
void
-gcr_viewer_add_renderer (GcrViewer *self, GcrRenderer *renderer)
+gcr_viewer_add_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer)
{
- g_return_if_fail (GCR_IS_VIEWER (self));
+ g_return_if_fail (GCR_IS_VIEWER (viewer));
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);
+ g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->add_renderer);
+ GCR_VIEWER_GET_INTERFACE (viewer)->add_renderer (viewer, renderer);
+}
+
+void
+gcr_viewer_insert_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before)
+{
+ g_return_if_fail (GCR_IS_VIEWER (viewer));
+ g_return_if_fail (GCR_IS_RENDERER (renderer));
+ g_return_if_fail (!before || GCR_IS_RENDERER (before));
+ g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->insert_renderer);
+ GCR_VIEWER_GET_INTERFACE (viewer)->insert_renderer (viewer, renderer, before);
}
/**
* gcr_viewer_remove_renderer:
- * @self: The viewer
+ * @viewer: The viewer
* @renderer: The renderer to remove
*
* Remove a renderer from this viewer.
*/
void
-gcr_viewer_remove_renderer (GcrViewer *self, GcrRenderer *renderer)
+gcr_viewer_remove_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer)
{
- g_return_if_fail (GCR_IS_VIEWER (self));
+ g_return_if_fail (GCR_IS_VIEWER (viewer));
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);
+ g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->remove_renderer);
+ GCR_VIEWER_GET_INTERFACE (viewer)->remove_renderer (viewer, renderer);
}
/**
* gcr_viewer_count_renderers:
- * @self: The viewer
+ * @viewer: The viewer
*
* Get the number of renderers present in the viewer.
*
* Returns: The number of renderers.
*/
guint
-gcr_viewer_count_renderers (GcrViewer *self)
+gcr_viewer_count_renderers (GcrViewer *viewer)
{
- 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);
+ g_return_val_if_fail (GCR_IS_VIEWER (viewer), 0);
+ g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->count_renderers, 0);
+ return GCR_VIEWER_GET_INTERFACE (viewer)->count_renderers (viewer);
}
/**
* gcr_viewer_get_renderer:
- * @self: The viewer
+ * @viewer: The viewer
* @index_: The index of the renderer to get
*
* Get a pointer to the renderer at the given index. It is an error to request
@@ -176,9 +191,10 @@ gcr_viewer_count_renderers (GcrViewer *self)
* Returns: The render, owned by the viewer.
*/
GcrRenderer*
-gcr_viewer_get_renderer (GcrViewer *self, guint index_)
+gcr_viewer_get_renderer (GcrViewer *viewer,
+ 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_);
+ g_return_val_if_fail (GCR_IS_VIEWER (viewer), NULL);
+ g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->get_renderer, NULL);
+ return GCR_VIEWER_GET_INTERFACE (viewer)->get_renderer (viewer, index_);
}
diff --git a/gcr/gcr-viewer.h b/gcr/gcr-viewer.h
index 20956ee..b806cda 100644
--- a/gcr/gcr-viewer.h
+++ b/gcr/gcr-viewer.h
@@ -39,13 +39,20 @@ typedef struct _GcrViewerIface GcrViewerIface;
struct _GcrViewerIface {
GTypeInterface parent;
- void (*add_renderer) (GcrViewer *self, GcrRenderer *viewer);
+ void (*add_renderer) (GcrViewer *viewer,
+ GcrRenderer *renderer);
- void (*remove_renderer) (GcrViewer *self, GcrRenderer *viewer);
+ void (*insert_renderer) (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before);
- guint (*count_renderers) (GcrViewer *self);
+ void (*remove_renderer) (GcrViewer *viewer,
+ GcrRenderer *renderer);
- GcrRenderer* (*get_renderer) (GcrViewer *self, guint index_);
+ guint (*count_renderers) (GcrViewer *viewer);
+
+ GcrRenderer* (*get_renderer) (GcrViewer *viewer,
+ guint index_);
/*< private >*/
gpointer dummy1;
@@ -60,15 +67,19 @@ GcrViewer* gcr_viewer_new (void);
GcrViewer* gcr_viewer_new_scrolled (void);
-void gcr_viewer_add_renderer (GcrViewer *self,
+void gcr_viewer_add_renderer (GcrViewer *viewer,
GcrRenderer *renderer);
-void gcr_viewer_remove_renderer (GcrViewer *self,
+void gcr_viewer_insert_renderer (GcrViewer *viewer,
+ GcrRenderer *renderer,
+ GcrRenderer *before);
+
+void gcr_viewer_remove_renderer (GcrViewer *viewer,
GcrRenderer *renderer);
-guint gcr_viewer_count_renderers (GcrViewer *self);
+guint gcr_viewer_count_renderers (GcrViewer *viewer);
-GcrRenderer* gcr_viewer_get_renderer (GcrViewer *self,
+GcrRenderer* gcr_viewer_get_renderer (GcrViewer *viewer,
guint index_);
G_END_DECLS
diff --git a/gcr/gcr.h b/gcr/gcr.h
index 0b789fc..e6a1238 100644
--- a/gcr/gcr.h
+++ b/gcr/gcr.h
@@ -58,6 +58,7 @@
#include "gcr-unlock-options.h"
#include "gcr-unlock-options-widget.h"
#include "gcr-viewer.h"
+#include "gcr-viewer-window.h"
#undef __GCR_H_INSIDE__
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index 5729c8e..ed98f4d 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -2,7 +2,7 @@
INCLUDES = \
-I$(top_builddir) \
-I$(top_srcdir) \
- -DSRCDIR="\"$(srcdir)\"" \
+ -DSRCDIR="\"@abs_srcdir \"" \
-DGCR_API_SUBJECT_TO_CHANGE \
-DGCK_API_SUBJECT_TO_CHANGE \
-DGCR_COMPILATION \
@@ -56,4 +56,5 @@ noinst_PROGRAMS = \
frob-key \
frob-tree-selector \
frob-parser \
+ frob-unlock \
frob-unlock-options
diff --git a/gcr/tests/frob-unlock.c b/gcr/tests/frob-unlock.c
new file mode 100644
index 0000000..3a7f511
--- /dev/null
+++ b/gcr/tests/frob-unlock.c
@@ -0,0 +1,111 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "gcr/gcr.h"
+#include "gcr/gcr-unlock-renderer.h"
+
+#include <gtk/gtk.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static gboolean
+delete_event(GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ gtk_main_quit ();
+ return FALSE;
+}
+
+static void
+on_parser_parsed (GcrParser *parser, gpointer unused)
+{
+
+}
+
+static void
+on_parser_authenticate (GcrParser *parser,
+ gint count,
+ gpointer user_data)
+{
+ GcrUnlockRenderer *renderer;
+ GtkWindow *window;
+
+ window = GTK_WINDOW (gcr_viewer_window_new ());
+ g_object_ref_sink (window);
+
+ renderer = _gcr_unlock_renderer_new_for_parsed (parser);
+ gcr_viewer_add_renderer (GCR_VIEWER (window), GCR_RENDERER (renderer));
+ g_object_unref (renderer);
+
+ gtk_window_set_default_size (window, 550, 400);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 20);
+
+ g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL);
+ gtk_widget_show (GTK_WIDGET (window));
+
+ gtk_main ();
+
+ g_object_unref (window);
+
+}
+
+static void
+test_key (const gchar *path)
+{
+ GcrParser *parser;
+ 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);
+
+ parser = gcr_parser_new ();
+ g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), NULL);
+ g_signal_connect (parser, "authenticate", G_CALLBACK (on_parser_authenticate), NULL);
+ if (!gcr_parser_parse_data (parser, data, n_data, &err))
+ g_error ("couldn't parse data: %s", err->message);
+
+ g_object_unref (parser);
+ g_free (data);
+}
+
+int
+main(int argc, char *argv[])
+{
+ gtk_init (&argc, &argv);
+ g_set_prgname ("frob-unlock");
+
+ if (argc > 1) {
+ test_key (argv[1]);
+ } else {
+ test_key (SRCDIR "/files/email.p12");
+ }
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]