[seahorse/refactor: 30/37] Save the set of selected place in settings
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/refactor: 30/37] Save the set of selected place in settings
- Date: Thu, 20 Oct 2011 08:38:57 +0000 (UTC)
commit 44f3eda0a6b0ddc9ce6c1b55724fc0865b642d08
Author: Stef Walter <stefw collabora co uk>
Date: Fri Oct 14 12:34:48 2011 +0200
Save the set of selected place in settings
* Each place has a uri, and remember the set of chosen uris
even when the uri is no longer present.
data/org.gnome.seahorse.manager.gschema.xml | 5 +
gkr/seahorse-gkr-keyring.c | 12 +-
libseahorse/seahorse-source.c | 4 +
libseahorse/seahorse-source.h | 10 -
pgp/seahorse-gpgme-keyring.c | 7 +-
pgp/seahorse-server-source.c | 4 +-
pkcs11/seahorse-pkcs11-backend.c | 2 +
pkcs11/seahorse-token.c | 20 ++-
src/seahorse-key-manager.c | 38 +++--
src/seahorse-sidebar.c | 300 ++++++++++++++++++++-------
src/seahorse-sidebar.h | 5 +
ssh/seahorse-ssh-source.c | 12 +-
12 files changed, 308 insertions(+), 111 deletions(-)
---
diff --git a/data/org.gnome.seahorse.manager.gschema.xml b/data/org.gnome.seahorse.manager.gschema.xml
index b6fa3f8..efd3e2f 100644
--- a/data/org.gnome.seahorse.manager.gschema.xml
+++ b/data/org.gnome.seahorse.manager.gschema.xml
@@ -16,6 +16,11 @@
<summary>Width of the side pane</summary>
<description>The default width of the side pane.</description>
</key>
+ <key name="places-selected" type="as">
+ <default>["secret-service://login"]</default>
+ <summary>The places chosen</summary>
+ <description>The URIs of the places chosen in the sidebar.</description>
+ </key>
<!-- Unused, remove once stable -->
diff --git a/gkr/seahorse-gkr-keyring.c b/gkr/seahorse-gkr-keyring.c
index 8a83ba4..5caab44 100644
--- a/gkr/seahorse-gkr-keyring.c
+++ b/gkr/seahorse-gkr-keyring.c
@@ -39,7 +39,8 @@ enum {
PROP_DESCRIPTION,
PROP_KEYRING_NAME,
PROP_KEYRING_INFO,
- PROP_IS_DEFAULT
+ PROP_IS_DEFAULT,
+ PROP_URI,
};
struct _SeahorseGkrKeyringPrivate {
@@ -410,7 +411,8 @@ seahorse_gkr_keyring_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
{
SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (obj);
-
+ gchar *text;
+
switch (prop_id) {
case PROP_DESCRIPTION:
g_value_set_string (value, seahorse_gkr_keyring_get_description (self));
@@ -424,6 +426,10 @@ seahorse_gkr_keyring_get_property (GObject *obj, guint prop_id, GValue *value,
case PROP_IS_DEFAULT:
g_value_set_boolean (value, seahorse_gkr_keyring_get_is_default (self));
break;
+ case PROP_URI:
+ text = g_strdup_printf ("secret-service://%s", self->pv->keyring_name);
+ g_value_take_string (value, text);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -444,6 +450,8 @@ seahorse_gkr_keyring_class_init (SeahorseGkrKeyringClass *klass)
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_URI, "uri");
+
g_object_class_install_property (gobject_class, PROP_KEYRING_NAME,
g_param_spec_string ("keyring-name", "Gnome Keyring Name", "Name of keyring.",
"", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
diff --git a/libseahorse/seahorse-source.c b/libseahorse/seahorse-source.c
index 28b6603..dfd562e 100644
--- a/libseahorse/seahorse-source.c
+++ b/libseahorse/seahorse-source.c
@@ -64,6 +64,10 @@ seahorse_source_default_init (SeahorseSourceIface *iface)
"", G_PARAM_READABLE));
g_object_interface_install_property (iface,
+ g_param_spec_string ("uri", "URI", "URI for the source",
+ "", G_PARAM_READABLE));
+
+ g_object_interface_install_property (iface,
g_param_spec_object ("icon", "Icon", "Icon for this source",
G_TYPE_ICON, G_PARAM_READABLE));
diff --git a/libseahorse/seahorse-source.h b/libseahorse/seahorse-source.h
index 162b895..2f717c6 100644
--- a/libseahorse/seahorse-source.h
+++ b/libseahorse/seahorse-source.h
@@ -21,19 +21,9 @@
*/
/**
- * SeahorseSource: Base class for other sources.
- *
* - A generic interface for accessing sources.
* - Eventually more functionality will be merged from seahorse-op.* into
* this class and derived classes.
- *
- * Properties base classes must implement:
- * ktype: (GQuark) The ktype (ie: SEAHORSE_PGP) of objects originating from this
- * object source.
- * location: (SeahorseLocation) The location of objects that come from this
- * source. (ie: SEAHORSE_LOCATION_LOCAL, SEAHORSE_LOCATION_REMOTE)
- * uri: (gchar*) Only for remote object sources. The full URI of the keyserver
- * being used.
*/
diff --git a/pgp/seahorse-gpgme-keyring.c b/pgp/seahorse-gpgme-keyring.c
index c275e40..33a3090 100644
--- a/pgp/seahorse-gpgme-keyring.c
+++ b/pgp/seahorse-gpgme-keyring.c
@@ -52,7 +52,8 @@ enum {
PROP_0,
PROP_LABEL,
PROP_DESCRIPTION,
- PROP_ICON
+ PROP_ICON,
+ PROP_URI
};
/* Amount of keys to load in a batch */
@@ -965,6 +966,9 @@ seahorse_gpgme_keyring_get_property (GObject *obj,
case PROP_ICON:
g_value_take_object (value, g_themed_icon_new (GCR_ICON_HOME_DIRECTORY));
break;
+ case PROP_URI:
+ g_value_set_string (value, "gnupg://");
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -1031,6 +1035,7 @@ seahorse_gpgme_keyring_class_init (SeahorseGpgmeKeyringClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_URI, "uri");
g_object_class_override_property (gobject_class, PROP_ICON, "icon");
}
diff --git a/pgp/seahorse-server-source.c b/pgp/seahorse-server-source.c
index 91161b0..387c10c 100644
--- a/pgp/seahorse-server-source.c
+++ b/pgp/seahorse-server-source.c
@@ -106,7 +106,7 @@ seahorse_server_source_class_init (SeahorseServerSourceClass *klass)
g_object_class_install_property (gobject_class, PROP_URI,
g_param_spec_string ("uri", "Key Server URI",
"Key Server full URI", "",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ G_PARAM_READWRITE));
}
/**
@@ -167,7 +167,7 @@ seahorse_server_set_property (GObject *object, guint prop_id,
g_return_if_fail (ssrc->priv->server && ssrc->priv->server[0]);
break;
case PROP_URI:
- g_assert (ssrc->priv->uri == NULL);
+ g_free (ssrc->priv->uri);
ssrc->priv->uri = g_strdup (g_value_get_string (value));
g_return_if_fail (ssrc->priv->uri && ssrc->priv->uri[0]);
break;
diff --git a/pkcs11/seahorse-pkcs11-backend.c b/pkcs11/seahorse-pkcs11-backend.c
index 1f87d9d..93c84c9 100644
--- a/pkcs11/seahorse-pkcs11-backend.c
+++ b/pkcs11/seahorse-pkcs11-backend.c
@@ -142,6 +142,8 @@ on_initialized_registered (GObject *unused,
slots = gck_module_get_slots (m->data, TRUE);
for (s = slots; s; s = g_list_next (s)) {
token = gck_slot_get_token_info (s->data);
+ if (token == NULL)
+ continue;
if (is_token_usable (self, s->data, token)) {
source = SEAHORSE_SOURCE (seahorse_token_new (s->data));
self->slots = g_list_append (self->slots, source);
diff --git a/pkcs11/seahorse-token.c b/pkcs11/seahorse-token.c
index cb5fd12..6b015d2 100644
--- a/pkcs11/seahorse-token.c
+++ b/pkcs11/seahorse-token.c
@@ -44,11 +44,13 @@ enum {
PROP_DESCRIPTION,
PROP_ICON,
PROP_SLOT,
- PROP_FLAGS
+ PROP_FLAGS,
+ PROP_URI,
};
struct _SeahorseTokenPrivate {
GckSlot *slot;
+ gchar *uri;
GHashTable *objects;
};
@@ -216,9 +218,17 @@ static void
seahorse_token_constructed (GObject *obj)
{
SeahorseToken *self = SEAHORSE_TOKEN (obj);
+ GckUriData *data;
G_OBJECT_CLASS (seahorse_token_parent_class)->constructed (obj);
+ g_return_if_fail (self->pv->slot != NULL);
+
+ data = gck_uri_data_new ();
+ data->token_info = gck_slot_get_token_info (self->pv->slot);
+ self->pv->uri = gck_uri_build (data, GCK_URI_FOR_TOKEN);
+ gck_uri_data_free (data);
+
seahorse_token_refresh_async (self, NULL, NULL, NULL);
}
@@ -262,6 +272,12 @@ seahorse_token_get_property (GObject *object,
case PROP_FLAGS:
g_value_set_uint (value, 0);
break;
+ case PROP_URI:
+ g_value_set_string (value, self->pv->uri);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
@@ -303,6 +319,7 @@ seahorse_token_finalize (GObject *obj)
g_hash_table_destroy (self->pv->objects);
g_assert (self->pv->slot == NULL);
+ g_free (self->pv->uri);
G_OBJECT_CLASS (seahorse_token_parent_class)->finalize (obj);
}
@@ -322,6 +339,7 @@ seahorse_token_class_init (SeahorseTokenClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_URI, "uri");
g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_install_property (gobject_class, PROP_SLOT,
diff --git a/src/seahorse-key-manager.c b/src/seahorse-key-manager.c
index 1aae0fe..e7261d0 100644
--- a/src/seahorse-key-manager.c
+++ b/src/seahorse-key-manager.c
@@ -497,12 +497,12 @@ on_sidebar_panes_size_allocate (GtkWidget *widget,
{
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (user_data);
- if (self->pv->sidebar_width_sig != 0) {
- g_source_remove (self->pv->sidebar_width_sig);
- self->pv->sidebar_width_sig = 0;
- }
-
if (allocation->width != self->pv->sidebar_width && allocation->width > 1) {
+ if (self->pv->sidebar_width_sig != 0) {
+ g_source_remove (self->pv->sidebar_width_sig);
+ self->pv->sidebar_width_sig = 0;
+ }
+
self->pv->sidebar_width = allocation->width;
self->pv->sidebar_width_sig = g_idle_add (on_idle_save_sidebar_width, self);
}
@@ -521,22 +521,32 @@ setup_sidebar (SeahorseKeyManager *self)
gtk_container_add (GTK_CONTAINER (area), GTK_WIDGET (sidebar));
gtk_widget_show (GTK_WIDGET (sidebar));
- self->pv->sidebar_width = g_settings_get_int (self->pv->settings, "sidebar-width");
- panes = seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "sidebar-panes");
- gtk_paned_set_position (GTK_PANED (panes), self->pv->sidebar_width);
- g_signal_connect (sidebar, "size_allocate", G_CALLBACK (on_sidebar_panes_size_allocate), self);
-
actions = gtk_action_group_new ("sidebar");
gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
gtk_action_group_add_toggle_actions (actions, SIDEBAR_ACTIONS,
G_N_ELEMENTS (SIDEBAR_ACTIONS), self);
action = gtk_action_group_get_action (actions, "view-places");
- g_object_bind_property (action, "active", area, "visible", G_BINDING_DEFAULT);
- g_object_bind_property (action, "active", sidebar, "combined", G_BINDING_INVERT_BOOLEAN);
- g_settings_bind (self->pv->settings, "sidebar-visible", action, "active", G_SETTINGS_BIND_DEFAULT);
+ g_object_bind_property (action, "active",
+ area, "visible",
+ G_BINDING_DEFAULT);
+ g_object_bind_property (action, "active",
+ sidebar, "combined",
+ G_BINDING_INVERT_BOOLEAN);
+ g_settings_bind (self->pv->settings, "sidebar-visible",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
seahorse_viewer_include_actions (SEAHORSE_VIEWER (self), actions);
g_object_unref (actions);
+ g_settings_bind (self->pv->settings, "places-selected",
+ sidebar, "selected-uris",
+ G_SETTINGS_BIND_DEFAULT);
+
+ self->pv->sidebar_width = g_settings_get_int (self->pv->settings, "sidebar-width");
+ panes = seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "sidebar-panes");
+ gtk_paned_set_position (GTK_PANED (panes), self->pv->sidebar_width);
+ g_signal_connect (sidebar, "size_allocate", G_CALLBACK (on_sidebar_panes_size_allocate), self);
+
return seahorse_sidebar_get_collection (sidebar);
}
@@ -570,7 +580,7 @@ seahorse_key_manager_constructed (GObject *object)
seahorse_viewer_include_actions (SEAHORSE_VIEWER (self), self->pv->view_actions);
/* Notify us when settings change */
- g_signal_connect_object (self->pv->settings, "changed",
+ g_signal_connect_object (self->pv->settings, "changed::item-filter",
G_CALLBACK (on_item_filter_changed), action, 0);
/* close event */
diff --git a/src/seahorse-sidebar.c b/src/seahorse-sidebar.c
index 30e87a6..ab42602 100644
--- a/src/seahorse-sidebar.c
+++ b/src/seahorse-sidebar.c
@@ -32,12 +32,6 @@
#include <glib/gi18n.h>
-typedef enum {
- SEAHORSE_SIDEBAR_MODE_COMBINED,
- SEAHORSE_SIDEBAR_MODE_CHECKED,
- SEAHORSE_SIDEBAR_MODE_SELECTED
-} SeahorseSidebarMode;
-
struct _SeahorseSidebar {
GtkScrolledWindow parent;
@@ -45,10 +39,16 @@ struct _SeahorseSidebar {
GtkListStore *store;
GPtrArray *backends;
- SeahorseSidebarMode mode;
- GHashTable *checked;
GcrUnionCollection *objects;
+
+ /* The selection */
+ GHashTable *checked;
GcrCollection *selected;
+ gboolean combined;
+ gboolean updating;
+
+ /* A set of chosen uris, used with settings */
+ GHashTable *chosen;
guint update_places_sig;
};
@@ -60,7 +60,8 @@ struct _SeahorseSidebarClass {
enum {
PROP_0,
PROP_COLLECTION,
- PROP_COMBINED
+ PROP_COMBINED,
+ PROP_SELECTED_URIS
};
typedef enum {
@@ -76,6 +77,7 @@ enum {
SIDEBAR_EDITABLE,
SIDEBAR_CATEGORY,
SIDEBAR_COLLECTION,
+ SIDEBAR_URI,
SIDEBAR_N_COLUMNS
};
@@ -87,6 +89,7 @@ static GType column_types[] = {
G_TYPE_BOOLEAN,
G_TYPE_STRING,
0 /* later */,
+ G_TYPE_STRING,
};
G_DEFINE_TYPE (SeahorseSidebar, seahorse_sidebar, GTK_TYPE_SCROLLED_WINDOW);
@@ -102,11 +105,11 @@ seahorse_sidebar_init (SeahorseSidebar *self)
self->backends = g_ptr_array_new_with_free_func (g_object_unref);
self->checked = g_hash_table_new (g_direct_hash, g_direct_equal);
self->objects = GCR_UNION_COLLECTION (gcr_union_collection_new ());
- self->mode = SEAHORSE_SIDEBAR_MODE_SELECTED;
+ self->chosen = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
static void
-next_or_append_row (SeahorseSidebar *self,
+next_or_append_row (GtkListStore *store,
GtkTreeIter *iter,
const gchar *category,
GcrCollection *collection)
@@ -128,18 +131,18 @@ next_or_append_row (SeahorseSidebar *self,
/* A marker that tells us the iter is not yet valid */
if (iter->stamp == GPOINTER_TO_INT (iter) && iter->user_data3 == iter &&
iter->user_data2 == iter && iter->user_data == iter) {
- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->store), iter))
- gtk_list_store_append (self->store, iter);
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), iter))
+ gtk_list_store_append (store, iter);
return;
}
- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (self->store), iter)) {
- gtk_list_store_append (self->store, iter);
+ if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), iter)) {
+ gtk_list_store_append (store, iter);
return;
}
for (;;) {
- gtk_tree_model_get (GTK_TREE_MODEL (self->store), iter,
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter,
SIDEBAR_CATEGORY, &row_category,
SIDEBAR_COLLECTION, &row_collection,
-1);
@@ -152,9 +155,8 @@ next_or_append_row (SeahorseSidebar *self,
if (found)
return;
- g_hash_table_remove (self->checked, row_collection);
- if (!gtk_list_store_remove (self->store, iter)) {
- gtk_list_store_append (self->store, iter);
+ if (!gtk_list_store_remove (store, iter)) {
+ gtk_list_store_append (store, iter);
return;
}
}
@@ -171,6 +173,7 @@ update_backend (SeahorseSidebar *self,
gchar *tooltip;
gchar *label;
GIcon *icon = NULL;
+ gchar *uri;
collections = gcr_collection_get_objects (backend);
@@ -184,7 +187,7 @@ update_backend (SeahorseSidebar *self,
"description", &tooltip,
NULL);
- next_or_append_row (self, iter, category, GCR_COLLECTION (backend));
+ next_or_append_row (self->store, iter, category, GCR_COLLECTION (backend));
gtk_list_store_set (self->store, iter,
SIDEBAR_ROW_TYPE, TYPE_BACKEND,
SIDEBAR_CATEGORY, category,
@@ -198,18 +201,18 @@ update_backend (SeahorseSidebar *self,
g_free (tooltip);
for (l = collections; l != NULL; l = g_list_next (l)) {
-
label = tooltip = NULL;
g_object_get (l->data,
"label", &label,
"description", &tooltip,
"icon", &icon,
+ "uri", &uri,
NULL);
spec = g_object_class_find_property (G_OBJECT_GET_CLASS (l->data), "label");
g_return_if_fail (spec != NULL);
- next_or_append_row (self, iter, category, l->data);
+ next_or_append_row (self->store, iter, category, l->data);
gtk_list_store_set (self->store, iter,
SIDEBAR_ROW_TYPE, TYPE_PLACE,
SIDEBAR_CATEGORY, category,
@@ -218,11 +221,13 @@ update_backend (SeahorseSidebar *self,
SIDEBAR_ICON, icon,
SIDEBAR_EDITABLE, (spec->flags & G_PARAM_WRITABLE) ? TRUE : FALSE,
SIDEBAR_COLLECTION, l->data,
+ SIDEBAR_URI, uri,
-1);
g_clear_object (&icon);
g_free (label);
g_free (tooltip);
+ g_free (uri);
}
g_free (category);
@@ -230,31 +235,50 @@ update_backend (SeahorseSidebar *self,
}
static void
-update_objects_in_collection (SeahorseSidebar *self)
+update_objects_in_collection (SeahorseSidebar *self,
+ gboolean update_chosen)
{
GList *collections;
gboolean include;
gboolean have;
+ gboolean changed = FALSE;
+ gchar *uri;
GList *l;
guint i;
+ /* Updating collection is blocked */
+ if (self->updating)
+ return;
+
for (i = 0; i < self->backends->len; i++) {
collections = gcr_collection_get_objects (self->backends->pdata[i]);
for (l = collections; l != NULL; l = g_list_next (l)) {
- switch (self->mode) {
- case SEAHORSE_SIDEBAR_MODE_COMBINED:
- include = TRUE;
- break;
- case SEAHORSE_SIDEBAR_MODE_CHECKED:
+
+ /* Checked collections are chosen*/
+ if (g_hash_table_size (self->checked) > 0)
include = (g_hash_table_lookup (self->checked, l->data) != NULL);
- break;
- case SEAHORSE_SIDEBAR_MODE_SELECTED:
+
+ /* Just selected one is chosen */
+ else
include = (l->data == self->selected);
- break;
- default:
- g_assert_not_reached ();
+
+ if (update_chosen) {
+ g_object_get (l->data, "uri", &uri, NULL);
+ have = g_hash_table_lookup (self->chosen, uri) != NULL;
+ if (include && !have) {
+ g_hash_table_insert (self->chosen, g_strdup (uri), "");
+ changed = TRUE;
+ } else if (!include && have) {
+ g_hash_table_remove (self->chosen, uri);
+ changed = TRUE;
+ }
+ g_free (uri);
}
+ /* Combined overrides and shows all objects */
+ if (self->combined)
+ include = TRUE;
+
have = gcr_union_collection_have (self->objects, l->data);
if (include && !have)
gcr_union_collection_add (self->objects, l->data);
@@ -263,6 +287,9 @@ update_objects_in_collection (SeahorseSidebar *self)
}
g_list_free (collections);
}
+
+ if (update_chosen && changed)
+ g_object_notify (G_OBJECT (self), "selected-uris");
}
static void
@@ -281,8 +308,8 @@ update_objects_for_selection (SeahorseSidebar *self,
if (selected != self->selected) {
g_clear_object (&self->selected);
self->selected = selected ? g_object_ref (selected) : NULL;
- if (self->mode == SEAHORSE_SIDEBAR_MODE_SELECTED)
- update_objects_in_collection (self);
+ if (g_hash_table_size (self->checked) == 0)
+ update_objects_in_collection (self, TRUE);
}
g_clear_object (&selected);
@@ -293,11 +320,7 @@ update_objects_for_checked (SeahorseSidebar *self,
GcrCollection *place)
{
g_hash_table_insert (self->checked, place, place);
-
- if (self->mode == SEAHORSE_SIDEBAR_MODE_SELECTED)
- self->mode = SEAHORSE_SIDEBAR_MODE_CHECKED;
- if (self->mode != SEAHORSE_SIDEBAR_MODE_COMBINED)
- update_objects_in_collection (self);
+ update_objects_in_collection (self, TRUE);
}
static void
@@ -306,33 +329,121 @@ update_objects_for_unchecked (SeahorseSidebar *self,
{
if (!g_hash_table_remove (self->checked, place))
g_assert_not_reached ();
+ update_objects_in_collection (self, TRUE);
+}
- if (self->mode == SEAHORSE_SIDEBAR_MODE_CHECKED &&
- g_hash_table_size (self->checked) == 0)
- self->mode = SEAHORSE_SIDEBAR_MODE_SELECTED;
- if (self->mode != SEAHORSE_SIDEBAR_MODE_COMBINED)
- update_objects_in_collection (self);
+static void
+update_objects_for_combine (SeahorseSidebar *self,
+ gboolean combine)
+{
+ if (self->combined != combine) {
+ self->combined = combine;
+ update_objects_in_collection (self, FALSE);
+ }
}
static void
-update_objects_for_combine (SeahorseSidebar *self)
+invalidate_all_rows (GtkTreeModel *model)
{
- if (self->mode != SEAHORSE_SIDEBAR_MODE_COMBINED) {
- self->mode = SEAHORSE_SIDEBAR_MODE_COMBINED;
- update_objects_in_collection (self);
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ path = gtk_tree_model_get_path (model, &iter);
+ gtk_tree_model_row_changed (model, path, &iter);
+ gtk_tree_path_free (path);
+ } while (gtk_tree_model_iter_next (model, &iter));
}
}
static void
-update_objects_for_uncombine (SeahorseSidebar *self)
+update_objects_for_chosen (SeahorseSidebar *self,
+ GHashTable *chosen)
{
- if (self->mode == SEAHORSE_SIDEBAR_MODE_COMBINED) {
- if (g_hash_table_size (self->checked) > 0)
- self->mode = SEAHORSE_SIDEBAR_MODE_CHECKED;
- else
- self->mode = SEAHORSE_SIDEBAR_MODE_SELECTED;
- update_objects_in_collection (self);
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GcrCollection *collection;
+ gboolean checked;
+ gchar *uri;
+ gint count = 0;
+ gboolean changed = FALSE;
+ GcrCollection *selected = NULL;
+ GtkTreeIter select_iter;
+ GtkTreeSelection *selection;
+
+ self->updating = TRUE;
+
+ /* Update the display */
+ model = GTK_TREE_MODEL (self->store);
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ gtk_tree_model_get (model, &iter,
+ SIDEBAR_COLLECTION, &collection,
+ SIDEBAR_URI, &uri,
+ -1);
+
+ if (collection && uri) {
+ checked = g_hash_table_size (self->checked) > 0;
+
+ /* Chosen */
+ if (g_hash_table_lookup (chosen, uri)) {
+ if (!checked) {
+ /* First one update selection */
+ if (count == 0) {
+ g_clear_object (&selected);
+ selected = collection;
+ collection = NULL;
+ select_iter = iter;
+ changed = TRUE;
+
+ /* Second one, change to checked if necessary */
+ } else if (count == 1) {
+ g_assert (selected != NULL);
+ g_hash_table_insert (self->checked,
+ selected,
+ selected);
+ g_clear_object (&selected);
+ checked = TRUE;
+ changed = TRUE;
+ }
+ }
+
+ if (checked) {
+ g_hash_table_insert (self->checked,
+ collection,
+ collection);
+ changed = TRUE;
+ }
+
+ count++;
+
+ /* Not chosen */
+ } else {
+ if (!checked)
+ changed = TRUE;
+ if (g_hash_table_remove (self->checked, collection))
+ changed = TRUE;
+ }
+ }
+
+ g_clear_object (&collection);
+ g_free (uri);
+ } while (gtk_tree_model_iter_next (model, &iter));
}
+
+ if (selected) {
+ selection = gtk_tree_view_get_selection (self->tree_view);
+ gtk_tree_selection_select_iter (selection, &select_iter);
+ g_object_unref (selected);
+ }
+
+ self->updating = FALSE;
+
+ if (changed)
+ invalidate_all_rows (model);
+
+ update_objects_in_collection (self, FALSE);
}
static void
@@ -349,7 +460,7 @@ update_places (SeahorseSidebar *self)
update_backend (self, GCR_COLLECTION (self->backends->pdata[i]), &iter);
/* Update selection */
- update_objects_in_collection (self);
+ update_objects_for_chosen (self, self->chosen);
}
static gboolean
@@ -457,7 +568,8 @@ on_cell_renderer_check (GtkTreeViewColumn *column,
active = g_hash_table_lookup (self->checked, collection) != NULL;
visible = TRUE;
} else {
- visible = (collection == self->selected);
+ visible = (gtk_widget_is_focus (GTK_WIDGET (self->tree_view)) &&
+ collection == self->selected);
}
/* self->mnemonics_visible */
@@ -470,21 +582,6 @@ on_cell_renderer_check (GtkTreeViewColumn *column,
g_clear_object (&collection);
}
-static void
-invalidate_all_rows (GtkTreeModel *model)
-{
- GtkTreeIter iter;
- GtkTreePath *path;
-
- if (gtk_tree_model_get_iter_first (model, &iter)) {
- do {
- path = gtk_tree_model_get_path (model, &iter);
- gtk_tree_model_row_changed (model, path, &iter);
- gtk_tree_path_free (path);
- } while (gtk_tree_model_iter_next (model, &iter));
- }
-}
-
static gboolean
on_tree_selection_validate (GtkTreeSelection *selection,
GtkTreeModel *model,
@@ -779,6 +876,9 @@ seahorse_sidebar_get_property (GObject *obj,
case PROP_COMBINED:
g_value_set_boolean (value, seahorse_sidebar_get_combined (self));
break;
+ case PROP_SELECTED_URIS:
+ g_value_take_boxed (value, seahorse_sidebar_get_selected_uris (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -797,6 +897,9 @@ seahorse_sidebar_set_property (GObject *obj,
case PROP_COMBINED:
seahorse_sidebar_set_combined (self, g_value_get_boolean (value));
break;
+ case PROP_SELECTED_URIS:
+ seahorse_sidebar_set_selected_uris (self, g_value_get_boxed (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -831,6 +934,7 @@ seahorse_sidebar_finalize (GObject *obj)
g_clear_object (&self->selected);
g_hash_table_destroy (self->checked);
+ g_hash_table_destroy (self->chosen);
g_object_unref (self->objects);
if (self->update_places_sig)
@@ -860,6 +964,10 @@ seahorse_sidebar_class_init (SeahorseSidebarClass *klass)
g_object_class_install_property (gobject_class, PROP_COMBINED,
g_param_spec_boolean ("combined", "Combined", "Collection shows all objects combined",
FALSE, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_SELECTED_URIS,
+ g_param_spec_boxed ("selected-uris", "Selected URIs", "URIs selected by the user",
+ G_TYPE_STRV, G_PARAM_READWRITE));
}
SeahorseSidebar *
@@ -880,7 +988,7 @@ gboolean
seahorse_sidebar_get_combined (SeahorseSidebar *self)
{
g_return_val_if_fail (SEAHORSE_IS_SIDEBAR (self), FALSE);
- return self->mode == SEAHORSE_SIDEBAR_MODE_COMBINED;
+ return self->combined;
}
void
@@ -888,9 +996,45 @@ seahorse_sidebar_set_combined (SeahorseSidebar *self,
gboolean combined)
{
g_return_if_fail (SEAHORSE_IS_SIDEBAR (self));
- if (combined)
- update_objects_for_combine (self);
- else
- update_objects_for_uncombine (self);
+ update_objects_for_combine (self, combined);
g_object_notify (G_OBJECT (self), "combined");
}
+
+gchar **
+seahorse_sidebar_get_selected_uris (SeahorseSidebar *self)
+{
+ GHashTableIter iter;
+ GPtrArray *results;
+ gchar *uri;
+
+ g_return_val_if_fail (SEAHORSE_IS_SIDEBAR (self), NULL);
+
+ results = g_ptr_array_new ();
+ g_hash_table_iter_init (&iter, self->chosen);
+ while (g_hash_table_iter_next (&iter, (gpointer *)&uri, NULL))
+ g_ptr_array_add (results, g_strdup (uri));
+ g_ptr_array_add (results, NULL);
+
+ return (gchar **)g_ptr_array_free (results, FALSE);
+}
+
+void
+seahorse_sidebar_set_selected_uris (SeahorseSidebar *self,
+ const gchar **value)
+{
+ GHashTable *chosen;
+ gint i;
+
+ g_return_if_fail (SEAHORSE_IS_SIDEBAR (self));
+
+ /* For quick lookups */
+ chosen = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ for (i = 0; value != NULL && value[i] != NULL; i++)
+ g_hash_table_insert (chosen, g_strdup (value[i]), "");
+
+ update_objects_for_chosen (self, chosen);
+ g_hash_table_destroy (self->chosen);
+ self->chosen = chosen;
+
+ g_object_notify (G_OBJECT (self), "selected-uris");
+}
diff --git a/src/seahorse-sidebar.h b/src/seahorse-sidebar.h
index 48b57ef..fb59f36 100644
--- a/src/seahorse-sidebar.h
+++ b/src/seahorse-sidebar.h
@@ -47,4 +47,9 @@ void seahorse_sidebar_set_combined (SeahorseSideba
GcrCollection * seahorse_sidebar_get_collection (SeahorseSidebar *self);
+gchar ** seahorse_sidebar_get_selected_uris (SeahorseSidebar *self);
+
+void seahorse_sidebar_set_selected_uris (SeahorseSidebar *self,
+ const gchar **value);
+
#endif /* __SEAHORSE_SIDEBAR_H__ */
diff --git a/ssh/seahorse-ssh-source.c b/ssh/seahorse-ssh-source.c
index b08f5e7..0f283d9 100644
--- a/ssh/seahorse-ssh-source.c
+++ b/ssh/seahorse-ssh-source.c
@@ -49,7 +49,8 @@ enum {
PROP_LABEL,
PROP_DESCRIPTION,
PROP_ICON,
- PROP_BASE_DIRECTORY
+ PROP_BASE_DIRECTORY,
+ PROP_URI
};
struct _SeahorseSSHSourcePrivate {
@@ -230,7 +231,7 @@ seahorse_ssh_source_get_property (GObject *obj,
g_value_set_string (value, _("OpenSSH directory"));
break;
case PROP_DESCRIPTION:
- text = g_strdup_printf (_("OpenSSH: %s"), "~/.ssh/");
+ text = g_strdup_printf (_("OpenSSH: %s"), self->priv->ssh_homedir);
g_value_take_string (value, text);
break;
case PROP_ICON:
@@ -239,6 +240,10 @@ seahorse_ssh_source_get_property (GObject *obj,
case PROP_BASE_DIRECTORY:
g_value_set_string (value, self->priv->ssh_homedir);
break;
+ case PROP_URI:
+ g_value_take_string (value, g_strdup_printf ("openssh://%s",
+ self->priv->ssh_homedir));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -295,7 +300,7 @@ seahorse_ssh_source_init (SeahorseSSHSource *ssrc)
ssrc->priv->scheduled_refresh = 0;
ssrc->priv->monitor_handle = NULL;
- ssrc->priv->ssh_homedir = g_strdup_printf ("%s/.ssh/", g_get_home_dir ());
+ ssrc->priv->ssh_homedir = g_strdup_printf ("%s/.ssh", g_get_home_dir ());
/* Make the .ssh directory if it doesn't exist */
if (!g_file_test (ssrc->priv->ssh_homedir, G_FILE_TEST_EXISTS)) {
@@ -329,6 +334,7 @@ seahorse_ssh_source_class_init (SeahorseSSHSourceClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_URI, "uri");
g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_install_property (gobject_class, PROP_BASE_DIRECTORY,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]