[seahorse] pkcs11: Implement toolbar and deletion from pkcs11 properties window



commit 1aa3c8c6b9dc704fc8f6f6029f876b83e836bb80
Author: Stef Walter <stefw collabora co uk>
Date:   Tue Nov 22 16:53:03 2011 +0100

    pkcs11: Implement toolbar and deletion from pkcs11 properties window

 gkr/seahorse-gkr-actions.c           |    9 +-
 libseahorse/Makefile.am              |    1 +
 libseahorse/seahorse-delete-dialog.c |  279 ++++++++++++++++++++++++++++++++++
 libseahorse/seahorse-delete-dialog.h |   63 ++++++++
 libseahorse/seahorse-util.c          |   45 ------
 libseahorse/seahorse-util.h          |    3 -
 pgp/seahorse-pgp-actions.c           |    7 +-
 pgp/seahorse-pgp-key-properties.c    |    5 +-
 pkcs11/seahorse-pkcs11-actions.c     |    7 +-
 pkcs11/seahorse-pkcs11-properties.c  |  166 ++++++++++++++++++++-
 ssh/seahorse-ssh-actions.c           |    7 +-
 11 files changed, 527 insertions(+), 65 deletions(-)
---
diff --git a/gkr/seahorse-gkr-actions.c b/gkr/seahorse-gkr-actions.c
index 4884768..9236188 100644
--- a/gkr/seahorse-gkr-actions.c
+++ b/gkr/seahorse-gkr-actions.c
@@ -30,6 +30,7 @@
 
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
+#include "seahorse-delete-dialog.h"
 #include "seahorse-object-list.h"
 #include "seahorse-progress.h"
 #include "seahorse-registry.h"
@@ -330,7 +331,7 @@ on_keyrings_delete (GtkAction* action,
 	                          seahorse_object_get_label (objects->data));
 	parent = seahorse_action_get_window (action);
 
-	ret = seahorse_util_prompt_delete (prompt, GTK_WIDGET (parent));
+	ret = seahorse_delete_dialog_prompt (parent, prompt);
 	if (ret) {
 		cancellable = g_cancellable_new ();
 		seahorse_gkr_delete_async (objects, cancellable,
@@ -516,7 +517,7 @@ on_delete_passwords (GtkAction *action,
                      gpointer user_data)
 {
 	GCancellable *cancellable;
-	GtkWidget *parent;
+	GtkWindow *parent;
 	GList *objects;
 	gchar *prompt;
 	gboolean ret;
@@ -536,8 +537,8 @@ on_delete_passwords (GtkAction *action,
 		                                    num), num);
 	}
 
-	parent = GTK_WIDGET (seahorse_action_get_window (action));
-	ret = seahorse_util_prompt_delete (prompt, parent);
+	parent = seahorse_action_get_window (action);
+	ret = seahorse_delete_dialog_prompt (parent, prompt);
 
 	if (ret) {
 		cancellable = g_cancellable_new ();
diff --git a/libseahorse/Makefile.am b/libseahorse/Makefile.am
index 89894f7..83f1c4d 100644
--- a/libseahorse/Makefile.am
+++ b/libseahorse/Makefile.am
@@ -36,6 +36,7 @@ libseahorse_la_SOURCES = \
 	seahorse-collection.c seahorse-collection.h \
 	seahorse-context.c seahorse-context.h \
 	seahorse-debug.c seahorse-debug.h \
+	seahorse-delete-dialog.c seahorse-delete-dialog.h \
 	seahorse-icons.c seahorse-icons.h \
 	seahorse-key-manager-store.c seahorse-key-manager-store.h \
 	seahorse-object.c seahorse-object.h \
diff --git a/libseahorse/seahorse-delete-dialog.c b/libseahorse/seahorse-delete-dialog.c
new file mode 100644
index 0000000..adbbb94
--- /dev/null
+++ b/libseahorse/seahorse-delete-dialog.c
@@ -0,0 +1,279 @@
+/*
+ * Seahorse
+ *
+ * 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 "seahorse-delete-dialog.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#define SEAHORSE_DELETE_DIALOG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_DELETE_DIALOG, SeahorseDeleteDialogClass))
+#define SEAHORSE_IS_DELETE_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_DELETE_DIALOG))
+#define SEAHORSE_DELETE_DIALOG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_DELETE_DIALOG, SeahorseDeleteDialogClass))
+
+typedef struct _SeahorseDeleteDialogClass SeahorseDeleteDialogClass;
+
+struct _SeahorseDeleteDialog {
+	GtkMessageDialog dialog;
+	GtkWidget *check;
+	gboolean check_require;
+};
+
+struct _SeahorseDeleteDialogClass {
+	GtkMessageDialogClass dialog;
+};
+
+enum {
+	PROP_0,
+	PROP_CHECK_LABEL,
+	PROP_CHECK_VALUE,
+	PROP_CHECK_REQUIRE
+};
+
+G_DEFINE_TYPE (SeahorseDeleteDialog, seahorse_delete_dialog, GTK_TYPE_MESSAGE_DIALOG);
+
+static void
+seahorse_delete_dialog_init (SeahorseDeleteDialog *self)
+{
+
+}
+
+static void
+update_response_buttons (SeahorseDeleteDialog *self)
+{
+	gboolean active;
+
+	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->check));
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK,
+	                                   !self->check_require || active);
+}
+
+static void
+on_check_toggled (GtkToggleButton *toggle,
+                  gpointer user_data)
+{
+	update_response_buttons (user_data);
+}
+
+static void
+seahorse_delete_dialog_constructed (GObject *obj)
+{
+	SeahorseDeleteDialog *self = SEAHORSE_DELETE_DIALOG (obj);
+	GtkWidget *content;
+	GtkWidget *button;
+
+	G_OBJECT_CLASS (seahorse_delete_dialog_parent_class)->constructed (obj);
+
+	gtk_window_set_modal (GTK_WINDOW (self), TRUE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (self), TRUE);
+
+	self->check = gtk_check_button_new ();
+	content = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (self));
+	gtk_container_add (GTK_CONTAINER (content), self->check);
+	g_signal_connect (self->check, "toggled", G_CALLBACK (on_check_toggled), self);
+
+	button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+	gtk_dialog_add_action_widget (GTK_DIALOG (self), button, GTK_RESPONSE_CANCEL);
+	gtk_widget_show (button);
+
+	button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+	gtk_dialog_add_action_widget (GTK_DIALOG (self), button, GTK_RESPONSE_OK);
+	gtk_widget_show (button);
+}
+
+static void
+seahorse_delete_dialog_get_property (GObject *obj,
+                                     guint prop_id,
+                                     GValue *value,
+                                     GParamSpec *pspec)
+{
+	SeahorseDeleteDialog *self = SEAHORSE_DELETE_DIALOG (obj);
+
+	switch (prop_id) {
+	case PROP_CHECK_LABEL:
+		g_value_set_string (value, seahorse_delete_dialog_get_check_label (self));
+		break;
+	case PROP_CHECK_VALUE:
+		g_value_set_boolean (value, seahorse_delete_dialog_get_check_value (self));
+		break;
+	case PROP_CHECK_REQUIRE:
+		g_value_set_boolean (value, seahorse_delete_dialog_get_check_require (self));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+seahorse_delete_dialog_set_property (GObject *obj,
+                                     guint prop_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec)
+{
+	SeahorseDeleteDialog *self = SEAHORSE_DELETE_DIALOG (obj);
+
+	switch (prop_id) {
+	case PROP_CHECK_LABEL:
+		seahorse_delete_dialog_set_check_label (self, g_value_get_string (value));
+		break;
+	case PROP_CHECK_VALUE:
+		seahorse_delete_dialog_set_check_value (self, g_value_get_boolean (value));
+		break;
+	case PROP_CHECK_REQUIRE:
+		seahorse_delete_dialog_set_check_require (self, g_value_get_boolean (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+seahorse_delete_dialog_class_init (SeahorseDeleteDialogClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->constructed = seahorse_delete_dialog_constructed;
+	gobject_class->get_property = seahorse_delete_dialog_get_property;
+	gobject_class->set_property = seahorse_delete_dialog_set_property;
+
+	g_object_class_install_property (gobject_class, PROP_CHECK_LABEL,
+	            g_param_spec_string ("check-label", "Check label", "Check label",
+	                                 NULL, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_CHECK_VALUE,
+	           g_param_spec_boolean ("check-value", "Check value", "Check value",
+	                                 FALSE, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_CHECK_REQUIRE,
+	           g_param_spec_boolean ("check-require", "Check require", "Check require",
+	                                 FALSE, G_PARAM_READWRITE));
+}
+
+GtkDialog *
+seahorse_delete_dialog_new (GtkWindow *parent,
+                            const gchar *format,
+                            ...)
+{
+	GtkDialog *dialog;
+	gchar *message;
+	va_list va;
+
+	g_return_val_if_fail (format != NULL, NULL);
+
+	va_start (va, format);
+	message = g_strdup_vprintf (format, va);
+	va_end (va);
+
+	dialog = g_object_new (SEAHORSE_TYPE_DELETE_DIALOG,
+	                       "message-type", GTK_MESSAGE_QUESTION,
+	                       "transient-for", parent,
+	                       "text", message,
+	                       NULL);
+
+	g_free (message);
+	return dialog;
+}
+
+const gchar *
+seahorse_delete_dialog_get_check_label (SeahorseDeleteDialog *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_DELETE_DIALOG (self), NULL);
+
+	if (gtk_widget_get_visible (self->check))
+		return gtk_button_get_label (GTK_BUTTON (self->check));
+	return NULL;
+}
+
+void
+seahorse_delete_dialog_set_check_label (SeahorseDeleteDialog *self,
+                                        const gchar *label)
+{
+	g_return_if_fail (SEAHORSE_IS_DELETE_DIALOG (self));
+
+	if (label == NULL) {
+		gtk_widget_hide (self->check);
+		label = "";
+	} else {
+		gtk_widget_show (self->check);
+	}
+
+	gtk_button_set_label (GTK_BUTTON (self->check), label);
+	g_object_notify (G_OBJECT (self), "check-label");
+}
+
+gboolean
+seahorse_delete_dialog_get_check_value (SeahorseDeleteDialog *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_DELETE_DIALOG (self), FALSE);
+
+	if (gtk_widget_get_visible (self->check))
+		return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->check));
+	return FALSE;
+}
+
+void
+seahorse_delete_dialog_set_check_value (SeahorseDeleteDialog *self,
+                                        gboolean value)
+{
+	g_return_if_fail (SEAHORSE_IS_DELETE_DIALOG (self));
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->check), value);
+	g_object_notify (G_OBJECT (self), "check-value");
+}
+
+gboolean
+seahorse_delete_dialog_get_check_require (SeahorseDeleteDialog *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_DELETE_DIALOG (self), FALSE);
+	return self->check_require;
+}
+
+void
+seahorse_delete_dialog_set_check_require (SeahorseDeleteDialog *self,
+                                          gboolean value)
+{
+	g_return_if_fail (SEAHORSE_IS_DELETE_DIALOG (self));
+	self->check_require = value;
+	update_response_buttons (self);
+	g_object_notify (G_OBJECT (self), "check-require");
+}
+
+gboolean
+seahorse_delete_dialog_prompt (GtkWindow *parent,
+                               const gchar *text)
+{
+	GtkDialog *dialog;
+	gint response;
+
+	g_return_val_if_fail (text != NULL, FALSE);
+
+	dialog = seahorse_delete_dialog_new (parent, "%s", text);
+
+	response = gtk_dialog_run (dialog);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+
+	return (response == GTK_RESPONSE_OK);
+}
diff --git a/libseahorse/seahorse-delete-dialog.h b/libseahorse/seahorse-delete-dialog.h
new file mode 100644
index 0000000..d3004b1
--- /dev/null
+++ b/libseahorse/seahorse-delete-dialog.h
@@ -0,0 +1,63 @@
+/*
+ * Seahorse
+ *
+ * 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 __SEAHORSE_DELETE_DIALOG_H__
+#define __SEAHORSE_DELETE_DIALOG_H__
+
+#include <glib-object.h>
+
+#include "seahorse-widget.h"
+
+#define SEAHORSE_DELETE_DIALOG_MENU_OBJECT   "ObjectPopup"
+
+#define SEAHORSE_TYPE_DELETE_DIALOG               (seahorse_delete_dialog_get_type ())
+#define SEAHORSE_DELETE_DIALOG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_DELETE_DIALOG, SeahorseDeleteDialog))
+#define SEAHORSE_IS_DELETE_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_DELETE_DIALOG))
+
+typedef struct _SeahorseDeleteDialog SeahorseDeleteDialog;
+
+GType               seahorse_delete_dialog_get_type                 (void) G_GNUC_CONST;
+
+GtkDialog *         seahorse_delete_dialog_new                      (GtkWindow *parent,
+                                                                     const gchar *format,
+                                                                     ...) G_GNUC_PRINTF (2, 3);
+
+const gchar *       seahorse_delete_dialog_get_check_label          (SeahorseDeleteDialog *self);
+
+void                seahorse_delete_dialog_set_check_label          (SeahorseDeleteDialog *self,
+                                                                     const gchar *label);
+
+gboolean            seahorse_delete_dialog_get_check_value          (SeahorseDeleteDialog *self);
+
+void                seahorse_delete_dialog_set_check_value          (SeahorseDeleteDialog *self,
+                                                                     gboolean value);
+
+gboolean            seahorse_delete_dialog_get_check_require        (SeahorseDeleteDialog *self);
+
+void                seahorse_delete_dialog_set_check_require        (SeahorseDeleteDialog *self,
+                                                                     gboolean value);
+
+gboolean            seahorse_delete_dialog_prompt                   (GtkWindow *parent,
+                                                                     const gchar *text);
+
+#endif /* __SEAHORSE_DELETE_DIALOG_H__ */
diff --git a/libseahorse/seahorse-util.c b/libseahorse/seahorse-util.c
index f9ee911..55c99b3 100644
--- a/libseahorse/seahorse-util.c
+++ b/libseahorse/seahorse-util.c
@@ -154,51 +154,6 @@ seahorse_util_handle_error (GError **error,
 }
 
 /**
- * seahorse_util_prompt_delete:
- * @text: The text to display in the delete-dialog
- * @parent: The widget to display the dialog for. Can be NULL
- *
- * Displays a modal dialog with "cancel" and "delete"
- *
- * Returns: TRUE if the user pressed "delete", FALSE else
- */
-gboolean
-seahorse_util_prompt_delete (const gchar *text, GtkWidget *parent)
-{
-	GtkWidget *warning, *button;
-	gint response;
-	
-	if (parent) {
-		if (!GTK_IS_WIDGET (parent)) {
-			g_warn_if_reached ();
-			parent = NULL;
-		} else {
-			if (!GTK_IS_WINDOW (parent)) 
-				parent = gtk_widget_get_toplevel (parent);
-			if (!GTK_IS_WINDOW (parent) && gtk_widget_is_toplevel (parent))
-				parent = NULL;
-		}
-	}
-	
-	warning = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_MODAL,
-	                                  GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
-	                                  "%s", text);
-    
-	button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
-	gtk_dialog_add_action_widget (GTK_DIALOG (warning), GTK_WIDGET (button), GTK_RESPONSE_REJECT);
-	gtk_widget_show (button);
-	
-	button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
-	gtk_dialog_add_action_widget (GTK_DIALOG (warning), GTK_WIDGET (button), GTK_RESPONSE_ACCEPT);
-	gtk_widget_show (button);
-	
-	response = gtk_dialog_run (GTK_DIALOG (warning));
-	gtk_widget_destroy (warning);
-	
-	return (response == GTK_RESPONSE_ACCEPT);
-}
-
-/**
  * seahorse_util_error_domain:
  *
  * Returns: The GError domain for generic seahorse errors
diff --git a/libseahorse/seahorse-util.h b/libseahorse/seahorse-util.h
index 1a9b290..f6d6d79 100644
--- a/libseahorse/seahorse-util.h
+++ b/libseahorse/seahorse-util.h
@@ -58,9 +58,6 @@ void        seahorse_util_handle_error          (GError **error,
                                                  const gchar* description,
                                                  ...);
 
-gboolean    seahorse_util_prompt_delete         (const gchar *text,
-                                                 GtkWidget *parent);
-
 guchar*     seahorse_util_read_to_memory        (GInputStream *     input,
                                                  guint              *len);
 
diff --git a/pgp/seahorse-pgp-actions.c b/pgp/seahorse-pgp-actions.c
index d5698bb..21998cf 100644
--- a/pgp/seahorse-pgp-actions.c
+++ b/pgp/seahorse-pgp-actions.c
@@ -36,6 +36,7 @@
 
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
+#include "seahorse-delete-dialog.h"
 #include "seahorse-object.h"
 #include "seahorse-object-list.h"
 #include "seahorse-registry.h"
@@ -206,7 +207,7 @@ on_delete_objects (GtkAction *action,
 	char* message;
 	SeahorseObject *obj;
 	GList* to_delete, *l;
-	GtkWidget *parent;
+	GtkWindow *parent;
 	gpgme_error_t gerr;
 	guint length;
 	GError *error = NULL;
@@ -272,8 +273,8 @@ on_delete_objects (GtkAction *action,
 		break;
 	}
 
-	parent = GTK_WIDGET (seahorse_action_get_window (action));
-	if (!seahorse_util_prompt_delete (message, parent)) {
+	parent = seahorse_action_get_window (action);
+	if (!seahorse_delete_dialog_prompt (parent, message)) {
 		g_free (message);
 		g_cancellable_cancel (g_cancellable_get_current ());
 		return;
diff --git a/pgp/seahorse-pgp-key-properties.c b/pgp/seahorse-pgp-key-properties.c
index 58bbc3b..d29b5ef 100644
--- a/pgp/seahorse-pgp-key-properties.c
+++ b/pgp/seahorse-pgp-key-properties.c
@@ -31,6 +31,7 @@
 #include <glib/gi18n.h>
 
 #include "seahorse-bind.h"
+#include "seahorse-delete-dialog.h"
 #include "seahorse-icons.h"
 #include "seahorse-object.h"
 #include "seahorse-object-model.h"
@@ -340,7 +341,7 @@ on_pgp_names_delete_clicked (GtkWidget *widget,
 	g_return_if_fail (SEAHORSE_IS_GPGME_UID (uid));
 	message = g_strdup_printf (_("Are you sure you want to permanently delete the '%s' user ID?"), 
 	                           seahorse_object_get_label (SEAHORSE_OBJECT (uid)));
-	ret = seahorse_util_prompt_delete (message, seahorse_widget_get_toplevel (swidget));
+	ret = seahorse_delete_dialog_prompt (GTK_WINDOW (seahorse_widget_get_toplevel (swidget)), message);
 	g_free (message);
 	
 	if (ret == FALSE)
@@ -1076,7 +1077,7 @@ on_pgp_details_del_subkey_button (GtkButton *button,
 	index = seahorse_pgp_subkey_get_index (subkey);
 	label = seahorse_object_get_label (SEAHORSE_OBJECT (pkey));
 	message = g_strdup_printf (_("Are you sure you want to permanently delete subkey %d of %s?"), index, label);
-	ret = seahorse_util_prompt_delete (message, seahorse_widget_get_toplevel (swidget));
+	ret = seahorse_delete_dialog_prompt (GTK_WINDOW (seahorse_widget_get_toplevel (swidget)), message);
 	g_free (message);
 	
 	if (ret == FALSE)
diff --git a/pkcs11/seahorse-pkcs11-actions.c b/pkcs11/seahorse-pkcs11-actions.c
index 472ce09..809822c 100644
--- a/pkcs11/seahorse-pkcs11-actions.c
+++ b/pkcs11/seahorse-pkcs11-actions.c
@@ -33,6 +33,7 @@
 
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
+#include "seahorse-delete-dialog.h"
 #include "seahorse-object-list.h"
 #include "seahorse-progress.h"
 #include "seahorse-registry.h"
@@ -226,7 +227,7 @@ on_delete_objects (GtkAction *action,
 	GCancellable *cancellable;
 	gchar *prompt;
 	gchar *display;
-	GtkWidget *parent;
+	GtkWindow *parent;
 	gboolean ret;
 	guint num;
 	GList *objects;
@@ -244,8 +245,8 @@ on_delete_objects (GtkAction *action,
 				num), num);
 	}
 
-	parent = GTK_WIDGET (seahorse_action_get_window (action));
-	ret = seahorse_util_prompt_delete (prompt, parent);
+	parent = seahorse_action_get_window (action);
+	ret = seahorse_delete_dialog_prompt (parent, prompt);
 	g_free (prompt);
 
 	if (ret) {
diff --git a/pkcs11/seahorse-pkcs11-properties.c b/pkcs11/seahorse-pkcs11-properties.c
index fcb81d3..540b6c8 100644
--- a/pkcs11/seahorse-pkcs11-properties.c
+++ b/pkcs11/seahorse-pkcs11-properties.c
@@ -23,9 +23,25 @@
 
 #include "seahorse-certificate.h"
 #include "seahorse-pkcs11-properties.h"
+#include "seahorse-pkcs11-operations.h"
+#include "seahorse-private-key.h"
+
+#include "seahorse-delete-dialog.h"
+#include "seahorse-progress.h"
+#include "seahorse-util.h"
 
 #include <gcr/gcr.h>
 
+static const gchar *UI_STRING =
+"<ui>"
+"	<toolbar name='Toolbar'>"
+"		<toolitem action='export-object'/>"
+"		<toolitem action='delete-object'/>"
+"		<separator name='MiddleSeparator' expand='true'/>"
+"		<toolitem action='extra-action'/>"
+"	</toolbar>"
+"</ui>";
+
 #define SEAHORSE_PKCS11_PROPERTIES_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PKCS11_PROPERTIES, SeahorsePkcs11PropertiesClass))
 #define SEAHORSE_IS_PKCS11_PROPERTIES_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PKCS11_PROPERTIES))
 #define SEAHORSE_PKCS11_PROPERTIES_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PKCS11_PROPERTIES, SeahorsePkcs11PropertiesClass))
@@ -34,8 +50,11 @@ typedef struct _SeahorsePkcs11PropertiesClass SeahorsePkcs11PropertiesClass;
 
 struct _SeahorsePkcs11Properties {
 	GtkWindow parent;
+	GtkBox *content;
 	GcrViewer *viewer;
 	GObject *object;
+	GtkUIManager *ui_manager;
+	GtkActionGroup *actions;
 };
 
 struct _SeahorsePkcs11PropertiesClass {
@@ -58,9 +77,13 @@ seahorse_pkcs11_properties_init (SeahorsePkcs11Properties *self)
 
 	gtk_window_set_default_size (GTK_WINDOW (self), 400, 400);
 
+	self->content = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
+	gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->content));
+	gtk_widget_show (GTK_WIDGET (self->content));
+
 	self->viewer = gcr_viewer_new_scrolled ();
 	viewer = GTK_WIDGET (self->viewer);
-	gtk_container_add (GTK_CONTAINER (self), viewer);
+	gtk_container_add (GTK_CONTAINER (self->content), viewer);
 	gtk_widget_set_hexpand (viewer, TRUE);
 	gtk_widget_set_vexpand (viewer, TRUE);
 	gtk_widget_show (viewer);
@@ -123,17 +146,151 @@ on_object_label_changed (GObject *obj,
 }
 
 static void
+on_export_certificate (GtkAction *action,
+                       gpointer user_data)
+{
+	/* TODO: Exporter not done */
+}
+
+static void
+on_delete_complete (GObject *source,
+                    GAsyncResult *result,
+                    gpointer user_data)
+{
+	SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (user_data);
+	GError *error = NULL;
+
+	if (seahorse_pkcs11_delete_finish (result, &error))
+		gtk_widget_destroy (GTK_WIDGET (self));
+
+	else
+		seahorse_util_handle_error (&error, self, _("Couldn't delete"));
+
+	g_object_unref (self);
+}
+
+static void
+on_delete_objects (GtkAction *action,
+                   gpointer user_data)
+{
+	SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (user_data);
+	gboolean with_partner = FALSE;
+	GObject *partner = NULL;
+	GtkDialog *dialog = NULL;
+	GCancellable *cancellable;
+	GList *objects = NULL;
+	gchar *label;
+
+	g_object_get (self->object,
+	              "label", &label,
+	              "partner", &partner,
+	              NULL);
+
+	if (SEAHORSE_IS_CERTIFICATE (self->object)) {
+		objects = g_list_prepend (objects, g_object_ref (self->object));
+		dialog = seahorse_delete_dialog_new (GTK_WINDOW (self),
+		                                     _("Are you sure you want to delete the certificate '%s'?"),
+		                                     label);
+
+		if (SEAHORSE_IS_PRIVATE_KEY (partner)) {
+			seahorse_delete_dialog_set_check_value (SEAHORSE_DELETE_DIALOG (dialog), FALSE);
+			seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog),
+			                                        _("Also delete matching private key"));
+			with_partner = TRUE;
+		}
+
+	} else if (SEAHORSE_IS_PRIVATE_KEY (self->object)) {
+		objects = g_list_prepend (objects, g_object_ref (self->object));
+		dialog = seahorse_delete_dialog_new (GTK_WINDOW (self),
+		                                     _("Are you sure you want to delete the private key '%s'?"),
+		                                     label);
+
+		seahorse_delete_dialog_set_check_value (SEAHORSE_DELETE_DIALOG (dialog), FALSE);
+		seahorse_delete_dialog_set_check_require (SEAHORSE_DELETE_DIALOG (dialog), TRUE);
+		seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog),
+		                                        _("I understand that this action cannot be undone"));
+	}
+
+	if (dialog && gtk_dialog_run (dialog) == GTK_RESPONSE_OK) {
+		if (with_partner)
+			objects = g_list_prepend (objects, partner);
+
+		cancellable = g_cancellable_new ();
+		seahorse_pkcs11_delete_async (objects, cancellable,
+		                              on_delete_complete, g_object_ref (self));
+		seahorse_progress_show (cancellable, _("Deleting"), TRUE);
+		g_object_unref (cancellable);
+	}
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+	g_list_free_full (objects, g_object_unref);
+	g_clear_object (&partner);
+	g_free (label);
+}
+
+static void
+on_extra_action (GtkAction *action,
+                 gpointer user_data)
+{
+
+}
+
+
+static const GtkActionEntry UI_ACTIONS[] = {
+	{ "export-object", GTK_STOCK_SAVE_AS, N_("_Export"), "",
+	  N_("Export the certificate"), G_CALLBACK (on_export_certificate) },
+	{ "delete-object", GTK_STOCK_DELETE, N_("_Delete"), "<Ctrl>Delete",
+	  N_("Delete this certificate or key"), G_CALLBACK (on_delete_objects) },
+	{ "extra-action", NULL, N_("Extra _Action"), NULL,
+	  N_("An extra action on the certificate"), G_CALLBACK (on_extra_action) },
+};
+
+static void
+on_ui_manager_add_widget (GtkUIManager *manager,
+                          GtkWidget *widget,
+                          gpointer user_data)
+{
+	SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (user_data);
+
+	if (!GTK_IS_TOOLBAR (widget))
+		return;
+
+	gtk_box_pack_start (self->content, widget, FALSE, TRUE, 0);
+	gtk_box_reorder_child (self->content, widget, 0);
+
+	gtk_style_context_add_class (gtk_widget_get_style_context (widget),
+	                             GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+	gtk_widget_reset_style (widget);
+	gtk_widget_show (widget);
+}
+
+static void
 seahorse_pkcs11_properties_constructed (GObject *obj)
 {
 	SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (obj);
 	GObject *partner = NULL;
+	GError *error = NULL;
 
 	G_OBJECT_CLASS (seahorse_pkcs11_properties_parent_class)->constructed (obj);
 
+	self->actions = gtk_action_group_new ("Pkcs11Actions");
+	gtk_action_group_add_actions (self->actions, UI_ACTIONS, G_N_ELEMENTS (UI_ACTIONS), self);
+
+	self->ui_manager = gtk_ui_manager_new ();
+	gtk_ui_manager_insert_action_group (self->ui_manager, self->actions, 0);
+	g_signal_connect (self->ui_manager, "add-widget", G_CALLBACK (on_ui_manager_add_widget), self);
+	gtk_ui_manager_add_ui_from_string (self->ui_manager, UI_STRING, -1, &error);
+	if (error != NULL) {
+		g_warning ("couldn't load ui: %s", error->message);
+		g_error_free (error);
+	}
+	gtk_ui_manager_ensure_update (self->ui_manager);
+
 	g_return_if_fail (self->object != NULL);
 	g_object_set_qdata (self->object, QUARK_WINDOW, self);
 
-	g_signal_connect (self->object, "notify::label", G_CALLBACK (on_object_label_changed), self);
+	g_signal_connect_object (self->object, "notify::label", G_CALLBACK (on_object_label_changed),
+	                         self, G_CONNECT_AFTER);
 	on_object_label_changed (self->object, NULL, self);
 
 	add_renderer_for_object (self, self->object);
@@ -143,6 +300,8 @@ seahorse_pkcs11_properties_constructed (GObject *obj)
 		add_renderer_for_object (self, partner);
 		g_object_unref (partner);
 	}
+
+	gtk_widget_grab_focus (GTK_WIDGET (self->viewer));
 }
 
 static void
@@ -187,6 +346,9 @@ seahorse_pkcs11_properties_finalize (GObject *obj)
 {
 	SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (obj);
 
+	g_object_unref (self->actions);
+	g_object_unref (self->ui_manager);
+
 	if (self->object) {
 		if (g_object_get_qdata (self->object, QUARK_WINDOW) == self)
 			g_object_set_qdata (self->object, QUARK_WINDOW, NULL);
diff --git a/ssh/seahorse-ssh-actions.c b/ssh/seahorse-ssh-actions.c
index ae05cde..0ba6ade 100644
--- a/ssh/seahorse-ssh-actions.c
+++ b/ssh/seahorse-ssh-actions.c
@@ -29,6 +29,7 @@
 
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
+#include "seahorse-delete-dialog.h"
 #include "seahorse-object.h"
 #include "seahorse-object-list.h"
 #include "seahorse-registry.h"
@@ -96,7 +97,7 @@ on_delete_objects (GtkAction *action,
 	guint num;
 	gchar* prompt;
 	GList *l;
-	GtkWidget *parent;
+	GtkWindow *parent;
 	GError *error = NULL;
 	GList* objects;
 
@@ -116,8 +117,8 @@ on_delete_objects (GtkAction *action,
 		                          num);
 	}
 
-	parent = GTK_WIDGET (seahorse_action_get_window (action));
-	if (seahorse_util_prompt_delete (prompt, NULL)) {
+	parent = seahorse_action_get_window (action);
+	if (seahorse_delete_dialog_prompt (parent, prompt)) {
 		for (l = objects; l != NULL; l = g_list_next (l)) {
 			if (!seahorse_ssh_op_delete_sync (l->data, &error)) {
 				seahorse_util_handle_error (&error, parent, _("Couldn't delete key"));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]