[seahorse] Rework actions again
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse] Rework actions again
- Date: Wed, 2 Nov 2011 09:06:28 +0000 (UTC)
commit 700ae51c40e90cef388dab0cf89c5e82933b4757
Author: Stef Walter <stefw collabora co uk>
Date: Tue Oct 25 09:44:42 2011 +0200
Rework actions again
* We clone action groups for the current selection, that clone
contains a reference to the current selection.
gkr/seahorse-gkr-actions.c | 202 ++++++++++++++-----------
libseahorse/seahorse-action.c | 123 +++-------------
libseahorse/seahorse-action.h | 19 +--
libseahorse/seahorse-actions.c | 35 +++--
libseahorse/seahorse-actions.h | 8 +-
libseahorse/seahorse-object-list.c | 5 +-
libseahorse/seahorse-object-list.h | 2 +-
libseahorse/seahorse-viewer.c | 289 ++++++++++++------------------------
libseahorse/seahorse-viewer.h | 24 +---
pgp/seahorse-keyserver-results.c | 13 +-
pgp/seahorse-pgp-actions.c | 68 +++++++--
pkcs11/seahorse-pkcs11-actions.c | 50 +++++--
src/seahorse-generate-select.c | 24 ++-
src/seahorse-key-manager.c | 21 ++-
ssh/seahorse-ssh-actions.c | 53 +++++--
ssh/seahorse-ssh-actions.h | 2 +
ssh/seahorse-ssh-key.c | 14 ++-
17 files changed, 445 insertions(+), 507 deletions(-)
---
diff --git a/gkr/seahorse-gkr-actions.c b/gkr/seahorse-gkr-actions.c
index d8b0358..9e5e71b 100644
--- a/gkr/seahorse-gkr-actions.c
+++ b/gkr/seahorse-gkr-actions.c
@@ -30,6 +30,7 @@
#include "seahorse-action.h"
#include "seahorse-actions.h"
+#include "seahorse-object-list.h"
#include "seahorse-progress.h"
#include "seahorse-registry.h"
#include "seahorse-util.h"
@@ -69,29 +70,29 @@ on_new_keyring (GtkAction *action,
static void
on_new_item (GtkAction *action,
- gpointer unused)
+ gpointer unused)
{
seahorse_gkr_add_item_show (seahorse_action_get_window (action));
}
static const GtkActionEntry BACKEND_ACTIONS[] = {
- { "gkr-keyring-new", NULL, N_("New password keyring"), "",
+ { "keyring-new", NULL, N_("New password keyring"), "",
N_("Used to store application and network passwords"), G_CALLBACK (on_new_keyring) },
- { "gkr-item-new", NULL, N_("New password..."), "",
+ { "keyring-item-new", NULL, N_("New password..."), "",
N_("Safely store a password or secret."), G_CALLBACK (on_new_item) },
};
static const GtkActionEntry ENTRIES_NEW[] = {
- { "gkr-add-keyring", "folder", N_("Password Keyring"), "",
+ { "keyring-new", "folder", N_("Password Keyring"), "",
N_("Used to store application and network passwords"), G_CALLBACK (on_new_keyring) },
- { "gkr-add-item", GCR_ICON_PASSWORD, N_("Stored Password"), "",
+ { "keyring-item-new", GCR_ICON_PASSWORD, N_("Stored Password"), "",
N_("Safely store a password or secret."), G_CALLBACK (on_new_item) }
};
static const gchar* BACKEND_UI =
"<ui>"
" <popup name='SeahorseGkrBackend'>"
-" <menuitem action='gkr-keyring-new'/>"
+" <menuitem action='keyring-new'/>"
" </popup>"\
"</ui>";
@@ -101,7 +102,7 @@ seahorse_gkr_backend_actions_init (SeahorseGkrBackendActions *self)
GtkActionGroup *actions = GTK_ACTION_GROUP (self);
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, BACKEND_ACTIONS, G_N_ELEMENTS (BACKEND_ACTIONS), self);
+ gtk_action_group_add_actions (actions, BACKEND_ACTIONS, G_N_ELEMENTS (BACKEND_ACTIONS), NULL);
seahorse_actions_register_definition (SEAHORSE_ACTIONS (self), BACKEND_UI);
/* Register another set of actions as a generator */
@@ -125,7 +126,7 @@ seahorse_gkr_backend_actions_instance (void)
if (actions == NULL) {
actions = g_object_new (SEAHORSE_TYPE_GKR_BACKEND_ACTIONS,
- "name", "gkr-backend",
+ "name", "KeyringBackend",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
@@ -145,17 +146,13 @@ seahorse_gkr_backend_actions_instance (void)
typedef struct {
SeahorseActions parent;
- GtkAction *action_lock;
- GtkAction *action_unlock;
- GtkAction *action_default;
} SeahorseGkrKeyringActions;
typedef struct {
SeahorseActionsClass parent_class;
} SeahorseGkrKeyringActionsClass;
-GType seahorse_gkr_keyring_actions_get_type (void);
-
+GType seahorse_gkr_keyring_actions_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (SeahorseGkrKeyringActions, seahorse_gkr_keyring_actions, SEAHORSE_TYPE_ACTIONS);
@@ -176,14 +173,14 @@ on_keyring_unlock_done (GnomeKeyringResult result,
}
static void
-on_keyring_unlock (GtkAction *action,
- gpointer user_data)
+on_keyrings_unlock (GtkAction *action,
+ gpointer user_data)
{
- GList *keys, *l;
+ GList *keys = user_data;
GtkWindow *parent;
+ GList *l;
parent = seahorse_action_get_window (action);
- keys = seahorse_action_get_objects (action);
for (l = keys; l; l = g_list_next (l)) {
g_return_if_fail (SEAHORSE_IS_GKR_KEYRING (l->data));
gnome_keyring_unlock (seahorse_gkr_keyring_get_name (l->data), NULL,
@@ -207,14 +204,14 @@ on_keyring_lock_done (GnomeKeyringResult result, gpointer user_data)
}
static void
-on_keyring_lock (GtkAction *action,
- gpointer user_data)
+on_keyrings_lock (GtkAction *action,
+ gpointer user_data)
{
- GList *keyrings, *l;
+ GList *keyrings = user_data;
GtkWindow *parent;
+ GList *l;
parent = seahorse_action_get_window (action);
- keyrings = seahorse_action_get_objects (action);
for (l = keyrings; l; l = g_list_next (l)) {
g_return_if_fail (SEAHORSE_IS_GKR_KEYRING (l->data));
gnome_keyring_lock (seahorse_gkr_keyring_get_name (l->data),
@@ -242,11 +239,8 @@ static void
on_keyring_default (GtkAction *action,
gpointer user_data)
{
- SeahorseGkrKeyring *keyring;
- GtkWindow *parent;
-
- parent = seahorse_action_get_window (action);
- keyring = seahorse_action_get_object (action);
+ SeahorseGkrKeyring *keyring = SEAHORSE_GKR_KEYRING (user_data);
+ GtkWindow *parent = seahorse_action_get_window (action);
gnome_keyring_set_default_keyring (seahorse_gkr_keyring_get_name (keyring),
on_set_default_keyring_done,
g_object_ref (parent), g_object_unref);
@@ -271,24 +265,19 @@ static void
on_keyring_password (GtkAction *action,
gpointer user_data)
{
- GtkWindow *window;
- GList *keys, *l;
+ SeahorseGkrKeyring *keyring = SEAHORSE_GKR_KEYRING (user_data);
+ GtkWindow *window = seahorse_action_get_window (action);
- window = seahorse_action_get_window (action);
- keys = seahorse_action_get_objects (action);
- for (l = keys; l; l = g_list_next (l)) {
- g_return_if_fail (SEAHORSE_IS_GKR_KEYRING (l->data));
- gnome_keyring_change_password (seahorse_gkr_keyring_get_name (l->data), NULL, NULL,
- on_change_password_done, g_object_ref (window), g_object_unref);
- }
+ gnome_keyring_change_password (seahorse_gkr_keyring_get_name (keyring),
+ NULL, NULL, on_change_password_done,
+ g_object_ref (window), g_object_unref);
}
-
static void
on_keyring_properties (GtkAction* action,
gpointer user_data)
{
- seahorse_gkr_keyring_properties_show (seahorse_action_get_object (action),
+ seahorse_gkr_keyring_properties_show (SEAHORSE_GKR_KEYRING (user_data),
seahorse_action_get_window (action));
}
@@ -307,16 +296,15 @@ on_delete_objects_complete (GObject *source, GAsyncResult *result, gpointer user
}
static void
-on_keyring_delete (GtkAction* action,
- gpointer user_data)
+on_keyrings_delete (GtkAction* action,
+ gpointer user_data)
{
+ GList *objects = user_data;
GCancellable *cancellable;
GtkWindow *parent;
gchar *prompt;
gboolean ret;
- GList *objects;
- objects = seahorse_action_get_objects (action);
if (!objects)
return;
@@ -334,37 +322,39 @@ on_keyring_delete (GtkAction* action,
g_list_length (objects)), TRUE);
g_object_unref (cancellable);
} else {
- seahorse_action_cancel (action);
+ g_cancellable_cancel (g_cancellable_get_current ());
}
g_free (prompt);
}
+static const GtkActionEntry KEYRINGS_ACTIONS[] = {
+ { "keyring-lock", NULL, N_("_Lock"), "",
+ 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[] = {
- { "gkr-keyring-lock", NULL, N_("_Lock"), "",
- N_("Lock the password storage keyring so a master password is required to unlock it."), G_CALLBACK (on_keyring_lock) },
- { "gkr-keyring-unlock", NULL, N_("_Unlock"), "",
- N_("Unlock the password storage keyring with a master password so it is available for use."), G_CALLBACK (on_keyring_unlock) },
- { "gkr-keyring-default", NULL, N_("_Set as default"), "",
+ { "keyring-default", NULL, N_("_Set as default"), "",
N_("Applications usually store new passwords in the default keyring."), G_CALLBACK (on_keyring_default) },
- { "gkr-keyring-password", NULL, N_("Change _Password"), "",
+ { "keyring-password", NULL, N_("Change _Password"), "",
N_("Change the unlock password of the password storage keyring"), G_CALLBACK (on_keyring_password) },
- { "gkr-keyring-properties", GTK_STOCK_PROPERTIES, NULL, NULL,
+ { "keyring-properties", GTK_STOCK_PROPERTIES, NULL, NULL,
N_("Properties of the keyring."), G_CALLBACK (on_keyring_properties) },
- { "gkr-keyring-delete", GTK_STOCK_DELETE, NULL, NULL,
- N_("Delete the keyring."), G_CALLBACK (on_keyring_delete) },
};
static const gchar* KEYRING_UI =
"<ui>"
" <popup name='SeahorseGkrKeyring'>"
-" <menuitem action='gkr-keyring-unlock'/>"
-" <menuitem action='gkr-keyring-lock'/>"
-" <menuitem action='gkr-keyring-default'/>"
-" <menuitem action='gkr-keyring-password'/>"
-" <menuitem action='gkr-keyring-delete'/>"
-" <menuitem action='gkr-keyring-properties'/>"
+" <menuitem action='keyring-unlock'/>"
+" <menuitem action='keyring-lock'/>"
+" <menuitem action='keyring-default'/>"
+" <menuitem action='keyring-password'/>"
+" <menuitem action='keyring-delete'/>"
+" <menuitem action='keyring-properties'/>"
" </popup>"\
"</ui>";
@@ -372,25 +362,29 @@ static void
seahorse_gkr_keyring_actions_init (SeahorseGkrKeyringActions *self)
{
GtkActionGroup *actions = GTK_ACTION_GROUP (self);
+
+ /* Add these actions, but none of them are visible until cloned */
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, KEYRING_ACTIONS, G_N_ELEMENTS (KEYRING_ACTIONS), self);
- self->action_lock = g_object_ref (gtk_action_group_get_action (actions, "gkr-keyring-lock"));
- self->action_unlock = g_object_ref (gtk_action_group_get_action (actions, "gkr-keyring-unlock"));
- self->action_default = g_object_ref (gtk_action_group_get_action (actions, "gkr-keyring-default"));
+ gtk_action_group_add_actions (actions, KEYRINGS_ACTIONS, G_N_ELEMENTS (KEYRINGS_ACTIONS), NULL);
+ gtk_action_group_add_actions (actions, KEYRING_ACTIONS, G_N_ELEMENTS (KEYRING_ACTIONS), NULL);
+ gtk_action_group_set_sensitive (actions, FALSE);
+
seahorse_actions_register_definition (SEAHORSE_ACTIONS (self), KEYRING_UI);
}
-static void
-seahorse_gkr_keyring_actions_update (SeahorseActions *actions,
- GList *objects)
+static GtkActionGroup *
+seahorse_gkr_keyring_actions_clone_for_objects (SeahorseActions *actions,
+ GList *objects)
{
- SeahorseGkrKeyringActions *self = SEAHORSE_GKR_KEYRING_ACTIONS (actions);
GnomeKeyringInfo *info;
gboolean locked = FALSE;
gboolean unlocked = FALSE;
gboolean can_default = FALSE;
+ GtkActionGroup *cloned;
GList *l;
+ g_return_val_if_fail (objects != NULL, NULL);
+
for (l = objects; l; l = g_list_next (l)) {
info = seahorse_gkr_keyring_get_info (l->data);
if (info != NULL) {
@@ -403,31 +397,33 @@ seahorse_gkr_keyring_actions_update (SeahorseActions *actions,
}
}
- gtk_action_set_sensitive (self->action_lock, unlocked);
- gtk_action_set_sensitive (self->action_unlock, locked);
- gtk_action_set_sensitive (self->action_default, can_default);
-}
-
-static void
-seahorse_gkr_keyring_actions_finalize (GObject *obj)
-{
- SeahorseGkrKeyringActions *self = SEAHORSE_GKR_KEYRING_ACTIONS (obj);
-
- g_clear_object (&self->action_lock);
- g_clear_object (&self->action_unlock);
- g_clear_object (&self->action_default);
+ cloned = gtk_action_group_new ("KeyringObject");
+ gtk_action_group_set_translation_domain (cloned, GETTEXT_PACKAGE);
+
+ gtk_action_group_add_actions_full (cloned, KEYRINGS_ACTIONS,
+ G_N_ELEMENTS (KEYRINGS_ACTIONS),
+ seahorse_object_list_copy (objects),
+ seahorse_object_list_free);
+ gtk_action_set_sensitive (gtk_action_group_get_action (cloned, "keyring-lock"), unlocked);
+ gtk_action_set_sensitive (gtk_action_group_get_action (cloned, "keyring-unlock"), locked);
+
+ /* Single object */
+ if (!objects->next) {
+ gtk_action_group_add_actions_full (cloned, KEYRING_ACTIONS,
+ G_N_ELEMENTS (KEYRING_ACTIONS),
+ g_object_ref (objects->data),
+ g_object_unref);
+ gtk_action_set_sensitive (gtk_action_group_get_action (cloned, "keyring-default"), can_default);
+ }
- G_OBJECT_CLASS (seahorse_gkr_keyring_actions_parent_class)->finalize (obj);
+ return cloned;
}
static void
seahorse_gkr_keyring_actions_class_init (SeahorseGkrKeyringActionsClass *klass)
{
SeahorseActionsClass *actions_class = SEAHORSE_ACTIONS_CLASS (klass);
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = seahorse_gkr_keyring_actions_finalize;
- actions_class->update = seahorse_gkr_keyring_actions_update;
+ actions_class->clone_for_objects = seahorse_gkr_keyring_actions_clone_for_objects;
}
GtkActionGroup *
@@ -470,7 +466,7 @@ static void
on_password_properties (GtkAction *action,
gpointer user_data)
{
- seahorse_gkr_item_properties_show (seahorse_action_get_object (action),
+ seahorse_gkr_item_properties_show (SEAHORSE_GKR_ITEM (user_data),
seahorse_action_get_window (action));
}
@@ -501,7 +497,7 @@ on_delete_passwords (GtkAction *action,
gboolean ret;
guint num;
- objects = seahorse_action_get_objects (action);
+ objects = user_data;
if (objects == NULL)
return;
@@ -524,7 +520,7 @@ on_delete_passwords (GtkAction *action,
seahorse_progress_show (cancellable, ngettext ("Deleting item", "Deleting items", num), TRUE);
g_object_unref (cancellable);
} else {
- seahorse_action_cancel (action);
+ g_cancellable_cancel (g_cancellable_get_current ());
}
@@ -534,6 +530,9 @@ on_delete_passwords (GtkAction *action,
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) },
};
@@ -541,15 +540,36 @@ static const GtkActionEntry ITEM_ACTIONS[] = {
static void
seahorse_gkr_item_actions_init (SeahorseGkrItemActions *self)
{
- GtkActionGroup *actions = GTK_ACTION_GROUP (self);
- gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, ITEM_ACTIONS, G_N_ELEMENTS (ITEM_ACTIONS), self);
+
+}
+
+static GtkActionGroup *
+seahorse_gkr_item_actions_clone_for_objects (SeahorseActions *actions,
+ GList *objects)
+{
+ GtkActionGroup *cloned;
+
+ 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,
+ G_N_ELEMENTS (ITEM_ACTIONS),
+ g_object_ref (objects->data),
+ g_object_unref);
+
+ return cloned;
}
static void
seahorse_gkr_item_actions_class_init (SeahorseGkrItemActionsClass *klass)
{
-
+ SeahorseActionsClass *actions_class = SEAHORSE_ACTIONS_CLASS (klass);
+ actions_class->clone_for_objects = seahorse_gkr_item_actions_clone_for_objects;
}
GtkActionGroup *
@@ -559,7 +579,7 @@ seahorse_gkr_item_actions_instance (void)
if (actions == NULL) {
actions = g_object_new (SEAHORSE_TYPE_GKR_ITEM_ACTIONS,
- "name", "gkr-item",
+ "name", "KeyringItem",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
diff --git a/libseahorse/seahorse-action.c b/libseahorse/seahorse-action.c
index 8f81653..ea42f24 100644
--- a/libseahorse/seahorse-action.c
+++ b/libseahorse/seahorse-action.c
@@ -23,139 +23,60 @@
#include "config.h"
#include "seahorse-action.h"
+#include "seahorse-actions.h"
#include <gck/gck.h>
-typedef struct {
- GtkWindow *window;
- GList *objects;
- GCancellable *cancellable;
-} SeahorseActionInfo;
-
static GQuark seahorse_action_info_quark (void) G_GNUC_CONST;
-static void
-seahorse_action_info_free (gpointer data)
-{
- SeahorseActionInfo *info = data;
- g_clear_object (&info->window);
- g_clear_object (&info->cancellable);
- gck_list_unref_free (info->objects);
- g_slice_free (SeahorseActionInfo, info);
-}
-
static GQuark
seahorse_action_info_quark (void)
{
static GQuark quark = 0;
if (quark == 0)
- quark = g_quark_from_static_string ("seahorse-action-info");
+ quark = g_quark_from_static_string ("seahorse-action-window");
return quark;
}
-static SeahorseActionInfo *
-seahorse_action_info_lookup (GtkAction *action)
-{
- SeahorseActionInfo *info;
-
- info = g_object_get_qdata (G_OBJECT (action), seahorse_action_info_quark ());
- if (info == NULL) {
- info = g_slice_new0 (SeahorseActionInfo);
- g_object_set_qdata_full (G_OBJECT (action), seahorse_action_info_quark (),
- info, seahorse_action_info_free);
- }
-
- return info;
-}
-
void
-seahorse_action_reset (GtkAction *action)
+seahorse_action_pre_activate_with_window (GtkAction *action,
+ GtkWindow *window)
{
g_return_if_fail (GTK_IS_ACTION (action));
- g_object_set_qdata (G_OBJECT (action), seahorse_action_info_quark (), NULL);
+ g_return_if_fail (window != NULL || GTK_IS_WINDOW (window));
+
+ g_object_set_qdata_full (G_OBJECT (action), seahorse_action_info_quark (),
+ window ? g_object_ref (window) : NULL, g_object_unref);
}
void
-seahorse_action_cancel (GtkAction *action)
+seahorse_action_activate_with_window (GtkAction *action,
+ GtkWindow *window)
{
- SeahorseActionInfo *info;
-
g_return_if_fail (GTK_IS_ACTION (action));
+ g_return_if_fail (window != NULL || GTK_IS_WINDOW (window));
- info = seahorse_action_info_lookup (action);
- if (info->cancellable)
- g_cancellable_cancel (info->cancellable);
-}
-
-GtkWindow *
-seahorse_action_get_window (GtkAction *action)
-{
- SeahorseActionInfo *info;
-
- g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
-
- info = seahorse_action_info_lookup (action);
- return info->window;
-}
-
-gpointer
-seahorse_action_get_object (GtkAction *action)
-{
- SeahorseActionInfo *info;
+ g_object_ref (action);
- g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+ seahorse_action_pre_activate_with_window (action, window);
+ gtk_action_activate (action);
+ seahorse_action_post_activate (action);
- info = seahorse_action_info_lookup (action);
- return info->objects ? info->objects->data : NULL;
-}
-
-GList *
-seahorse_action_get_objects (GtkAction *action)
-{
- SeahorseActionInfo *info;
-
- g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
-
- info = seahorse_action_info_lookup (action);
- return info->objects;
+ g_object_unref (action);
}
void
-seahorse_action_set_window (GtkAction *action,
- GtkWindow *window)
+seahorse_action_post_activate (GtkAction *action)
{
- SeahorseActionInfo *info;
-
g_return_if_fail (GTK_IS_ACTION (action));
- info = seahorse_action_info_lookup (action);
- g_clear_object (&info->window);
- info->window = window ? g_object_ref (window) : NULL;
+ g_object_set_qdata (G_OBJECT (action), seahorse_action_info_quark (), NULL);
}
-void
-seahorse_action_set_objects (GtkAction *action,
- GList *objects)
-{
- SeahorseActionInfo *info;
-
- g_return_if_fail (GTK_IS_ACTION (action));
-
- info = seahorse_action_info_lookup (action);
- gck_list_unref_free (info->objects);
- info->objects = gck_list_ref_copy (objects);
-}
-void
-seahorse_action_set_cancellable (GtkAction *action,
- GCancellable *cancellable)
+GtkWindow *
+seahorse_action_get_window (GtkAction *action)
{
- SeahorseActionInfo *info;
-
- g_return_if_fail (cancellable == NULL ||
- G_IS_CANCELLABLE (cancellable));
-
- info = seahorse_action_info_lookup (action);
- g_clear_object (&info->cancellable);
- info->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
+ return g_object_get_qdata (G_OBJECT (action), seahorse_action_info_quark ());
}
diff --git a/libseahorse/seahorse-action.h b/libseahorse/seahorse-action.h
index f9df96e..7eceafb 100644
--- a/libseahorse/seahorse-action.h
+++ b/libseahorse/seahorse-action.h
@@ -25,23 +25,14 @@
#include <gtk/gtk.h>
-void seahorse_action_reset (GtkAction *action);
+void seahorse_action_pre_activate_with_window (GtkAction *action,
+ GtkWindow *window);
-void seahorse_action_set_cancellable (GtkAction *action,
- GCancellable *cancellable);
+void seahorse_action_activate_with_window (GtkAction *action,
+ GtkWindow *window);
-void seahorse_action_cancel (GtkAction *action);
+void seahorse_action_post_activate (GtkAction *action);
GtkWindow * seahorse_action_get_window (GtkAction *action);
-gpointer seahorse_action_get_object (GtkAction *action);
-
-GList * seahorse_action_get_objects (GtkAction *action);
-
-void seahorse_action_set_window (GtkAction *action,
- GtkWindow *window);
-
-void seahorse_action_set_objects (GtkAction *action,
- GList *objects);
-
#endif
diff --git a/libseahorse/seahorse-actions.c b/libseahorse/seahorse-actions.c
index 50abfd1..8af7f89 100644
--- a/libseahorse/seahorse-actions.c
+++ b/libseahorse/seahorse-actions.c
@@ -30,11 +30,11 @@ struct _SeahorseActionsPrivate {
G_DEFINE_TYPE (SeahorseActions, seahorse_actions, GTK_TYPE_ACTION_GROUP);
-static void
-seahorse_actions_real_update (SeahorseActions *self,
- GList *selected)
+static GtkActionGroup *
+seahorse_actions_real_clone_for_objects (SeahorseActions *self,
+ GList *selected)
{
-
+ return gtk_action_group_new ("internal");
}
static void
@@ -57,8 +57,7 @@ static void
seahorse_actions_class_init (SeahorseActionsClass *klass)
{
g_type_class_add_private (klass, sizeof (SeahorseActionsPrivate));
-
- klass->update = seahorse_actions_real_update;
+ klass->clone_for_objects = seahorse_actions_real_clone_for_objects;
}
const gchar *
@@ -69,15 +68,6 @@ seahorse_actions_get_definition (SeahorseActions* self)
}
void
-seahorse_actions_update (SeahorseActions *self,
- GList *selected)
-{
- g_return_if_fail (SEAHORSE_IS_ACTIONS (self));
- g_return_if_fail (SEAHORSE_ACTIONS_GET_CLASS (self)->update);
- SEAHORSE_ACTIONS_GET_CLASS (self)->update (self, selected);
-}
-
-void
seahorse_actions_register_definition (SeahorseActions *self,
const gchar *definition)
{
@@ -85,3 +75,18 @@ seahorse_actions_register_definition (SeahorseActions *self,
g_return_if_fail (self->pv->definition == NULL);
self->pv->definition = definition;
}
+
+GtkActionGroup *
+seahorse_actions_clone_for_objects (GtkActionGroup *actions,
+ GList *objects)
+{
+ SeahorseActionsClass *klass;
+
+ g_return_val_if_fail (GTK_IS_ACTION_GROUP (actions), NULL);
+
+ if (!SEAHORSE_IS_ACTIONS (actions))
+ return g_object_ref (actions);
+ klass = SEAHORSE_ACTIONS_GET_CLASS (actions);
+ g_assert (klass->clone_for_objects != NULL);
+ return (klass->clone_for_objects) (SEAHORSE_ACTIONS (actions), objects);
+}
diff --git a/libseahorse/seahorse-actions.h b/libseahorse/seahorse-actions.h
index c67c101..9fdcce1 100644
--- a/libseahorse/seahorse-actions.h
+++ b/libseahorse/seahorse-actions.h
@@ -47,8 +47,8 @@ struct _SeahorseActions {
struct _SeahorseActionsClass {
GtkActionGroupClass parent_class;
- void (*update) (SeahorseActions *self,
- GList *selected);
+ GtkActionGroup * (*clone_for_objects) (SeahorseActions *actions,
+ GList *objects);
};
GType seahorse_actions_get_type (void);
@@ -60,7 +60,7 @@ const gchar * seahorse_actions_get_definition (SeahorseActions
void seahorse_actions_register_definition (SeahorseActions *self,
const gchar *definition);
-void seahorse_actions_update (SeahorseActions *actions,
- GList *selected);
+GtkActionGroup * seahorse_actions_clone_for_objects (GtkActionGroup *actions,
+ GList *objects);
#endif
diff --git a/libseahorse/seahorse-object-list.c b/libseahorse/seahorse-object-list.c
index 2435317..5d46088 100644
--- a/libseahorse/seahorse-object-list.c
+++ b/libseahorse/seahorse-object-list.c
@@ -64,12 +64,13 @@ seahorse_object_list_copy (GList *original)
}
void
-seahorse_object_list_free (GList *list)
+seahorse_object_list_free (gpointer list)
{
GList *l;
-
+
for (l = list; l; l = g_list_next (l))
g_object_unref (l->data);
+ g_list_free (list);
}
GType
diff --git a/libseahorse/seahorse-object-list.h b/libseahorse/seahorse-object-list.h
index b77068c..8a64916 100644
--- a/libseahorse/seahorse-object-list.h
+++ b/libseahorse/seahorse-object-list.h
@@ -37,6 +37,6 @@ GList* seahorse_object_list_remove (GList *original, gpointer object);
GList* seahorse_object_list_copy (GList *original);
-void seahorse_object_list_free (GList *list);
+void seahorse_object_list_free (gpointer list);
#endif /* SEAHORSEOBJECTLIST_H_ */
diff --git a/libseahorse/seahorse-viewer.c b/libseahorse/seahorse-viewer.c
index a8b8575..5be8b5b 100644
--- a/libseahorse/seahorse-viewer.c
+++ b/libseahorse/seahorse-viewer.c
@@ -50,8 +50,7 @@ struct _SeahorseViewerPrivate {
GHashTable *actions;
GtkAction *edit_delete;
GtkAction *properties_object;
- GtkAction *properties_place;
- GtkAction *properties_backend;
+ GList *selection_actions;
};
G_DEFINE_TYPE (SeahorseViewer, seahorse_viewer, SEAHORSE_TYPE_WIDGET);
@@ -128,73 +127,74 @@ on_help_show (GtkAction *action,
seahorse_widget_show_help (SEAHORSE_WIDGET (self));
}
-static void
-on_object_delete (GtkAction *action,
- gpointer user_data)
+static GList *
+lookup_actions_for_objects (SeahorseViewer *self,
+ GList *objects)
{
- SeahorseViewer *self = SEAHORSE_VIEWER (user_data);
- GCancellable *cancellable;
GtkActionGroup *actions;
- GtkAction *delete_action;
- GList *objects;
- GHashTable *perform;
GHashTableIter iter;
+ GList *results;
+ GHashTable *table;
GQueue *queue;
GList *l;
- cancellable = g_cancellable_new ();
- perform = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)g_queue_free);
+ table = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ g_object_unref,
+ (GDestroyNotify)g_queue_free);
- objects = seahorse_viewer_get_selected_objects (self);
for (l = objects; l != NULL; l = g_list_next (l)) {
g_object_get (l->data, "actions", &actions, NULL);
- delete_action = gtk_action_group_get_action (actions, "delete");
- g_object_unref (actions);
-
- if (delete_action == NULL)
+ if (actions == NULL)
continue;
-
- queue = g_hash_table_lookup (perform, delete_action);
+ if (g_hash_table_lookup (self->pv->actions, actions) == NULL)
+ seahorse_viewer_include_actions (self, actions);
+ queue = g_hash_table_lookup (table, actions);
if (queue == NULL) {
queue = g_queue_new ();
- g_hash_table_insert (perform, delete_action, queue);
+ g_hash_table_insert (table, g_object_ref (actions), queue);
}
g_queue_push_tail (queue, l->data);
+ g_object_unref (actions);
}
- g_list_free (objects);
-
- /* Now go through and execute the deletes */
- g_hash_table_iter_init (&iter, perform);
- while (!g_cancellable_is_cancelled (cancellable) &&
- g_hash_table_iter_next (&iter, (gpointer *)&delete_action, (gpointer *)&queue)) {
- seahorse_action_set_window (delete_action, seahorse_viewer_get_window (self));
- seahorse_action_set_objects (delete_action, queue->head);
- seahorse_action_set_cancellable (delete_action, cancellable);
- gtk_action_activate (delete_action);
-
- seahorse_action_reset (delete_action);
+ results = NULL;
+ g_hash_table_iter_init (&iter, table);
+ while (g_hash_table_iter_next (&iter, (gpointer *)&actions, (gpointer *)&queue)) {
+ results = g_list_prepend (results,
+ seahorse_actions_clone_for_objects (actions, queue->head));
}
- g_object_unref (cancellable);
- g_hash_table_destroy (perform);
+ g_hash_table_destroy (table);
+ return results;
}
-static GtkAction *
-properties_action_for_object (GObject *object)
+static void
+on_object_delete (GtkAction *action,
+ gpointer user_data)
{
- GtkActionGroup *actions = NULL;
- GtkAction *action;
+ SeahorseViewer *self = SEAHORSE_VIEWER (user_data);
+ GCancellable *cancellable;
+ GtkAction *delete_action;
+ GtkWindow *window;
+ GList *l;
- g_object_get (object, "actions", &actions, NULL);
- if (actions == NULL)
- return NULL;
+ cancellable = g_cancellable_new ();
- action = gtk_action_group_get_action (actions, "properties");
- g_object_unref (actions);
+ g_cancellable_push_current (cancellable);
+ window = seahorse_viewer_get_window (self);
+
+ /* 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);
+ }
- return action;
+ g_cancellable_pop_current (cancellable);
+ g_object_unref (cancellable);
}
static void
@@ -223,19 +223,6 @@ on_properties_place (GtkAction *action,
g_list_free (objects);
}
-static void
-on_properties_backend (GtkAction *action,
- gpointer user_data)
-{
- SeahorseViewer *self = SEAHORSE_VIEWER (user_data);
- GList *objects;
-
- objects = seahorse_viewer_get_selected_backends (self);
- if (objects != NULL)
- seahorse_viewer_show_properties (self, objects->data);
- g_list_free (objects);
-}
-
static const GtkActionEntry UI_ENTRIES[] = {
/* Top menu items */
@@ -247,8 +234,6 @@ static const GtkActionEntry UI_ENTRIES[] = {
N_("Show the properties of this item"), G_CALLBACK (on_properties_object) },
{ "properties-place", GTK_STOCK_PROPERTIES, NULL, NULL,
N_("Show the properties of this place"), G_CALLBACK (on_properties_place) },
- { "properties-backend", GTK_STOCK_PROPERTIES, NULL, NULL,
- N_("Show the properties of this backend"), G_CALLBACK (on_properties_backend) },
{ "app-preferences", GTK_STOCK_PREFERENCES, N_("Prefere_nces"), NULL,
N_("Change preferences for this program"), G_CALLBACK (on_app_preferences) },
{ "view-menu", NULL, N_("_View") },
@@ -396,43 +381,8 @@ on_ui_manager_pre_activate (GtkUIManager *ui_manager,
gpointer user_data)
{
SeahorseViewer *self = SEAHORSE_VIEWER (user_data);
- GtkActionGroup *actions;
- GList *selected = NULL;
- GList *objects;
- const gchar *name;
- GList *l;
-
- name = gtk_action_get_name (action);
- g_return_if_fail (name != NULL);
-
- /* These guys do their own object selection */
- if (seahorse_action_get_object (action) ||
- action == self->pv->properties_object ||
- action == self->pv->properties_place ||
- action == self->pv->properties_backend ||
- action == self->pv->edit_delete)
- return;
-
- objects = seahorse_viewer_get_selected_objects (self);
- objects = g_list_concat (objects, seahorse_viewer_get_selected_places (self));
- objects = g_list_concat (objects, seahorse_viewer_get_selected_backends (self));
-
- for (l = objects; l != NULL; l = g_list_next (l)) {
- actions = NULL;
- g_object_get (l->data, "actions", &actions, NULL);
- if (actions != NULL) {
- if (gtk_action_group_get_action (actions, name) == action)
- selected = g_list_prepend (selected, l->data);
- g_object_unref (actions);
- }
- }
-
- selected = g_list_reverse (selected);
- seahorse_action_set_objects (action, selected);
- seahorse_action_set_window (action, seahorse_viewer_get_window (self));
-
- g_list_free (selected);
- g_list_free (objects);
+ seahorse_action_pre_activate_with_window (action,
+ seahorse_viewer_get_window (self));
}
static void
@@ -440,108 +390,49 @@ on_ui_manager_post_activate (GtkUIManager *ui_manager,
GtkAction *action,
gpointer user_data)
{
- seahorse_action_reset (action);
-}
-
-static void
-viewer_find_actions_for_selection (SeahorseViewer *self,
- GHashTable *found,
- GList *objects)
-{
- GtkActionGroup *actions;
- GPtrArray *selected;
- GList *l;
-
- for (l = objects; l != NULL; l = g_list_next (l)) {
- actions = NULL;
- g_object_get (l->data, "actions", &actions, NULL);
- if (actions != NULL) {
- if (g_hash_table_lookup (self->pv->actions, actions) == NULL) {
- g_hash_table_insert (self->pv->actions, g_object_ref (actions), actions);
- seahorse_viewer_include_actions (self, actions);
- }
- selected = g_hash_table_lookup (found, actions);
- if (selected == NULL) {
- selected = g_ptr_array_new ();
- g_hash_table_insert (found, actions, selected);
- }
- g_ptr_array_add (selected, l->data);
- g_object_unref (actions);
- }
- }
+ seahorse_action_post_activate (action);
}
-
static void
seahorse_viewer_real_selection_changed (SeahorseViewer *self)
{
- GHashTableIter iter;
- GHashTable *seen;
+ GList *groups;
GList *objects;
- GPtrArray *selected;
- GtkActionGroup *actions;
- GtkAction *action;
- gboolean deletes;
- guint i;
-
- seen = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify)g_ptr_array_unref);
+ GList *previous;
+ gboolean can_properties;
+ gboolean can_delete;
+ GList *l;
objects = seahorse_viewer_get_selected_objects (self);
- viewer_find_actions_for_selection (self, seen, objects);
- if (objects != NULL)
- gtk_action_set_sensitive (self->pv->properties_object,
- properties_action_for_object (objects->data) != NULL);
+ groups = lookup_actions_for_objects (self, objects);
g_list_free (objects);
- /*
- * At this point we only have the actions for real objects, so hook
- * in the delete logic here.
- */
-
- deletes = FALSE;
+ can_properties = FALSE;
+ can_delete = FALSE;
- g_hash_table_iter_init (&iter, seen);
- while (g_hash_table_iter_next (&iter, (gpointer *)&actions, NULL)) {
- action = gtk_action_group_get_action (actions, "delete");
- if (action != NULL)
- deletes = TRUE;
+ /* Add all those actions */
+ 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->edit_delete, deletes);
+ gtk_action_set_sensitive (self->pv->properties_object, can_properties);
+ gtk_action_set_sensitive (self->pv->edit_delete, can_delete);
- /* Now proceed to bring in the other commands */
objects = seahorse_viewer_get_selected_places (self);
- viewer_find_actions_for_selection (self, seen, objects);
- if (objects != NULL)
- gtk_action_set_sensitive (self->pv->properties_place,
- properties_action_for_object (objects->data) != NULL);
+ groups = g_list_concat (groups, lookup_actions_for_objects (self, objects));
g_list_free (objects);
- objects = seahorse_viewer_get_selected_backends (self);
- viewer_find_actions_for_selection (self, seen, objects);
- if (objects != NULL)
- gtk_action_set_sensitive (self->pv->properties_backend,
- properties_action_for_object (objects->data) != NULL);
- g_list_free (objects);
-
- g_hash_table_iter_init (&iter, self->pv->actions);
- while (g_hash_table_iter_next (&iter, (gpointer *)&actions, NULL))
- gtk_action_group_set_visible (actions, g_hash_table_lookup (seen, actions) != NULL);
-
- g_hash_table_iter_init (&iter, seen);
- while (g_hash_table_iter_next (&iter, (gpointer *)&actions, (gpointer *)&selected)) {
- if (SEAHORSE_IS_ACTIONS (actions)) {
- objects = NULL;
- for (i = 0; i < selected->len; i++)
- objects = g_list_prepend (objects, selected->pdata[i]);
- objects = g_list_reverse (objects);
- seahorse_actions_update (SEAHORSE_ACTIONS (actions), objects);
- g_list_free (objects);
- }
- }
+ previous = self->pv->selection_actions;
+ self->pv->selection_actions = groups;
- g_hash_table_destroy (seen);
+ for (l = self->pv->selection_actions; l != NULL; l = g_list_next (l))
+ gtk_ui_manager_insert_action_group (self->pv->ui_manager, l->data, 5);
+ for (l = previous; l != NULL; l = g_list_next (l))
+ gtk_ui_manager_remove_action_group (self->pv->ui_manager, l->data);
+ g_list_free_full (previous, g_object_unref);
}
static void
@@ -603,10 +494,6 @@ seahorse_viewer_constructed (GObject *obj)
g_object_ref (self->pv->edit_delete);
self->pv->properties_object = gtk_action_group_get_action (actions, "properties-object");
g_object_ref (self->pv->properties_object);
- self->pv->properties_place = gtk_action_group_get_action (actions, "properties-place");
- g_object_ref (self->pv->properties_place);
- self->pv->properties_backend = gtk_action_group_get_action (actions, "properties-backend");
- g_object_ref (self->pv->properties_backend);
gtk_ui_manager_insert_action_group (self->pv->ui_manager, actions, 0);
g_object_unref (actions);
}
@@ -632,11 +519,14 @@ static void
seahorse_viewer_dispose (GObject *obj)
{
SeahorseViewer *self = SEAHORSE_VIEWER (obj);
+ GList *l;
g_clear_object (&self->pv->edit_delete);
g_clear_object (&self->pv->properties_object);
- g_clear_object (&self->pv->properties_place);
- g_clear_object (&self->pv->properties_backend);
+
+ for (l = self->pv->selection_actions; l != NULL; l = g_list_next (l))
+ gtk_ui_manager_remove_action_group (self->pv->ui_manager, l->data);
+ g_list_free_full (self->pv->selection_actions, g_object_unref);
g_signal_handlers_disconnect_by_func (self->pv->ui_manager, on_ui_manager_add_widget, self);
g_signal_handlers_disconnect_by_func (self->pv->ui_manager, on_ui_manager_pre_activate, self);
@@ -716,7 +606,7 @@ seahorse_viewer_include_actions (SeahorseViewer* self,
g_return_if_fail (SEAHORSE_IS_VIEWER (self));
g_return_if_fail (GTK_IS_ACTION_GROUP (actions));
- gtk_ui_manager_insert_action_group (self->pv->ui_manager, actions, 0);
+ gtk_ui_manager_insert_action_group (self->pv->ui_manager, actions, 10);
if (SEAHORSE_IS_ACTIONS (actions)) {
definition = seahorse_actions_get_definition (SEAHORSE_ACTIONS (actions));
@@ -729,6 +619,8 @@ seahorse_viewer_include_actions (SeahorseViewer* self,
}
}
}
+
+ g_hash_table_insert (self->pv->actions, g_object_ref (actions), actions);
}
void
@@ -762,21 +654,24 @@ void
seahorse_viewer_show_properties (SeahorseViewer* self,
GObject* obj)
{
+ GtkActionGroup *actions, *cloned;
GtkAction *action;
GList *objects;
- action = properties_action_for_object (obj);
- if (action == NULL)
+ g_object_get (obj, "actions", &actions, NULL);
+ if (actions == NULL)
return;
objects = g_list_append (NULL, obj);
- seahorse_action_set_objects (action, objects);
- seahorse_action_set_window (action, seahorse_viewer_get_window (self));
+ cloned = seahorse_actions_clone_for_objects (actions, objects);
+ g_object_unref (actions);
g_list_free (objects);
- gtk_action_activate (action);
+ action = gtk_action_group_get_action (cloned, "properties");
+ if (action != NULL)
+ seahorse_action_activate_with_window (action, seahorse_viewer_get_window (self));
- seahorse_action_reset (action);
+ g_object_unref (cloned);
}
GtkWindow *
@@ -803,9 +698,9 @@ seahorse_viewer_get_selected_places (SeahorseViewer* self)
}
GList *
-seahorse_viewer_get_selected_backends (SeahorseViewer* self)
+seahorse_viewer_get_backends (SeahorseViewer* self)
{
g_return_val_if_fail (SEAHORSE_IS_VIEWER (self), NULL);
- g_return_val_if_fail (SEAHORSE_VIEWER_GET_CLASS (self)->get_selected_backends, NULL);
- return SEAHORSE_VIEWER_GET_CLASS (self)->get_selected_backends (self);
+ g_return_val_if_fail (SEAHORSE_VIEWER_GET_CLASS (self)->get_backends, NULL);
+ return SEAHORSE_VIEWER_GET_CLASS (self)->get_backends (self);
}
diff --git a/libseahorse/seahorse-viewer.h b/libseahorse/seahorse-viewer.h
index 4a6508b..526bb1d 100644
--- a/libseahorse/seahorse-viewer.h
+++ b/libseahorse/seahorse-viewer.h
@@ -47,7 +47,7 @@ struct _SeahorseViewer {
struct _SeahorseViewerClass {
SeahorseWidgetClass parent;
- GList * (*get_selected_backends) (SeahorseViewer *self);
+ GList * (*get_backends) (SeahorseViewer *self);
GList * (*get_selected_places) (SeahorseViewer *self);
@@ -67,7 +67,7 @@ GList * seahorse_viewer_get_selected_objects (SeahorseVie
GList * seahorse_viewer_get_selected_places (SeahorseViewer* self);
-GList * seahorse_viewer_get_selected_backends (SeahorseViewer* self);
+GList * seahorse_viewer_get_backends (SeahorseViewer* self);
void seahorse_viewer_show_context_menu (SeahorseViewer* self,
const gchar *which,
@@ -77,26 +77,6 @@ void seahorse_viewer_show_context_menu (SeahorseVie
void seahorse_viewer_show_properties (SeahorseViewer* self,
GObject* obj);
-#if 0
-void seahorse_viewer_set_status (SeahorseViewer* self,
- const char* text);
-
-void seahorse_viewer_set_numbered_status (SeahorseViewer* self,
- const char* text,
- gint num);
-#endif
-
GtkWindow * seahorse_viewer_get_window (SeahorseViewer* self);
-#if 0
-void seahorse_viewer_register_ui (SeahorseViewer *self,
- SeahorsePredicate *pred,
- const gchar *uidef,
- GtkActionGroup *actions);
-
-void seahorse_viewer_register_commands (SeahorseViewer *self,
- SeahorsePredicate *pred,
- SeahorseCommands *commands);
-#endif
-
#endif /* __SEAHORSE_VIEWER_H__ */
diff --git a/pgp/seahorse-keyserver-results.c b/pgp/seahorse-keyserver-results.c
index 7207749..6f74c00 100644
--- a/pgp/seahorse-keyserver-results.c
+++ b/pgp/seahorse-keyserver-results.c
@@ -264,12 +264,6 @@ seahorse_keyserver_results_get_selected_objects (SeahorseViewer* viewer)
}
static GList *
-seahorse_keyserver_results_get_selected_backends (SeahorseViewer* viewer)
-{
- return NULL;
-}
-
-static GList *
seahorse_keyserver_results_get_selected_places (SeahorseViewer* viewer)
{
return NULL;
@@ -347,6 +341,12 @@ seahorse_keyserver_results_constructor (GType type, guint n_props, GObjectConstr
self->pv->settings);
on_view_selection_changed (selection, self);
+ /* Include actions from the backend */
+ actions = NULL;
+ g_object_get (seahorse_pgp_backend_get (), "actions", &actions, NULL);
+ seahorse_viewer_include_actions (SEAHORSE_VIEWER (self), actions);
+ g_object_unref (actions);
+
return G_OBJECT (self);
}
@@ -473,7 +473,6 @@ seahorse_keyserver_results_class_init (SeahorseKeyserverResultsClass *klass)
SEAHORSE_VIEWER_CLASS (klass)->get_selected_objects = seahorse_keyserver_results_get_selected_objects;
SEAHORSE_VIEWER_CLASS (klass)->get_selected_places = seahorse_keyserver_results_get_selected_places;
- SEAHORSE_VIEWER_CLASS (klass)->get_selected_backends = seahorse_keyserver_results_get_selected_backends;
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEARCH,
g_param_spec_string ("search", "search", "search", NULL,
diff --git a/pgp/seahorse-pgp-actions.c b/pgp/seahorse-pgp-actions.c
index 9a2b7db..f90786b 100644
--- a/pgp/seahorse-pgp-actions.c
+++ b/pgp/seahorse-pgp-actions.c
@@ -37,6 +37,7 @@
#include "seahorse-action.h"
#include "seahorse-actions.h"
#include "seahorse-object.h"
+#include "seahorse-object-list.h"
#include "seahorse-registry.h"
#include "seahorse-util.h"
@@ -82,9 +83,8 @@ on_remote_sync (GtkAction* action,
gpointer user_data)
{
SeahorseGpgmeKeyring *keyring;
- GList* objects;
+ GList* objects = user_data;
- objects = seahorse_action_get_objects (action);
if (objects == NULL) {
keyring = seahorse_pgp_backend_get_default_keyring (NULL);
objects = gcr_collection_get_objects (GCR_COLLECTION (keyring));
@@ -96,9 +96,12 @@ on_remote_sync (GtkAction* action,
g_list_free (objects);
}
-static const GtkActionEntry BACKEND_ACTIONS[] = {
+static const GtkActionEntry FIND_ACTIONS[] = {
{ "remote-find", GTK_STOCK_FIND, N_("_Find Remote Keys..."), "",
N_("Search for keys on a key server"), G_CALLBACK (on_remote_find) },
+};
+
+static const GtkActionEntry SYNC_ACTIONS[] = {
{ "remote-sync", GTK_STOCK_REFRESH, N_("_Sync and Publish Keys..."), "",
N_("Publish and/or synchronize your keys with those online."), G_CALLBACK (on_remote_sync) }
};
@@ -108,8 +111,10 @@ seahorse_pgp_backend_actions_init (SeahorsePgpBackendActions *self)
{
GtkActionGroup *actions = GTK_ACTION_GROUP (self);
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, BACKEND_ACTIONS,
- G_N_ELEMENTS (BACKEND_ACTIONS), self);
+ gtk_action_group_add_actions (actions, FIND_ACTIONS,
+ G_N_ELEMENTS (FIND_ACTIONS), NULL);
+ gtk_action_group_add_actions (actions, SYNC_ACTIONS,
+ G_N_ELEMENTS (SYNC_ACTIONS), NULL);
seahorse_actions_register_definition (SEAHORSE_ACTIONS (self), BACKEND_DEFINITION);
}
@@ -174,19 +179,20 @@ on_key_sign (GtkAction* action,
gpointer user_data)
{
GtkWindow *window;
- GObject *key;
+ GList *objects = user_data;
+
+ g_return_if_fail (objects->data);
- key = seahorse_action_get_object (action);
window = seahorse_action_get_window (action);
- seahorse_gpgme_sign_prompt (SEAHORSE_GPGME_KEY (key), window);
+ seahorse_gpgme_sign_prompt (SEAHORSE_GPGME_KEY (objects->data), window);
}
static void
on_show_properties (GtkAction *action,
gpointer user_data)
{
- seahorse_pgp_key_properties_show (seahorse_action_get_object (action),
+ seahorse_pgp_key_properties_show (SEAHORSE_PGP_KEY (user_data),
seahorse_action_get_window (action));
}
@@ -206,7 +212,7 @@ on_delete_objects (GtkAction *action,
GError *error = NULL;
GList *objects;
- objects = seahorse_action_get_objects (action);
+ objects = user_data;
num = g_list_length (objects);
if (num == 0)
return;
@@ -260,7 +266,7 @@ on_delete_objects (GtkAction *action,
parent = GTK_WIDGET (seahorse_action_get_window (action));
if (!seahorse_util_prompt_delete (message, parent)) {
g_free (message);
- seahorse_action_cancel (action);
+ g_cancellable_cancel (g_cancellable_get_current ());
return;
}
@@ -292,6 +298,9 @@ static const GtkActionEntry KEY_ACTIONS[] = {
N_("Sign public key"), G_CALLBACK (on_key_sign) },
{ "properties", GTK_STOCK_PROPERTIES, NULL, NULL,
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) },
};
@@ -302,15 +311,48 @@ seahorse_gpgme_key_actions_init (SeahorseGpgmeKeyActions *self)
GtkActionGroup *actions = GTK_ACTION_GROUP (self);
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
gtk_action_group_add_actions (actions, KEY_ACTIONS,
- G_N_ELEMENTS (KEY_ACTIONS), self);
+ 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);
}
+static GtkActionGroup *
+seahorse_gpgme_key_actions_clone_for_objects (SeahorseActions *actions,
+ GList *objects)
+{
+ GtkActionGroup *cloned;
+
+ 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),
+ seahorse_object_list_free);
+
+ /* Single key */
+ if (!objects->next) {
+ gtk_action_group_add_actions_full (cloned, KEY_ACTIONS,
+ G_N_ELEMENTS (KEY_ACTIONS),
+ g_object_ref (objects->data),
+ g_object_unref);
+ }
+
+ return cloned;
+}
+
static void
seahorse_gpgme_key_actions_class_init (SeahorseGpgmeKeyActionsClass *klass)
{
-
+ SeahorseActionsClass *actions_class = SEAHORSE_ACTIONS_CLASS (klass);
+ actions_class->clone_for_objects = seahorse_gpgme_key_actions_clone_for_objects;
}
GtkActionGroup *
diff --git a/pkcs11/seahorse-pkcs11-actions.c b/pkcs11/seahorse-pkcs11-actions.c
index 94599d3..160080f 100644
--- a/pkcs11/seahorse-pkcs11-actions.c
+++ b/pkcs11/seahorse-pkcs11-actions.c
@@ -31,6 +31,7 @@
#include "seahorse-action.h"
#include "seahorse-actions.h"
+#include "seahorse-object-list.h"
#include "seahorse-progress.h"
#include "seahorse-registry.h"
#include "seahorse-util.h"
@@ -69,10 +70,10 @@ on_show_properties (GtkAction *action,
gpointer previous;
GObject *object;
- object = seahorse_action_get_object (action);
+ object = G_OBJECT (user_data);
/* Try to show an already present window */
- previous = g_object_get_qdata (G_OBJECT (object), QUARK_WINDOW);
+ previous = g_object_get_qdata (object, QUARK_WINDOW);
if (GTK_IS_WINDOW (previous)) {
window = GTK_WINDOW (previous);
if (gtk_widget_get_visible (GTK_WIDGET (window))) {
@@ -111,17 +112,18 @@ on_delete_objects (GtkAction *action,
{
GCancellable *cancellable;
gchar *prompt;
- const gchar *display;
+ gchar *display;
GtkWidget *parent;
gboolean ret;
guint num;
GList *objects;
- objects = seahorse_action_get_objects (action);
+ objects = user_data;
num = g_list_length (objects);
if (num == 1) {
- display = seahorse_object_get_label (SEAHORSE_OBJECT (objects->data));
+ 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?",
@@ -140,13 +142,16 @@ on_delete_objects (GtkAction *action,
seahorse_progress_show (cancellable, _("Deleting"), TRUE);
g_object_unref (cancellable);
} else {
- seahorse_action_cancel (action);
+ 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) },
};
@@ -154,15 +159,40 @@ static const GtkActionEntry CERTIFICATE_ACTIONS[] = {
static void
seahorse_pkcs11_actions_init (SeahorsePkcs11Actions *self)
{
- GtkActionGroup *actions = GTK_ACTION_GROUP (self);
- gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, CERTIFICATE_ACTIONS, G_N_ELEMENTS (CERTIFICATE_ACTIONS), self);
+
+}
+
+static GtkActionGroup *
+seahorse_pkcs11_actions_clone_for_objects (SeahorseActions *actions,
+ GList *objects)
+{
+ GtkActionGroup *cloned;
+
+ g_return_val_if_fail (objects != NULL, NULL);
+
+ cloned = gtk_action_group_new ("Certificate");
+ 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)
+ gtk_action_group_add_actions_full (cloned, CERTIFICATE_ACTIONS,
+ G_N_ELEMENTS (CERTIFICATE_ACTIONS),
+ g_object_ref (objects->data),
+ g_object_unref);
+
+ return cloned;
}
static void
seahorse_pkcs11_actions_class_init (SeahorsePkcs11ActionsClass *klass)
{
+ SeahorseActionsClass *actions_class = SEAHORSE_ACTIONS_CLASS (klass);
QUARK_WINDOW = g_quark_from_static_string ("seahorse-pkcs11-actions-window");
+ actions_class->clone_for_objects = seahorse_pkcs11_actions_clone_for_objects;
}
GtkActionGroup *
@@ -172,7 +202,7 @@ seahorse_pkcs11_actions_instance (void)
if (actions == NULL) {
actions = g_object_new (SEAHORSE_TYPE_PKCS11_ACTIONS,
- "name", "pkcs11-certificate",
+ "name", "Certificate",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
diff --git a/src/seahorse-generate-select.c b/src/seahorse-generate-select.c
index 7fdd201..28f4824 100644
--- a/src/seahorse-generate-select.c
+++ b/src/seahorse-generate-select.c
@@ -69,7 +69,6 @@ get_selected_action (SeahorseGenerateSelect *self)
GtkTreeIter iter;
GtkTreeModel *model;
GtkAction *action;
- GtkWindow *parent;
selection = gtk_tree_view_get_selection (self->view);
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
@@ -79,9 +78,6 @@ get_selected_action (SeahorseGenerateSelect *self)
COLUMN_ACTION, &action, -1);
g_assert (action != NULL);
- parent = gtk_window_get_transient_for (GTK_WINDOW (self));
- seahorse_action_set_window (action, parent);
-
return action;
}
@@ -93,12 +89,20 @@ on_row_activated (GtkTreeView *view,
{
SeahorseGenerateSelect *self = SEAHORSE_GENERATE_SELECT (user_data);
GtkAction *action;
+ GtkWindow *parent;
action = get_selected_action (self);
if (action != NULL) {
+ parent = gtk_window_get_transient_for (GTK_WINDOW (self));
+ if (parent != NULL)
+ g_object_ref (parent);
+
g_object_ref (action);
gtk_widget_destroy (GTK_WIDGET (self));
- gtk_action_activate (action);
+
+ seahorse_action_activate_with_window (action, parent);
+
+ g_clear_object (&parent);
g_object_unref (action);
}
}
@@ -110,17 +114,23 @@ on_response (GtkDialog *dialog,
{
SeahorseGenerateSelect *self = SEAHORSE_GENERATE_SELECT (user_data);
GtkAction *action = NULL;
+ GtkWindow *parent = NULL;
if (response == GTK_RESPONSE_OK)
action = get_selected_action (self);
- if (action != NULL)
+ if (action != NULL) {
g_object_ref (action);
+ parent = gtk_window_get_transient_for (GTK_WINDOW (self));
+ if (parent != NULL)
+ g_object_ref (parent);
+ }
gtk_widget_destroy (GTK_WIDGET (self));
if (action != NULL) {
- gtk_action_activate (action);
+ seahorse_action_activate_with_window (action, parent);
g_object_unref (action);
+ g_clear_object (&parent);
}
}
diff --git a/src/seahorse-key-manager.c b/src/seahorse-key-manager.c
index 0d88f61..c0e94c4 100644
--- a/src/seahorse-key-manager.c
+++ b/src/seahorse-key-manager.c
@@ -478,13 +478,6 @@ seahorse_key_manager_get_selected_places (SeahorseViewer* viewer)
return seahorse_sidebar_get_selected_places (self->pv->sidebar);
}
-static GList *
-seahorse_key_manager_get_selected_backends (SeahorseViewer* viewer)
-{
- SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (viewer);
- return seahorse_sidebar_get_backends (self->pv->sidebar);
-}
-
static gboolean
on_idle_save_sidebar_width (gpointer user_data)
{
@@ -533,6 +526,7 @@ setup_sidebar (SeahorseKeyManager *self)
GtkWidget *area, *panes;
GtkActionGroup *actions;
GtkAction *action;
+ GList *backends, *l;
self->pv->sidebar = seahorse_sidebar_new ();
area = seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "sidebar-area");
@@ -566,6 +560,16 @@ setup_sidebar (SeahorseKeyManager *self)
g_signal_connect (self->pv->sidebar, "size_allocate", G_CALLBACK (on_sidebar_panes_size_allocate), self);
g_signal_connect (self->pv->sidebar, "context-menu", G_CALLBACK (on_sidebar_popup_menu), self);
+ backends = seahorse_sidebar_get_backends (self->pv->sidebar);
+ for (l = backends; l != NULL; l = g_list_next (l)) {
+ actions = NULL;
+ g_object_get (l->data, "actions", &actions, NULL);
+ if (actions != NULL) {
+ seahorse_viewer_include_actions (SEAHORSE_VIEWER (self), actions);
+ g_object_unref (actions);
+ }
+ }
+
return seahorse_sidebar_get_collection (self->pv->sidebar);
}
@@ -584,7 +588,7 @@ seahorse_key_manager_constructed (GObject *object)
self->pv->collection = setup_sidebar (self);
gtk_window_set_title (seahorse_viewer_get_window (SEAHORSE_VIEWER (self)), _("Passwords and Keys"));
-
+
actions = gtk_action_group_new ("general");
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
gtk_action_group_add_actions (actions, GENERAL_ACTIONS, G_N_ELEMENTS (GENERAL_ACTIONS), self);
@@ -760,7 +764,6 @@ seahorse_key_manager_class_init (SeahorseKeyManagerClass *klass)
SEAHORSE_VIEWER_CLASS (klass)->get_selected_objects = seahorse_key_manager_get_selected_objects;
SEAHORSE_VIEWER_CLASS (klass)->get_selected_places = seahorse_key_manager_get_selected_places;
- SEAHORSE_VIEWER_CLASS (klass)->get_selected_backends = seahorse_key_manager_get_selected_backends;
}
SeahorseWidget *
diff --git a/ssh/seahorse-ssh-actions.c b/ssh/seahorse-ssh-actions.c
index 917518c..2741a77 100644
--- a/ssh/seahorse-ssh-actions.c
+++ b/ssh/seahorse-ssh-actions.c
@@ -30,6 +30,7 @@
#include "seahorse-action.h"
#include "seahorse-actions.h"
#include "seahorse-object.h"
+#include "seahorse-object-list.h"
#include "seahorse-registry.h"
#include "seahorse-util.h"
@@ -72,9 +73,8 @@ static void
on_ssh_upload (GtkAction* action,
gpointer user_data)
{
- GList *ssh_keys;
+ GList *ssh_keys = user_data;
- ssh_keys = seahorse_action_get_objects (action);
if (ssh_keys == NULL)
return;
@@ -85,7 +85,7 @@ static void
on_show_properties (GtkAction *action,
gpointer user_data)
{
- seahorse_ssh_key_properties_show (seahorse_action_get_object (action),
+ seahorse_ssh_key_properties_show (SEAHORSE_SSH_KEY (user_data),
seahorse_action_get_window (action));
}
@@ -100,7 +100,7 @@ on_delete_objects (GtkAction *action,
GError *error = NULL;
GList* objects;
- objects = seahorse_action_get_objects (action);
+ objects = user_data;
num = g_list_length (objects);
if (num == 0) {
return;
@@ -121,36 +121,67 @@ on_delete_objects (GtkAction *action,
}
}
} else {
- seahorse_action_cancel (action);
+ g_cancellable_cancel (g_cancellable_get_current ());
}
g_free (prompt);
}
-static const GtkActionEntry KEY_ACTIONS[] = {
+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) },
- { "properties", GTK_STOCK_PROPERTIES, NULL, NULL,
- N_("Properties of the key."), G_CALLBACK (on_show_properties) },
{ "delete", GTK_STOCK_DELETE, NULL, NULL,
N_("Delete the key."), G_CALLBACK (on_delete_objects) },
};
+static const GtkActionEntry KEY_ACTIONS[] = {
+ { "properties", GTK_STOCK_PROPERTIES, NULL, NULL,
+ N_("Properties of the key."), G_CALLBACK (on_show_properties) },
+};
+
static void
seahorse_ssh_actions_init (SeahorseSshActions *self)
{
GtkActionGroup *actions = GTK_ACTION_GROUP (self);
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, KEY_ACTIONS, G_N_ELEMENTS (KEY_ACTIONS), self);
+ 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), UI_DEFINITION);
}
+static GtkActionGroup *
+seahorse_ssh_actions_clone_for_objects (SeahorseActions *actions,
+ GList *objects)
+{
+ GtkActionGroup *cloned;
+
+ g_return_val_if_fail (actions, NULL);
+
+ cloned = gtk_action_group_new ("SshKey");
+ gtk_action_group_set_translation_domain (cloned, GETTEXT_PACKAGE);
+
+ gtk_action_group_add_actions_full (cloned, KEYS_ACTIONS,
+ G_N_ELEMENTS (KEYS_ACTIONS),
+ seahorse_object_list_copy (objects),
+ seahorse_object_list_free);
+
+ /* A single object */
+ if (!objects->next)
+ gtk_action_group_add_actions_full (cloned, KEY_ACTIONS,
+ G_N_ELEMENTS (KEY_ACTIONS),
+ g_object_ref (objects->data),
+ g_object_unref);
+
+ return cloned;
+}
+
static void
seahorse_ssh_actions_class_init (SeahorseSshActionsClass *klass)
{
-
+ SeahorseActionsClass *actions_class = SEAHORSE_ACTIONS_CLASS (klass);
+ actions_class->clone_for_objects = seahorse_ssh_actions_clone_for_objects;
}
GtkActionGroup *
@@ -160,7 +191,7 @@ seahorse_ssh_actions_instance (void)
if (actions == NULL) {
actions = g_object_new (SEAHORSE_TYPE_SSH_ACTIONS,
- "name", "ssh-key",
+ "name", "SshKey",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
diff --git a/ssh/seahorse-ssh-actions.h b/ssh/seahorse-ssh-actions.h
index 53732b1..63f19c7 100644
--- a/ssh/seahorse-ssh-actions.h
+++ b/ssh/seahorse-ssh-actions.h
@@ -23,6 +23,8 @@
#ifndef __SEAHORSE_SSH_ACTIONS_H__
#define __SEAHORSE_SSH_ACTIONS_H__
+#include <gtk/gtk.h>
+
GtkActionGroup * seahorse_ssh_actions_instance (void);
#endif
diff --git a/ssh/seahorse-ssh-key.c b/ssh/seahorse-ssh-key.c
index d2811b9..0078dff 100644
--- a/ssh/seahorse-ssh-key.c
+++ b/ssh/seahorse-ssh-key.c
@@ -22,6 +22,11 @@
#include "config.h"
+#include "seahorse-ssh-actions.h"
+#include "seahorse-ssh-key.h"
+#include "seahorse-ssh-operation.h"
+#include "seahorse-ssh-source.h"
+
#include <gcr/gcr.h>
#include <glib.h>
@@ -31,10 +36,8 @@
#include <errno.h>
#include <string.h>
+
#include "seahorse-place.h"
-#include "seahorse-ssh-source.h"
-#include "seahorse-ssh-key.h"
-#include "seahorse-ssh-operation.h"
#include "seahorse-icons.h"
#include "seahorse-validity.h"
@@ -75,6 +78,7 @@ changed_key (SeahorseSSHKey *self)
const gchar *display = NULL;
gchar *identifier;
gchar *simple = NULL;
+ GtkActionGroup *actions;
GIcon *icon;
gchar *filename;
gchar *markup;
@@ -131,11 +135,13 @@ changed_key (SeahorseSSHKey *self)
display, filename);
identifier = seahorse_ssh_key_calc_identifier (self->keydata->fingerprint);
+ actions = seahorse_ssh_actions_instance ();
if (self->keydata->authorized)
flags |= SEAHORSE_FLAG_TRUSTED;
g_object_set (obj,
+ "actions", actions,
"markup", markup,
"label", display,
"icon", icon,
@@ -144,6 +150,8 @@ changed_key (SeahorseSSHKey *self)
"identifier", identifier,
"flags", flags,
NULL);
+
+ g_object_unref (actions);
g_object_unref (icon);
g_free (identifier);
g_free (markup);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]