[gnome-keyring] gcr: Complete GcrViewerWidget and GcrImportButton
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Complete GcrViewerWidget and GcrImportButton
- Date: Tue, 27 Sep 2011 15:15:32 +0000 (UTC)
commit d94dd8459298bac84b70190fd8db0ef2b480db49
Author: Stef Walter <stefw collabora co uk>
Date: Thu Sep 22 16:59:17 2011 +0200
gcr: Complete GcrViewerWidget and GcrImportButton
* Cleanup documentation
* Rework how the GcrViewerWindow works so that it can be used
elsewhere.
* Create GcrImportButton which can import certificates and widgets.
docs/reference/gcr/Makefile.am | 13 +-
docs/reference/gcr/gcr-docs.sgml | 2 +
docs/reference/gcr/gcr-sections.txt | 46 ++-
docs/reference/gcr/gcr-widgets.c | 46 ++-
docs/reference/gcr/gcr.types | 23 +-
docs/reference/gcr/images/certificate-widget.png | Bin 15090 -> 16144 bytes
docs/reference/gcr/images/import-button.png | Bin 0 -> 2925 bytes
docs/reference/gcr/images/key-widget.png | Bin 10159 -> 10159 bytes
docs/reference/gcr/images/viewer-widget.png | Bin 0 -> 13167 bytes
gcr/Makefile.am | 15 +-
gcr/gcr-base.h | 1 +
gcr/gcr-collection-model.c | 1 -
gcr/gcr-combo-selector.c | 1 -
gcr/gcr-failure-renderer.c | 32 +-
gcr/gcr-failure-renderer.h | 11 +-
gcr/gcr-gnupg-process.c | 62 ++--
gcr/gcr-import-button.c | 485 ++++++++++++++++++++++
gcr/gcr-import-button.h | 68 +++
gcr/gcr-list-selector.c | 1 -
gcr/gcr-marshal.list | 2 +
gcr/gcr-pkcs11-importer.c | 2 +-
gcr/gcr-simple-collection.c | 1 -
gcr/gcr-tree-selector.c | 1 -
gcr/gcr-union-collection.c | 1 -
gcr/gcr-unlock-renderer.c | 98 ++---
gcr/gcr-unlock-renderer.h | 12 +-
gcr/gcr-viewer-tool.c | 6 +-
gcr/gcr-viewer-widget.c | 436 +++++++++++++++++++
gcr/gcr-viewer-widget.h | 53 +++
gcr/gcr-viewer-window.c | 371 ++++-------------
gcr/gcr-viewer-window.h | 12 +-
gcr/gcr-viewer.c | 25 +-
gcr/gcr.h | 8 +-
gcr/tests/Makefile.am | 4 +
gcr/tests/frob-unlock.c | 3 +-
35 files changed, 1365 insertions(+), 477 deletions(-)
---
diff --git a/docs/reference/gcr/Makefile.am b/docs/reference/gcr/Makefile.am
index dc2d717..aa940d2 100644
--- a/docs/reference/gcr/Makefile.am
+++ b/docs/reference/gcr/Makefile.am
@@ -75,6 +75,7 @@ IGNORE_HFILES= \
gcr-pkcs11-renderer.h \
gcr-record.h \
gcr-unlock-renderer.h \
+ gcr-viewer-window.h \
gcr-xxx.h \
gcr-zzz.h
@@ -82,10 +83,12 @@ IGNORE_HFILES= \
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES= \
$(srcdir)/images/certificate-widget.png \
- $(srcdir)/images/key-widget.png \
$(srcdir)/images/combo-selector.png \
+ $(srcdir)/images/import-button.png \
+ $(srcdir)/images/list-selector.png \
+ $(srcdir)/images/key-widget.png \
$(srcdir)/images/tree-selector.png \
- $(srcdir)/images/list-selector.png
+ $(srcdir)/images/viewer-widget.png
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
@@ -127,10 +130,12 @@ DISTCLEANFILES = tmpl/gcr-unused.sgml
WIDGETS = \
certificate-widget \
- key-widget \
combo-selector \
+ import-button \
+ key-widget \
+ list-selector \
tree-selector \
- list-selector
+ viewer-widget
shots: gcr-shooter
mkdir -p $(builddir)/images
diff --git a/docs/reference/gcr/gcr-docs.sgml b/docs/reference/gcr/gcr-docs.sgml
index 9e2f64d..8d0de72 100644
--- a/docs/reference/gcr/gcr-docs.sgml
+++ b/docs/reference/gcr/gcr-docs.sgml
@@ -35,10 +35,12 @@
<xi:include href="xml/gcr-key-widget.xml"/>
<xi:include href="xml/gcr-column.xml"/>
<xi:include href="xml/gcr-combo-selector.xml"/>
+ <xi:include href="xml/gcr-import-button.xml"/>
<xi:include href="xml/gcr-list-selector.xml"/>
<xi:include href="xml/gcr-tree-selector.xml"/>
<xi:include href="xml/gcr-renderer.xml"/>
<xi:include href="xml/gcr-viewer.xml"/>
+ <xi:include href="xml/gcr-viewer-widget.xml"/>
<chapter>
<title>Widget Gallery</title>
<xi:include href="gcr-visual-index.xml" />
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index 22e19b0..6f0fd8b 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -117,6 +117,24 @@ GcrPkcs11ImporterPrivate
</SECTION>
<SECTION>
+<FILE>gcr-import-button</FILE>
+GcrImportButton
+GcrImportButtonClass
+gcr_import_button_new
+gcr_import_button_add_parsed
+<SUBSECTION Standard>
+GCR_IMPORT_BUTTON
+GCR_IMPORT_BUTTON_CLASS
+GCR_IMPORT_BUTTON_GET_CLASS
+GCR_IS_IMPORT_BUTTON
+GCR_IS_IMPORT_BUTTON_CLASS
+gcr_import_button_get_type
+GCR_TYPE_IMPORT_BUTTON
+<SUBSECTION Private>
+GcrImportButtonPrivate
+</SECTION>
+
+<SECTION>
<FILE>gcr-simple-certificate</FILE>
<TITLE>GcrSimpleCertificate</TITLE>
GcrSimpleCertificate
@@ -523,20 +541,22 @@ GcrUnlockOptionsWidgetPrivate
</SECTION>
<SECTION>
-<FILE>gcr-viewer-window</FILE>
-GcrViewerWindow
-GcrViewerWindowClass
-gcr_viewer_window_new
-gcr_viewer_window_load
+<FILE>gcr-viewer-widget</FILE>
+GcrViewerWidget
+GcrViewerWidgetClass
+gcr_viewer_widget_new
+gcr_viewer_widget_load_data
+gcr_viewer_widget_load_file
+<SUBSECTION Standard>
+gcr_viewer_widget_get_type
+GCR_TYPE_VIEWER_WIDGET
+GCR_IS_VIEWER_WIDGET
+GCR_IS_VIEWER_WIDGET_CLASS
+GCR_VIEWER_WIDGET
+GCR_VIEWER_WIDGET_CLASS
+GCR_VIEWER_WIDGET_GET_CLASS
<SUBSECTION Private>
-gcr_viewer_window_get_type
-GcrViewerWindowPrivate
-GCR_IS_VIEWER_WINDOW
-GCR_IS_VIEWER_WINDOW_CLASS
-GCR_TYPE_VIEWER_WINDOW
-GCR_VIEWER_WINDOW
-GCR_VIEWER_WINDOW_CLASS
-GCR_VIEWER_WINDOW_GET_CLASS
+GcrViewerWidgetPrivate
</SECTION>
<SECTION>
diff --git a/docs/reference/gcr/gcr-widgets.c b/docs/reference/gcr/gcr-widgets.c
index 3f23bc5..d8458ed 100644
--- a/docs/reference/gcr/gcr-widgets.c
+++ b/docs/reference/gcr/gcr-widgets.c
@@ -177,6 +177,38 @@ create_list_selector (const gchar *name)
return gcr_shooter_info_new (name, align, GCR_SHOOTER_MEDIUM);
}
+static GcrShooterInfo *
+create_import_button (const gchar *name)
+{
+ GcrImportButton *import;
+ GtkWidget *align;
+
+ import = gcr_import_button_new ("Import");
+
+ align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (import));
+
+ return gcr_shooter_info_new (name, align, GCR_SHOOTER_MEDIUM);
+}
+
+static GcrShooterInfo *
+create_viewer_widget (const gchar *name)
+{
+ GcrViewerWidget *viewer;
+ GtkWidget *align;
+ gchar *contents;
+ gsize length;
+
+ contents = load_gcr_test_file ("email.p12", &length);
+ viewer = gcr_viewer_widget_new ();
+ gcr_viewer_widget_load_data (viewer, "Email certificate", (gpointer)contents, length);
+ g_free (contents);
+
+ align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (viewer));
+
+ return gcr_shooter_info_new (name, align, GCR_SHOOTER_LARGE);
+}
GcrShooterInfo*
gcr_widgets_create (const gchar *name)
@@ -185,14 +217,20 @@ gcr_widgets_create (const gchar *name)
if (g_str_equal (name, "certificate-widget"))
return create_certificate_widget (name);
- else if (g_str_equal (name, "key-widget"))
- return create_key_widget (name);
else if (g_str_equal (name, "combo-selector"))
return create_combo_selector (name);
- else if (g_str_equal (name, "tree-selector"))
- return create_tree_selector (name);
+ else if (g_str_equal (name, "import-button"))
+ return create_import_button (name);
+ else if (g_str_equal (name, "key-widget"))
+ return create_key_widget (name);
else if (g_str_equal (name, "list-selector"))
return create_list_selector (name);
+ else if (g_str_equal (name, "tree-selector"))
+ return create_tree_selector (name);
+ else if (g_str_equal (name, "viewer-widget"))
+ return create_viewer_widget (name);
+ else
+ g_assert_not_reached ();
return NULL;
}
diff --git a/docs/reference/gcr/gcr.types b/docs/reference/gcr/gcr.types
index a54679c..7838906 100644
--- a/docs/reference/gcr/gcr.types
+++ b/docs/reference/gcr/gcr.types
@@ -1,6 +1,23 @@
-gcr_parser_get_type
+gcr_certificate_chain_get_type
gcr_certificate_get_type
+gcr_certificate_renderer_get_type
+gcr_certificate_widget_get_type
+gcr_collection_get_type
+gcr_collection_model_get_type
+gcr_combo_selector_get_type
+gcr_comparable_get_type
+gcr_import_button_get_type
gcr_importer_get_type
-gcr_simple_certificate_get_type
+gcr_key_renderer_get_type
+gcr_key_widget_get_type
+gcr_list_selector_get_type
+gcr_parser_get_type
gcr_pkcs11_certificate_get_type
-gcr_certificate_chain_get_type
\ No newline at end of file
+gcr_renderer_get_type
+gcr_simple_certificate_get_type
+gcr_simple_collection_get_type
+gcr_tree_selector_get_type
+gcr_union_collection_get_type
+gcr_unlock_options_widget_get_type
+gcr_viewer_get_type
+gcr_viewer_widget_get_type
diff --git a/docs/reference/gcr/images/certificate-widget.png b/docs/reference/gcr/images/certificate-widget.png
index 1a82626..e3c9158 100644
Binary files a/docs/reference/gcr/images/certificate-widget.png and b/docs/reference/gcr/images/certificate-widget.png differ
diff --git a/docs/reference/gcr/images/import-button.png b/docs/reference/gcr/images/import-button.png
new file mode 100644
index 0000000..9166bb8
Binary files /dev/null and b/docs/reference/gcr/images/import-button.png differ
diff --git a/docs/reference/gcr/images/key-widget.png b/docs/reference/gcr/images/key-widget.png
index 938dbbf..db3a371 100644
Binary files a/docs/reference/gcr/images/key-widget.png and b/docs/reference/gcr/images/key-widget.png differ
diff --git a/docs/reference/gcr/images/viewer-widget.png b/docs/reference/gcr/images/viewer-widget.png
new file mode 100644
index 0000000..1933e04
Binary files /dev/null and b/docs/reference/gcr/images/viewer-widget.png differ
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 6494bc5..1f76297 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -49,7 +49,7 @@ HEADER_UI_FILES = \
gcr-tree-selector.h \
gcr-unlock-options-widget.h \
gcr-viewer.h \
- gcr-viewer-window.h
+ gcr-viewer-widget.h
incdir = $(includedir)/gcr- GCR_MAJOR@/gcr
@@ -102,12 +102,11 @@ libgcr_base_ GCR_MAJOR@_la_SOURCES = \
gcr-gnupg-process.c gcr-gnupg-process.h \
gcr-gnupg-records.c gcr-gnupg-records.h \
gcr-gnupg-util.c gcr-gnupg-util.h \
- gcr-library.c gcr-library.h \
gcr-importer.c gcr-importer.h \
gcr-internal.h \
+ gcr-library.c gcr-library.h \
gcr-memory.c \
gcr-memory-icon.c gcr-memory-icon.h \
- gcr-menu-button.c gcr-menu-button.h \
gcr-openpgp.c gcr-openpgp.h \
gcr-openssh.c gcr-openssh.h \
gcr-parser.c gcr-parser.h \
@@ -139,6 +138,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-gnupg-renderer.c gcr-gnupg-renderer.h \
gcr-gnupg-records.c gcr-gnupg-records.h \
gcr-icons.c gcr-icons.h \
+ gcr-import-button.c gcr-import-button.h \
gcr-import-dialog.c gcr-import-dialog.h \
gcr-key-renderer.c gcr-key-renderer.h \
gcr-key-widget.c gcr-key-widget.h \
@@ -146,6 +146,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-live-search.c gcr-live-search.h \
gcr-memory.c \
gcr-memory-icon.c gcr-memory-icon.h \
+ gcr-menu-button.c gcr-menu-button.h \
gcr-record.c gcr-record.h \
gcr-renderer.c gcr-renderer.h \
gcr-tree-selector.c gcr-tree-selector.h \
@@ -153,7 +154,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
gcr-unlock-renderer.c gcr-unlock-renderer.h \
gcr-viewer.c gcr-viewer.h \
- gcr-viewer-window.c \
+ gcr-viewer-widget.c gcr-viewer-widget.h \
$(BUILT_UI_FILES)
libgcr_base_ GCR_MAJOR@_la_CFLAGS = \
@@ -270,11 +271,13 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
bin_PROGRAMS = gcr-viewer
gcr_viewer_SOURCES = \
- gcr-viewer-tool.c
+ gcr-viewer-tool.c \
+ gcr-viewer-window.c gcr-viewer-window.h
gcr_viewer_CFLAGS = \
$(GTK_CFLAGS) \
- -DLOCALEDIR=\""$(datadir)/locale"\"
+ -DLOCALEDIR=\""$(datadir)/locale"\" \
+ -DGCR_API_SUBJECT_TO_CHANGE
gcr_viewer_LDADD = \
$(builddir)/libgcr-$(GCR_MAJOR).la \
diff --git a/gcr/gcr-base.h b/gcr/gcr-base.h
index f70720b..54cc629 100644
--- a/gcr/gcr-base.h
+++ b/gcr/gcr-base.h
@@ -39,6 +39,7 @@
#include "gcr-deprecated-base.h"
#include "gcr-enum-types-base.h"
#include "gcr-icons.h"
+#include "gcr-importer.h"
#include "gcr-library.h"
#include "gcr-parser.h"
#include "gcr-pkcs11-certificate.h"
diff --git a/gcr/gcr-collection-model.c b/gcr/gcr-collection-model.c
index e46bf51..c5ebe07 100644
--- a/gcr/gcr-collection-model.c
+++ b/gcr/gcr-collection-model.c
@@ -55,7 +55,6 @@
/**
* GcrCollectionModel:
- * @parent: The parent object
*
* A #GtkTreeModel which contains a row for each object in a #GcrCollection.
*/
diff --git a/gcr/gcr-combo-selector.c b/gcr/gcr-combo-selector.c
index 91328a2..6811139 100644
--- a/gcr/gcr-combo-selector.c
+++ b/gcr/gcr-combo-selector.c
@@ -40,7 +40,6 @@
/**
* GcrComboSelector:
- * @parent: Parent object
*
* A combo selector widget.
*/
diff --git a/gcr/gcr-failure-renderer.c b/gcr/gcr-failure-renderer.c
index b6f829f..8417307 100644
--- a/gcr/gcr-failure-renderer.c
+++ b/gcr/gcr-failure-renderer.c
@@ -42,30 +42,30 @@ struct _GcrFailureRendererPrivate {
static void gcr_renderer_iface_init (GcrRendererIface *iface);
-G_DEFINE_TYPE_WITH_CODE (GcrFailureRenderer, _gcr_failure_renderer, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (GcrFailureRenderer, gcr_failure_renderer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
);
static void
-_gcr_failure_renderer_init (GcrFailureRenderer *self)
+gcr_failure_renderer_init (GcrFailureRenderer *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_FAILURE_RENDERER,
GcrFailureRendererPrivate));
}
static void
-_gcr_failure_renderer_finalize (GObject *obj)
+gcr_failure_renderer_finalize (GObject *obj)
{
GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
g_error_free (self->pv->error);
g_free (self->pv->label);
- G_OBJECT_CLASS (_gcr_failure_renderer_parent_class)->finalize (obj);
+ G_OBJECT_CLASS (gcr_failure_renderer_parent_class)->finalize (obj);
}
static void
-_gcr_failure_renderer_set_property (GObject *obj,
+gcr_failure_renderer_set_property (GObject *obj,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
@@ -88,7 +88,7 @@ _gcr_failure_renderer_set_property (GObject *obj,
}
static void
-_gcr_failure_renderer_get_property (GObject *obj,
+gcr_failure_renderer_get_property (GObject *obj,
guint prop_id,
GValue *value,
GParamSpec *pspec)
@@ -109,28 +109,28 @@ _gcr_failure_renderer_get_property (GObject *obj,
}
static void
-_gcr_failure_renderer_class_init (GcrFailureRendererClass *klass)
+gcr_failure_renderer_class_init (GcrFailureRendererClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (GcrFailureRendererPrivate));
- gobject_class->finalize = _gcr_failure_renderer_finalize;
- gobject_class->set_property = _gcr_failure_renderer_set_property;
- gobject_class->get_property = _gcr_failure_renderer_get_property;
+ gobject_class->finalize = gcr_failure_renderer_finalize;
+ gobject_class->set_property = gcr_failure_renderer_set_property;
+ gobject_class->get_property = gcr_failure_renderer_get_property;
g_object_class_install_property (gobject_class, PROP_LABEL,
g_param_spec_string ("label", "Label", "Failure Label",
"", G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
+ g_param_spec_boxed ("attributes", "Attributes", "Renderer attributes",
GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
}
static void
gcr_failure_renderer_render (GcrRenderer *renderer,
- GcrViewer *viewer)
+ GcrViewer *viewer)
{
GcrFailureRenderer *self = GCR_FAILURE_RENDERER (renderer);
GcrDisplayView *view;
@@ -178,8 +178,8 @@ gcr_renderer_iface_init (GcrRendererIface *iface)
}
GcrRenderer *
-_gcr_failure_renderer_new (const gchar *label,
- GError *error)
+gcr_failure_renderer_new (const gchar *label,
+ GError *error)
{
GcrFailureRenderer *renderer;
@@ -192,7 +192,7 @@ _gcr_failure_renderer_new (const gchar *label,
}
GcrRenderer *
-_gcr_failure_renderer_new_unsupported (const gchar *label)
+gcr_failure_renderer_new_unsupported (const gchar *label)
{
GcrRenderer *renderer;
GError *error;
@@ -200,7 +200,7 @@ _gcr_failure_renderer_new_unsupported (const gchar *label)
error = g_error_new (GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
_("Cannot display a file of this type."));
- renderer = _gcr_failure_renderer_new (label, error);
+ renderer = gcr_failure_renderer_new (label, error);
g_error_free (error);
return renderer;
diff --git a/gcr/gcr-failure-renderer.h b/gcr/gcr-failure-renderer.h
index 0e8311e..9b70f36 100644
--- a/gcr/gcr-failure-renderer.h
+++ b/gcr/gcr-failure-renderer.h
@@ -30,11 +30,10 @@
#include <gtk/gtk.h>
#include "gcr-renderer.h"
-#include "gcr-types.h"
G_BEGIN_DECLS
-#define GCR_TYPE_FAILURE_RENDERER (_gcr_failure_renderer_get_type ())
+#define GCR_TYPE_FAILURE_RENDERER (gcr_failure_renderer_get_type ())
#define GCR_FAILURE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_FAILURE_RENDERER, GcrFailureRenderer))
#define GCR_FAILURE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_FAILURE_RENDERER, GcrFailureRendererClass))
#define GCR_IS_FAILURE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_FAILURE_RENDERER))
@@ -56,12 +55,12 @@ struct _GcrFailureRendererClass {
GObjectClass parent_class;
};
-GType _gcr_failure_renderer_get_type (void);
+GType gcr_failure_renderer_get_type (void);
-GcrRenderer * _gcr_failure_renderer_new (const gchar *label,
- GError *error);
+GcrRenderer * gcr_failure_renderer_new (const gchar *label,
+ GError *error);
-GcrRenderer * _gcr_failure_renderer_new_unsupported (const gchar *label);
+GcrRenderer * gcr_failure_renderer_new_unsupported (const gchar *label);
G_END_DECLS
diff --git a/gcr/gcr-gnupg-process.c b/gcr/gcr-gnupg-process.c
index 0e87ea9..81423da 100644
--- a/gcr/gcr-gnupg-process.c
+++ b/gcr/gcr-gnupg-process.c
@@ -81,6 +81,7 @@ typedef struct _GnupgSource {
GByteArray *input_buf;
GString *error_buf;
GString *status_buf;
+ guint source_sig;
GPid child_pid;
guint child_sig;
@@ -101,8 +102,6 @@ struct _GcrGnupgProcessPrivate {
gboolean complete;
GError *error;
- guint source_sig;
-
GAsyncReadyCallback async_callback;
gpointer user_data;
};
@@ -458,11 +457,6 @@ complete_run_process (GcrGnupgProcess *self)
self->pv->running = FALSE;
self->pv->complete = TRUE;
- if (self->pv->source_sig) {
- g_source_remove (self->pv->source_sig);
- self->pv->source_sig = 0;
- }
-
if (self->pv->error == NULL) {
_gcr_debug ("completed process");
} else {
@@ -472,20 +466,13 @@ complete_run_process (GcrGnupgProcess *self)
}
static gboolean
-complete_if_source_is_done (GnupgSource *gnupg_source)
+complete_source_is_done (GnupgSource *gnupg_source)
{
- gint i;
-
- for (i = 0; i < NUM_FDS; ++i) {
- if (gnupg_source->polls[i].fd >= 0)
- return FALSE;
- }
-
- if (gnupg_source->child_pid)
- return FALSE;
-
_gcr_debug ("all fds closed and process exited, completing");
+ g_assert (gnupg_source->child_sig == 0);
+ g_assert (gnupg_source->source_sig == 0);
+
complete_run_process (gnupg_source->process);
run_async_ready_callback (gnupg_source->process);
@@ -772,6 +759,7 @@ on_gnupg_source_dispatch (GSource *source, GSourceFunc unused, gpointer user_dat
GnupgSource *gnupg_source = (GnupgSource*)source;
GcrGnupgProcess *self = gnupg_source->process;
GPollFD *poll;
+ guint i;
/* Standard input, no support yet */
poll = &gnupg_source->polls[FD_INPUT];
@@ -829,10 +817,18 @@ on_gnupg_source_dispatch (GSource *source, GSourceFunc unused, gpointer user_dat
poll->revents = 0;
}
- if (complete_if_source_is_done (gnupg_source))
- return FALSE; /* Disconnect this source */
+ for (i = 0; i < NUM_FDS; ++i) {
+ if (gnupg_source->polls[i].fd >= 0)
+ return TRUE;
+ }
- return TRUE;
+ /* Because we return below */
+ gnupg_source->source_sig = 0;
+
+ if (!gnupg_source->child_pid)
+ complete_source_is_done (gnupg_source);
+
+ return FALSE; /* Disconnect this source */
}
static GSourceFuncs gnupg_source_funcs = {
@@ -849,6 +845,7 @@ on_gnupg_process_child_exited (GPid pid, gint status, gpointer user_data)
GcrGnupgProcess *self = gnupg_source->process;
GError *error = NULL;
gint code;
+ guint i;
_gcr_debug ("process exited: %d", (int)pid);
@@ -881,7 +878,12 @@ on_gnupg_process_child_exited (GPid pid, gint status, gpointer user_data)
g_error_free (error);
}
- complete_if_source_is_done (gnupg_source);
+ for (i = 0; i < NUM_FDS; ++i) {
+ if (gnupg_source->polls[i].fd >= 0)
+ return;
+ }
+
+ complete_source_is_done (gnupg_source);
}
static void
@@ -913,19 +915,17 @@ on_cancellable_cancelled (GCancellable *cancellable, gpointer user_data)
_gcr_debug ("process cancelled");
+ /* Set an error, which is respected when this actually completes. */
+ if (gnupg_source->process->pv->error == NULL)
+ gnupg_source->process->pv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ _("The operation was cancelled"));
+
/* Try and kill the child process */
if (gnupg_source->child_pid) {
_gcr_debug ("sending term signal to process: %d",
(int)gnupg_source->child_pid);
kill (gnupg_source->child_pid, SIGTERM);
}
-
- /* Set an error, which is respected when this actually completes. */
- if (gnupg_source->process->pv->error == NULL)
- gnupg_source->process->pv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("The operation was cancelled"));
-
- complete_if_source_is_done (gnupg_source);
}
/**
@@ -1108,9 +1108,8 @@ _gcr_gnupg_process_run_async (GcrGnupgProcess *self, const gchar **argv, const g
(GDestroyNotify)g_source_unref);
}
- g_assert (!self->pv->source_sig);
g_source_set_callback (source, unused_callback, NULL, NULL);
- self->pv->source_sig = g_source_attach (source, g_main_context_default ());
+ gnupg_source->source_sig = g_source_attach (source, g_main_context_default ());
/* This assumes the outstanding reference to source */
g_assert (!gnupg_source->child_sig);
@@ -1147,7 +1146,6 @@ _gcr_gnupg_process_run_finish (GcrGnupgProcess *self, GAsyncResult *result,
g_assert (!self->pv->running);
g_assert (!self->pv->async_callback);
g_assert (!self->pv->user_data);
- g_assert (!self->pv->source_sig);
if (self->pv->error) {
g_propagate_error (error, self->pv->error);
diff --git a/gcr/gcr-import-button.c b/gcr/gcr-import-button.c
new file mode 100644
index 0000000..15bd961
--- /dev/null
+++ b/gcr/gcr-import-button.c
@@ -0,0 +1,485 @@
+/*
+ * 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-import-button.h"
+#include "gcr-internal.h"
+#include "gcr-marshal.h"
+#include "gcr-parser.h"
+
+#include <glib/gi18n-lib.h>
+
+enum {
+ PROP_0,
+ PROP_LABEL
+};
+
+/**
+ * SECTION:gcr-import-button
+ * @title: GcrImportButton
+ * @short_description: Button which imports parsed certificates and keys
+ *
+ * A button which imports keys and certificates. Shows a spinner when the
+ * button is activated. When more than one importer is available shows
+ * a drop down to select which to import to.
+ */
+
+/**
+ * GcrImportButton:
+ *
+ * Button which imports parsed certificates and keys.
+ */
+
+/**
+ * GcrImportButtonClass:
+ * @parent_class: The parent class
+ * @imported: Emitted when the import completes, or fails.
+ *
+ * Class for #GcrImportButton.
+ */
+
+struct _GcrImportButtonPrivate {
+ GList *importers;
+ gboolean created;
+ gboolean importing;
+ gchar *imported;
+ GtkWidget *spinner;
+ GtkWidget *arrow;
+ GtkWidget *label;
+ GCancellable *cancellable;
+ GtkMenu *menu;
+};
+
+enum {
+ IMPORTED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GQuark QUARK_IMPORTER = 0;
+
+G_DEFINE_TYPE (GcrImportButton, gcr_import_button, GTK_TYPE_BUTTON);
+
+static void
+gcr_import_button_init (GcrImportButton *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_IMPORT_BUTTON, GcrImportButtonPrivate);
+ self->pv->cancellable = g_cancellable_new ();
+ self->pv->label = gtk_label_new ("");
+}
+
+static void
+gcr_import_button_constructed (GObject *obj)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
+ GtkWidget *grid;
+
+ G_OBJECT_CLASS (gcr_import_button_parent_class)->constructed (obj);
+
+ self->pv->spinner = gtk_spinner_new ();
+ self->pv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ grid = gtk_grid_new ();
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_HORIZONTAL);
+ gtk_container_add (GTK_CONTAINER (grid), self->pv->spinner);
+ gtk_container_add (GTK_CONTAINER (grid), self->pv->label);
+ gtk_container_add (GTK_CONTAINER (grid), self->pv->arrow);
+ gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
+ gtk_widget_set_hexpand (grid, TRUE);
+ gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
+
+ gtk_widget_show (self->pv->label);
+ gtk_widget_show (grid);
+
+ gtk_container_add (GTK_CONTAINER (self), grid);
+}
+
+static void
+gcr_import_button_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ gtk_label_set_label (GTK_LABEL (self->pv->label), g_value_get_string (value));
+ g_object_notify (obj, "label");
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_import_button_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_set_string (value, gtk_label_get_label (GTK_LABEL (self->pv->label)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_import_button_dispose (GObject *obj)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
+
+ gck_list_unref_free (self->pv->importers);
+ self->pv->importers = NULL;
+ g_cancellable_cancel (self->pv->cancellable);
+ g_clear_object (&self->pv->menu);
+
+ G_OBJECT_CLASS (gcr_import_button_parent_class)->dispose (obj);
+}
+
+static void
+gcr_import_button_finalize (GObject *obj)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
+
+ g_object_unref (self->pv->cancellable);
+
+ G_OBJECT_CLASS (gcr_import_button_parent_class)->finalize (obj);
+}
+
+static void
+update_import_button (GcrImportButton *self)
+{
+ gchar *message;
+ gchar *label;
+
+ /* Importing, set a spinner */
+ if (self->pv->importing) {
+ gtk_widget_show (self->pv->spinner);
+ gtk_widget_hide (self->pv->arrow);
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Import is in progress..."));
+
+ } else if (self->pv->imported) {
+ gtk_widget_hide (self->pv->spinner);
+ gtk_widget_hide (self->pv->arrow);
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ message = g_strdup_printf (_("Imported to: %s"), self->pv->imported);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), message);
+ g_free (message);
+
+ /* Not importing, but have importers */
+ } else if (self->pv->importers) {
+ gtk_widget_hide (self->pv->spinner);
+ gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
+
+ /* More than one importer */
+ if (self->pv->importers->next) {
+ gtk_widget_show (self->pv->arrow);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), NULL);
+
+ /* Only one importer */
+ } else {
+ gtk_widget_hide (self->pv->arrow);
+ g_object_get (self->pv->importers->data, "label", &label, NULL);
+ message = g_strdup_printf (_("Import to: %s"), label);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), message);
+ g_free (message);
+ g_free (label);
+ }
+
+ /* No importers, none compatible */
+ } else if (self->pv->created) {
+ gtk_widget_hide (self->pv->spinner);
+ gtk_widget_hide (self->pv->arrow);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Cannot import because there are no compatible importers"));
+
+ /* No importers yet added */
+ } else {
+ gtk_widget_hide (self->pv->spinner);
+ gtk_widget_hide (self->pv->arrow);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("No data to import"));
+ }
+}
+
+static void
+on_import_complete (GObject *importer,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
+ GError *error = NULL;
+
+ g_return_if_fail (self->pv->imported == NULL);
+
+ self->pv->importing = FALSE;
+
+ gcr_importer_import_finish (GCR_IMPORTER (importer), result, &error);
+ if (error == NULL) {
+ g_object_get (importer, "label", &self->pv->imported, NULL);
+ gck_list_unref_free (self->pv->importers);
+ self->pv->importers = NULL;
+ }
+
+ g_signal_emit (self, signals[IMPORTED], 0, importer, error);
+ g_clear_error (&error);
+
+ update_import_button (self);
+}
+
+static void
+begin_import (GcrImportButton *self,
+ GcrImporter *importer)
+{
+ g_return_if_fail (self->pv->importing == FALSE);
+
+ self->pv->importing = TRUE;
+ g_free (self->pv->imported);
+ self->pv->imported = NULL;
+
+ gcr_importer_import_async (importer,
+ self->pv->cancellable,
+ on_import_complete,
+ g_object_ref (self));
+}
+
+static void
+on_importer_menu_activated (GtkMenuItem *menu_item,
+ gpointer user_data)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
+ GcrImporter *importer;
+
+ importer = g_object_get_qdata (G_OBJECT (menu_item), QUARK_IMPORTER);
+ g_return_if_fail (GCR_IMPORTER (importer));
+ g_return_if_fail (self->pv->importing == FALSE);
+
+ begin_import (self, importer);
+ update_import_button (self);
+}
+
+static void
+update_importer_menu (GcrImportButton *self)
+{
+ GtkWidget *menu_item;
+ GtkWidget *image;
+ GList *children, *l;
+ GIcon *icon;
+ gchar *label;
+
+ if (!self->pv->menu) {
+ self->pv->menu = GTK_MENU (gtk_menu_new ());
+ g_object_ref_sink (self->pv->menu);
+ }
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->pv->menu));
+ for (l = children; l != NULL; l = g_list_next (l))
+ gtk_container_remove (GTK_CONTAINER (self->pv->menu), l->data);
+ g_list_free (children);
+
+ for (l = self->pv->importers; l != NULL; l = g_list_next (l)) {
+ g_object_get (l->data, "label", &label, "icon", &icon, NULL);
+ menu_item = gtk_image_menu_item_new_with_label (label);
+ g_signal_connect (menu_item, "activate", G_CALLBACK (on_importer_menu_activated), self);
+ g_object_set_qdata (G_OBJECT (menu_item), QUARK_IMPORTER, l->data);
+ image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
+ gtk_widget_show (image);
+ gtk_widget_show (menu_item);
+ gtk_container_add (GTK_CONTAINER (self->pv->menu), menu_item);
+ g_object_unref (icon);
+ g_free (label);
+ }
+}
+
+static void
+on_menu_position (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
+ GtkWidget *widget = GTK_WIDGET (self);
+ GtkAllocation allocation;
+ GtkRequisition menu_req;
+ GdkRectangle monitor;
+ GdkWindow *window;
+ GtkWidget *toplevel;
+ GdkScreen *screen;
+ gint monitor_num;
+ gint sx = 0;
+ gint sy = 0;
+
+ g_return_if_fail (x != NULL);
+ g_return_if_fail (y != NULL);
+ g_return_if_fail (push_in != NULL);
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ if (!gtk_widget_get_has_window (widget)) {
+ sx += allocation.x;
+ sy += allocation.y;
+ }
+
+ window = gtk_widget_get_window (widget);
+ gdk_window_get_root_coords (window, sx, sy, &sx, &sy);
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &menu_req);
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ *x = sx;
+ else
+ *x = sx + allocation.width - menu_req.width;
+ *y = sy;
+
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen, window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ if (*x < monitor.x)
+ *x = monitor.x;
+ else if (*x + menu_req.width > monitor.x + monitor.width)
+ *x = monitor.x + monitor.width - menu_req.width;
+
+ if (monitor.y + monitor.height - *y - allocation.height >= menu_req.height)
+ *y += allocation.height;
+ else if (*y - monitor.y >= menu_req.height)
+ *y -= menu_req.height;
+ else if (monitor.y + monitor.height - *y - allocation.height > *y - monitor.y)
+ *y += allocation.height;
+ else
+ *y -= menu_req.height;
+
+ gtk_menu_set_monitor (menu, monitor_num);
+
+ toplevel = gtk_widget_get_parent (GTK_WIDGET (menu));
+ if (GTK_IS_WINDOW (toplevel) && gtk_widget_get_visible (toplevel))
+ gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
+
+ *push_in = FALSE;
+}
+
+static void
+gcr_import_button_clicked (GtkButton *button)
+{
+ GcrImportButton *self = GCR_IMPORT_BUTTON (button);
+
+ g_return_if_fail (self->pv->importing == FALSE);
+ g_return_if_fail (self->pv->importers != NULL);
+
+ /* More than one importer, show the menu */
+ if (self->pv->importers->next) {
+ update_importer_menu (self);
+ gtk_menu_popup (self->pv->menu, NULL, NULL, on_menu_position,
+ self, 1, gtk_get_current_event_time ());
+
+ /* Only one importer, import on click */
+ } else {
+ begin_import (self, self->pv->importers->data);
+ }
+
+ update_import_button (self);
+}
+
+static void
+gcr_import_button_class_init (GcrImportButtonClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
+
+ gobject_class->constructed = gcr_import_button_constructed;
+ gobject_class->dispose = gcr_import_button_dispose;
+ gobject_class->finalize = gcr_import_button_finalize;
+ gobject_class->get_property = gcr_import_button_get_property;
+ gobject_class->set_property = gcr_import_button_set_property;
+
+ button_class->clicked = gcr_import_button_clicked;
+
+ g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+
+ /**
+ * GcrImportButton::imported:
+ * @self: the import button
+ * @importer: the importer that was imported to
+ * @error: if import was successful %NULL, or an error
+ *
+ * Signal emitted when an import completes or fails.
+ */
+ signals[IMPORTED] = g_signal_new ("imported", GCR_TYPE_IMPORT_BUTTON, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrImportButtonClass, imported),
+ NULL, NULL, _gcr_marshal_VOID__OBJECT_BOXED,
+ G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_ERROR);
+
+ QUARK_IMPORTER = g_quark_from_static_string ("gcr-import-button-importer");
+
+ g_type_class_add_private (klass, sizeof (GcrImportButtonPrivate));
+}
+
+GcrImportButton*
+gcr_import_button_new (const gchar *label)
+{
+ return g_object_new (GCR_TYPE_IMPORT_BUTTON,
+ "label", label,
+ NULL);
+}
+
+void
+gcr_import_button_add_parsed (GcrImportButton *self,
+ GcrParser *parser)
+{
+ GList *importers;
+
+ g_return_if_fail (GCR_IS_IMPORT_BUTTON (self));
+ g_return_if_fail (GCR_IS_PARSER (parser));
+
+ g_free (self->pv->imported);
+ self->pv->imported = NULL;
+
+ if (self->pv->created) {
+ importers = gcr_importer_queue_and_filter_for_parsed (self->pv->importers, parser);
+ } else {
+ importers = gcr_importer_create_for_parsed (parser);
+ self->pv->created = TRUE;
+ }
+
+ gck_list_unref_free (self->pv->importers);
+ self->pv->importers = importers;
+
+ update_import_button (self);
+}
diff --git a/gcr/gcr-import-button.h b/gcr/gcr-import-button.h
new file mode 100644
index 0000000..35b116c
--- /dev/null
+++ b/gcr/gcr-import-button.h
@@ -0,0 +1,68 @@
+/*
+ * 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>
+ */
+
+#ifndef __GCR_IMPORT_BUTTON_H__
+#define __GCR_IMPORT_BUTTON_H__
+
+#include "gcr.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_IMPORT_BUTTON (gcr_import_button_get_type ())
+#define GCR_IMPORT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORT_BUTTON, GcrImportButton))
+#define GCR_IMPORT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_IMPORT_BUTTON, GcrImportButtonClass))
+#define GCR_IS_IMPORT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORT_BUTTON))
+#define GCR_IS_IMPORT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_IMPORT_BUTTON))
+#define GCR_IMPORT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_IMPORT_BUTTON, GcrImportButtonClass))
+
+typedef struct _GcrImportButton GcrImportButton;
+typedef struct _GcrImportButtonClass GcrImportButtonClass;
+typedef struct _GcrImportButtonPrivate GcrImportButtonPrivate;
+
+struct _GcrImportButton {
+ GtkButton parent;
+
+ /*< private >*/
+ GcrImportButtonPrivate *pv;
+};
+
+struct _GcrImportButtonClass {
+ GtkButtonClass parent_class;
+
+ void (*imported) (GcrImportButton *self,
+ GcrImporter *importer,
+ GError *error);
+};
+
+GType gcr_import_button_get_type (void) G_GNUC_CONST;
+
+GcrImportButton * gcr_import_button_new (const gchar *label);
+
+void gcr_import_button_add_parsed (GcrImportButton *button,
+ GcrParser *parser);
+
+G_END_DECLS
+
+#endif /* __GCR_IMPORT_BUTTON_H__ */
diff --git a/gcr/gcr-list-selector.c b/gcr/gcr-list-selector.c
index b7e6beb..aacde0f 100644
--- a/gcr/gcr-list-selector.c
+++ b/gcr/gcr-list-selector.c
@@ -45,7 +45,6 @@
/**
* GcrListSelector:
- * @parent: Parent object
*
* A list selector widget.
*/
diff --git a/gcr/gcr-marshal.list b/gcr/gcr-marshal.list
index 09f114f..5e36589 100644
--- a/gcr/gcr-marshal.list
+++ b/gcr/gcr-marshal.list
@@ -3,3 +3,5 @@ BOOLEAN:BOXED
VOID:STRING,BOXED
VOID:BOXED
VOID:STRING
+VOID:OBJECT,BOXED
+VOID:OBJECT,OBJECT
diff --git a/gcr/gcr-pkcs11-importer.c b/gcr/gcr-pkcs11-importer.c
index 714e13a..29a2972 100644
--- a/gcr/gcr-pkcs11-importer.c
+++ b/gcr/gcr-pkcs11-importer.c
@@ -332,7 +332,7 @@ calculate_icon (GcrPkcs11Importer *self)
info = gck_slot_get_token_info (self->pv->slot);
if (g_strcmp0 (info->manufacturer_id, "Gnome Keyring") == 0)
- result = g_themed_icon_new ("home-folder");
+ result = g_themed_icon_new ("user-home");
else
result = g_themed_icon_new ("media-flash");
gck_token_info_free (info);
diff --git a/gcr/gcr-simple-collection.c b/gcr/gcr-simple-collection.c
index 05c17ae..2ac411a 100644
--- a/gcr/gcr-simple-collection.c
+++ b/gcr/gcr-simple-collection.c
@@ -40,7 +40,6 @@
/**
* GcrSimpleCollection:
- * @parent: The parent object
*
* A simple implementation of #GcrCollection.
*/
diff --git a/gcr/gcr-tree-selector.c b/gcr/gcr-tree-selector.c
index 11836b4..5cb2556 100644
--- a/gcr/gcr-tree-selector.c
+++ b/gcr/gcr-tree-selector.c
@@ -40,7 +40,6 @@
/**
* GcrTreeSelector:
- * @parent: The parent object
*
* A tree selector widget.
*/
diff --git a/gcr/gcr-union-collection.c b/gcr/gcr-union-collection.c
index 55e1785..dca7614 100644
--- a/gcr/gcr-union-collection.c
+++ b/gcr/gcr-union-collection.c
@@ -41,7 +41,6 @@
/**
* GcrUnionCollection:
- * @parent: The parent object
*
* A union implementation of #GcrCollection.
*/
diff --git a/gcr/gcr-unlock-renderer.c b/gcr/gcr-unlock-renderer.c
index 9d15678..4615057 100644
--- a/gcr/gcr-unlock-renderer.c
+++ b/gcr/gcr-unlock-renderer.c
@@ -50,6 +50,13 @@ struct _GcrUnlockRendererPrivate {
gint no_destroy;
};
+enum {
+ UNLOCK_CLICKED,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
static void gcr_renderer_iface_init (GcrRendererIface *iface);
G_DEFINE_TYPE_WITH_CODE (GcrUnlockRenderer, _gcr_unlock_renderer, GTK_TYPE_ALIGNMENT,
@@ -65,42 +72,15 @@ calculate_label (GcrUnlockRenderer *self)
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)
+void
+_gcr_unlock_renderer_show_warning (GcrUnlockRenderer *self,
+ const gchar *message)
{
gchar *text;
+ g_return_if_fail (GCR_UNLOCK_RENDERER (self));
+ g_return_if_fail (message != NULL);
+
text = g_strdup_printf ("<i>%s</i>", message);
gtk_label_set_markup (self->pv->warning, text);
g_free (text);
@@ -113,34 +93,7 @@ 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));
+ g_signal_emit (self, signals[UNLOCK_CLICKED], 0);
}
static void
@@ -265,6 +218,10 @@ _gcr_unlock_renderer_class_init (GcrUnlockRendererClass *klass)
g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+
+ signals[UNLOCK_CLICKED] = g_signal_new ("unlock-clicked", GCR_TYPE_UNLOCK_RENDERER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrUnlockRendererClass, unlock_clicked),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
static void
@@ -363,7 +320,26 @@ _gcr_unlock_renderer_new_for_parsed (GcrParser *parser)
gconstpointer block;
gsize n_block;
+ g_return_val_if_fail (GCR_IS_PARSER (parser), NULL);
+
block = gcr_parser_get_parsed_block (parser, &n_block);
return _gcr_unlock_renderer_new (gcr_parser_get_parsed_label (parser),
block, n_block);
}
+
+const gchar *
+_gcr_unlock_renderer_get_password (GcrUnlockRenderer *self)
+{
+ g_return_val_if_fail (GCR_IS_UNLOCK_RENDERER (self), NULL);
+ return gtk_entry_get_text (self->pv->entry);
+}
+
+gconstpointer
+_gcr_unlock_renderer_get_locked_data (GcrUnlockRenderer *self,
+ gsize *n_data)
+{
+ g_return_val_if_fail (GCR_IS_UNLOCK_RENDERER (self), NULL);
+ g_return_val_if_fail (n_data != NULL, NULL);
+ *n_data = self->pv->n_locked_data;
+ return self->pv->locked_data;
+}
diff --git a/gcr/gcr-unlock-renderer.h b/gcr/gcr-unlock-renderer.h
index 739133a..bc695b1 100644
--- a/gcr/gcr-unlock-renderer.h
+++ b/gcr/gcr-unlock-renderer.h
@@ -52,8 +52,10 @@ struct _GcrUnlockRenderer {
};
struct _GcrUnlockRendererClass {
- /*< private >*/
GtkAlignmentClass parent_class;
+
+ /* signals */
+ void (*unlock_clicked) (GcrUnlockRenderer *unlock);
};
GType _gcr_unlock_renderer_get_type (void);
@@ -64,6 +66,14 @@ GcrUnlockRenderer * _gcr_unlock_renderer_new (const gchar *labe
GcrUnlockRenderer * _gcr_unlock_renderer_new_for_parsed (GcrParser *parser);
+const gchar * _gcr_unlock_renderer_get_password (GcrUnlockRenderer *self);
+
+void _gcr_unlock_renderer_show_warning (GcrUnlockRenderer *self,
+ const gchar *message);
+
+gconstpointer _gcr_unlock_renderer_get_locked_data (GcrUnlockRenderer *self,
+ gsize *n_data);
+
G_END_DECLS
#endif /* __GCR_UNLOCK_RENDERER_H__ */
diff --git a/gcr/gcr-viewer-tool.c b/gcr/gcr-viewer-tool.c
index 2b0e260..85205ca 100644
--- a/gcr/gcr-viewer-tool.c
+++ b/gcr/gcr-viewer-tool.c
@@ -61,7 +61,7 @@ on_idle_load_files (gpointer user_data)
if (remaining_args) {
for (i = 0; remaining_args[i] != NULL; ++i) {
file = g_file_new_for_commandline_arg (remaining_args[i]);
- gcr_viewer_window_load (window, file);
+ _gcr_viewer_window_load (window, file);
g_object_unref (file);
}
@@ -85,7 +85,7 @@ main (int argc, char *argv[])
{
GOptionContext *context;
GError *error = NULL;
- GcrViewerWindow *window;
+ GtkWindow *window;
g_type_init ();
g_thread_init (NULL);
@@ -119,7 +119,7 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
- window = gcr_viewer_window_new ();
+ window = _gcr_viewer_window_new ();
gtk_widget_show (GTK_WIDGET (window));
g_idle_add (on_idle_load_files, window);
diff --git a/gcr/gcr-viewer-widget.c b/gcr/gcr-viewer-widget.c
new file mode 100644
index 0000000..a4bf8c6
--- /dev/null
+++ b/gcr/gcr-viewer-widget.c
@@ -0,0 +1,436 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gcr-viewer-widget: Widget for viewer
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. 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-display-scrolled.h"
+#include "gcr-failure-renderer.h"
+#include "gcr-importer.h"
+#include "gcr-marshal.h"
+#include "gcr-parser.h"
+#include "gcr-renderer.h"
+#include "gcr-unlock-renderer.h"
+#include "gcr-viewer-widget.h"
+#include "gcr-viewer.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <locale.h>
+#include <string.h>
+
+/**
+ * SECTION:gcr-viewer-widget
+ * @title: GcrViewerWidget
+ * @short_description: A widget which shows certificates or keys
+ *
+ * A viewer widget which can display certificates and keys that are
+ * located in files.
+ */
+
+/**
+ * GcrViewerWidget:
+ *
+ * A viewer widget object.
+ */
+
+/**
+ * GcrViewerWidgetClass:
+ *
+ * Class for #GcrViewerWidget
+ */
+
+/*
+ * Not yet figured out how to expose these without locking down our
+ * implementation, the parent class we derive from.
+ */
+
+struct _GcrViewerWidget {
+ /*< private >*/
+ GcrDisplayScrolled parent;
+ GcrViewerWidgetPrivate *pv;
+};
+
+struct _GcrViewerWidgetClass {
+ GcrDisplayScrolledClass parent_class;
+
+ void (*added) (GcrViewerWidget *widget,
+ GcrRenderer *renderer,
+ GcrParser *parser);
+};
+
+struct _GcrViewerWidgetPrivate {
+ GQueue *files_to_load;
+ GcrParser *parser;
+ GCancellable *cancellable;
+ GList *unlocks;
+ gboolean loading;
+ gchar *display_name;
+};
+
+enum {
+ ADDED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static void viewer_load_next_file (GcrViewerWidget *self);
+static void viewer_stop_loading_files (GcrViewerWidget *self);
+
+G_DEFINE_TYPE (GcrViewerWidget, gcr_viewer_widget, GCR_TYPE_DISPLAY_SCROLLED);
+
+static const gchar *
+get_parsed_label_or_display_name (GcrViewerWidget *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)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
+ GckAttributes *attrs;
+ GcrRenderer *renderer;
+ const gchar *label;
+ gboolean actual = TRUE;
+
+ label = get_parsed_label_or_display_name (self, parser);
+ attrs = gcr_parser_get_parsed_attributes (parser);
+
+ renderer = gcr_renderer_create (label, attrs);
+
+ if (renderer == NULL) {
+ renderer = gcr_failure_renderer_new_unsupported (label);
+ actual = FALSE;
+ }
+
+ /* And show the data */
+ gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+
+ /* Let callers know we're rendering data */
+ if (actual == TRUE)
+ g_signal_emit (self, signals[ADDED], 0, renderer, parser);
+
+ g_object_unref (renderer);
+}
+
+static gboolean
+on_parser_authenticate_for_unlock (GcrParser *parser,
+ guint count,
+ gpointer user_data)
+{
+ GcrUnlockRenderer *unlock = GCR_UNLOCK_RENDERER (user_data);
+ const gchar *password;
+
+ if (count == 0) {
+ password = _gcr_unlock_renderer_get_password (unlock);
+ gcr_parser_add_password (parser, password);
+ }
+
+ return TRUE;
+}
+
+static void
+on_unlock_renderer_clicked (GcrUnlockRenderer *unlock,
+ gpointer user_data)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
+ GError *error = NULL;
+ gconstpointer data;
+ gsize n_data;
+ gulong sig;
+
+ /* Override our main authenticate signal handler */
+ sig = g_signal_connect (self->pv->parser, "authenticate",
+ G_CALLBACK (on_parser_authenticate_for_unlock), unlock);
+
+ data = _gcr_unlock_renderer_get_locked_data (unlock, &n_data);
+ if (gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
+
+ /* Done with this unlock renderer */
+ gcr_viewer_remove_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
+ self->pv->unlocks = g_list_remove (self->pv->unlocks, unlock);
+ g_object_unref (unlock);
+
+ } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)){
+ _gcr_unlock_renderer_show_warning (unlock, _("The password was incorrect"));
+ g_error_free (error);
+
+ } else {
+ _gcr_unlock_renderer_show_warning (unlock, error->message);
+ g_error_free (error);
+ }
+
+ g_signal_handler_disconnect (self->pv->parser, sig);
+}
+
+static gboolean
+on_parser_authenticate_for_data (GcrParser *parser,
+ guint count,
+ gpointer user_data)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
+ GcrUnlockRenderer *unlock;
+
+ unlock = _gcr_unlock_renderer_new_for_parsed (parser);
+ if (unlock != NULL) {
+ g_object_set (unlock, "label", get_parsed_label_or_display_name (self, parser), NULL);
+ gcr_viewer_add_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
+ g_signal_connect (unlock, "unlock-clicked", G_CALLBACK (on_unlock_renderer_clicked), self);
+ self->pv->unlocks = g_list_prepend (self->pv->unlocks, unlock);
+ }
+
+ return TRUE;
+}
+
+static void
+gcr_viewer_widget_init (GcrViewerWidget *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_VIEWER_WIDGET,
+ GcrViewerWidgetPrivate);
+
+ self->pv->files_to_load = g_queue_new ();
+ self->pv->parser = gcr_parser_new ();
+ self->pv->cancellable = g_cancellable_new ();
+ self->pv->unlocks = NULL;
+
+ 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_for_data), self);
+}
+
+static void
+gcr_viewer_widget_dispose (GObject *obj)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (obj);
+ GList *l;
+
+ g_signal_handlers_disconnect_by_func (self->pv->parser, on_parser_parsed, self);
+
+ for (l = self->pv->unlocks; l != NULL; l = g_list_next (l)) {
+ g_signal_handlers_disconnect_by_func (l->data, on_unlock_renderer_clicked, self);
+ g_object_unref (l->data);
+ }
+ g_list_free (self->pv->unlocks);
+ self->pv->unlocks = NULL;
+
+ while (!g_queue_is_empty (self->pv->files_to_load))
+ g_object_unref (g_queue_pop_head (self->pv->files_to_load));
+
+ g_cancellable_cancel (self->pv->cancellable);
+
+ G_OBJECT_CLASS (gcr_viewer_widget_parent_class)->dispose (obj);
+}
+
+static void
+gcr_viewer_widget_finalize (GObject *obj)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (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);
+
+ G_OBJECT_CLASS (gcr_viewer_widget_parent_class)->finalize (obj);
+}
+
+static void
+gcr_viewer_widget_class_init (GcrViewerWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->dispose = gcr_viewer_widget_dispose;
+ gobject_class->finalize = gcr_viewer_widget_finalize;
+
+ g_type_class_add_private (klass, sizeof (GcrViewerWidget));
+
+ signals[ADDED] = g_signal_new ("added", GCR_TYPE_VIEWER_WIDGET, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrViewerWidgetClass, added),
+ NULL, NULL, _gcr_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
+}
+
+static void
+on_parser_parse_stream_returned (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
+ GError *error = NULL;
+ GcrRenderer *renderer;
+
+ gcr_parser_parse_stream_finish (self->pv->parser, result, &error);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+ g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_CANCELLED)) {
+ viewer_stop_loading_files (self);
+
+ } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)) {
+ /* Just skip this one, an unlock renderer was added */
+
+ } else if (error) {
+ renderer = gcr_failure_renderer_new (self->pv->display_name, error);
+ gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ g_object_unref (renderer);
+ g_error_free (error);
+ }
+
+ viewer_load_next_file (self);
+}
+
+static void
+update_display_name (GcrViewerWidget *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
+on_file_read_returned (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
+ GFile *file = G_FILE (source);
+ GError *error = NULL;
+ GFileInputStream *fis;
+ GcrRenderer *renderer;
+
+ fis = g_file_read_finish (file, result, &error);
+ update_display_name (self, file);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ viewer_stop_loading_files (self);
+
+ } else if (error) {
+ renderer = gcr_failure_renderer_new (self->pv->display_name, error);
+ gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ g_object_unref (renderer);
+ g_error_free (error);
+
+ viewer_load_next_file (self);
+
+ } else {
+ gcr_parser_parse_stream_async (self->pv->parser, G_INPUT_STREAM (fis),
+ self->pv->cancellable, on_parser_parse_stream_returned,
+ self);
+ g_object_unref (fis);
+ }
+}
+
+static void
+viewer_stop_loading_files (GcrViewerWidget *self)
+{
+ self->pv->loading = FALSE;
+}
+
+static void
+viewer_load_next_file (GcrViewerWidget *self)
+{
+ GFile* file;
+
+ file = g_queue_pop_head (self->pv->files_to_load);
+ if (file == NULL) {
+ viewer_stop_loading_files (self);
+ return;
+ }
+
+ g_file_read_async (file, G_PRIORITY_DEFAULT, self->pv->cancellable,
+ on_file_read_returned, self);
+
+ g_object_unref (file);
+}
+
+/**
+ * gcr_viewer_widget_new:
+ *
+ * Create a new viewer widget.
+ *
+ * Returns: (transfer full): A new #GcrViewerWidget object
+ */
+GcrViewerWidget *
+gcr_viewer_widget_new (void)
+{
+ return g_object_new (GCR_TYPE_VIEWER_WIDGET, NULL);
+}
+
+/**
+ * gcr_viewer_widget_load_file:
+ * @self: a viewer widget
+ * @file: a file to load
+ *
+ * Display contents of a file in the viewer widget. Multiple files can
+ * be loaded.
+ */
+void
+gcr_viewer_widget_load_file (GcrViewerWidget *self,
+ GFile *file)
+{
+ g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
+ g_return_if_fail (G_IS_FILE (file));
+
+ g_queue_push_tail (self->pv->files_to_load, g_object_ref (file));
+
+ if (!self->pv->loading)
+ viewer_load_next_file (self);
+}
+
+void
+gcr_viewer_widget_load_data (GcrViewerWidget *self,
+ const gchar *display_name,
+ gconstpointer *data,
+ gsize n_data)
+{
+ GError *error = NULL;
+ GcrRenderer *renderer;
+
+ g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
+
+ g_free (self->pv->display_name);
+ self->pv->display_name = g_strdup (display_name);
+
+ if (!gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
+ renderer = gcr_failure_renderer_new (display_name, error);
+ gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ g_object_unref (renderer);
+ g_error_free (error);
+ }
+}
diff --git a/gcr/gcr-viewer-widget.h b/gcr/gcr-viewer-widget.h
new file mode 100644
index 0000000..a4dbbb1
--- /dev/null
+++ b/gcr/gcr-viewer-widget.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gcr-viewer-widget.h: Widget for viewer
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. 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>
+*/
+
+#ifndef GCR_VIEWER_WIDGET_H
+#define GCR_VIEWER_WIDGET_H
+
+#include <gtk/gtk.h>
+
+#define GCR_TYPE_VIEWER_WIDGET (gcr_viewer_widget_get_type ())
+#define GCR_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidget))
+#define GCR_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
+#define GCR_IS_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER_WIDGET))
+#define GCR_IS_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_VIEWER_WIDGET))
+#define GCR_VIEWER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
+
+typedef struct _GcrViewerWidget GcrViewerWidget;
+typedef struct _GcrViewerWidgetClass GcrViewerWidgetClass;
+typedef struct _GcrViewerWidgetPrivate GcrViewerWidgetPrivate;
+
+
+GType gcr_viewer_widget_get_type (void);
+
+GcrViewerWidget * gcr_viewer_widget_new (void);
+
+void gcr_viewer_widget_load_file (GcrViewerWidget *self,
+ GFile *file);
+
+void gcr_viewer_widget_load_data (GcrViewerWidget *self,
+ const gchar *display_name,
+ gconstpointer *data,
+ gsize n_data);
+
+#endif /* GCR_VIEWER_WIDGET_H */
diff --git a/gcr/gcr-viewer-window.c b/gcr/gcr-viewer-window.c
index 44e2f30..6301917 100644
--- a/gcr/gcr-viewer-window.c
+++ b/gcr/gcr-viewer-window.c
@@ -23,12 +23,7 @@
#include "config.h"
-#include "gcr-failure-renderer.h"
-#include "gcr-parser.h"
-#include "gcr-renderer.h"
-#include "gcr-unlock-renderer.h"
#include "gcr-viewer-window.h"
-#include "gcr-viewer.h"
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
@@ -36,342 +31,134 @@
#include <locale.h>
#include <string.h>
-/**
- * SECTION:gcr-viewer-window
- * @title: GcrViewerWindow
- * @short_description: A window which shows certificates or keys
- *
- * A viewer window which can display certificates and keys that are
- * located in files.
- */
-
-/**
- * GcrViewerWindow:
- *
- * A viewer window object.
- */
-
-/**
- * GcrViewerWindowClass:
- *
- * Class for #GcrViewerWindow
- */
-
struct _GcrViewerWindowPrivate {
- GQueue *files_to_load;
- GcrParser *parser;
- GCancellable *cancellable;
- GcrViewer *viewer;
- gboolean loading;
- gchar *display_name;
+ GcrViewerWidget *viewer;
+ GcrImportButton *import;
};
-static void viewer_load_next_file (GcrViewerWindow *self);
-static void viewer_stop_loading_files (GcrViewerWindow *self);
-
-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;
-}
+G_DEFINE_TYPE (GcrViewerWindow, _gcr_viewer_window, GTK_TYPE_WINDOW);
static void
-on_parser_parsed (GcrParser *parser, gpointer user_data)
+on_viewer_renderer_added (GcrViewerWidget *viewer,
+ GcrRenderer *renderer,
+ GcrParser *parser,
+ gpointer user_data)
{
GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- GcrRenderer *renderer;
-
- renderer = gcr_renderer_create (get_parsed_label_or_display_name (self, parser),
- gcr_parser_get_parsed_attributes (parser));
-
- if (renderer == NULL)
- renderer = _gcr_failure_renderer_new_unsupported (get_parsed_label_or_display_name (self, parser));
-
- gcr_viewer_add_renderer (self->pv->viewer, renderer);
- g_object_unref (renderer);
-}
-
-static gboolean
-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;
+ gcr_import_button_add_parsed (self->pv->import, parser);
}
static void
-gcr_viewer_window_init (GcrViewerWindow *self)
+_gcr_viewer_window_init (GcrViewerWindow *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_VIEWER_WINDOW,
GcrViewerWindowPrivate);
-
- self->pv->files_to_load = g_queue_new ();
- self->pv->parser = gcr_parser_new ();
- 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
-gcr_viewer_window_constructed (GObject *obj)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (obj);
-
- if (G_OBJECT_CLASS (gcr_viewer_window_parent_class)->constructed)
- G_OBJECT_CLASS (gcr_viewer_window_parent_class)->constructed (obj);
-
- self->pv->viewer = gcr_viewer_new_scrolled ();
-
- gtk_widget_show (GTK_WIDGET (self->pv->viewer));
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->viewer));
-
- gtk_window_set_default_size (GTK_WINDOW (self), 250, 400);
-}
-
-static void
-gcr_viewer_window_dispose (GObject *obj)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (obj);
-
- g_signal_handlers_disconnect_by_func (self->pv->parser, on_parser_parsed, self);
-
- while (!g_queue_is_empty (self->pv->files_to_load))
- g_object_unref (g_queue_pop_head (self->pv->files_to_load));
-
- g_cancellable_cancel (self->pv->cancellable);
-
- G_OBJECT_CLASS (gcr_viewer_window_parent_class)->dispose (obj);
-}
-
-static void
-gcr_viewer_window_finalize (GObject *obj)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (obj);
-
- /* self->pv->viewer is owned by container */
-
- 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);
-
- G_OBJECT_CLASS (gcr_viewer_window_parent_class)->finalize (obj);
-}
-
-static void
-gcr_viewer_window_class_init (GcrViewerWindowClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gcr_viewer_window_parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->dispose = gcr_viewer_window_dispose;
- gobject_class->finalize = gcr_viewer_window_finalize;
- gobject_class->constructed = gcr_viewer_window_constructed;
-
- g_type_class_add_private (klass, sizeof (GcrViewerWindow));
-}
-
-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)
+on_import_button_imported (GcrImportButton *button,
+ GcrImporter *importer,
+ GError *error,
+ gpointer user_data)
{
GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- GError *error = NULL;
GcrRenderer *renderer;
- gcr_parser_parse_stream_finish (self->pv->parser, result, &error);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
- g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_CANCELLED)) {
- viewer_stop_loading_files (self);
+ if (error == NULL) {
+ g_object_set (button, "label", _("Imported"), NULL);
- } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)) {
- /* Just skip this one, an unlock renderer was added */
-
- } else if (error) {
- renderer = _gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (self->pv->viewer, renderer);
- g_object_unref (renderer);
- g_error_free (error);
+ } else {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ renderer = gcr_failure_renderer_new (_("Import failed"), error);
+ gcr_viewer_add_renderer (GCR_VIEWER (self->pv->viewer), renderer);
+ g_object_unref (renderer);
+ }
}
-
- viewer_load_next_file (self);
}
static void
-update_display_name (GcrViewerWindow *self,
- GFile *file)
+on_close_clicked (GtkButton *button,
+ gpointer user_data)
{
- 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);
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
+ gtk_widget_destroy (GTK_WIDGET (self));
}
static void
-on_file_read_returned (GObject *source, GAsyncResult *result, gpointer user_data)
+_gcr_viewer_window_constructed (GObject *obj)
{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- GFile *file = G_FILE (source);
- GError *error = NULL;
- GFileInputStream *fis;
- GcrRenderer *renderer;
-
- fis = g_file_read_finish (file, result, &error);
- update_display_name (self, file);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- viewer_stop_loading_files (self);
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (obj);
+ GtkWidget *bbox;
+ GtkWidget *box;
+ GtkWidget *button;
+ GtkWidget *align;
+
+ G_OBJECT_CLASS (_gcr_viewer_window_parent_class)->constructed (obj);
+
+ bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_set_spacing (GTK_BOX (bbox), 12);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_widget_show (bbox);
+
+ self->pv->import = gcr_import_button_new (_("Import"));
+ g_signal_connect_object (self->pv->import, "imported",
+ G_CALLBACK (on_import_button_imported),
+ self, 0);
+ gtk_widget_show (GTK_WIDGET (self->pv->import));
+
+ button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ g_signal_connect_object (button, "clicked",
+ G_CALLBACK (on_close_clicked),
+ self, 0);
+ gtk_widget_show (button);
+
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (bbox), GTK_WIDGET (self->pv->import), FALSE, TRUE, 0);
+
+ align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 0, 12);
+ gtk_widget_show (align);
+ gtk_container_add (GTK_CONTAINER (align), bbox);
+
+ self->pv->viewer = gcr_viewer_widget_new ();
+ g_signal_connect_object (self->pv->viewer, "added",
+ G_CALLBACK (on_viewer_renderer_added),
+ self, 0);
+ gtk_widget_show (GTK_WIDGET (self->pv->viewer));
- } else if (error) {
- renderer = _gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (self->pv->viewer, renderer);
- g_object_unref (renderer);
- g_error_free (error);
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_show (box);
- viewer_load_next_file (self);
+ gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (self->pv->viewer), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), align, FALSE, FALSE, 6);
- } else {
- gcr_parser_parse_stream_async (self->pv->parser, G_INPUT_STREAM (fis),
- self->pv->cancellable, on_parser_parse_stream_returned,
- self);
- g_object_unref (fis);
- }
-}
+ gtk_container_add (GTK_CONTAINER (self), box);
-static void
-viewer_stop_loading_files (GcrViewerWindow *self)
-{
- self->pv->loading = FALSE;
+ gtk_window_set_default_size (GTK_WINDOW (self), 250, 400);
}
static void
-viewer_load_next_file (GcrViewerWindow *self)
+_gcr_viewer_window_class_init (GcrViewerWindowClass *klass)
{
- GFile* file;
-
- file = g_queue_pop_head (self->pv->files_to_load);
- if (file == NULL) {
- viewer_stop_loading_files (self);
- return;
- }
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- g_file_read_async (file, G_PRIORITY_DEFAULT, self->pv->cancellable,
- on_file_read_returned, self);
+ gobject_class->constructed = _gcr_viewer_window_constructed;
- g_object_unref (file);
+ g_type_class_add_private (klass, sizeof (GcrViewerWindow));
}
-/**
- * gcr_viewer_window_new:
- *
- * Create a new viewer window.
- *
- * Returns: (transfer full): A new #GcrViewerWindow object
- */
-GcrViewerWindow *
-gcr_viewer_window_new (void)
+GtkWindow *
+_gcr_viewer_window_new (void)
{
return g_object_new (GCR_TYPE_VIEWER_WINDOW, NULL);
}
-/**
- * gcr_viewer_window_load:
- * @self: a viewer window
- * @file: a file to load
- *
- * Display contents of a file in the viewer window. Multiple files can
- * be loaded.
- */
void
-gcr_viewer_window_load (GcrViewerWindow *self, GFile *file)
+_gcr_viewer_window_load (GcrViewerWindow *self,
+ GFile *file)
{
g_return_if_fail (GCR_IS_VIEWER_WINDOW (self));
g_return_if_fail (G_IS_FILE (file));
- g_queue_push_tail (self->pv->files_to_load, g_object_ref (file));
-
- if (!self->pv->loading)
- viewer_load_next_file (self);
+ return gcr_viewer_widget_load_file (self->pv->viewer, file);
}
diff --git a/gcr/gcr-viewer-window.h b/gcr/gcr-viewer-window.h
index d5ac88d..90b0744 100644
--- a/gcr/gcr-viewer-window.h
+++ b/gcr/gcr-viewer-window.h
@@ -26,7 +26,9 @@
#include <gtk/gtk.h>
-#define GCR_TYPE_VIEWER_WINDOW (gcr_viewer_window_get_type ())
+#include "gcr/gcr.h"
+
+#define GCR_TYPE_VIEWER_WINDOW (_gcr_viewer_window_get_type ())
#define GCR_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER_WINDOW, GcrViewerWindow))
#define GCR_VIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WINDOW, GcrViewerWindowClass))
#define GCR_IS_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER_WINDOW))
@@ -48,11 +50,11 @@ struct _GcrViewerWindowClass {
GtkWindowClass parent_class;
};
-GType gcr_viewer_window_get_type (void);
+GType _gcr_viewer_window_get_type (void);
-GcrViewerWindow * gcr_viewer_window_new (void);
+GtkWindow * _gcr_viewer_window_new (void);
-void gcr_viewer_window_load (GcrViewerWindow *self,
- GFile *file);
+void _gcr_viewer_window_load (GcrViewerWindow *self,
+ GFile *file);
#endif /* GCR_VIEWER_WINDOW_H */
diff --git a/gcr/gcr-viewer.c b/gcr/gcr-viewer.c
index 26b65df..b210c61 100644
--- a/gcr/gcr-viewer.c
+++ b/gcr/gcr-viewer.c
@@ -57,31 +57,14 @@
* The interface for #GcrViewer
*/
-static void
-gcr_viewer_base_init (gpointer gobject_iface)
-{
- static gboolean initialized = FALSE;
- if (!initialized) {
+typedef GcrViewerIface GcrViewerInterface;
- initialized = TRUE;
- }
-}
+G_DEFINE_INTERFACE (GcrViewer, gcr_viewer, GTK_TYPE_WIDGET);
-GType
-gcr_viewer_get_type (void)
+static void
+gcr_viewer_default_init (GcrViewerIface *iface)
{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (GcrViewerIface),
- gcr_viewer_base_init, /* base init */
- NULL, /* base finalize */
- };
- type = g_type_register_static (G_TYPE_INTERFACE, "GcrViewerIface", &info, 0);
- g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET);
- }
-
- return type;
+
}
/* -----------------------------------------------------------------------------
diff --git a/gcr/gcr.h b/gcr/gcr.h
index b3078ee..ec150a9 100644
--- a/gcr/gcr.h
+++ b/gcr/gcr.h
@@ -42,14 +42,18 @@
#include "gcr-deprecated.h"
#include "gcr-key-renderer.h"
#include "gcr-key-widget.h"
-#include "gcr-importer.h"
+#include "gcr-enum-types.h"
+#include "gcr-failure-renderer.h"
+#include "gcr-key-renderer.h"
+#include "gcr-key-widget.h"
+#include "gcr-import-button.h"
#include "gcr-list-selector.h"
#include "gcr-renderer.h"
#include "gcr-tree-selector.h"
#include "gcr-union-collection.h"
#include "gcr-unlock-options-widget.h"
#include "gcr-viewer.h"
-#include "gcr-viewer-window.h"
+#include "gcr-viewer-widget.h"
#undef __GCR_INSIDE_HEADER__
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index 15c0cb8..018f0bb 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -61,3 +61,7 @@ noinst_PROGRAMS = \
frob-parser \
frob-unlock \
frob-unlock-options
+
+frob_unlock_SOURCES = \
+ frob-unlock.c \
+ ../gcr-viewer-window.c
diff --git a/gcr/tests/frob-unlock.c b/gcr/tests/frob-unlock.c
index 3a7f511..ac9c608 100644
--- a/gcr/tests/frob-unlock.c
+++ b/gcr/tests/frob-unlock.c
@@ -25,6 +25,7 @@
#include "gcr/gcr.h"
#include "gcr/gcr-unlock-renderer.h"
+#include "gcr/gcr-viewer-window.h"
#include <gtk/gtk.h>
@@ -55,7 +56,7 @@ on_parser_authenticate (GcrParser *parser,
GcrUnlockRenderer *renderer;
GtkWindow *window;
- window = GTK_WINDOW (gcr_viewer_window_new ());
+ window = GTK_WINDOW (_gcr_viewer_window_new ());
g_object_ref_sink (window);
renderer = _gcr_unlock_renderer_new_for_parsed (parser);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]