[seahorse] Refactor deleting, add SeahorseDeleter and SeahorseDeletable types
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse] Refactor deleting, add SeahorseDeleter and SeahorseDeletable types
- Date: Thu, 1 Dec 2011 11:20:19 +0000 (UTC)
commit 3b34b0009119313d903566ecd01a21a62500e345
Author: Stef Walter <stefw collabora co uk>
Date: Thu Dec 1 12:18:34 2011 +0100
Refactor deleting, add SeahorseDeleter and SeahorseDeletable types
* SeahorseDeletable is an interface implemented by objects that can
be deletable, with a "deletable" boolean property, and a create_deleter()
method.
* SeahorseDeleter is an object that can delete objects, combining them
if possible.
gkr/Makefile.am | 2 +
gkr/seahorse-gkr-actions.c | 110 +-------
gkr/seahorse-gkr-item-deleter.c | 271 ++++++++++++++++++++
gkr/seahorse-gkr-item-deleter.h | 42 +++
gkr/seahorse-gkr-item.c | 25 ++-
gkr/seahorse-gkr-keyring-deleter.c | 228 ++++++++++++++++
gkr/seahorse-gkr-keyring-deleter.h | 42 +++
gkr/seahorse-gkr-keyring.c | 22 ++-
gkr/seahorse-gkr-operation.c | 148 -----------
gkr/seahorse-gkr-operation.h | 8 -
libseahorse/Makefile.am | 2 +
libseahorse/seahorse-deletable.c | 185 +++++++++++++
libseahorse/seahorse-deletable.h | 53 ++++
libseahorse/seahorse-deleter.c | 135 ++++++++++
libseahorse/seahorse-deleter.h | 92 +++++++
libseahorse/seahorse-exportable.c | 22 ++-
libseahorse/seahorse-exportable.h | 2 +
libseahorse/seahorse-object.c | 18 ++-
libseahorse/seahorse-viewer.c | 32 +--
pgp/Makefile.am | 2 +
pgp/seahorse-gpgme-key-deleter.c | 181 +++++++++++++
pgp/seahorse-gpgme-key-deleter.h | 42 +++
pgp/seahorse-gpgme-key.c | 22 ++
pgp/seahorse-gpgme-secret-deleter.c | 177 +++++++++++++
pgp/seahorse-gpgme-secret-deleter.h | 42 +++
pgp/seahorse-pgp-actions.c | 117 ---------
pkcs11/Makefile.am | 3 +-
pkcs11/seahorse-certificate.c | 51 ++++-
pkcs11/seahorse-pkcs11-actions.c | 63 -----
pkcs11/seahorse-pkcs11-deleter.c | 235 +++++++++++++++++
pkcs11/seahorse-pkcs11-deleter.h | 55 ++++
pkcs11/seahorse-pkcs11-key-deleter.c | 150 +++++++++++
pkcs11/seahorse-pkcs11-key-deleter.h | 42 +++
pkcs11/seahorse-pkcs11-operations.c | 146 -----------
pkcs11/seahorse-pkcs11-properties.c | 67 ++----
pkcs11/seahorse-private-key.c | 29 ++-
pkcs11/seahorse-token.c | 25 ++-
pkcs11/seahorse-token.h | 3 +
ssh/Makefile.am | 1 +
ssh/seahorse-ssh-actions.c | 44 ----
ssh/seahorse-ssh-deleter.c | 205 +++++++++++++++
.../seahorse-ssh-deleter.h | 38 ++--
ssh/seahorse-ssh-key.c | 20 ++-
43 files changed, 2476 insertions(+), 723 deletions(-)
---
diff --git a/gkr/Makefile.am b/gkr/Makefile.am
index ef1e392..7fc401b 100644
--- a/gkr/Makefile.am
+++ b/gkr/Makefile.am
@@ -23,8 +23,10 @@ libseahorse_gkr_la_SOURCES = \
seahorse-gkr-backend.c seahorse-gkr-backend.h \
seahorse-gkr-dialogs.h seahorse-gkr-dialogs.c \
seahorse-gkr-item.c seahorse-gkr-item.h \
+ seahorse-gkr-item-deleter.c seahorse-gkr-item-deleter.h \
seahorse-gkr-item-properties.c \
seahorse-gkr-keyring.c seahorse-gkr-keyring.h \
+ seahorse-gkr-keyring-deleter.c seahorse-gkr-keyring-deleter.h \
seahorse-gkr-keyring-properties.c \
seahorse-gkr-operation.c seahorse-gkr-operation.h
diff --git a/gkr/seahorse-gkr-actions.c b/gkr/seahorse-gkr-actions.c
index 9236188..533a3ad 100644
--- a/gkr/seahorse-gkr-actions.c
+++ b/gkr/seahorse-gkr-actions.c
@@ -25,6 +25,7 @@
#include "seahorse-gkr-actions.h"
#include "seahorse-gkr-backend.h"
#include "seahorse-gkr-keyring.h"
+#include "seahorse-gkr-keyring-deleter.h"
#include "seahorse-gkr-dialogs.h"
#include "seahorse-gkr-operation.h"
@@ -301,12 +302,14 @@ on_keyring_properties (GtkAction* action,
}
static void
-on_delete_objects_complete (GObject *source, GAsyncResult *result, gpointer user_data)
+on_delete_keyring_complete (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
GtkWindow *parent = GTK_WINDOW (user_data);
GError *error = NULL;
- if (!seahorse_gkr_delete_finish (result, &error)) {
+ if (!seahorse_deleter_delete_finish (SEAHORSE_DELETER (source), result, &error)) {
seahorse_util_show_error (parent, _("Couldn't delete keyring"), error->message);
g_error_free (error);
}
@@ -318,33 +321,16 @@ static void
on_keyrings_delete (GtkAction* action,
gpointer user_data)
{
- GList *objects = user_data;
- GCancellable *cancellable;
- GtkWindow *parent;
- gchar *prompt;
- gboolean ret;
-
- if (!objects)
- return;
+ SeahorseGkrKeyring *keyring = SEAHORSE_GKR_KEYRING (user_data);
+ GtkWindow *parent = seahorse_action_get_window (action);
+ SeahorseDeleter *deleter;
- prompt = g_strdup_printf (_ ("Are you sure you want to delete the password keyring '%s'?"),
- seahorse_object_get_label (objects->data));
- parent = seahorse_action_get_window (action);
+ deleter = seahorse_gkr_keyring_deleter_new (keyring);
- ret = seahorse_delete_dialog_prompt (parent, prompt);
- if (ret) {
- cancellable = g_cancellable_new ();
- seahorse_gkr_delete_async (objects, cancellable,
- on_delete_objects_complete,
- g_object_ref (parent));
- seahorse_progress_show (cancellable, ngettext ("Deleting keyring", "Deleting keyrings",
- g_list_length (objects)), TRUE);
- g_object_unref (cancellable);
- } else {
- g_cancellable_cancel (g_cancellable_get_current ());
- }
-
- g_free (prompt);
+ if (seahorse_deleter_prompt (deleter, parent))
+ seahorse_deleter_delete_async (deleter, NULL, on_delete_keyring_complete,
+ g_object_ref (parent));
+ g_object_unref (deleter);
}
static const GtkActionEntry KEYRINGS_ACTIONS[] = {
@@ -352,8 +338,6 @@ static const GtkActionEntry KEYRINGS_ACTIONS[] = {
N_("Lock the password storage keyring so a master password is required to unlock it."), G_CALLBACK (on_keyrings_lock) },
{ "keyring-unlock", NULL, N_("_Unlock"), "",
N_("Unlock the password storage keyring with a master password so it is available for use."), G_CALLBACK (on_keyrings_unlock) },
- { "keyring-delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the keyring."), G_CALLBACK (on_keyrings_delete) },
};
static const GtkActionEntry KEYRING_ACTIONS[] = {
@@ -363,6 +347,8 @@ static const GtkActionEntry KEYRING_ACTIONS[] = {
N_("Change the unlock password of the password storage keyring"), G_CALLBACK (on_keyring_password) },
{ "keyring-properties", GTK_STOCK_PROPERTIES, NULL, NULL,
N_("Properties of the keyring."), G_CALLBACK (on_keyring_properties) },
+ { "keyring-delete", GTK_STOCK_DELETE, NULL, NULL,
+ N_("Delete the keyring."), G_CALLBACK (on_keyrings_delete) },
/* Generic actions used by the sidebar for the current selection */
{ "lock", NULL, NULL, "",
@@ -496,73 +482,11 @@ on_password_properties (GtkAction *action,
seahorse_action_get_window (action));
}
-static void
-on_delete_objects (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GtkWidget *parent = GTK_WIDGET (user_data);
- GError *error = NULL;
-
- if (!seahorse_gkr_delete_finish (result, &error)) {
- seahorse_util_show_error (parent, _("Couldn't delete item"), error->message);
- g_error_free (error);
- }
-
- g_object_unref (parent);
-}
-
-static void
-on_delete_passwords (GtkAction *action,
- gpointer user_data)
-{
- GCancellable *cancellable;
- GtkWindow *parent;
- GList *objects;
- gchar *prompt;
- gboolean ret;
- guint num;
-
- objects = user_data;
- if (objects == NULL)
- return;
-
- num = g_list_length (objects);
- if (num == 1) {
- prompt = g_strdup_printf (_ ("Are you sure you want to delete the password '%s'?"),
- seahorse_object_get_label (SEAHORSE_OBJECT (objects->data)));
- } else {
- prompt = g_strdup_printf (ngettext ("Are you sure you want to delete %d password?",
- "Are you sure you want to delete %d passwords?",
- num), num);
- }
-
- parent = seahorse_action_get_window (action);
- ret = seahorse_delete_dialog_prompt (parent, prompt);
-
- if (ret) {
- cancellable = g_cancellable_new ();
- seahorse_gkr_delete_async (objects, cancellable, on_delete_objects, g_object_ref (parent));
- seahorse_progress_show (cancellable, ngettext ("Deleting item", "Deleting items", num), TRUE);
- g_object_unref (cancellable);
- } else {
- g_cancellable_cancel (g_cancellable_get_current ());
-
- }
-
- g_free (prompt);
-}
-
static const GtkActionEntry ITEM_ACTIONS[] = {
{ "properties", GTK_STOCK_PROPERTIES, NULL, NULL,
N_("Properties of the password."), G_CALLBACK (on_password_properties) },
};
-static const GtkActionEntry ITEMS_ACTIONS[] = {
- { "delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the password."), G_CALLBACK (on_delete_passwords) },
-};
-
static void
seahorse_gkr_item_actions_init (SeahorseGkrItemActions *self)
{
@@ -577,10 +501,6 @@ seahorse_gkr_item_actions_clone_for_objects (SeahorseActions *actions,
cloned = gtk_action_group_new ("KeyringItem");
gtk_action_group_set_translation_domain (cloned, GETTEXT_PACKAGE);
- gtk_action_group_add_actions_full (cloned, ITEMS_ACTIONS,
- G_N_ELEMENTS (ITEMS_ACTIONS),
- seahorse_object_list_copy (objects),
- seahorse_object_list_free);
if (!objects->next)
gtk_action_group_add_actions_full (cloned, ITEM_ACTIONS,
diff --git a/gkr/seahorse-gkr-item-deleter.c b/gkr/seahorse-gkr-item-deleter.c
new file mode 100644
index 0000000..441a58f
--- /dev/null
+++ b/gkr/seahorse-gkr-item-deleter.c
@@ -0,0 +1,271 @@
+/*
+ * 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-gkr-backend.h"
+#include "seahorse-gkr-item-deleter.h"
+#include "seahorse-gkr-operation.h"
+
+#include "seahorse-delete-dialog.h"
+#include "seahorse-object.h"
+
+#include <gnome-keyring.h>
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_GKR_ITEM_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_GKR_ITEM_DELETER, SeahorseGkrItemDeleterClass))
+#define SEAHORSE_IS_GKR_ITEM_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_GKR_ITEM_DELETER))
+#define SEAHORSE_GKR_ITEM_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_GKR_ITEM_DELETER, SeahorseGkrItemDeleterClass))
+
+typedef struct _SeahorseGkrItemDeleterClass SeahorseGkrItemDeleterClass;
+
+struct _SeahorseGkrItemDeleter {
+ SeahorseDeleter parent;
+ GList *items;
+};
+
+struct _SeahorseGkrItemDeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+static void delete_one_item (GSimpleAsyncResult *res);
+
+G_DEFINE_TYPE (SeahorseGkrItemDeleter, seahorse_gkr_item_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_gkr_item_deleter_init (SeahorseGkrItemDeleter *self)
+{
+
+}
+
+static void
+seahorse_gkr_item_deleter_finalize (GObject *obj)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (obj);
+
+ g_list_free_full (self->items, g_object_unref);
+
+ G_OBJECT_CLASS (seahorse_gkr_item_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_gkr_item_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (deleter);
+ GtkDialog *dialog;
+ gchar *prompt;
+ guint num;
+
+ num = g_list_length (self->items);
+ if (num == 1) {
+ prompt = g_strdup_printf (_ ("Are you sure you want to delete the password '%s'?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->items->data)));
+ } else {
+ prompt = g_strdup_printf (ngettext ("Are you sure you want to delete %d password?",
+ "Are you sure you want to delete %d passwords?",
+ num), num);
+ }
+
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+ g_free (prompt);
+
+ return dialog;
+}
+
+static GList *
+seahorse_gkr_item_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (deleter);
+ return self->items;
+}
+
+static gboolean
+seahorse_gkr_item_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (deleter);
+
+ if (!SEAHORSE_IS_GKR_ITEM (object))
+ return FALSE;
+ self->items = g_list_append (self->items, g_object_ref (object));
+ return TRUE;
+}
+
+typedef struct {
+ SeahorseGkrItem *current;
+ GCancellable *cancellable;
+ GQueue queue;
+ gpointer request;
+ gulong cancelled_sig;
+} DeleteClosure;
+
+static void
+delete_closure_free (gpointer data)
+{
+ DeleteClosure *closure = data;
+ SeahorseGkrItem *item;
+
+ g_clear_object (&closure->current);
+ while ((item = g_queue_pop_head (&closure->queue)))
+ g_object_unref (item);
+ g_queue_clear (&closure->queue);
+ if (closure->cancellable && closure->cancelled_sig)
+ g_signal_handler_disconnect (closure->cancellable,
+ closure->cancelled_sig);
+ g_clear_object (&closure->cancellable);
+ g_assert (!closure->request);
+ g_free (closure);
+}
+
+static void
+on_delete_gkr_complete (GnomeKeyringResult result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (g_async_result_get_source_object (user_data));
+ SeahorseGkrKeyring *keyring;
+ GError *error = NULL;
+ guint32 item_id;
+
+ closure->request = NULL;
+
+ if (seahorse_gkr_propagate_error (result, &error)) {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete_in_idle (res);
+
+ } else {
+ g_object_get (closure->current, "place", &keyring, NULL);
+ item_id = seahorse_gkr_item_get_item_id (closure->current);
+ seahorse_gkr_keyring_remove_item (keyring, item_id);
+ g_object_unref (keyring);
+ delete_one_item (res);
+ }
+
+ g_object_unref (self);
+}
+
+static void
+delete_one_item (GSimpleAsyncResult *res)
+{
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ const gchar *name;
+ guint32 item_id;
+
+ g_clear_object (&closure->current);
+ closure->current = g_queue_pop_head (&closure->queue);
+ if (closure->current == NULL) {
+ g_simple_async_result_complete_in_idle (res);
+
+ } else {
+ name = seahorse_gkr_item_get_keyring_name (closure->current);
+ item_id = seahorse_gkr_item_get_item_id (closure->current);
+ gnome_keyring_item_delete (name, item_id, on_delete_gkr_complete,
+ g_object_ref (res), g_object_unref);
+ }
+}
+
+static void
+on_delete_gkr_cancelled (GCancellable *cancellable,
+ gpointer user_data)
+{
+ DeleteClosure *closure = user_data;
+
+ if (closure->request)
+ gnome_keyring_cancel_request (closure->request);
+}
+
+static void
+seahorse_gkr_item_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ DeleteClosure *closure;
+ GList *l;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_gkr_item_deleter_delete_async);
+ closure = g_new0 (DeleteClosure, 1);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ g_queue_init (&closure->queue);
+ for (l = self->items; l != NULL; l = g_list_next (l))
+ g_queue_push_tail (&closure->queue, g_object_ref (l->data));
+ g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
+
+ if (cancellable)
+ closure->cancelled_sig = g_cancellable_connect (cancellable,
+ G_CALLBACK (on_delete_gkr_cancelled),
+ closure, NULL);
+
+ delete_one_item (res);
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_gkr_item_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseGkrItemDeleter *self = SEAHORSE_GKR_ITEM_DELETER (deleter);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ seahorse_gkr_item_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+seahorse_gkr_item_deleter_class_init (SeahorseGkrItemDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_gkr_item_deleter_finalize;
+
+ deleter_class->add_object = seahorse_gkr_item_deleter_add_object;
+ deleter_class->create_confirm = seahorse_gkr_item_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_gkr_item_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_gkr_item_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_gkr_item_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_gkr_item_deleter_new (SeahorseGkrItem *item)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_GKR_ITEM_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (item)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/gkr/seahorse-gkr-item-deleter.h b/gkr/seahorse-gkr-item-deleter.h
new file mode 100644
index 0000000..1d493ac
--- /dev/null
+++ b/gkr/seahorse-gkr-item-deleter.h
@@ -0,0 +1,42 @@
+/*
+ * 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_GKR_ITEM_DELETER_H__
+#define __SEAHORSE_GKR_ITEM_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-gkr-item.h"
+
+#define SEAHORSE_TYPE_GKR_ITEM_DELETER (seahorse_gkr_item_deleter_get_type ())
+#define SEAHORSE_GKR_ITEM_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_GKR_ITEM_DELETER, SeahorseGkrItemDeleter))
+#define SEAHORSE_IS_GKR_ITEM_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_GKR_ITEM_DELETER))
+
+typedef struct _SeahorseGkrItemDeleter SeahorseGkrItemDeleter;
+
+GType seahorse_gkr_item_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_gkr_item_deleter_new (SeahorseGkrItem *item);
+
+#endif /* __SEAHORSE_GKR_ITEM_DELETER_H__ */
diff --git a/gkr/seahorse-gkr-item.c b/gkr/seahorse-gkr-item.c
index 8c9e1ea..4e5486d 100644
--- a/gkr/seahorse-gkr-item.c
+++ b/gkr/seahorse-gkr-item.c
@@ -29,9 +29,11 @@
#include "seahorse-gkr.h"
#include "seahorse-gkr-actions.h"
#include "seahorse-gkr-item.h"
+#include "seahorse-gkr-item-deleter.h"
#include "seahorse-gkr-keyring.h"
#include "seahorse-gkr-operation.h"
+#include "seahorse-deletable.h"
#include "seahorse-icons.h"
#include "seahorse-place.h"
#include "seahorse-util.h"
@@ -472,9 +474,13 @@ struct _SeahorseGkrItemPrivate {
DisplayInfo *display_info;
};
-static gboolean require_item_attrs (SeahorseGkrItem *self);
+static gboolean require_item_attrs (SeahorseGkrItem *self);
-G_DEFINE_TYPE (SeahorseGkrItem, seahorse_gkr_item, SEAHORSE_TYPE_OBJECT);
+static void seahorse_gkr_item_deletable_iface (SeahorseDeletableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SeahorseGkrItem, seahorse_gkr_item, SEAHORSE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_gkr_item_deletable_iface);
+);
/* -----------------------------------------------------------------------------
* INTERNAL HELPERS
@@ -907,9 +913,18 @@ seahorse_gkr_item_class_init (SeahorseGkrItemClass *klass)
FALSE, G_PARAM_READABLE));
}
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
+static SeahorseDeleter *
+seahorse_gkr_item_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (deletable);
+ return seahorse_gkr_item_deleter_new (self);
+}
+
+static void
+seahorse_gkr_item_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_gkr_item_create_deleter;
+}
SeahorseGkrItem *
seahorse_gkr_item_new (SeahorseGkrKeyring *keyring,
diff --git a/gkr/seahorse-gkr-keyring-deleter.c b/gkr/seahorse-gkr-keyring-deleter.c
new file mode 100644
index 0000000..a304225
--- /dev/null
+++ b/gkr/seahorse-gkr-keyring-deleter.c
@@ -0,0 +1,228 @@
+/*
+ * 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-gkr-backend.h"
+#include "seahorse-gkr-keyring-deleter.h"
+#include "seahorse-gkr-operation.h"
+
+#include "seahorse-delete-dialog.h"
+#include "seahorse-object.h"
+
+#include <gnome-keyring.h>
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_GKR_KEYRING_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_GKR_KEYRING_DELETER, SeahorseGkrKeyringDeleterClass))
+#define SEAHORSE_IS_GKR_KEYRING_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_GKR_KEYRING_DELETER))
+#define SEAHORSE_GKR_KEYRING_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_GKR_KEYRING_DELETER, SeahorseGkrKeyringDeleterClass))
+
+typedef struct _SeahorseGkrKeyringDeleterClass SeahorseGkrKeyringDeleterClass;
+
+struct _SeahorseGkrKeyringDeleter {
+ SeahorseDeleter parent;
+ SeahorseGkrKeyring *keyring;
+ GList *objects;
+};
+
+struct _SeahorseGkrKeyringDeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+G_DEFINE_TYPE (SeahorseGkrKeyringDeleter, seahorse_gkr_keyring_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_gkr_keyring_deleter_init (SeahorseGkrKeyringDeleter *self)
+{
+
+}
+
+static void
+seahorse_gkr_keyring_deleter_finalize (GObject *obj)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (obj);
+
+ g_object_unref (self->keyring);
+ g_list_free (self->objects);
+
+ G_OBJECT_CLASS (seahorse_gkr_keyring_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_gkr_keyring_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (deleter);
+ GtkDialog *dialog;
+
+ dialog = seahorse_delete_dialog_new (parent,
+ _("Are you sure you want to delete the password keyring '%s'?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->keyring)));
+
+ seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog), _("I understand that all items will be permanently deleted."));
+ seahorse_delete_dialog_set_check_require (SEAHORSE_DELETE_DIALOG (dialog), TRUE);
+
+ return dialog;
+}
+
+static GList *
+seahorse_gkr_keyring_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (deleter);
+ return self->objects;
+}
+
+static gboolean
+seahorse_gkr_keyring_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (deleter);
+ if (self->keyring)
+ return FALSE;
+ if (!SEAHORSE_IS_GKR_KEYRING (object))
+ return FALSE;
+ self->keyring = g_object_ref (object);
+ self->objects = g_list_append (self->objects, self->keyring);
+ return TRUE;
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ gpointer request;
+ gulong cancelled_sig;
+} DeleteClosure;
+
+static void
+delete_closure_free (gpointer data)
+{
+ DeleteClosure *closure = data;
+ if (closure->cancellable && closure->cancelled_sig)
+ g_signal_handler_disconnect (closure->cancellable,
+ closure->cancelled_sig);
+ g_clear_object (&closure->cancellable);
+ g_assert (!closure->request);
+ g_free (closure);
+}
+
+static void
+on_delete_gkr_complete (GnomeKeyringResult result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (g_async_result_get_source_object (user_data));
+ GError *error = NULL;
+
+ closure->request = NULL;
+
+ if (seahorse_gkr_propagate_error (result, &error))
+ g_simple_async_result_take_error (res, error);
+ else
+ seahorse_gkr_backend_remove_keyring (NULL, self->keyring);
+
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (self);
+}
+
+static void
+on_delete_gkr_cancelled (GCancellable *cancellable,
+ gpointer user_data)
+{
+ DeleteClosure *closure = user_data;
+
+ if (closure->request)
+ gnome_keyring_cancel_request (closure->request);
+}
+
+static void
+seahorse_gkr_keyring_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ DeleteClosure *closure;
+ const gchar *name;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_gkr_keyring_deleter_delete_async);
+ closure = g_new0 (DeleteClosure, 1);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
+
+ name = seahorse_gkr_keyring_get_name (self->keyring);
+ closure->request = gnome_keyring_delete (name, on_delete_gkr_complete,
+ g_object_ref (res), g_object_unref);
+
+ if (cancellable)
+ closure->cancelled_sig = g_cancellable_connect (cancellable,
+ G_CALLBACK (on_delete_gkr_cancelled),
+ closure, NULL);
+
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_gkr_keyring_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseGkrKeyringDeleter *self = SEAHORSE_GKR_KEYRING_DELETER (deleter);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ seahorse_gkr_keyring_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+seahorse_gkr_keyring_deleter_class_init (SeahorseGkrKeyringDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_gkr_keyring_deleter_finalize;
+
+ deleter_class->add_object = seahorse_gkr_keyring_deleter_add_object;
+ deleter_class->create_confirm = seahorse_gkr_keyring_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_gkr_keyring_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_gkr_keyring_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_gkr_keyring_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_gkr_keyring_deleter_new (SeahorseGkrKeyring *keyring)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_GKR_KEYRING_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (keyring)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/gkr/seahorse-gkr-keyring-deleter.h b/gkr/seahorse-gkr-keyring-deleter.h
new file mode 100644
index 0000000..75c23d2
--- /dev/null
+++ b/gkr/seahorse-gkr-keyring-deleter.h
@@ -0,0 +1,42 @@
+/*
+ * 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_GKR_KEYRING_DELETER_H__
+#define __SEAHORSE_GKR_KEYRING_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-gkr-keyring.h"
+
+#define SEAHORSE_TYPE_GKR_KEYRING_DELETER (seahorse_gkr_keyring_deleter_get_type ())
+#define SEAHORSE_GKR_KEYRING_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_GKR_KEYRING_DELETER, SeahorseGkrKeyringDeleter))
+#define SEAHORSE_IS_GKR_KEYRING_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_GKR_KEYRING_DELETER))
+
+typedef struct _SeahorseGkrKeyringDeleter SeahorseGkrKeyringDeleter;
+
+GType seahorse_gkr_keyring_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_gkr_keyring_deleter_new (SeahorseGkrKeyring *keyring);
+
+#endif /* __SEAHORSE_GKR_KEYRING_DELETER_H__ */
diff --git a/gkr/seahorse-gkr-keyring.c b/gkr/seahorse-gkr-keyring.c
index ee917b2..b309e6f 100644
--- a/gkr/seahorse-gkr-keyring.c
+++ b/gkr/seahorse-gkr-keyring.c
@@ -23,11 +23,13 @@
#include "config.h"
#include "seahorse-gkr.h"
+#include "seahorse-gkr-keyring-deleter.h"
#include "seahorse-gkr-keyring.h"
#include "seahorse-gkr-operation.h"
#include "seahorse-gkr-actions.h"
#include "seahorse-action.h"
+#include "seahorse-deletable.h"
#include "seahorse-progress.h"
#include "seahorse-util.h"
@@ -59,11 +61,15 @@ struct _SeahorseGkrKeyringPrivate {
};
static void seahorse_keyring_place_iface (SeahorsePlaceIface *iface);
+
static void seahorse_keyring_collection_iface (GcrCollectionIface *iface);
+static void seahorse_keyring_deletable_iface (SeahorseDeletableIface *iface);
+
G_DEFINE_TYPE_WITH_CODE (SeahorseGkrKeyring, seahorse_gkr_keyring, SEAHORSE_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_keyring_collection_iface);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_keyring_place_iface);
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_keyring_deletable_iface);
);
static GType
@@ -520,9 +526,19 @@ seahorse_keyring_collection_iface (GcrCollectionIface *iface)
iface->contains = seahorse_gkr_keyring_contains;
}
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
+static SeahorseDeleter *
+seahorse_gkr_keyring_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (deletable);
+ return seahorse_gkr_keyring_deleter_new (self);
+}
+
+static void
+seahorse_keyring_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_gkr_keyring_create_deleter;
+}
+
SeahorseGkrKeyring*
seahorse_gkr_keyring_new (const gchar *keyring_name)
diff --git a/gkr/seahorse-gkr-operation.c b/gkr/seahorse-gkr-operation.c
index 46d7252..bc45636 100644
--- a/gkr/seahorse-gkr-operation.c
+++ b/gkr/seahorse-gkr-operation.c
@@ -360,151 +360,3 @@ seahorse_gkr_update_description_finish (SeahorseGkrItem *item,
return TRUE;
}
-
-typedef struct {
- gpointer request;
- GQueue *objects;
- GCancellable *cancellable;
- gulong cancelled_sig;
-} delete_gkr_closure;
-
-static void
-delete_gkr_free (gpointer data)
-{
- delete_gkr_closure *closure = data;
- g_queue_foreach (closure->objects, (GFunc)g_object_unref, NULL);
- g_queue_free (closure->objects);
- if (closure->cancellable && closure->cancelled_sig)
- g_signal_handler_disconnect (closure->cancellable,
- closure->cancelled_sig);
- g_clear_object (&closure->cancellable);
- g_assert (!closure->request);
- g_free (closure);
-}
-
-static void delete_gkr_one_object (GSimpleAsyncResult *res);
-
-static void
-on_delete_gkr_complete (GnomeKeyringResult result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- delete_gkr_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
- GObject *object;
- SeahorseGkrKeyring *keyring = NULL;
- SeahorseGkrItem *item;
-
- closure->request = NULL;
- object = g_queue_pop_head (closure->objects);
- seahorse_progress_end (closure->cancellable, object);
-
- if (seahorse_gkr_propagate_error (result, &error)) {
- g_simple_async_result_take_error (res, error);
- g_simple_async_result_complete_in_idle (res);
-
- } else if (SEAHORSE_IS_GKR_ITEM (object)) {
- g_object_get (object, "place", &keyring, NULL);
- item = SEAHORSE_GKR_ITEM (object);
- seahorse_gkr_keyring_remove_item (keyring, seahorse_gkr_item_get_item_id (item));
-
- delete_gkr_one_object (res);
- } else if (SEAHORSE_IS_GKR_KEYRING (object)) {
- keyring = SEAHORSE_GKR_KEYRING (object);
- seahorse_gkr_backend_remove_keyring (NULL, keyring);
-
- delete_gkr_one_object (res);
- }
-
- g_object_unref (object);
-}
-
-static void
-on_delete_gkr_cancelled (GCancellable *cancellable,
- gpointer user_data)
-{
- delete_gkr_closure *closure = user_data;
-
- if (closure->request)
- gnome_keyring_cancel_request (closure->request);
-}
-
-static void
-delete_gkr_one_object (GSimpleAsyncResult *res)
-{
- delete_gkr_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
- GObject *object;
- const gchar *keyring;
- guint32 item;
-
- if (g_queue_is_empty (closure->objects)) {
- g_simple_async_result_complete_in_idle (res);
- return;
- }
-
- g_assert (!closure->request);
- object = g_queue_peek_head (closure->objects);
-
- seahorse_progress_begin (closure->cancellable, object);
- if (SEAHORSE_IS_GKR_ITEM (object)) {
- keyring = seahorse_gkr_item_get_keyring_name (SEAHORSE_GKR_ITEM (object));
- item = seahorse_gkr_item_get_item_id (SEAHORSE_GKR_ITEM (object));
- closure->request = gnome_keyring_item_delete (keyring, item,
- on_delete_gkr_complete,
- g_object_ref (res), g_object_unref);
- } else if (SEAHORSE_IS_GKR_KEYRING (object)) {
- keyring = seahorse_gkr_keyring_get_name (SEAHORSE_GKR_KEYRING (object));
- closure->request = gnome_keyring_delete (keyring,
- on_delete_gkr_complete,
- g_object_ref (res), g_object_unref);
- } else {
- g_assert_not_reached ();
- }
-}
-
-void
-seahorse_gkr_delete_async (GList *objects,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- delete_gkr_closure *closure;
- GList *l;
-
- res = g_simple_async_result_new (NULL, callback, user_data,
- seahorse_gkr_delete_async);
-
- closure = g_new0 (delete_gkr_closure, 1);
- closure->objects = g_queue_new ();
- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- g_simple_async_result_set_op_res_gpointer (res, closure, delete_gkr_free);
-
- for (l = objects; l != NULL; l = g_list_next (l)) {
- g_return_if_fail (SEAHORSE_IS_GKR_ITEM (l->data) || SEAHORSE_IS_GKR_KEYRING (l->data));
- g_queue_push_tail (closure->objects, g_object_ref (l->data));
- seahorse_progress_prep (cancellable, l->data, NULL);
- }
-
- delete_gkr_one_object (res);
-
- if (cancellable)
- closure->cancelled_sig = g_cancellable_connect (cancellable,
- G_CALLBACK (on_delete_gkr_cancelled),
- closure, NULL);
-
- g_object_unref (res);
-}
-
-gboolean
-seahorse_gkr_delete_finish (GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- seahorse_gkr_delete_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
diff --git a/gkr/seahorse-gkr-operation.h b/gkr/seahorse-gkr-operation.h
index 3f398ed..2172383 100644
--- a/gkr/seahorse-gkr-operation.h
+++ b/gkr/seahorse-gkr-operation.h
@@ -49,12 +49,4 @@ gboolean seahorse_gkr_update_secret_finish (SeahorseGkrItem *item,
GAsyncResult *result,
GError **error);
-void seahorse_gkr_delete_async (GList *objects,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean seahorse_gkr_delete_finish (GAsyncResult *result,
- GError **error);
-
#endif /* __SEAHORSE_GKR_OPERATION_H__ */
diff --git a/libseahorse/Makefile.am b/libseahorse/Makefile.am
index d1a4b15..ae6d681 100644
--- a/libseahorse/Makefile.am
+++ b/libseahorse/Makefile.am
@@ -37,6 +37,8 @@ libseahorse_la_SOURCES = \
seahorse-context.c seahorse-context.h \
seahorse-debug.c seahorse-debug.h \
seahorse-delete-dialog.c seahorse-delete-dialog.h \
+ seahorse-deletable.c seahorse-deletable.h \
+ seahorse-deleter.c seahorse-deleter.h \
seahorse-exportable.c seahorse-exportable.h \
seahorse-exporter.c seahorse-exporter.h \
seahorse-icons.c seahorse-icons.h \
diff --git a/libseahorse/seahorse-deletable.c b/libseahorse/seahorse-deletable.c
new file mode 100644
index 0000000..1dcd98e
--- /dev/null
+++ b/libseahorse/seahorse-deletable.c
@@ -0,0 +1,185 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2004,2005 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "seahorse-deletable.h"
+#include "seahorse-deleter.h"
+
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+typedef SeahorseDeletableIface SeahorseDeletableInterface;
+
+G_DEFINE_INTERFACE (SeahorseDeletable, seahorse_deletable, G_TYPE_OBJECT);
+
+SeahorseDeleter *
+seahorse_deletable_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseDeletableIface *iface;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETABLE (deletable), NULL);
+
+ iface = SEAHORSE_DELETABLE_GET_INTERFACE (deletable);
+ g_return_val_if_fail (iface->create_deleter, NULL);
+
+ return iface->create_deleter (deletable);
+}
+
+gboolean
+seahorse_deletable_can_delete (gpointer object)
+{
+ gboolean can = FALSE;
+
+ if (!SEAHORSE_IS_DELETABLE (object))
+ return FALSE;
+
+ g_object_get (object, "deletable", &can, NULL);
+ return can;
+}
+
+static void
+seahorse_deletable_default_init (SeahorseDeletableIface *iface)
+{
+ static gboolean initialized = FALSE;
+ if (!initialized) {
+ initialized = TRUE;
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("deletable", "Deletable", "Is actually deletable",
+ FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ }
+}
+
+typedef struct {
+ GMainLoop *loop;
+ GAsyncResult *result;
+} WaitClosure;
+
+static WaitClosure *
+wait_closure_new (void)
+{
+ WaitClosure *closure;
+
+ closure = g_slice_new0 (WaitClosure);
+ closure->loop = g_main_loop_new (NULL, FALSE);
+
+ return closure;
+}
+
+static void
+wait_closure_free (WaitClosure *closure)
+{
+ g_clear_object (&closure->result);
+ g_main_loop_unref (closure->loop);
+ g_slice_free (WaitClosure, closure);
+}
+
+static void
+on_wait_complete (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ WaitClosure *closure = user_data;
+ g_assert (closure->result == NULL);
+ closure->result = g_object_ref (result);
+ g_main_loop_quit (closure->loop);
+}
+
+guint
+seahorse_deletable_delete_with_prompt_wait (GList *objects,
+ GtkWindow *parent,
+ GError **error)
+{
+ SeahorseDeleter *deleter;
+ WaitClosure *closure;
+ GHashTable *pending;
+ guint count = 0;
+ gboolean ret;
+ GList *l, *x;
+ GList *deleted;
+
+ g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), 0);
+ g_return_val_if_fail (error == NULL || *error == NULL, 0);
+
+ /* A table for monitoring which objects are still pending */
+ pending = g_hash_table_new (g_direct_hash, g_direct_equal);
+ for (l = objects; l != NULL; l = g_list_next (l))
+ g_hash_table_replace (pending, l->data, l->data);
+
+ closure = wait_closure_new ();
+
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ if (!g_hash_table_lookup (pending, l->data))
+ continue;
+
+ if (!seahorse_deletable_can_delete (l->data)) {
+ g_hash_table_remove (pending, l->data);
+ continue;
+ }
+
+ deleter = seahorse_deletable_create_deleter (SEAHORSE_DELETABLE (l->data));
+ if (!deleter)
+ continue;
+
+ /* Now go and add all pending to each exporter */
+ for (x = objects; x != NULL; x = g_list_next (x)) {
+ if (x->data == l->data)
+ continue;
+ if (g_hash_table_lookup (pending, x->data))
+ seahorse_deleter_add_object (deleter, x->data);
+ }
+
+ /* Now show a prompt choosing between the exporters */
+ ret = seahorse_deleter_prompt (deleter, parent);
+
+ if (!ret) {
+ g_object_unref (deleter);
+ break;
+ }
+
+ seahorse_deleter_delete_async (deleter, NULL, on_wait_complete, closure);
+
+ g_main_loop_run (closure->loop);
+
+ ret = seahorse_deleter_delete_finish (deleter, closure->result, error);
+ g_object_unref (closure->result);
+ closure->result = NULL;
+
+ if (ret) {
+ deleted = seahorse_deleter_get_objects (deleter);
+ for (x = deleted; x != NULL; x = g_list_next (x)) {
+ g_hash_table_remove (pending, x->data);
+ count++;
+ }
+ }
+
+ g_object_unref (deleter);
+
+ if (!ret)
+ break;
+ }
+
+ wait_closure_free (closure);
+ g_hash_table_destroy (pending);
+ return count;
+}
diff --git a/libseahorse/seahorse-deletable.h b/libseahorse/seahorse-deletable.h
new file mode 100644
index 0000000..28b2ab3
--- /dev/null
+++ b/libseahorse/seahorse-deletable.h
@@ -0,0 +1,53 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Deletable, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __SEAHORSE_DELETABLE_H__
+#define __SEAHORSE_DELETABLE_H__
+
+#include "seahorse-deleter.h"
+
+#define SEAHORSE_TYPE_DELETABLE (seahorse_deletable_get_type ())
+#define SEAHORSE_DELETABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_DELETABLE, SeahorseDeletable))
+#define SEAHORSE_IS_DELETABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_DELETABLE))
+#define SEAHORSE_DELETABLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SEAHORSE_TYPE_DELETABLE, SeahorseDeletableIface))
+
+typedef struct _SeahorseDeletable SeahorseDeletable;
+typedef struct _SeahorseDeletableIface SeahorseDeletableIface;
+
+struct _SeahorseDeletableIface {
+ GTypeInterface parent;
+
+ SeahorseDeleter * (* create_deleter) (SeahorseDeletable *deletable);
+};
+
+GType seahorse_deletable_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_deletable_create_deleter (SeahorseDeletable *deletable);
+
+gboolean seahorse_deletable_can_delete (gpointer object);
+
+guint seahorse_deletable_delete_with_prompt_wait (GList *objects,
+ GtkWindow *parent,
+ GError **error);
+
+#endif /* __SEAHORSE_DELETABLE_H__ */
diff --git a/libseahorse/seahorse-deleter.c b/libseahorse/seahorse-deleter.c
new file mode 100644
index 0000000..1b5b519
--- /dev/null
+++ b/libseahorse/seahorse-deleter.c
@@ -0,0 +1,135 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU 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-deleter.h"
+
+G_DEFINE_TYPE (SeahorseDeleter, seahorse_deleter, G_TYPE_OBJECT);
+
+static void
+seahorse_deleter_init (SeahorseDeleter *deleter)
+{
+
+}
+
+static void
+seahorse_deleter_class_init (SeahorseDeleterClass *klass)
+{
+
+}
+
+GtkDialog *
+seahorse_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseDeleterClass *class;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETER (deleter), NULL);
+
+ class = SEAHORSE_DELETER_GET_CLASS (deleter);
+ g_return_val_if_fail (class->create_confirm != NULL, NULL);
+
+ return (class->create_confirm) (deleter, parent);
+}
+
+GList *
+seahorse_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseDeleterClass *class;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETER (deleter), NULL);
+
+ class = SEAHORSE_DELETER_GET_CLASS (deleter);
+ g_return_val_if_fail (class->get_objects != NULL, NULL);
+
+ return (class->get_objects) (deleter);
+}
+
+gboolean
+seahorse_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseDeleterClass *class;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETER (deleter), FALSE);
+ g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+
+ class = SEAHORSE_DELETER_GET_CLASS (deleter);
+ g_return_val_if_fail (class->add_object != NULL, FALSE);
+
+ return (class->add_object) (deleter, object);
+}
+
+void
+seahorse_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseDeleterClass *class;
+
+ g_return_if_fail (SEAHORSE_IS_DELETER (deleter));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ class = SEAHORSE_DELETER_GET_CLASS (deleter);
+ g_return_if_fail (class->delete_async != NULL);
+
+ (class->delete_async) (deleter, cancellable, callback, user_data);
+}
+
+gboolean
+seahorse_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseDeleterClass *class;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETER (deleter), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ class = SEAHORSE_DELETER_GET_CLASS (deleter);
+ g_return_val_if_fail (class->delete_finish != NULL, FALSE);
+
+ return (class->delete_finish) (deleter, result, error);
+}
+
+gboolean
+seahorse_deleter_prompt (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ GtkDialog *prompt;
+ gint res;
+
+ g_return_val_if_fail (SEAHORSE_IS_DELETER (deleter), FALSE);
+ g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
+
+ prompt = seahorse_deleter_create_confirm (deleter, parent);
+ g_return_val_if_fail (prompt != NULL, FALSE);
+
+ res = gtk_dialog_run (prompt);
+ gtk_widget_destroy (GTK_WIDGET (prompt));
+
+ return res == GTK_RESPONSE_OK || res == GTK_RESPONSE_ACCEPT;
+}
diff --git a/libseahorse/seahorse-deleter.h b/libseahorse/seahorse-deleter.h
new file mode 100644
index 0000000..5b261ec
--- /dev/null
+++ b/libseahorse/seahorse-deleter.h
@@ -0,0 +1,92 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Deleter, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __SEAHORSE_DELETER_H__
+#define __SEAHORSE_DELETER_H__
+
+#include "seahorse-types.h"
+
+#include <gio/gio.h>
+
+#include <gtk/gtk.h>
+
+#define SEAHORSE_TYPE_DELETER (seahorse_deleter_get_type ())
+#define SEAHORSE_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_DELETER, SeahorseDeleter))
+#define SEAHORSE_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_DELETER, SeahorseDeleterClass))
+#define SEAHORSE_IS_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_DELETER))
+#define SEAHORSE_IS_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_DELETER))
+#define SEAHORSE_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_DELETER, SeahorseDeleterClass))
+
+typedef struct _SeahorseDeleter SeahorseDeleter;
+typedef struct _SeahorseDeleterClass SeahorseDeleterClass;
+
+struct _SeahorseDeleter {
+ GObject parent;
+};
+
+struct _SeahorseDeleterClass {
+ GObjectClass parent;
+
+ /* virtual methods ------------------------------------------------- */
+
+ GtkDialog * (* create_confirm) (SeahorseDeleter *deleter,
+ GtkWindow *parent);
+
+ GList * (* get_objects) (SeahorseDeleter *deleter);
+
+ gboolean (* add_object) (SeahorseDeleter *deleter,
+ GObject *object);
+
+ void (* delete_async) (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ gboolean (* delete_finish) (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error);
+};
+
+GType seahorse_deleter_get_type (void) G_GNUC_CONST;
+
+GtkDialog * seahorse_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent);
+
+GList * seahorse_deleter_get_objects (SeahorseDeleter *deleter);
+
+gboolean seahorse_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object);
+
+void seahorse_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean seahorse_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error);
+
+gboolean seahorse_deleter_prompt (SeahorseDeleter *deleter,
+ GtkWindow *parent);
+
+#endif /* __SEAHORSE_DELETER_H__ */
diff --git a/libseahorse/seahorse-exportable.c b/libseahorse/seahorse-exportable.c
index ad4bad5..b41c4fd 100644
--- a/libseahorse/seahorse-exportable.c
+++ b/libseahorse/seahorse-exportable.c
@@ -47,6 +47,19 @@ seahorse_exportable_create_exporters (SeahorseExportable *exportable,
return iface->create_exporters (exportable, type);
}
+
+gboolean
+seahorse_exportable_can_export (gpointer object)
+{
+ gboolean can = FALSE;
+
+ if (!SEAHORSE_IS_EXPORTABLE (object))
+ return FALSE;
+
+ g_object_get (object, "exportable", &can, NULL);
+ return can;
+}
+
typedef struct {
GMainLoop *loop;
GAsyncResult *result;
@@ -88,6 +101,9 @@ seahorse_exportable_default_init (SeahorseExportableIface *iface)
static gboolean initialized = FALSE;
if (!initialized) {
initialized = TRUE;
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("exportable", "Exportable", "Is actually exportable",
+ FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
}
@@ -112,7 +128,7 @@ seahorse_exportable_export_to_directory_wait (GList *objects,
closure = wait_closure_new ();
for (l = objects; l != NULL; l = g_list_next (l)) {
- if (!SEAHORSE_IS_EXPORTABLE (l->data))
+ if (!seahorse_exportable_can_export (l->data))
continue;
exporters = seahorse_exportable_create_exporters (SEAHORSE_EXPORTABLE (l->data),
@@ -168,7 +184,7 @@ seahorse_exportable_export_to_text_wait (GList *objects,
g_return_val_if_fail (size != NULL, 0);
for (l = objects; l != NULL; l = g_list_next (l)) {
- if (!SEAHORSE_IS_EXPORTABLE (l->data))
+ if (!seahorse_exportable_can_export (l->data))
continue;
/* If we've already found exporters, then add to those */
@@ -244,7 +260,7 @@ seahorse_exportable_export_to_prompt_wait (GList *objects,
if (!g_hash_table_lookup (pending, l->data))
continue;
- if (!SEAHORSE_IS_EXPORTABLE (l->data)) {
+ if (!seahorse_exportable_can_export (l->data)) {
g_hash_table_remove (pending, l->data);
continue;
}
diff --git a/libseahorse/seahorse-exportable.h b/libseahorse/seahorse-exportable.h
index 4474151..b6e910d 100644
--- a/libseahorse/seahorse-exportable.h
+++ b/libseahorse/seahorse-exportable.h
@@ -50,6 +50,8 @@ GType seahorse_exportable_get_type (void) G_GNUC_CONST;
GList * seahorse_exportable_create_exporters (SeahorseExportable *exportable,
SeahorseExporterType type);
+gboolean seahorse_exportable_can_export (gpointer object);
+
guint seahorse_exportable_export_to_directory_wait (GList *objects,
const gchar *directory,
GError **error);
diff --git a/libseahorse/seahorse-object.c b/libseahorse/seahorse-object.c
index 18c49bb..5fa9930 100644
--- a/libseahorse/seahorse-object.c
+++ b/libseahorse/seahorse-object.c
@@ -40,7 +40,9 @@ enum {
PROP_ICON,
PROP_IDENTIFIER,
PROP_USAGE,
- PROP_FLAGS
+ PROP_FLAGS,
+ PROP_DELETABLE,
+ PROP_EXPORTABLE
};
/**
@@ -274,6 +276,12 @@ seahorse_object_get_property (GObject *obj, guint prop_id, GValue *value,
case PROP_FLAGS:
g_value_set_uint (value, seahorse_object_get_flags (self));
break;
+ case PROP_DELETABLE:
+ g_value_set_boolean (value, seahorse_object_get_flags (self) & SEAHORSE_FLAG_DELETABLE ? TRUE : FALSE);
+ break;
+ case PROP_EXPORTABLE:
+ g_value_set_boolean (value, seahorse_object_get_flags (self) & SEAHORSE_FLAG_EXPORTABLE ? TRUE : FALSE);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -414,6 +422,14 @@ seahorse_object_class_init (SeahorseObjectClass *klass)
g_object_class_install_property (gobject_class, PROP_FLAGS,
g_param_spec_uint ("flags", "Object Flags", "This object's flags.",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_DELETABLE,
+ g_param_spec_boolean ("deletable", "Deletable", "Object is deletable.",
+ FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_EXPORTABLE,
+ g_param_spec_boolean ("exportable", "Exportable", "Object is exportable.",
+ FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
/* -----------------------------------------------------------------------------
diff --git a/libseahorse/seahorse-viewer.c b/libseahorse/seahorse-viewer.c
index ae3893b..8930dbf 100644
--- a/libseahorse/seahorse-viewer.c
+++ b/libseahorse/seahorse-viewer.c
@@ -25,6 +25,7 @@
#include "seahorse-action.h"
#include "seahorse-actions.h"
#include "seahorse-backend.h"
+#include "seahorse-deletable.h"
#include "seahorse-exportable.h"
#include "seahorse-object.h"
#include "seahorse-preferences.h"
@@ -177,27 +178,18 @@ on_object_delete (GtkAction *action,
gpointer user_data)
{
SeahorseViewer *self = SEAHORSE_VIEWER (user_data);
- GCancellable *cancellable;
- GtkAction *delete_action;
+ GError *error = NULL;
GtkWindow *window;
- GList *l;
-
- cancellable = g_cancellable_new ();
+ GList *objects;
- g_cancellable_push_current (cancellable);
window = seahorse_viewer_get_window (self);
+ objects = seahorse_viewer_get_selected_objects (self);
+ seahorse_deletable_delete_with_prompt_wait (objects, window, &error);
- /* Now go through and clone for the selection */
- for (l = self->pv->selection_actions;
- l != NULL && !g_cancellable_is_cancelled (cancellable);
- l = g_list_next (l)) {
- delete_action = gtk_action_group_get_action (l->data, "delete");
- if (delete_action != NULL && gtk_action_is_sensitive (delete_action))
- seahorse_action_activate_with_window (delete_action, window);
- }
+ if (error != NULL)
+ seahorse_util_handle_error (&error, window, _("Cannot delete"));
- g_cancellable_pop_current (cancellable);
- g_object_unref (cancellable);
+ g_list_free (objects);
}
static void
@@ -340,10 +332,12 @@ seahorse_viewer_real_selection_changed (SeahorseViewer *self)
objects = seahorse_viewer_get_selected_objects (self);
for (l = objects; l != NULL; l = g_list_next (l)) {
- if (SEAHORSE_IS_EXPORTABLE (l->data)) {
+ if (seahorse_exportable_can_export (l->data))
can_export = TRUE;
+ if (seahorse_deletable_can_delete (l->data))
+ can_delete = TRUE;
+ if (can_export && can_delete)
break;
- }
}
groups = lookup_actions_for_objects (self, objects);
@@ -353,8 +347,6 @@ seahorse_viewer_real_selection_changed (SeahorseViewer *self)
for (l = groups; l != NULL; l = g_list_next (l)) {
if (gtk_action_group_get_action (l->data, "properties"))
can_properties = TRUE;
- if (gtk_action_group_get_action (l->data, "delete"))
- can_delete = TRUE;
}
gtk_action_set_sensitive (self->pv->properties_object, can_properties);
diff --git a/pgp/Makefile.am b/pgp/Makefile.am
index d7c260f..b1ddb75 100644
--- a/pgp/Makefile.am
+++ b/pgp/Makefile.am
@@ -49,11 +49,13 @@ libseahorse_pgp_la_SOURCES = \
seahorse-gpgme-exporter.c seahorse-gpgme-exporter.h \
seahorse-gpgme-generate.c \
seahorse-gpgme-key.c seahorse-gpgme-key.h \
+ seahorse-gpgme-key-deleter.c seahorse-gpgme-key-deleter.h \
seahorse-gpgme-key-op.c seahorse-gpgme-key-op.h \
seahorse-gpgme-keyring.c seahorse-gpgme-keyring.h \
seahorse-gpgme-photo.c seahorse-gpgme-photo.h \
seahorse-gpgme-photos.c \
seahorse-gpgme-revoke.c \
+ seahorse-gpgme-secret-deleter.c seahorse-gpgme-secret-deleter.h \
seahorse-gpgme-sign.c \
seahorse-gpgme-subkey.c seahorse-gpgme-subkey.h \
seahorse-gpgme-uid.c seahorse-gpgme-uid.h \
diff --git a/pgp/seahorse-gpgme-key-deleter.c b/pgp/seahorse-gpgme-key-deleter.c
new file mode 100644
index 0000000..ea4cd13
--- /dev/null
+++ b/pgp/seahorse-gpgme-key-deleter.c
@@ -0,0 +1,181 @@
+/*
+ * 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-gpgme.h"
+#include "seahorse-gpgme-key-deleter.h"
+#include "seahorse-gpgme-key-op.h"
+
+#include "seahorse-delete-dialog.h"
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_GPGME_KEY_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_GPGME_KEY_DELETER, SeahorseGpgmeKeyDeleterClass))
+#define SEAHORSE_IS_GPGME_KEY_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_GPGME_KEY_DELETER))
+#define SEAHORSE_GPGME_KEY_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_GPGME_KEY_DELETER, SeahorseGpgmeKeyDeleterClass))
+
+typedef struct _SeahorseGpgmeKeyDeleterClass SeahorseGpgmeKeyDeleterClass;
+
+struct _SeahorseGpgmeKeyDeleter {
+ SeahorseDeleter parent;
+ GList *keys;
+};
+
+struct _SeahorseGpgmeKeyDeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+G_DEFINE_TYPE (SeahorseGpgmeKeyDeleter, seahorse_gpgme_key_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_gpgme_key_deleter_init (SeahorseGpgmeKeyDeleter *self)
+{
+
+}
+
+static void
+seahorse_gpgme_key_deleter_finalize (GObject *obj)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (obj);
+
+ g_list_free_full (self->keys, g_object_unref);
+
+ G_OBJECT_CLASS (seahorse_gpgme_key_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_gpgme_key_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (deleter);
+ GtkDialog *dialog;
+ gchar *prompt;
+ guint num;
+
+ num = g_list_length (self->keys);
+ if (num == 1) {
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete %s?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->keys->data)));
+ } else {
+ prompt = g_strdup_printf (ngettext ("Are you sure you want to permanently delete %d keys?",
+ "Are you sure you want to permanently delete %d keys?",
+ num),
+ num);
+ }
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+ g_free (prompt);
+
+ return dialog;
+}
+
+static GList *
+seahorse_gpgme_key_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (deleter);
+ return self->keys;
+}
+
+static gboolean
+seahorse_gpgme_key_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (deleter);
+
+ if (!SEAHORSE_IS_GPGME_KEY (object))
+ return FALSE;
+ self->keys = g_list_append (self->keys, g_object_ref (object));
+ return TRUE;
+}
+
+static void
+seahorse_gpgme_key_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ GError *error = NULL;
+ gpgme_error_t gerr;
+ GList *l;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_gpgme_key_deleter_delete_async);
+
+ for (l = self->keys; l != NULL && !g_cancellable_is_cancelled (cancellable);
+ l = g_list_next (l)) {
+ gerr = seahorse_gpgme_key_op_delete (l->data);
+ if (seahorse_gpgme_propagate_error (gerr, &error)) {
+ g_simple_async_result_take_error (res, error);
+ break;
+ }
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_gpgme_key_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseGpgmeKeyDeleter *self = SEAHORSE_GPGME_KEY_DELETER (deleter);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ seahorse_gpgme_key_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+seahorse_gpgme_key_deleter_class_init (SeahorseGpgmeKeyDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_gpgme_key_deleter_finalize;
+
+ deleter_class->add_object = seahorse_gpgme_key_deleter_add_object;
+ deleter_class->create_confirm = seahorse_gpgme_key_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_gpgme_key_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_gpgme_key_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_gpgme_key_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_gpgme_key_deleter_new (SeahorseGpgmeKey *item)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_GPGME_KEY_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (item)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/pgp/seahorse-gpgme-key-deleter.h b/pgp/seahorse-gpgme-key-deleter.h
new file mode 100644
index 0000000..2dce664
--- /dev/null
+++ b/pgp/seahorse-gpgme-key-deleter.h
@@ -0,0 +1,42 @@
+/*
+ * 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_GPGME_KEY_DELETER_H__
+#define __SEAHORSE_GPGME_KEY_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-gpgme-key.h"
+
+#define SEAHORSE_TYPE_GPGME_KEY_DELETER (seahorse_gpgme_key_deleter_get_type ())
+#define SEAHORSE_GPGME_KEY_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_GPGME_KEY_DELETER, SeahorseGpgmeKeyDeleter))
+#define SEAHORSE_IS_GPGME_KEY_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_GPGME_KEY_DELETER))
+
+typedef struct _SeahorseGpgmeKeyDeleter SeahorseGpgmeKeyDeleter;
+
+GType seahorse_gpgme_key_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_gpgme_key_deleter_new (SeahorseGpgmeKey *key);
+
+#endif /* __SEAHORSE_GPGME_KEY_DELETER_H__ */
diff --git a/pgp/seahorse-gpgme-key.c b/pgp/seahorse-gpgme-key.c
index b90c0d6..5cc7603 100644
--- a/pgp/seahorse-gpgme-key.c
+++ b/pgp/seahorse-gpgme-key.c
@@ -24,13 +24,16 @@
#include "seahorse-gpgme.h"
#include "seahorse-gpgme-exporter.h"
#include "seahorse-gpgme-key-op.h"
+#include "seahorse-gpgme-key-deleter.h"
#include "seahorse-gpgme-photo.h"
#include "seahorse-gpgme-keyring.h"
+#include "seahorse-gpgme-secret-deleter.h"
#include "seahorse-gpgme-uid.h"
#include "seahorse-pgp-actions.h"
#include "seahorse-pgp-backend.h"
#include "seahorse-pgp-key.h"
+#include "seahorse-deletable.h"
#include "seahorse-exportable.h"
#include "seahorse-icons.h"
#include "seahorse-predicate.h"
@@ -50,10 +53,13 @@ enum {
PROP_TRUST
};
+static void seahorse_gpgme_key_deletable_iface (SeahorseDeletableIface *iface);
+
static void seahorse_gpgme_key_exportable_iface (SeahorseExportableIface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorseGpgmeKey, seahorse_gpgme_key, SEAHORSE_TYPE_PGP_KEY,
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_EXPORTABLE, seahorse_gpgme_key_exportable_iface);
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_gpgme_key_deletable_iface);
);
struct _SeahorseGpgmeKeyPrivate {
@@ -550,6 +556,22 @@ seahorse_gpgme_key_class_init (SeahorseGpgmeKeyClass *klass)
g_object_class_override_property (gobject_class, PROP_TRUST, "trust");
}
+static SeahorseDeleter *
+seahorse_gpgme_key_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseGpgmeKey *self = SEAHORSE_GPGME_KEY (deletable);
+ if (self->pv->seckey)
+ return seahorse_gpgme_secret_deleter_new (self);
+ else
+ return seahorse_gpgme_key_deleter_new (self);
+}
+
+static void
+seahorse_gpgme_key_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_gpgme_key_create_deleter;
+}
+
static GList *
seahorse_gpgme_key_create_exporters (SeahorseExportable *exportable,
SeahorseExporterType type)
diff --git a/pgp/seahorse-gpgme-secret-deleter.c b/pgp/seahorse-gpgme-secret-deleter.c
new file mode 100644
index 0000000..3a2bcfa
--- /dev/null
+++ b/pgp/seahorse-gpgme-secret-deleter.c
@@ -0,0 +1,177 @@
+/*
+ * 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-gpgme.h"
+#include "seahorse-gpgme-key-op.h"
+#include "seahorse-gpgme-secret-deleter.h"
+
+#include "seahorse-delete-dialog.h"
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_GPGME_SECRET_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_GPGME_SECRET_DELETER, SeahorseGpgmeSecretDeleterClass))
+#define SEAHORSE_IS_GPGME_SECRET_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_GPGME_SECRET_DELETER))
+#define SEAHORSE_GPGME_SECRET_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_GPGME_SECRET_DELETER, SeahorseGpgmeSecretDeleterClass))
+
+typedef struct _SeahorseGpgmeSecretDeleterClass SeahorseGpgmeSecretDeleterClass;
+
+struct _SeahorseGpgmeSecretDeleter {
+ SeahorseDeleter parent;
+ SeahorseGpgmeKey *key;
+ GList *keys;
+};
+
+struct _SeahorseGpgmeSecretDeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+G_DEFINE_TYPE (SeahorseGpgmeSecretDeleter, seahorse_gpgme_secret_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_gpgme_secret_deleter_init (SeahorseGpgmeSecretDeleter *self)
+{
+
+}
+
+static void
+seahorse_gpgme_secret_deleter_finalize (GObject *obj)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (obj);
+
+ g_clear_object (&self->key);
+ g_list_free (self->keys);
+
+ G_OBJECT_CLASS (seahorse_gpgme_secret_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_gpgme_secret_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (deleter);
+ GtkDialog *dialog;
+ gchar *prompt;
+
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete %s?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->key)));
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+
+ seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog), _("I understand that this secret key will be permanently deleted."));
+ seahorse_delete_dialog_set_check_require (SEAHORSE_DELETE_DIALOG (dialog), TRUE);
+
+ g_free (prompt);
+ return dialog;
+}
+
+static GList *
+seahorse_gpgme_secret_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (deleter);
+ return self->keys;
+}
+
+static gboolean
+seahorse_gpgme_secret_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (deleter);
+
+ if (!SEAHORSE_IS_GPGME_KEY (object))
+ return FALSE;
+ if (self->key)
+ return FALSE;
+ if (seahorse_object_get_usage (SEAHORSE_OBJECT (object)) != SEAHORSE_USAGE_PRIVATE_KEY)
+ return FALSE;
+ self->key = g_object_ref (object);
+ self->keys = g_list_append (self->keys, object);
+ return TRUE;
+}
+
+static void
+seahorse_gpgme_secret_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ GError *error = NULL;
+ gpgme_error_t gerr;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_gpgme_secret_deleter_delete_async);
+
+ gerr = seahorse_gpgme_key_op_delete_pair (self->key);
+ if (seahorse_gpgme_propagate_error (gerr, &error))
+ g_simple_async_result_take_error (res, error);
+
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_gpgme_secret_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseGpgmeSecretDeleter *self = SEAHORSE_GPGME_SECRET_DELETER (deleter);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ seahorse_gpgme_secret_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static void
+seahorse_gpgme_secret_deleter_class_init (SeahorseGpgmeSecretDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_gpgme_secret_deleter_finalize;
+
+ deleter_class->add_object = seahorse_gpgme_secret_deleter_add_object;
+ deleter_class->create_confirm = seahorse_gpgme_secret_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_gpgme_secret_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_gpgme_secret_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_gpgme_secret_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_gpgme_secret_deleter_new (SeahorseGpgmeKey *key)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_GPGME_SECRET_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (key)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/pgp/seahorse-gpgme-secret-deleter.h b/pgp/seahorse-gpgme-secret-deleter.h
new file mode 100644
index 0000000..766010a
--- /dev/null
+++ b/pgp/seahorse-gpgme-secret-deleter.h
@@ -0,0 +1,42 @@
+/*
+ * 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_GPGME_SECRET_DELETER_H__
+#define __SEAHORSE_GPGME_SECRET_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-gpgme-key.h"
+
+#define SEAHORSE_TYPE_GPGME_SECRET_DELETER (seahorse_gpgme_secret_deleter_get_type ())
+#define SEAHORSE_GPGME_SECRET_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_GPGME_SECRET_DELETER, SeahorseGpgmeSecretDeleter))
+#define SEAHORSE_IS_GPGME_SECRET_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_GPGME_SECRET_DELETER))
+
+typedef struct _SeahorseGpgmeSecretDeleter SeahorseGpgmeSecretDeleter;
+
+GType seahorse_gpgme_secret_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_gpgme_secret_deleter_new (SeahorseGpgmeKey *key);
+
+#endif /* __SEAHORSE_GPGME_SECRET_DELETER_H__ */
diff --git a/pgp/seahorse-pgp-actions.c b/pgp/seahorse-pgp-actions.c
index 21998cf..522f92d 100644
--- a/pgp/seahorse-pgp-actions.c
+++ b/pgp/seahorse-pgp-actions.c
@@ -197,112 +197,6 @@ on_show_properties (GtkAction *action,
seahorse_action_get_window (action));
}
-static void
-on_delete_objects (GtkAction *action,
- gpointer user_data)
-{
- guint num;
- gint num_keys;
- gint num_identities;
- char* message;
- SeahorseObject *obj;
- GList* to_delete, *l;
- GtkWindow *parent;
- gpgme_error_t gerr;
- guint length;
- GError *error = NULL;
- GList *objects;
-
- objects = user_data;
- num = g_list_length (objects);
- if (num == 0)
- return;
-
- num_keys = 0;
- num_identities = 0;
- message = NULL;
-
- /*
- * Go through and validate all what we have to delete,
- * removing UIDs where the parent Key is also on the
- * chopping block.
- */
- to_delete = NULL;
-
- for (l = objects; l; l = g_list_next (l)) {
- obj = SEAHORSE_OBJECT (l->data);
- if (SEAHORSE_IS_PGP_UID (obj)) {
- if (g_list_find (objects, seahorse_pgp_uid_get_parent (SEAHORSE_PGP_UID (obj))) == NULL) {
- to_delete = g_list_prepend (to_delete, obj);
- ++num_identities;
- }
- } else if (G_OBJECT_TYPE (obj) == SEAHORSE_TYPE_GPGME_KEY) {
- to_delete = g_list_prepend (to_delete, obj);
- ++num_keys;
- }
- }
-
- /* Figure out a good prompt message */
- length = g_list_length (to_delete);
- switch (length) {
- case 0:
- return;
- case 1:
- message = g_strdup_printf (_ ("Are you sure you want to permanently delete %s?"),
- seahorse_object_get_label (to_delete->data));
- break;
- default:
- if (num_keys > 0 && num_identities > 0) {
- message = g_strdup_printf (ngettext (_("Are you sure you want to permanently delete %d keys and identities?"),
- _("Are you sure you want to permanently delete %d keys and identities?"),
- length),
- length);
- } else if (num_keys > 0) {
- message = g_strdup_printf (ngettext (_("Are you sure you want to permanently delete %d keys?"),
- _("Are you sure you want to permanently delete %d keys?"),
- length),
- length);
- } else if (num_identities > 0){
- message = g_strdup_printf (ngettext (_("Are you sure you want to permanently delete %d identities?"),
- _("Are you sure you want to permanently delete %d identities?"),
- length),
- length);
- } else {
- g_assert_not_reached ();
- }
- break;
- }
-
- parent = seahorse_action_get_window (action);
- if (!seahorse_delete_dialog_prompt (parent, message)) {
- g_free (message);
- g_cancellable_cancel (g_cancellable_get_current ());
- return;
- }
-
- gerr = 0;
- for (l = objects; l; l = g_list_next (l)) {
- obj = SEAHORSE_OBJECT (l->data);
- if (SEAHORSE_IS_GPGME_UID (obj)) {
- gerr = seahorse_gpgme_key_op_del_uid (SEAHORSE_GPGME_UID (obj));
- message = _("Couldn't delete user ID");
- } else if (SEAHORSE_IS_GPGME_KEY (obj)) {
- if (seahorse_object_get_usage (obj) == SEAHORSE_USAGE_PRIVATE_KEY) {
- gerr = seahorse_gpgme_key_op_delete_pair (SEAHORSE_GPGME_KEY (obj));
- message = _("Couldn't delete private key");
- } else {
- gerr = seahorse_gpgme_key_op_delete (SEAHORSE_GPGME_KEY (obj));
- message = _("Couldn't delete public key");
- }
- }
-
- if (seahorse_gpgme_propagate_error (gerr, &error)) {
- seahorse_util_handle_error (&error, parent, "%s", message);
- return;
- }
- }
-}
-
static const GtkActionEntry KEY_ACTIONS[] = {
{ "key-sign", GTK_STOCK_INDEX, N_("_Sign Key..."), "",
N_("Sign public key"), G_CALLBACK (on_key_sign) },
@@ -310,11 +204,6 @@ static const GtkActionEntry KEY_ACTIONS[] = {
N_("Properties of the key."), G_CALLBACK (on_show_properties) },
};
-static const GtkActionEntry KEYS_ACTIONS[] = {
- { "delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the key."), G_CALLBACK (on_delete_objects) },
-};
-
static void
seahorse_gpgme_key_actions_init (SeahorseGpgmeKeyActions *self)
{
@@ -322,8 +211,6 @@ seahorse_gpgme_key_actions_init (SeahorseGpgmeKeyActions *self)
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
gtk_action_group_add_actions (actions, KEY_ACTIONS,
G_N_ELEMENTS (KEY_ACTIONS), NULL);
- gtk_action_group_add_actions (actions, KEYS_ACTIONS,
- G_N_ELEMENTS (KEYS_ACTIONS), NULL);
gtk_action_group_set_visible (actions, FALSE);
seahorse_actions_register_definition (SEAHORSE_ACTIONS (self), KEY_DEFINITION);
@@ -338,10 +225,6 @@ seahorse_gpgme_key_actions_clone_for_objects (SeahorseActions *actions,
g_return_val_if_fail (objects != NULL, NULL);
cloned = gtk_action_group_new ("GpgmeKey");
- gtk_action_group_add_actions_full (cloned, KEYS_ACTIONS,
- G_N_ELEMENTS (KEYS_ACTIONS),
- seahorse_object_list_copy (objects),
- seahorse_object_list_free);
gtk_action_group_add_actions_full (cloned, SYNC_ACTIONS,
G_N_ELEMENTS (SYNC_ACTIONS),
seahorse_object_list_copy (objects),
diff --git a/pkcs11/Makefile.am b/pkcs11/Makefile.am
index 7cdce84..7c07782 100644
--- a/pkcs11/Makefile.am
+++ b/pkcs11/Makefile.am
@@ -20,9 +20,10 @@ libseahorse_pkcs11_la_SOURCES = \
seahorse-interaction.c seahorse-interaction.h \
seahorse-pkcs11-actions.c seahorse-pkcs11-actions.h \
seahorse-pkcs11-backend.c seahorse-pkcs11-backend.h \
+ seahorse-pkcs11-deleter.c seahorse-pkcs11-deleter.h \
seahorse-pkcs11-helpers.c seahorse-pkcs11-helpers.h \
seahorse-pkcs11-generate.c seahorse-pkcs11-generate.h \
- seahorse-pkcs11-operations.c seahorse-pkcs11-operations.h \
+ seahorse-pkcs11-key-deleter.c seahorse-pkcs11-key-deleter.h \
seahorse-pkcs11-properties.c seahorse-pkcs11-properties.h \
seahorse-pkcs11-request.c seahorse-pkcs11-request.h \
seahorse-pkcs11.c seahorse-pkcs11.h \
diff --git a/pkcs11/seahorse-certificate.c b/pkcs11/seahorse-certificate.c
index 00091aa..2fc470c 100644
--- a/pkcs11/seahorse-certificate.c
+++ b/pkcs11/seahorse-certificate.c
@@ -26,11 +26,13 @@
#include "seahorse-certificate-der-exporter.h"
#include "seahorse-pkcs11.h"
#include "seahorse-pkcs11-actions.h"
+#include "seahorse-pkcs11-deleter.h"
#include "seahorse-pkcs11-helpers.h"
#include "seahorse-private-key.h"
#include "seahorse-token.h"
#include "seahorse-types.h"
+#include "seahorse-deletable.h"
#include "seahorse-exportable.h"
#include "seahorse-util.h"
#include "seahorse-validity.h"
@@ -45,7 +47,8 @@ static const gulong REQUIRED_ATTRS[] = {
CKA_ID,
CKA_LABEL,
CKA_CLASS,
- CKA_CERTIFICATE_CATEGORY
+ CKA_CERTIFICATE_CATEGORY,
+ CKA_MODIFIABLE
};
enum {
@@ -56,6 +59,8 @@ enum {
PROP_ACTIONS,
PROP_PARTNER,
+ PROP_EXPORTABLE,
+ PROP_DELETABLE,
PROP_ICON,
PROP_DESCRIPTION
};
@@ -74,12 +79,15 @@ static void seahorse_certificate_certificate_iface (GcrCertificateIf
static void seahorse_certificate_object_attributes_iface (GckObjectAttributesIface *iface);
+static void seahorse_certificate_deletable_iface (SeahorseDeletableIface *iface);
+
static void seahorse_certificate_exportable_iface (SeahorseExportableIface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorseCertificate, seahorse_certificate, GCK_TYPE_OBJECT,
GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, seahorse_certificate_certificate_iface);
G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES, seahorse_certificate_object_attributes_iface);
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_certificate_deletable_iface);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_EXPORTABLE, seahorse_certificate_exportable_iface);
);
@@ -213,6 +221,12 @@ seahorse_certificate_get_property (GObject *obj,
case PROP_DESCRIPTION:
g_value_set_string (value, seahorse_certificate_get_description (self));
break;
+ case PROP_EXPORTABLE:
+ g_value_set_boolean (value, gck_attributes_find (self->pv->attributes, CKA_VALUE) != NULL);
+ break;
+ case PROP_DELETABLE:
+ g_value_set_boolean (value, seahorse_token_is_deletable (self->pv->token, GCK_OBJECT (self)));
+ break;
default:
gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
break;
@@ -286,6 +300,10 @@ seahorse_certificate_class_init (SeahorseCertificateClass *klass)
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+ g_object_class_override_property (gobject_class, PROP_DELETABLE, "deletable");
+
+ g_object_class_override_property (gobject_class, PROP_EXPORTABLE, "exportable");
+
g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
@@ -322,6 +340,12 @@ seahorse_certificate_create_exporters (SeahorseExportable *exportable,
SeahorseExporterType type)
{
SeahorseExporter *exporter;
+ gboolean can_export = FALSE;
+
+ g_object_get (exportable, "exportable", &can_export, NULL);
+ if (!can_export)
+ return NULL;
+
exporter = seahorse_certificate_der_exporter_new (SEAHORSE_CERTIFICATE (exportable));
return g_list_append (NULL, exporter);
}
@@ -332,6 +356,31 @@ seahorse_certificate_exportable_iface (SeahorseExportableIface *iface)
iface->create_exporters = seahorse_certificate_create_exporters;
}
+static SeahorseDeleter *
+seahorse_certificate_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseCertificate *self = SEAHORSE_CERTIFICATE (deletable);
+ SeahorseDeleter *deleter = NULL;
+
+ if (self->pv->private_key)
+ deleter = seahorse_deletable_create_deleter (SEAHORSE_DELETABLE (self->pv->private_key));
+
+ if (seahorse_token_is_deletable (self->pv->token, GCK_OBJECT (self))) {
+ if (deleter == NULL)
+ deleter = seahorse_pkcs11_deleter_new (self);
+ else if (!seahorse_deleter_add_object (deleter, G_OBJECT (self)))
+ g_return_val_if_reached (NULL);
+ }
+
+ return deleter;
+}
+
+static void
+seahorse_certificate_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_certificate_create_deleter;
+}
+
GIcon *
seahorse_certificate_get_icon (SeahorseCertificate *self)
{
diff --git a/pkcs11/seahorse-pkcs11-actions.c b/pkcs11/seahorse-pkcs11-actions.c
index 809822c..dcabea4 100644
--- a/pkcs11/seahorse-pkcs11-actions.c
+++ b/pkcs11/seahorse-pkcs11-actions.c
@@ -28,7 +28,6 @@
#include "seahorse-interaction.h"
#include "seahorse-pkcs11.h"
#include "seahorse-pkcs11-properties.h"
-#include "seahorse-pkcs11-operations.h"
#include "seahorse-token.h"
#include "seahorse-action.h"
@@ -206,70 +205,12 @@ on_show_properties (GtkAction *action,
gtk_widget_show (GTK_WIDGET (window));
}
-static void
-on_delete_completed (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GtkWindow *parent = GTK_WINDOW (user_data);
- GError *error = NULL;
-
- if (!seahorse_pkcs11_delete_finish (result, &error))
- seahorse_util_handle_error (&error, parent, _("Couldn't delete"));
-
- g_object_unref (parent);
-}
-
-static void
-on_delete_objects (GtkAction *action,
- gpointer user_data)
-{
- GCancellable *cancellable;
- gchar *prompt;
- gchar *display;
- GtkWindow *parent;
- gboolean ret;
- guint num;
- GList *objects;
-
- objects = user_data;
- num = g_list_length (objects);
- if (num == 1) {
- g_object_get (objects->data, "label", &display, NULL);
- prompt = g_strdup_printf (_("Are you sure you want to delete the certificate '%s'?"), display);
- g_free (display);
- } else {
- prompt = g_strdup_printf (ngettext (
- "Are you sure you want to delete %d certificate?",
- "Are you sure you want to delete %d certificates?",
- num), num);
- }
-
- parent = seahorse_action_get_window (action);
- ret = seahorse_delete_dialog_prompt (parent, prompt);
- g_free (prompt);
-
- if (ret) {
- cancellable = g_cancellable_new ();
- seahorse_pkcs11_delete_async (objects, cancellable,
- on_delete_completed, g_object_ref (parent));
- seahorse_progress_show (cancellable, _("Deleting"), TRUE);
- g_object_unref (cancellable);
- } else {
- g_cancellable_cancel (g_cancellable_get_current ());
- }
-}
static const GtkActionEntry CERTIFICATE_ACTIONS[] = {
{ "properties", GTK_STOCK_PROPERTIES, NULL, NULL,
N_("Properties of the certificate."), G_CALLBACK (on_show_properties) },
};
-static const GtkActionEntry CERTIFICATES_ACTIONS[] = {
- { "delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the certificate."), G_CALLBACK (on_delete_objects) },
-};
-
static void
seahorse_pkcs11_object_actions_init (SeahorsePkcs11ObjectActions *self)
{
@@ -286,10 +227,6 @@ seahorse_pkcs11_object_actions_clone_for_objects (SeahorseActions *actions,
cloned = gtk_action_group_new ("Pkcs11Object");
gtk_action_group_set_translation_domain (cloned, GETTEXT_PACKAGE);
- gtk_action_group_add_actions_full (cloned, CERTIFICATES_ACTIONS,
- G_N_ELEMENTS (CERTIFICATES_ACTIONS),
- seahorse_object_list_copy (objects),
- seahorse_object_list_free);
/* Only one object? */
if (!objects->next)
diff --git a/pkcs11/seahorse-pkcs11-deleter.c b/pkcs11/seahorse-pkcs11-deleter.c
new file mode 100644
index 0000000..30d7b3c
--- /dev/null
+++ b/pkcs11/seahorse-pkcs11-deleter.c
@@ -0,0 +1,235 @@
+/*
+ * 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-pkcs11-deleter.h"
+#include "seahorse-token.h"
+
+#include "seahorse-delete-dialog.h"
+
+#include <gck/gck.h>
+
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (SeahorsePkcs11Deleter, seahorse_pkcs11_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_pkcs11_deleter_init (SeahorsePkcs11Deleter *self)
+{
+
+}
+
+static void
+seahorse_pkcs11_deleter_finalize (GObject *obj)
+{
+ SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (obj);
+
+ g_list_free_full (self->objects, g_object_unref);
+
+ G_OBJECT_CLASS (seahorse_pkcs11_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_pkcs11_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (deleter);
+ GtkDialog *dialog;
+ gchar *prompt;
+ gchar *label;
+ guint num;
+
+ num = g_list_length (self->objects);
+ if (num == 1) {
+ g_object_get (self->objects->data, "label", &label, NULL);
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete %s?"), label);
+ g_free (label);
+ } else {
+ prompt = g_strdup_printf (ngettext ("Are you sure you want to permanently delete %d certificate?",
+ "Are you sure you want to permanently delete %d certificates?",
+ num),
+ num);
+ }
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+ g_free (prompt);
+
+ return dialog;
+}
+
+static GList *
+seahorse_pkcs11_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (deleter);
+ return self->objects;
+}
+
+static gboolean
+seahorse_pkcs11_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (deleter);
+
+ if (!SEAHORSE_IS_CERTIFICATE (object))
+ return FALSE;
+
+ self->objects = g_list_append (self->objects, g_object_ref (object));
+ return TRUE;
+}
+
+typedef struct {
+ GQueue *objects;
+ GCancellable *cancellable;
+} DeleteClosure;
+
+
+static void
+delete_closure_free (gpointer data)
+{
+ DeleteClosure *closure = data;
+ g_queue_foreach (closure->objects, (GFunc)g_object_unref, NULL);
+ g_queue_free (closure->objects);
+ g_clear_object (&closure->cancellable);
+ g_free (closure);
+}
+
+static void pkcs11_delete_one_object (GSimpleAsyncResult *res);
+
+static void
+on_delete_object_completed (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+ GckObject *object;
+ SeahorseToken *pkcs11_token;
+
+ object = g_queue_pop_head (closure->objects);
+
+ if (!gck_object_destroy_finish (GCK_OBJECT (source), result, &error)) {
+
+ /* Ignore objects that have gone away */
+ if (g_error_matches (error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) {
+ g_clear_error (&error);
+ } else {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ }
+
+ }
+
+ if (error == NULL) {
+ g_object_get (object, "place", &pkcs11_token, NULL);
+ g_return_if_fail (SEAHORSE_IS_TOKEN (pkcs11_token));
+ seahorse_token_remove_object (pkcs11_token, GCK_OBJECT (object));
+ pkcs11_delete_one_object (res);
+ }
+
+ g_object_unref (object);
+ g_object_unref (res);
+}
+
+static void
+pkcs11_delete_one_object (GSimpleAsyncResult *res)
+{
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GckObject *object;
+
+ if (g_queue_is_empty (closure->objects)) {
+ g_simple_async_result_complete_in_idle (res);
+ return;
+ }
+
+ object = g_queue_peek_head (closure->objects);
+
+ gck_object_destroy_async (object, closure->cancellable,
+ on_delete_object_completed, g_object_ref (res));
+}
+
+static void
+seahorse_pkcs11_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorsePkcs11Deleter *self = SEAHORSE_PKCS11_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ DeleteClosure *closure;
+ GList *l;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_pkcs11_deleter_delete_async);
+ closure = g_new0 (DeleteClosure, 1);
+ closure->objects = g_queue_new ();
+ for (l = self->objects; l != NULL; l = g_list_next (l))
+ g_queue_push_tail (closure->objects, g_object_ref (l->data));
+ g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
+
+ pkcs11_delete_one_object (res);
+
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_pkcs11_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (deleter),
+ seahorse_pkcs11_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+seahorse_pkcs11_deleter_class_init (SeahorsePkcs11DeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_pkcs11_deleter_finalize;
+
+ deleter_class->add_object = seahorse_pkcs11_deleter_add_object;
+ deleter_class->create_confirm = seahorse_pkcs11_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_pkcs11_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_pkcs11_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_pkcs11_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_pkcs11_deleter_new (SeahorseCertificate *certificate)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_PKCS11_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (certificate)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/pkcs11/seahorse-pkcs11-deleter.h b/pkcs11/seahorse-pkcs11-deleter.h
new file mode 100644
index 0000000..bdb6b81
--- /dev/null
+++ b/pkcs11/seahorse-pkcs11-deleter.h
@@ -0,0 +1,55 @@
+/*
+ * 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_PKCS11_DELETER_H__
+#define __SEAHORSE_PKCS11_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-certificate.h"
+
+#define SEAHORSE_TYPE_PKCS11_DELETER (seahorse_pkcs11_deleter_get_type ())
+#define SEAHORSE_PKCS11_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PKCS11_DELETER, SeahorsePkcs11Deleter))
+#define SEAHORSE_IS_PKCS11_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PKCS11_DELETER))
+#define SEAHORSE_PKCS11_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PKCS11_DELETER, SeahorsePkcs11DeleterClass))
+#define SEAHORSE_IS_PKCS11_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PKCS11_DELETER))
+#define SEAHORSE_PKCS11_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PKCS11_DELETER, SeahorsePkcs11DeleterClass))
+
+typedef struct _SeahorsePkcs11Deleter SeahorsePkcs11Deleter;
+typedef struct _SeahorsePkcs11DeleterClass SeahorsePkcs11DeleterClass;
+
+struct _SeahorsePkcs11Deleter {
+ SeahorseDeleter parent;
+ GList *objects;
+};
+
+struct _SeahorsePkcs11DeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+GType seahorse_pkcs11_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_pkcs11_deleter_new (SeahorseCertificate *cert);
+
+#endif /* __SEAHORSE_PKCS11_DELETER_H__ */
diff --git a/pkcs11/seahorse-pkcs11-key-deleter.c b/pkcs11/seahorse-pkcs11-key-deleter.c
new file mode 100644
index 0000000..8b1d024
--- /dev/null
+++ b/pkcs11/seahorse-pkcs11-key-deleter.c
@@ -0,0 +1,150 @@
+/*
+ * 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-certificate.h"
+#include "seahorse-pkcs11-deleter.h"
+#include "seahorse-pkcs11-key-deleter.h"
+#include "seahorse-private-key.h"
+#include "seahorse-token.h"
+
+#include "seahorse-delete-dialog.h"
+
+#include <gck/gck.h>
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_PKCS11_KEY_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PKCS11_KEY_DELETER, SeahorsePkcs11KeyDeleterClass))
+#define SEAHORSE_IS_PKCS11_KEY_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PKCS11_KEY_DELETER))
+#define SEAHORSE_PKCS11_KEY_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PKCS11_KEY_DELETER, SeahorsePkcs11KeyDeleterClass))
+
+typedef struct _SeahorsePkcs11KeyDeleterClass SeahorsePkcs11KeyDeleterClass;
+
+struct _SeahorsePkcs11KeyDeleter {
+ SeahorsePkcs11Deleter parent;
+ SeahorseCertificate *cert;
+ SeahorsePrivateKey *key;
+ gchar *label;
+};
+
+struct _SeahorsePkcs11KeyDeleterClass {
+ SeahorsePkcs11DeleterClass parent_class;
+};
+
+G_DEFINE_TYPE (SeahorsePkcs11KeyDeleter, seahorse_pkcs11_key_deleter, SEAHORSE_TYPE_PKCS11_DELETER);
+
+static void
+seahorse_pkcs11_key_deleter_init (SeahorsePkcs11KeyDeleter *self)
+{
+
+}
+
+static void
+seahorse_pkcs11_key_deleter_finalize (GObject *obj)
+{
+ SeahorsePkcs11KeyDeleter *self = SEAHORSE_PKCS11_KEY_DELETER (obj);
+
+ g_free (self->label);
+
+ G_OBJECT_CLASS (seahorse_pkcs11_key_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_pkcs11_key_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorsePkcs11KeyDeleter *self = SEAHORSE_PKCS11_KEY_DELETER (deleter);
+ GtkDialog *dialog;
+ gchar *prompt;
+
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete %s?"), self->label);
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+
+ seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog), _("I understand that this key will be permanently deleted."));
+ seahorse_delete_dialog_set_check_require (SEAHORSE_DELETE_DIALOG (dialog), TRUE);
+
+ g_free (prompt);
+ return dialog;
+}
+
+static gboolean
+seahorse_pkcs11_key_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorsePkcs11KeyDeleter *self = SEAHORSE_PKCS11_KEY_DELETER (deleter);
+ SeahorsePkcs11Deleter *base = SEAHORSE_PKCS11_DELETER (deleter);
+ gpointer partner = NULL;
+
+ if (SEAHORSE_IS_PRIVATE_KEY (object)) {
+ if (self->key != NULL)
+ return FALSE;
+ if (self->cert != NULL) {
+ partner = seahorse_certificate_get_partner (SEAHORSE_CERTIFICATE (self->cert));
+ if (partner != object)
+ return FALSE;
+ }
+ self->key = SEAHORSE_PRIVATE_KEY (object);
+ base->objects = g_list_prepend (base->objects, g_object_ref (self->key));
+
+ } else if (SEAHORSE_IS_CERTIFICATE (object)) {
+ if (self->cert != NULL)
+ return FALSE;
+ if (self->key != NULL) {
+ partner = seahorse_private_key_get_partner (SEAHORSE_PRIVATE_KEY (self->key));
+ if (partner != object)
+ return FALSE;
+ }
+ self->cert = SEAHORSE_CERTIFICATE (object);
+ base->objects = g_list_append (base->objects, g_object_ref (self->cert));
+ }
+
+ if (self->label == NULL)
+ g_object_get (object, "label", &self->label, NULL);
+ return TRUE;
+}
+
+static void
+seahorse_pkcs11_key_deleter_class_init (SeahorsePkcs11KeyDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ deleter_class->add_object = seahorse_pkcs11_key_deleter_add_object;
+ deleter_class->create_confirm = seahorse_pkcs11_key_deleter_create_confirm;
+
+ gobject_class->finalize = seahorse_pkcs11_key_deleter_finalize;
+}
+
+SeahorseDeleter *
+seahorse_pkcs11_key_deleter_new (GObject *cert_or_key)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_PKCS11_KEY_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, cert_or_key))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/pkcs11/seahorse-pkcs11-key-deleter.h b/pkcs11/seahorse-pkcs11-key-deleter.h
new file mode 100644
index 0000000..e93308c
--- /dev/null
+++ b/pkcs11/seahorse-pkcs11-key-deleter.h
@@ -0,0 +1,42 @@
+/*
+ * 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_PKCS11_KEY_DELETER_H__
+#define __SEAHORSE_PKCS11_KEY_DELETER_H__
+
+#include <glib-object.h>
+
+#include "seahorse-deleter.h"
+#include "seahorse-certificate.h"
+
+#define SEAHORSE_TYPE_PKCS11_KEY_DELETER (seahorse_pkcs11_key_deleter_get_type ())
+#define SEAHORSE_PKCS11_KEY_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PKCS11_KEY_DELETER, SeahorsePkcs11KeyDeleter))
+#define SEAHORSE_IS_PKCS11_KEY_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PKCS11_KEY_DELETER))
+
+typedef struct _SeahorsePkcs11KeyDeleter SeahorsePkcs11KeyDeleter;
+
+GType seahorse_pkcs11_key_deleter_get_type (void) G_GNUC_CONST;
+
+SeahorseDeleter * seahorse_pkcs11_key_deleter_new (GObject *cert_or_key);
+
+#endif /* __SEAHORSE_PKCS11_KEY_DELETER_H__ */
diff --git a/pkcs11/seahorse-pkcs11-properties.c b/pkcs11/seahorse-pkcs11-properties.c
index fd00890..e45508a 100644
--- a/pkcs11/seahorse-pkcs11-properties.c
+++ b/pkcs11/seahorse-pkcs11-properties.c
@@ -22,13 +22,14 @@
#include "config.h"
#include "seahorse-certificate.h"
+#include "seahorse-pkcs11-deleter.h"
+#include "seahorse-pkcs11-key-deleter.h"
#include "seahorse-pkcs11-properties.h"
-#include "seahorse-pkcs11-operations.h"
#include "seahorse-pkcs11-request.h"
#include "seahorse-private-key.h"
#include "seahorse-action.h"
-#include "seahorse-delete-dialog.h"
+#include "seahorse-deleter.h"
#include "seahorse-exportable.h"
#include "seahorse-progress.h"
#include "seahorse-util.h"
@@ -177,7 +178,7 @@ on_delete_complete (GObject *source,
SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (user_data);
GError *error = NULL;
- if (seahorse_pkcs11_delete_finish (result, &error))
+ if (seahorse_deleter_delete_finish (SEAHORSE_DELETER (source), result, &error))
gtk_widget_destroy (GTK_WIDGET (self));
else
@@ -191,58 +192,25 @@ on_delete_objects (GtkAction *action,
gpointer user_data)
{
SeahorsePkcs11Properties *self = SEAHORSE_PKCS11_PROPERTIES (user_data);
- gboolean with_partner = FALSE;
+ SeahorseDeleter *deleter;
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);
+ g_object_get (self->object, "partner", &partner, NULL);
- 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 (partner || SEAHORSE_IS_PRIVATE_KEY (self->object)) {
+ deleter = seahorse_pkcs11_key_deleter_new (self->object);
+ if (!seahorse_deleter_add_object (SEAHORSE_DELETER (deleter), partner))
+ g_assert_not_reached ();
+ } else {
+ deleter = seahorse_pkcs11_deleter_new (SEAHORSE_CERTIFICATE (self->object));
}
- 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);
+ if (seahorse_deleter_prompt (deleter, GTK_WINDOW (self))) {
+ seahorse_deleter_delete_async (deleter, NULL, on_delete_complete, g_object_ref (self));
}
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_list_free_full (objects, g_object_unref);
+ g_object_unref (deleter);
g_clear_object (&partner);
- g_free (label);
}
static void
@@ -340,12 +308,17 @@ seahorse_pkcs11_properties_constructed (GObject *obj)
GError *error = NULL;
GList *exporters = NULL;
GtkAction *request;
+ GtkAction *action;
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);
gtk_action_group_set_translation_domain (self->actions, GETTEXT_PACKAGE);
+ action = gtk_action_group_get_action (self->actions, "delete-object");
+ g_object_bind_property (self->object, "deletable", action, "sensitive", G_BINDING_SYNC_CREATE);
+ action = gtk_action_group_get_action (self->actions, "export-object");
+ g_object_bind_property (self->object, "exportable", action, "sensitive", G_BINDING_SYNC_CREATE);
request = gtk_action_group_get_action (self->actions, "request-certificate");
gtk_action_set_is_important (request, TRUE);
gtk_action_set_visible (request, FALSE);
diff --git a/pkcs11/seahorse-private-key.c b/pkcs11/seahorse-private-key.c
index 4206657..04ceb5a 100644
--- a/pkcs11/seahorse-private-key.c
+++ b/pkcs11/seahorse-private-key.c
@@ -26,9 +26,11 @@
#include "seahorse-pkcs11.h"
#include "seahorse-pkcs11-actions.h"
#include "seahorse-pkcs11-helpers.h"
+#include "seahorse-pkcs11-key-deleter.h"
#include "seahorse-token.h"
#include "seahorse-types.h"
+#include "seahorse-deletable.h"
#include "seahorse-util.h"
#include <gcr/gcr.h>
@@ -43,6 +45,7 @@ static const gulong REQUIRED_ATTRS[] = {
CKA_LABEL,
CKA_CLASS,
CKA_KEY_TYPE,
+ CKA_MODIFIABLE,
};
enum {
@@ -53,6 +56,7 @@ enum {
PROP_ACTIONS,
PROP_PARTNER,
+ PROP_DELETABLE,
PROP_LABEL,
PROP_MARKUP,
PROP_DESCRIPTION,
@@ -67,10 +71,13 @@ struct _SeahorsePrivateKeyPrivate {
GIcon *icon;
};
+static void seahorse_private_key_deletable_iface (SeahorseDeletableIface *iface);
+
static void seahorse_private_key_object_attributes_iface (GckObjectAttributesIface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorsePrivateKey, seahorse_private_key, GCK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES, seahorse_private_key_object_attributes_iface)
+ G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES, seahorse_private_key_object_attributes_iface);
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_private_key_deletable_iface);
);
static void
@@ -156,6 +163,9 @@ seahorse_private_key_get_property (GObject *obj,
case PROP_MARKUP:
g_value_take_string (value, calculate_markup (self));
break;
+ case PROP_DELETABLE:
+ g_value_set_boolean (value, seahorse_token_is_deletable (self->pv->token, GCK_OBJECT (self)));
+ break;
case PROP_DESCRIPTION:
g_value_set_string (value, _("Private key"));
break;
@@ -244,6 +254,8 @@ seahorse_private_key_class_init (SeahorsePrivateKeyClass *klass)
G_TYPE_ICON, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+
+ g_object_class_override_property (gobject_class, PROP_DELETABLE, "deletable");
}
static void
@@ -253,6 +265,21 @@ seahorse_private_key_object_attributes_iface (GckObjectAttributesIface *iface)
iface->n_attribute_types = G_N_ELEMENTS (REQUIRED_ATTRS);
}
+static SeahorseDeleter *
+seahorse_private_key_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorsePrivateKey *self = SEAHORSE_PRIVATE_KEY (deletable);
+ if (!seahorse_token_is_deletable (self->pv->token, GCK_OBJECT (self)))
+ return NULL;
+ return seahorse_pkcs11_key_deleter_new (G_OBJECT (self));
+}
+
+static void
+seahorse_private_key_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_private_key_create_deleter;
+}
+
SeahorseCertificate *
seahorse_private_key_get_partner (SeahorsePrivateKey *self)
{
diff --git a/pkcs11/seahorse-token.c b/pkcs11/seahorse-token.c
index 890955f..a47775c 100644
--- a/pkcs11/seahorse-token.c
+++ b/pkcs11/seahorse-token.c
@@ -32,7 +32,6 @@
#include "seahorse-pkcs11.h"
#include "seahorse-pkcs11-actions.h"
#include "seahorse-pkcs11-helpers.h"
-#include "seahorse-pkcs11-operations.h"
#include "seahorse-private-key.h"
#include "seahorse-token.h"
@@ -1071,3 +1070,27 @@ seahorse_token_unlock_finish (SeahorseToken *self,
return TRUE;
}
+
+gboolean
+seahorse_token_is_deletable (SeahorseToken *self,
+ GckObject *object)
+{
+ GckAttributes *attrs;
+ GckTokenInfo *info;
+ gboolean ret;
+
+ g_return_val_if_fail (SEAHORSE_IS_TOKEN (self), FALSE);
+ g_return_val_if_fail (GCK_IS_OBJECT (object), FALSE);
+
+ info = seahorse_token_get_info (self);
+ if (info->flags & CKF_WRITE_PROTECTED)
+ return FALSE;
+
+ g_object_get (object, "attributes", &attrs, NULL);
+
+ if (!gck_attributes_find_boolean (attrs, CKA_MODIFIABLE, &ret))
+ ret = TRUE;
+
+ gck_attributes_unref (attrs);
+ return ret;
+}
diff --git a/pkcs11/seahorse-token.h b/pkcs11/seahorse-token.h
index 273479b..0b25027 100644
--- a/pkcs11/seahorse-token.h
+++ b/pkcs11/seahorse-token.h
@@ -70,6 +70,9 @@ gboolean seahorse_token_has_mechanism (SeahorseToken *self,
void seahorse_token_remove_object (SeahorseToken *self,
GckObject *object);
+gboolean seahorse_token_is_deletable (SeahorseToken *self,
+ GckObject *object);
+
void seahorse_token_lock_async (SeahorseToken *self,
GTlsInteraction *interaction,
GCancellable *cancellable,
diff --git a/ssh/Makefile.am b/ssh/Makefile.am
index af3a760..f2e6921 100644
--- a/ssh/Makefile.am
+++ b/ssh/Makefile.am
@@ -20,6 +20,7 @@ libseahorse_ssh_la_SOURCES = \
seahorse-ssh.h seahorse-ssh.c \
seahorse-ssh-actions.c seahorse-ssh-actions.h \
seahorse-ssh-backend.c seahorse-ssh-backend.h \
+ seahorse-ssh-deleter.c seahorse-ssh-deleter.h \
seahorse-ssh-dialogs.h \
seahorse-ssh-exporter.c seahorse-ssh-exporter.h \
seahorse-ssh-generate.c \
diff --git a/ssh/seahorse-ssh-actions.c b/ssh/seahorse-ssh-actions.c
index 0ba6ade..2087ca7 100644
--- a/ssh/seahorse-ssh-actions.c
+++ b/ssh/seahorse-ssh-actions.c
@@ -90,54 +90,10 @@ on_show_properties (GtkAction *action,
seahorse_action_get_window (action));
}
-static void
-on_delete_objects (GtkAction *action,
- gpointer user_data)
-{
- guint num;
- gchar* prompt;
- GList *l;
- GtkWindow *parent;
- GError *error = NULL;
- GList* objects;
-
- objects = user_data;
- num = g_list_length (objects);
- if (num == 0) {
- return;
-
- } else if (num == 1) {
- prompt = g_strdup_printf (_("Are you sure you want to delete the secure shell key '%s'?"),
- seahorse_object_get_label (objects->data));
-
- } else {
- prompt = g_strdup_printf (ngettext (_("Are you sure you want to delete %d secure shell keys?"),
- _("Are you sure you want to delete %d secure shell keys?"),
- num),
- num);
- }
-
- 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"));
- }
- }
- } else {
- g_cancellable_cancel (g_cancellable_get_current ());
- }
-
- g_free (prompt);
-
-}
-
static const GtkActionEntry KEYS_ACTIONS[] = {
{ "remote-ssh-upload", NULL, N_ ("Configure Key for _Secure Shell..."), "",
N_ ("Send public Secure Shell key to another machine, and enable logins using that key."),
G_CALLBACK (on_ssh_upload) },
- { "delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the key."), G_CALLBACK (on_delete_objects) },
};
static const GtkActionEntry KEY_ACTIONS[] = {
diff --git a/ssh/seahorse-ssh-deleter.c b/ssh/seahorse-ssh-deleter.c
new file mode 100644
index 0000000..69eedb3
--- /dev/null
+++ b/ssh/seahorse-ssh-deleter.c
@@ -0,0 +1,205 @@
+/*
+ * 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-ssh-key.h"
+#include "seahorse-ssh-deleter.h"
+#include "seahorse-ssh-operation.h"
+
+#include "seahorse-delete-dialog.h"
+
+#include <glib/gi18n.h>
+
+#define SEAHORSE_SSH_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_SSH_DELETER, SeahorseSshDeleterClass))
+#define SEAHORSE_IS_SSH_DELETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_SSH_DELETER))
+#define SEAHORSE_SSH_DELETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_SSH_DELETER, SeahorseSshDeleterClass))
+
+typedef struct _SeahorseSshDeleterClass SeahorseSshDeleterClass;
+
+struct _SeahorseSshDeleter {
+ SeahorseDeleter parent;
+ gboolean have_private;
+ GList *keys;
+};
+
+struct _SeahorseSshDeleterClass {
+ SeahorseDeleterClass parent_class;
+};
+
+G_DEFINE_TYPE (SeahorseSshDeleter, seahorse_ssh_deleter, SEAHORSE_TYPE_DELETER);
+
+static void
+seahorse_ssh_deleter_init (SeahorseSshDeleter *self)
+{
+
+}
+
+static void
+seahorse_ssh_deleter_finalize (GObject *obj)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (obj);
+
+ g_list_free_full (self->keys, g_object_unref);
+
+ G_OBJECT_CLASS (seahorse_ssh_deleter_parent_class)->finalize (obj);
+}
+
+static GtkDialog *
+seahorse_ssh_deleter_create_confirm (SeahorseDeleter *deleter,
+ GtkWindow *parent)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (deleter);
+ const gchar *confirm;
+ GtkDialog *dialog;
+ gchar *prompt;
+ guint num;
+
+ num = g_list_length (self->keys);
+ if (self->have_private) {
+ g_return_val_if_fail (num == 1, NULL);
+ prompt = g_strdup_printf (_("Are you sure you want to delete the secure shell key '%s'?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->keys->data)));
+ confirm = _("I understand that this secret key will be permanently deleted.");
+
+ } else if (num == 1) {
+ prompt = g_strdup_printf (_("Are you sure you want to delete the secure shell key '%s'?"),
+ seahorse_object_get_label (SEAHORSE_OBJECT (self->keys->data)));
+ confirm = NULL;
+
+ } else {
+ prompt = g_strdup_printf (ngettext (_("Are you sure you want to delete %d secure shell keys?"),
+ _("Are you sure you want to delete %d secure shell keys?"),
+ num),
+ num);
+ confirm = NULL;
+ }
+
+ dialog = seahorse_delete_dialog_new (parent, prompt);
+ g_free (prompt);
+
+ if (confirm) {
+ seahorse_delete_dialog_set_check_label (SEAHORSE_DELETE_DIALOG (dialog), confirm);
+ seahorse_delete_dialog_set_check_require (SEAHORSE_DELETE_DIALOG (dialog), TRUE);
+ }
+
+ return dialog;
+}
+
+static GList *
+seahorse_ssh_deleter_get_objects (SeahorseDeleter *deleter)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (deleter);
+ return self->keys;
+}
+
+static gboolean
+seahorse_ssh_deleter_add_object (SeahorseDeleter *deleter,
+ GObject *object)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (deleter);
+ SeahorseUsage usage;
+
+ if (!SEAHORSE_IS_SSH_KEY (object))
+ return FALSE;
+ if (self->have_private)
+ return FALSE;
+ usage = seahorse_object_get_usage (SEAHORSE_OBJECT (object));
+ if (usage == SEAHORSE_USAGE_PRIVATE_KEY) {
+ if (self->keys != NULL)
+ return FALSE;
+ self->have_private = TRUE;
+ }
+
+ self->keys = g_list_append (self->keys, g_object_ref (object));
+ return TRUE;
+}
+
+static void
+seahorse_ssh_deleter_delete_async (SeahorseDeleter *deleter,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (deleter);
+ GSimpleAsyncResult *res;
+ GError *error = NULL;
+ GList *l;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ seahorse_ssh_deleter_delete_async);
+
+ for (l = self->keys; l != NULL && !g_cancellable_is_cancelled (cancellable);
+ l = g_list_next (l)) {
+ if (!seahorse_ssh_op_delete_sync (l->data, &error)) {
+ g_simple_async_result_take_error (res, error);
+ break;
+ }
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+static gboolean
+seahorse_ssh_deleter_delete_finish (SeahorseDeleter *deleter,
+ GAsyncResult *result,
+ GError **error)
+{
+ SeahorseSshDeleter *self = SEAHORSE_SSH_DELETER (deleter);
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ seahorse_ssh_deleter_delete_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+seahorse_ssh_deleter_class_init (SeahorseSshDeleterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SeahorseDeleterClass *deleter_class = SEAHORSE_DELETER_CLASS (klass);
+
+ gobject_class->finalize = seahorse_ssh_deleter_finalize;
+
+ deleter_class->add_object = seahorse_ssh_deleter_add_object;
+ deleter_class->create_confirm = seahorse_ssh_deleter_create_confirm;
+ deleter_class->delete_async = seahorse_ssh_deleter_delete_async;
+ deleter_class->delete_finish = seahorse_ssh_deleter_delete_finish;
+ deleter_class->get_objects = seahorse_ssh_deleter_get_objects;
+}
+
+SeahorseDeleter *
+seahorse_ssh_deleter_new (SeahorseSSHKey *item)
+{
+ SeahorseDeleter *deleter;
+
+ deleter = g_object_new (SEAHORSE_TYPE_SSH_DELETER, NULL);
+ if (!seahorse_deleter_add_object (deleter, G_OBJECT (item)))
+ g_assert_not_reached ();
+
+ return deleter;
+}
diff --git a/pkcs11/seahorse-pkcs11-operations.h b/ssh/seahorse-ssh-deleter.h
similarity index 50%
rename from pkcs11/seahorse-pkcs11-operations.h
rename to ssh/seahorse-ssh-deleter.h
index a1b94e7..70d29e8 100644
--- a/pkcs11/seahorse-pkcs11-operations.h
+++ b/ssh/seahorse-ssh-deleter.h
@@ -1,36 +1,42 @@
-/*
+/*
* Seahorse
- *
- * Copyright (C) 2008 Stefan Walter
+ *
* Copyright (C) 2011 Collabora Ltd.
*
- * This program is free software; you can redistribute it and/or modify
+ * 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.
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
*/
-#ifndef __SEAHORSE_PKCS11_OPERATIONS_H__
-#define __SEAHORSE_PKCS11_OPERATIONS_H__
+#ifndef __SEAHORSE_SSH_DELETER_H__
+#define __SEAHORSE_SSH_DELETER_H__
#include <glib-object.h>
-void seahorse_pkcs11_delete_async (GList *objects,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+#include "seahorse-deleter.h"
+#include "seahorse-ssh-key.h"
+
+#define SEAHORSE_TYPE_SSH_DELETER (seahorse_ssh_deleter_get_type ())
+#define SEAHORSE_SSH_DELETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_SSH_DELETER, SeahorseSshDeleter))
+#define SEAHORSE_IS_SSH_DELETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_SSH_DELETER))
+
+typedef struct _SeahorseSshDeleter SeahorseSshDeleter;
+
+GType seahorse_ssh_deleter_get_type (void) G_GNUC_CONST;
-gboolean seahorse_pkcs11_delete_finish (GAsyncResult *result,
- GError **error);
+SeahorseDeleter * seahorse_ssh_deleter_new (SeahorseSSHKey *key);
-#endif /* __SEAHORSE_PKCS11_TOKEN_H__ */
+#endif /* __SEAHORSE_SSH_DELETER_H__ */
diff --git a/ssh/seahorse-ssh-key.c b/ssh/seahorse-ssh-key.c
index 27913d0..a20f91a 100644
--- a/ssh/seahorse-ssh-key.c
+++ b/ssh/seahorse-ssh-key.c
@@ -23,11 +23,13 @@
#include "config.h"
#include "seahorse-ssh-actions.h"
+#include "seahorse-ssh-deleter.h"
#include "seahorse-ssh-exporter.h"
#include "seahorse-ssh-key.h"
#include "seahorse-ssh-operation.h"
#include "seahorse-ssh-source.h"
+#include "seahorse-deletable.h"
#include "seahorse-exportable.h"
#include "seahorse-icons.h"
#include "seahorse-place.h"
@@ -53,10 +55,13 @@ enum {
PROP_LENGTH
};
+static void seahorse_ssh_key_deletable_iface (SeahorseDeletableIface *iface);
+
static void seahorse_ssh_key_exportable_iface (SeahorseExportableIface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorseSSHKey, seahorse_ssh_key, SEAHORSE_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_EXPORTABLE, seahorse_ssh_key_exportable_iface);
+ G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_ssh_key_deletable_iface);
);
/* -----------------------------------------------------------------------------
@@ -313,9 +318,18 @@ seahorse_ssh_key_exportable_iface (SeahorseExportableIface *iface)
iface->create_exporters = seahorse_ssh_key_create_exporters;
}
-/* -----------------------------------------------------------------------------
- * PUBLIC METHODS
- */
+static SeahorseDeleter *
+seahorse_ssh_key_create_deleter (SeahorseDeletable *deletable)
+{
+ SeahorseSSHKey *self = SEAHORSE_SSH_KEY (deletable);
+ return seahorse_ssh_deleter_new (self);
+}
+
+static void
+seahorse_ssh_key_deletable_iface (SeahorseDeletableIface *iface)
+{
+ iface->create_deleter = seahorse_ssh_key_create_deleter;
+}
SeahorseSSHKey*
seahorse_ssh_key_new (SeahorsePlace *place,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]