Useful for selecting object URIs from PKCS#11 tokens. --- po/POTFILES.in | 2 + ui/Makefile.am | 2 + ui/gcr-object-chooser-button.c | 183 ++++++++++++++++++++++++++++++++++++++++ ui/gcr-object-chooser-button.h | 38 +++++++++ ui/gcr-object-chooser-button.ui | 58 +++++++++++++ ui/gcr-ui.symbols | 2 + ui/gcr.gresource.xml | 1 + 7 files changed, 286 insertions(+) create mode 100644 ui/gcr-object-chooser-button.c create mode 100644 ui/gcr-object-chooser-button.h create mode 100644 ui/gcr-object-chooser-button.ui
diff --git a/po/POTFILES.in b/po/POTFILES.in index 012fb5f..f764574 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -27,6 +27,8 @@ ui/gcr-failure-renderer.c ui/gcr-gnupg-renderer.c ui/gcr-import-button.c ui/gcr-key-renderer.c +ui/gcr-object-chooser-button.c +[type: gettext/glade] ui/gcr-object-chooser-button.ui ui/gcr-object-chooser-widget.c [type: gettext/glade]ui/gcr-object-chooser-widget.ui ui/gcr-pkcs11-import-dialog.c diff --git a/ui/Makefile.am b/ui/Makefile.am index 74709b8..10d6ee0 100644 --- a/ui/Makefile.am +++ b/ui/Makefile.am @@ -59,6 +59,7 @@ ui_HEADER_FILES = \ ui/gcr-key-widget.h \ ui/gcr-import-button.h \ ui/gcr-list-selector.h \ + ui/gcr-object-chooser-button.h \ ui/gcr-object-chooser-dialog.h \ ui/gcr-object-chooser.h \ ui/gcr-object-chooser-widget.h \ @@ -89,6 +90,7 @@ ui_PUBLIC_FILES = \ ui/gcr-list-selector.c ui/gcr-list-selector.h \ ui/gcr-object-chooser.c ui/gcr-object-chooser.h \ ui/gcr-object-chooser-dialog.c ui/gcr-object-chooser-dialog.h \ + ui/gcr-object-chooser-button.c ui/gcr-object-chooser-button.h \ ui/gcr-prompt-dialog.c ui/gcr-prompt-dialog.h \ ui/gcr-renderer.c ui/gcr-renderer.h \ ui/gcr-secure-entry-buffer.c ui/gcr-secure-entry-buffer.h \ diff --git a/ui/gcr-object-chooser-button.c b/ui/gcr-object-chooser-button.c new file mode 100644 index 0000000..8f79131 --- /dev/null +++ b/ui/gcr-object-chooser-button.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2016 Lubomir Rintel + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include "gcr-object-chooser-button.h" +#include "gcr-object-chooser-dialog.h" + +#include "config.h" + +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> +#include <gck/gck.h> + +/** + * SECTION:gcr-object-chooser-button + * @title: GcrObjectChooserButton + * @short_description: The PKCS11 Object Chooser Button + * @see_also: #GcrObjectChooser + * + * #GcrObjectChooserButton is the PKCS11 object chooser button. It runs the + * #GcrObjectChooserDialog when clicked, to choose an object. + */ + +struct _GcrObjectChooserButtonPrivate +{ + GtkWidget *dialog; + GtkLabel *label; + + gchar *uri; +}; + +static void gcr_object_chooser_iface_init (GcrObjectChooserInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GcrObjectChooserButton, gcr_object_chooser_button, GTK_TYPE_BUTTON, + G_ADD_PRIVATE (GcrObjectChooserButton) + G_IMPLEMENT_INTERFACE (GCR_TYPE_OBJECT_CHOOSER, gcr_object_chooser_iface_init)); + +static void +set_uri (GcrObjectChooser *self, const gchar *uri) +{ + GcrObjectChooserButtonPrivate *priv = GCR_OBJECT_CHOOSER_BUTTON (self)->priv; + GckUriData *data; + GError *error = NULL; + gchar *label = NULL; + gchar *real_uri; + char *c; + + if (priv->uri) { + g_free (priv->uri); + priv->uri = NULL; + } + + if (uri) { + priv->uri = g_strdup (uri); + } else { + gtk_button_set_label (GTK_BUTTON (self), _("(None)")); + return; + } + + /* XXX: Fix GckUri to handle URI attributes instead of chopping them off. */ + real_uri = g_strdup (uri); + c = strchr (real_uri, '&'); + if (c) + *c = '\0'; + data = gck_uri_parse (real_uri, GCK_URI_FOR_ANY, &error); + g_free (real_uri); + + if (data) { + if (!gck_attributes_find_string (data->attributes, CKA_LABEL, &label)) { + if (data->token_info) + label = g_strdup_printf (_("Certificate in %s"), data->token_info->label); + } + } else { + g_warning ("Bad URI: %s\n", error->message); + g_error_free (error); + } + + if (!label) + label = g_strdup (_("(Unknown)")); + gtk_label_set_text (GTK_LABEL (priv->label), label); + g_free (label); + gck_uri_data_free (data); +} + +static gchar * +get_uri (GcrObjectChooser *self) +{ + GcrObjectChooserButtonPrivate *priv = GCR_OBJECT_CHOOSER_BUTTON (self)->priv; + + return priv->uri; +} + +static void +gcr_object_chooser_iface_init (GcrObjectChooserInterface *iface) +{ + iface->set_uri = set_uri; + iface->get_uri = get_uri; +} + +static void +clicked (GtkButton *button) +{ + GcrObjectChooserButtonPrivate *priv = GCR_OBJECT_CHOOSER_BUTTON (button)->priv; + + if (gtk_dialog_run (GTK_DIALOG (priv->dialog)) == GTK_RESPONSE_ACCEPT) { + gcr_object_chooser_set_uri (GCR_OBJECT_CHOOSER (button), + gcr_object_chooser_get_uri (GCR_OBJECT_CHOOSER (priv->dialog))); + } + gtk_widget_hide (priv->dialog); + +} + +static void +finalize (GObject *object) +{ + GcrObjectChooserButtonPrivate *priv = GCR_OBJECT_CHOOSER_BUTTON (object)->priv; + + if (priv->uri) + g_free (priv->uri); + gtk_widget_destroy (priv->dialog); +} + +static void +gcr_object_chooser_button_class_init (GcrObjectChooserButtonClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gcr/ui/gcr-object-chooser-button.ui"); + gtk_widget_class_bind_template_child_private (widget_class, GcrObjectChooserButton, label); + gtk_widget_class_bind_template_callback (widget_class, clicked); +} + +static void +gcr_object_chooser_button_init (GcrObjectChooserButton *self) +{ + self->priv = gcr_object_chooser_button_get_instance_private (self); + + gtk_widget_init_template (GTK_WIDGET (self)); +} + +/** + * gcr_object_chooser_button_new: + * @parent_window: (allow-none): parent window of the #GtkObjectChooserDialog or %NULL + * + * Creates the new #GcrObjectChooserButton. + * + * Returns: newly created #GcrObjectChooserButton + */ + +GtkWidget * +gcr_object_chooser_button_new (GtkWindow *parent_window) +{ + GtkWidget *self; + GcrObjectChooserButtonPrivate *priv; + + self = GTK_WIDGET (g_object_new (GCR_TYPE_OBJECT_CHOOSER_BUTTON, NULL)); + + priv = GCR_OBJECT_CHOOSER_BUTTON (self)->priv; + priv->dialog = gcr_object_chooser_dialog_new (_("Choose a certificate"), + parent_window, + GTK_DIALOG_USE_HEADER_BAR, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Select"), GTK_RESPONSE_ACCEPT, + NULL); + + return self; +} diff --git a/ui/gcr-object-chooser-button.h b/ui/gcr-object-chooser-button.h new file mode 100644 index 0000000..5f09979 --- /dev/null +++ b/ui/gcr-object-chooser-button.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 Lubomir Rintel + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GCR_OBJECT_CHOOSER_BUTTON_H__ +#define __GCR_OBJECT_CHOOSER_BUTTON_H__ + +#include <gtk/gtk.h> + +#include "gcr-object-chooser.h" + +typedef struct _GcrObjectChooserButtonPrivate GcrObjectChooserButtonPrivate; + +struct _GcrObjectChooserButton +{ + GtkButton parent_instance; + GcrObjectChooserButtonPrivate *priv; +}; + +#define GCR_TYPE_OBJECT_CHOOSER_BUTTON gcr_object_chooser_button_get_type () +G_DECLARE_FINAL_TYPE (GcrObjectChooserButton, gcr_object_chooser_button, GCR, OBJECT_CHOOSER_BUTTON, GtkButton) + +GtkWidget *gcr_object_chooser_button_new (GtkWindow *parent_window); + +#endif /* __GCR_OBJECT_CHOOSER_BUTTON_H__ */ diff --git a/ui/gcr-object-chooser-button.ui b/ui/gcr-object-chooser-button.ui new file mode 100644 index 0000000..e99b1b4 --- /dev/null +++ b/ui/gcr-object-chooser-button.ui @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> +<interface domain="gtk30"> + <requires lib="gtk+" version="3.10"/> + <template class="GcrObjectChooserButton" parent="GtkButton"> + <property name="can_focus">False</property> + <property name="receives_default">False</property> + <signal name="clicked" handler="clicked" swapped="no"/> + <child> + <object class="GtkBox" id="box2"> + <property name="can_focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel" id="label"> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="valign">baseline</property> + <property name="label" translatable="yes">(None)</property> + <property name="ellipsize">end</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkSeparator" id="separator1"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkImage" id="open_file_icon"> + <property name="can_focus">False</property> + <property name="valign">baseline</property> + <property name="icon_name">document-open-symbolic</property> + <property name="icon_size">1</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + </object> + </child> + <style> + <class name="file"/> + </style> + </template> +</interface> diff --git a/ui/gcr-ui.symbols b/ui/gcr-ui.symbols index afd2262..1a6589f 100644 --- a/ui/gcr-ui.symbols +++ b/ui/gcr-ui.symbols @@ -62,6 +62,8 @@ gcr_list_selector_get_selected gcr_list_selector_get_type gcr_list_selector_new gcr_list_selector_set_selected +gcr_object_chooser_button_get_type +gcr_object_chooser_button_new gcr_object_chooser_dialog_get_type gcr_object_chooser_dialog_new gcr_object_chooser_get_type diff --git a/ui/gcr.gresource.xml b/ui/gcr.gresource.xml index 55841cc..fb5aea3 100644 --- a/ui/gcr.gresource.xml +++ b/ui/gcr.gresource.xml @@ -7,5 +7,6 @@ <file preprocess="xml-stripblanks">gcr-object-chooser-widget.ui</file> <file preprocess="xml-stripblanks">gcr-token-login-dialog.ui</file> <file preprocess="xml-stripblanks">gcr-tokens-sidebar-row.ui</file> + <file preprocess="xml-stripblanks">gcr-object-chooser-button.ui</file> </gresource> </gresources> -- 2.9.3 _______________________________________________ gnome-keyring-list mailing list gnome-keyring-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnome-keyring-list