[seahorse/refactor: 11/37] Make the main key manager view reflect what's in the side pane.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/refactor: 11/37] Make the main key manager view reflect what's in the side pane.
- Date: Thu, 20 Oct 2011 08:37:21 +0000 (UTC)
commit 058b368f250195afd6ec227674d45b270640051b
Author: Stef Walter <stefw collabora co uk>
Date: Fri Sep 9 13:53:54 2011 +0200
Make the main key manager view reflect what's in the side pane.
src/seahorse-key-manager.c | 296 +++++-------------------------------------
src/seahorse-key-manager.xml | 111 ++---------------
src/seahorse-sidebar.c | 232 ++++++++++++++++++++-------------
src/seahorse-sidebar.h | 2 +
4 files changed, 188 insertions(+), 453 deletions(-)
---
diff --git a/src/seahorse-key-manager.c b/src/seahorse-key-manager.c
index 926facb..5f057f3 100644
--- a/src/seahorse-key-manager.c
+++ b/src/seahorse-key-manager.c
@@ -57,25 +57,16 @@ void on_keymanager_import_button (GtkButton* button,
enum {
PROP_0,
- PROP_SOURCES,
PROP_SELECTED
};
-typedef struct _TabInfo {
- guint id;
- gint page;
- GtkTreeView* view;
- SeahorseCollection *collection;
- GtkWidget* widget;
- SeahorseKeyManagerStore* store;
-} TabInfo;
struct _SeahorseKeyManagerPrivate {
- GcrCollection *sources;
- GcrUnionCollection *collection;
- GtkNotebook* notebook;
GtkActionGroup* view_actions;
GtkEntry* filter_entry;
- TabInfo* tabs;
+
+ GtkTreeView* view;
+ GcrCollection *collection; /* owned by the sidebar */
+ SeahorseKeyManagerStore* store;
GSettings *settings;
gint sidebar_width;
@@ -87,102 +78,12 @@ enum {
TARGETS_URIS
};
-enum {
- TAB_PUBLIC = 0,
- TAB_PRIVATE,
- TAB_PASSWORD,
- TAB_NUM_TABS
-} SeahorseKeyManagerTabs;
-
-static SeahorsePredicate pred_public = {
- 0,
- SEAHORSE_USAGE_PUBLIC_KEY,
- 0,
- 0,
- NULL
-};
-
-static SeahorsePredicate pred_private = {
- 0,
- SEAHORSE_USAGE_PRIVATE_KEY,
- 0,
- 0,
- NULL
-};
-
-static SeahorsePredicate pred_password = {
- 0, /* type filled in later */
- 0,
- 0,
- 0,
- NULL
-};
-
G_DEFINE_TYPE (SeahorseKeyManager, seahorse_key_manager, SEAHORSE_TYPE_VIEWER);
/* -----------------------------------------------------------------------------
* INTERNAL
*/
-static TabInfo*
-get_tab_for_object (SeahorseKeyManager* self, SeahorseObject* obj)
-{
- gint i;
-
- g_return_val_if_fail (SEAHORSE_IS_KEY_MANAGER (self), NULL);
- g_return_val_if_fail (SEAHORSE_IS_OBJECT (obj), NULL);
-
- for (i = 0; i < TAB_NUM_TABS; ++i) {
- TabInfo* tab = &self->pv->tabs[i];
- if (gcr_collection_contains (GCR_COLLECTION (tab->collection),
- G_OBJECT (obj)))
- return tab;
- }
-
- return NULL;
-}
-
-static TabInfo*
-get_tab_info (SeahorseKeyManager* self, gint page)
-{
- gint i;
-
- g_return_val_if_fail (SEAHORSE_IS_KEY_MANAGER (self), NULL);
-
- if (page < 0)
- page = gtk_notebook_get_current_page (self->pv->notebook);
- if (page < 0)
- return NULL;
-
- for (i = 0; i < TAB_NUM_TABS; ++i)
- {
- TabInfo* tab = &self->pv->tabs[i];
- if (tab->page == page)
- return tab;
- }
-
- return NULL;
-}
-
-static GtkTreeView*
-get_current_view (SeahorseKeyManager* self)
-{
- TabInfo* tab;
- g_return_val_if_fail (SEAHORSE_IS_KEY_MANAGER (self), NULL);
- tab = get_tab_info (self, -1);
- if (tab == NULL)
- return NULL;
- return tab->view;
-}
-
-static void
-set_tab_current (SeahorseKeyManager* self, TabInfo* tab)
-{
- g_return_if_fail (SEAHORSE_IS_KEY_MANAGER (self));
- gtk_notebook_set_current_page (self->pv->notebook, tab->page);
- g_signal_emit_by_name (G_OBJECT (SEAHORSE_VIEW (self)), "selection-changed");
-}
-
static gboolean
fire_selection_changed (gpointer user_data)
{
@@ -196,16 +97,6 @@ fire_selection_changed (gpointer user_data)
}
static void
-on_tab_changed (GtkNotebook* notebook, void* unused, guint page_num, SeahorseKeyManager* self)
-{
- g_return_if_fail (SEAHORSE_IS_KEY_MANAGER (self));
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
- gtk_entry_set_text (self->pv->filter_entry, "");
-
- fire_selection_changed (self);
-}
-
-static void
on_view_selection_changed (GtkTreeSelection* selection, SeahorseKeyManager* self)
{
g_return_if_fail (SEAHORSE_IS_KEY_MANAGER (self));
@@ -271,42 +162,7 @@ on_keymanager_new_button (GtkButton* button, SeahorseKeyManager* self)
seahorse_generate_select_show (seahorse_viewer_get_window (SEAHORSE_VIEWER (self)));
}
-static void
-initialize_tab (SeahorseKeyManager* self, const char* tabwidget, guint tabid, const char* viewwidget,
- const SeahorsePredicate* pred)
-{
- SeahorseCollection *collection;
- GtkTreeSelection *selection;
- GtkTreeView *view;
-
- g_assert (tabid < (int)TAB_NUM_TABS);
-
- self->pv->tabs[tabid].id = tabid;
- self->pv->tabs[tabid].widget = seahorse_widget_get_widget (SEAHORSE_WIDGET (self), tabwidget);
- g_return_if_fail (self->pv->tabs[tabid].widget != NULL);
-
- self->pv->tabs[tabid].page = gtk_notebook_page_num (self->pv->notebook, self->pv->tabs[tabid].widget);
- g_return_if_fail (self->pv->tabs[tabid].page >= 0);
-
- collection = seahorse_collection_new_for_predicate (GCR_COLLECTION (self->pv->collection),
- (SeahorsePredicate*)pred, NULL);
- self->pv->tabs[tabid].collection = SEAHORSE_COLLECTION (collection);
-
- /* Init key list & selection settings */
- view = GTK_TREE_VIEW (seahorse_widget_get_widget (SEAHORSE_WIDGET (self), viewwidget));
- self->pv->tabs[tabid].view = view;
- g_return_if_fail (view != NULL);
-
- selection = gtk_tree_view_get_selection (view);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (selection, "changed", G_CALLBACK (on_view_selection_changed), self);
- gtk_widget_realize (GTK_WIDGET (view));
-
- /* Add new key store and associate it */
- self->pv->tabs[tabid].store = seahorse_key_manager_store_new (GCR_COLLECTION (collection),
- view, self->pv->settings);
-}
-
+#if REFACTOR_FIRST
static gboolean
on_first_timer (SeahorseKeyManager* self)
{
@@ -326,6 +182,7 @@ on_first_timer (SeahorseKeyManager* self)
return FALSE;
}
+#endif
static void
on_clear_clicked (GtkEntry* entry, GtkEntryIconPosition icon_pos, GdkEvent* event, gpointer user_data)
@@ -337,14 +194,12 @@ static void
on_filter_changed (GtkEntry* entry, SeahorseKeyManager* self)
{
const gchar *text;
- gint i;
g_return_if_fail (SEAHORSE_IS_KEY_MANAGER (self));
g_return_if_fail (GTK_IS_ENTRY (entry));
text = gtk_entry_get_text (entry);
- for (i = 0; i < TAB_NUM_TABS; ++i)
- g_object_set (self->pv->tabs[i].store, "filter", text, NULL);
+ g_object_set (self->pv->store, "filter", text, NULL);
}
#ifdef REFACTOR_IMPORT
@@ -682,71 +537,22 @@ static GList*
seahorse_key_manager_get_selected_objects (SeahorseViewer* base)
{
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (base);
- TabInfo* tab = get_tab_info (self, -1);
- if (tab == NULL)
- return NULL;
- return seahorse_key_manager_store_get_selected_objects (tab->view);
+ return seahorse_key_manager_store_get_selected_objects (self->pv->view);
}
static void
seahorse_key_manager_set_selected_objects (SeahorseViewer* base, GList* objects)
{
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (base);
- GList** tab_lists;
- GList *l;
- gint i;
- guint highest_matched;
- TabInfo* highest_tab;
-
- tab_lists = g_new0 (GList*, TAB_NUM_TABS + 1);
-
- /* Break objects into what's on each tab */
- for (l = objects; l; l = g_list_next (l)) {
- SeahorseObject* obj = SEAHORSE_OBJECT (l->data);
- TabInfo* tab = get_tab_for_object (self, obj);
- if (tab == NULL)
- continue;
+ seahorse_key_manager_store_set_selected_objects (self->pv->view, objects);
- g_assert (tab->id < TAB_NUM_TABS);
- tab_lists[tab->id] = g_list_prepend (tab_lists[tab->id], obj);
- }
-
- highest_matched = 0;
- highest_tab = NULL;
-
- for (i = 0; i < TAB_NUM_TABS; ++i) {
- GList* list = tab_lists[i];
- TabInfo* tab = &self->pv->tabs[i];
-
- /* Save away the tab that had the most objects */
- guint num = g_list_length (list);
- if (num > highest_matched) {
- highest_matched = num;
- highest_tab = tab;
- }
-
- /* Select the objects on that tab */
- seahorse_key_manager_store_set_selected_objects (tab->view, list);
-
- /* Free the broken down list */
- g_list_free (list);
- }
-
- g_free (tab_lists);
-
- /* Change to the tab with the most objects */
- if (highest_tab != NULL)
- set_tab_current (self, highest_tab);
}
static SeahorseObject*
seahorse_key_manager_get_selected (SeahorseViewer* base)
{
SeahorseKeyManager* self = SEAHORSE_KEY_MANAGER (base);
- TabInfo* tab = get_tab_info (self, -1);
- if (tab == NULL)
- return NULL;
- return seahorse_key_manager_store_get_selected_object (tab->view);
+ return seahorse_key_manager_store_get_selected_object (self->pv->view);
}
static void
@@ -789,7 +595,7 @@ on_sidebar_panes_size_allocate (GtkWidget *widget,
}
}
-static void
+static GcrCollection *
setup_sidebar (SeahorseKeyManager *self)
{
SeahorseSidebar *sidebar;
@@ -804,6 +610,8 @@ setup_sidebar (SeahorseKeyManager *self)
widget = seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "sidebar-panes");
gtk_paned_set_position (GTK_PANED (widget), self->pv->sidebar_width);
g_signal_connect (sidebar, "size_allocate", G_CALLBACK (on_sidebar_panes_size_allocate), self);
+
+ return seahorse_sidebar_get_collection (sidebar);
}
static void
@@ -813,15 +621,13 @@ seahorse_key_manager_constructed (GObject *object)
GtkActionGroup* actions;
GtkToggleAction* action;
GtkTargetList* targets;
+ GtkTreeSelection *selection;
GtkWidget* widget;
G_OBJECT_CLASS (seahorse_key_manager_parent_class)->constructed (object);
- setup_sidebar (self);
-
- self->pv->tabs = g_new0 (TabInfo, TAB_NUM_TABS);
+ self->pv->collection = setup_sidebar (self);
- self->pv->notebook = GTK_NOTEBOOK (seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "notebook"));
gtk_window_set_title (seahorse_viewer_get_window (SEAHORSE_VIEWER (self)), _("Passwords and Keys"));
actions = gtk_action_group_new ("general");
@@ -855,10 +661,7 @@ seahorse_key_manager_constructed (GObject *object)
g_signal_connect_object (seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "new-button"),
"clicked", G_CALLBACK (on_keymanager_new_button), self, 0);
-
- /* The notebook */
- g_signal_connect_object (self->pv->notebook, "switch-page", G_CALLBACK (on_tab_changed), self, G_CONNECT_AFTER);
-
+
/* Flush all updates */
seahorse_viewer_ensure_updated (SEAHORSE_VIEWER (self));
@@ -925,17 +728,24 @@ seahorse_key_manager_constructed (GObject *object)
/* For the filtering */
g_signal_connect_object (GTK_EDITABLE (self->pv->filter_entry), "changed",
G_CALLBACK (on_filter_changed), self, 0);
-
- /* Initialize the tabs, and associate them up */
- initialize_tab (self, "pub-key-tab", TAB_PUBLIC, "pub-key-list", &pred_public);
- initialize_tab (self, "sec-key-tab", TAB_PRIVATE, "sec-key-list", &pred_private);
- pred_password.type = SEAHORSE_TYPE_GKR_KEYRING;
- initialize_tab (self, "password-tab", TAB_PASSWORD, "password-list", &pred_password);
-
+
+
+ /* Init key list & selection settings */
+ self->pv->view = GTK_TREE_VIEW (seahorse_widget_get_widget (SEAHORSE_WIDGET (self), "key-list"));
+ g_return_if_fail (self->pv->view != NULL);
+
+ selection = gtk_tree_view_get_selection (self->pv->view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (selection, "changed", G_CALLBACK (on_view_selection_changed), self);
+ gtk_widget_realize (GTK_WIDGET (self->pv->view));
+
+ /* Add new key store and associate it */
+ self->pv->store = seahorse_key_manager_store_new (self->pv->collection,
+ self->pv->view,
+ self->pv->settings);
+
/* Set focus to the current key list */
- widget = GTK_WIDGET (get_current_view (self));
gtk_widget_grab_focus (widget);
-
g_signal_emit_by_name (self, "selection-changed");
/* To avoid flicker */
@@ -954,8 +764,10 @@ seahorse_key_manager_constructed (GObject *object)
G_CALLBACK (on_target_drag_data_received), self, 0);
#endif
+#ifdef REFACTOR_FIRST
/* To show first time dialog */
g_timeout_add_seconds (1, (GSourceFunc)on_first_timer, self);
+#endif
}
static void
@@ -963,14 +775,12 @@ seahorse_key_manager_init (SeahorseKeyManager *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_KEY_MANAGER, SeahorseKeyManagerPrivate);
self->pv->settings = g_settings_new ("org.gnome.seahorse.manager");
- self->pv->collection = GCR_UNION_COLLECTION (gcr_union_collection_new ());
}
static void
seahorse_key_manager_finalize (GObject *obj)
{
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (obj);
- gint i;
if (self->pv->sidebar_width_sig != 0) {
g_source_remove (self->pv->sidebar_width_sig);
@@ -982,19 +792,8 @@ seahorse_key_manager_finalize (GObject *obj)
self->pv->view_actions = NULL;
self->pv->filter_entry = NULL;
-
- if (self->pv->tabs) {
- for (i = 0; i < TAB_NUM_TABS; ++i) {
- g_clear_object (&self->pv->tabs[i].store);
- g_clear_object (&self->pv->tabs[i].collection);
- }
- g_free (self->pv->tabs);
- self->pv->tabs = NULL;
- }
g_clear_object (&self->pv->settings);
- g_object_unref (self->pv->collection);
- g_clear_object (&self->pv->sources);
G_OBJECT_CLASS (seahorse_key_manager_parent_class)->finalize (obj);
}
@@ -1004,17 +803,8 @@ seahorse_key_manager_set_property (GObject *obj, guint prop_id, const GValue *va
GParamSpec *pspec)
{
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (obj);
- GList *collections, *l;
switch (prop_id) {
- case PROP_SOURCES:
- g_return_if_fail (self->pv->sources == NULL);
- self->pv->sources = g_value_dup_object (value);
- collections = gcr_collection_get_objects (self->pv->sources);
- for (l = collections; l != NULL; l = g_list_next (l))
- gcr_union_collection_add (self->pv->collection, l->data);
- g_list_free (collections);
- break;
case PROP_SELECTED:
seahorse_viewer_set_selected (SEAHORSE_VIEWER (self), g_value_get_object (value));
break;
@@ -1031,9 +821,6 @@ seahorse_key_manager_get_property (GObject *obj, guint prop_id, GValue *value,
SeahorseKeyManager *self = SEAHORSE_KEY_MANAGER (obj);
switch (prop_id) {
- case PROP_SOURCES:
- g_value_set_object (value, self->pv->sources);
- break;
case PROP_SELECTED:
g_value_set_object (value, seahorse_viewer_get_selected (SEAHORSE_VIEWER (self)));
break;
@@ -1061,10 +848,6 @@ seahorse_key_manager_class_init (SeahorseKeyManagerClass *klass)
SEAHORSE_VIEWER_CLASS (klass)->get_selected = seahorse_key_manager_get_selected;
SEAHORSE_VIEWER_CLASS (klass)->set_selected = seahorse_key_manager_set_selected;
- g_object_class_install_property (gobject_class, PROP_SOURCES,
- g_param_spec_object ("sources", "Sources" , "Collection of Sources",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
g_object_class_override_property (gobject_class, PROP_SELECTED, "selected");
}
@@ -1077,22 +860,11 @@ SeahorseWidget *
seahorse_key_manager_show (void)
{
SeahorseKeyManager *self;
- GcrUnionCollection *sources;
- GList *backends, *l;
-
- sources = GCR_UNION_COLLECTION (gcr_union_collection_new ());
-
- backends = seahorse_registry_object_instances (NULL, "backend", NULL);
- for (l = backends; l != NULL; l = g_list_next (l))
- gcr_union_collection_take (sources, GCR_COLLECTION (l->data));
- g_list_free (backends);
self = g_object_new (SEAHORSE_TYPE_KEY_MANAGER,
"name", "key-manager",
- "sources", sources,
NULL);
- g_object_unref (sources);
g_object_ref_sink (self);
return SEAHORSE_WIDGET (self);
diff --git a/src/seahorse-key-manager.xml b/src/seahorse-key-manager.xml
index 77285f8..c495028 100644
--- a/src/seahorse-key-manager.xml
+++ b/src/seahorse-key-manager.xml
@@ -61,116 +61,23 @@
</packing>
</child>
<child>
- <object class="GtkNotebook" id="notebook">
+ <object class="GtkScrolledWindow" id="key-list-scroll-area">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">3</property>
<child>
- <object class="GtkScrolledWindow" id="password-tab">
+ <object class="GtkTreeView" id="key-list">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="border_width">3</property>
- <child>
- <object class="GtkTreeView" id="password-list">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">12</property>
- <property name="rules_hint">True</property>
- <signal name="button-press-event" handler="on_keymanager_key_list_button_pressed" swapped="no"/>
- <signal name="row-activated" handler="on_keymanager_row_activated" swapped="no"/>
- <signal name="popup-menu" handler="on_keymanager_key_list_popup_menu" swapped="no"/>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label29">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xpad">3</property>
- <property name="label" translatable="yes">_Passwords</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="sec-key-tab">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">3</property>
- <child>
- <object class="GtkTreeView" id="sec-key-list">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">12</property>
- <property name="rules_hint">True</property>
- <signal name="button-press-event" handler="on_keymanager_key_list_button_pressed" swapped="no"/>
- <signal name="row-activated" handler="on_keymanager_row_activated" swapped="no"/>
- <signal name="popup-menu" handler="on_keymanager_key_list_popup_menu" swapped="no"/>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection1"/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label26">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xpad">3</property>
- <property name="label" translatable="yes">My _Personal Keys</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="pub-key-tab">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">3</property>
- <child>
- <object class="GtkTreeView" id="pub-key-list">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">12</property>
- <property name="rules_hint">True</property>
- <signal name="button-press-event" handler="on_keymanager_key_list_button_pressed" swapped="no"/>
- <signal name="row-activated" handler="on_keymanager_row_activated" swapped="no"/>
- <signal name="popup-menu" handler="on_keymanager_key_list_popup_menu" swapped="no"/>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection2"/>
- </child>
- </object>
+ <property name="border_width">12</property>
+ <property name="rules_hint">True</property>
+ <signal name="button-press-event" handler="on_keymanager_key_list_button_pressed" swapped="no"/>
+ <signal name="row-activated" handler="on_keymanager_row_activated" swapped="no"/>
+ <signal name="popup-menu" handler="on_keymanager_key_list_popup_menu" swapped="no"/>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection"/>
</child>
</object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label28">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xpad">3</property>
- <property name="label" translatable="yes">Other _Keys</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="position">2</property>
- <property name="tab_fill">False</property>
- </packing>
</child>
</object>
<packing>
diff --git a/src/seahorse-sidebar.c b/src/seahorse-sidebar.c
index f4e7960..19cddf0 100644
--- a/src/seahorse-sidebar.c
+++ b/src/seahorse-sidebar.c
@@ -39,11 +39,11 @@ struct _SeahorseSidebar {
GtkListStore *store;
GPtrArray *backends;
+ GHashTable *checked;
+ GcrUnionCollection *objects;
+ GcrCollection *selected;
guint update_places_sig;
-
- gint checks_checked;
- GtkTreePath *selected_path;
};
struct _SeahorseSidebarClass {
@@ -52,12 +52,13 @@ struct _SeahorseSidebarClass {
enum {
PROP_0,
+ PROP_COLLECTION
};
typedef enum {
- PLACES_HEADING,
- PLACES_COLLECTION,
-} PlaceType;
+ TYPE_BACKEND,
+ TYPE_PLACE,
+} RowType;
enum {
SIDEBAR_ROW_TYPE,
@@ -67,7 +68,6 @@ enum {
SIDEBAR_EDITABLE,
SIDEBAR_CATEGORY,
SIDEBAR_COLLECTION,
- SIDEBAR_CHECKED,
SIDEBAR_N_COLUMNS
};
@@ -79,7 +79,6 @@ static GType column_types[] = {
G_TYPE_BOOLEAN,
G_TYPE_STRING,
0 /* later */,
- G_TYPE_BOOLEAN,
};
G_DEFINE_TYPE (SeahorseSidebar, seahorse_sidebar, GTK_TYPE_SCROLLED_WINDOW);
@@ -93,7 +92,8 @@ seahorse_sidebar_init (SeahorseSidebar *self)
self->store = gtk_list_store_newv (SIDEBAR_N_COLUMNS, column_types);
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 ());
}
static void
@@ -176,7 +176,7 @@ update_backend (SeahorseSidebar *self,
next_or_append_row (self->store, iter, category, GCR_COLLECTION (backend));
gtk_list_store_set (self->store, iter,
- SIDEBAR_ROW_TYPE, PLACES_HEADING,
+ SIDEBAR_ROW_TYPE, TYPE_BACKEND,
SIDEBAR_CATEGORY, category,
SIDEBAR_LABEL, label,
SIDEBAR_TOOLTIP, tooltip,
@@ -201,7 +201,7 @@ update_backend (SeahorseSidebar *self,
next_or_append_row (self->store, iter, category, l->data);
gtk_list_store_set (self->store, iter,
- SIDEBAR_ROW_TYPE, PLACES_COLLECTION,
+ SIDEBAR_ROW_TYPE, TYPE_PLACE,
SIDEBAR_CATEGORY, category,
SIDEBAR_LABEL, label,
SIDEBAR_TOOLTIP, tooltip,
@@ -220,11 +220,80 @@ update_backend (SeahorseSidebar *self,
}
static void
+update_objects_for_selection (SeahorseSidebar *self,
+ GtkTreeSelection *selection)
+{
+ GcrCollection *selected = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (model, &iter,
+ SIDEBAR_COLLECTION, &selected,
+ -1);
+
+ if (selected != self->selected) {
+ if (self->selected && g_hash_table_size (self->checked) == 0)
+ gcr_union_collection_remove (self->objects, self->selected);
+
+ g_clear_object (&self->selected);
+ self->selected = selected ? g_object_ref (selected) : NULL;
+
+ if (self->selected && g_hash_table_size (self->checked) == 0)
+ gcr_union_collection_add (self->objects, self->selected);
+ }
+
+ g_clear_object (&selected);
+}
+
+static void
+update_objects_for_checked (SeahorseSidebar *self,
+ GcrCollection *place)
+{
+ g_hash_table_insert (self->checked, place, place);
+
+ /* The first check ... */
+ if (g_hash_table_size (self->checked) == 1) {
+
+ /* ... but the currently checked one was selected so leave same */
+ if (self->selected == place)
+ return;
+
+ /* ... something else was selected, so update */
+ else if (self->selected)
+ gcr_union_collection_remove (self->objects, self->selected);
+ }
+
+ gcr_union_collection_add (self->objects, place);
+}
+
+static void
+update_objects_for_unchecked (SeahorseSidebar *self,
+ GcrCollection *place)
+{
+ if (!g_hash_table_remove (self->checked, place))
+ g_assert_not_reached ();
+
+ /* No more checks ... */
+ if (g_hash_table_size (self->checked) == 0) {
+
+ /* ... but the currently unchecked one is selected so leave same ... */
+ if (self->selected == place)
+ return;
+
+ /* ... something else is selected, so update */
+ else if (self->selected)
+ gcr_union_collection_add (self->objects, self->selected);
+ }
+
+ gcr_union_collection_remove (self->objects, place);
+}
+
+static void
update_places (SeahorseSidebar *self)
{
GtkTreeSelection *selection;
GtkTreeIter iter;
- GtkTreeModel *model;
guint i;
/* A marker that tells us the iter is not yet valid */
@@ -235,11 +304,8 @@ update_places (SeahorseSidebar *self)
update_backend (self, GCR_COLLECTION (self->backends->pdata[i]), &iter);
/* Update selection */
- gtk_tree_path_free (self->selected_path);
- self->selected_path = NULL;
selection = gtk_tree_view_get_selection (self->tree_view);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- self->selected_path = gtk_tree_model_get_path (model, &iter);
+ update_objects_for_selection (self, selection);
}
static gboolean
@@ -267,12 +333,12 @@ on_cell_renderer_heading_visible (GtkTreeViewColumn *column,
GtkTreeIter *iter,
gpointer user_data)
{
- PlaceType type;
+ RowType type;
gtk_tree_model_get (model, iter,
SIDEBAR_ROW_TYPE, &type,
-1);
g_object_set (cell,
- "visible", (type == PLACES_HEADING),
+ "visible", (type == TYPE_BACKEND),
NULL);
}
@@ -283,12 +349,12 @@ on_padding_cell_renderer (GtkTreeViewColumn *column,
GtkTreeIter *iter,
gpointer user_data)
{
- PlaceType type;
+ RowType type;
gtk_tree_model_get (model, iter,
SIDEBAR_ROW_TYPE, &type,
-1);
- if (type == PLACES_HEADING) {
+ if (type == TYPE_BACKEND) {
g_object_set (cell,
"visible", FALSE,
"xpad", 0,
@@ -310,12 +376,12 @@ on_cell_renderer_heading_not_visible (GtkTreeViewColumn *column,
GtkTreeIter *iter,
gpointer user_data)
{
- PlaceType type;
+ RowType type;
gtk_tree_model_get (model, iter,
SIDEBAR_ROW_TYPE, &type,
-1);
g_object_set (cell,
- "visible", (type != PLACES_HEADING),
+ "visible", (type != TYPE_BACKEND),
NULL);
}
@@ -327,29 +393,27 @@ on_cell_renderer_check (GtkTreeViewColumn *column,
gpointer user_data)
{
SeahorseSidebar *self = SEAHORSE_SIDEBAR (user_data);
- PlaceType type;
+ GcrCollection *collection;
+ RowType type;
gboolean active;
gboolean inconsistent;
gboolean visible;
- GtkTreePath *only;
gtk_tree_model_get (model, iter,
SIDEBAR_ROW_TYPE, &type,
- SIDEBAR_CHECKED, &active,
+ SIDEBAR_COLLECTION, &collection,
-1);
+ active = FALSE;
inconsistent = FALSE;
- if (type == PLACES_HEADING) {
+ if (type == TYPE_BACKEND) {
visible = FALSE;
- } else if (self->checks_checked > 0) {
+ } else if (collection != NULL && g_hash_table_size (self->checked) > 0) {
+ active = g_hash_table_lookup (self->checked, collection) != NULL;
visible = TRUE;
- } else if (self->selected_path != NULL) {
- only = gtk_tree_model_get_path (model, iter);
- visible = gtk_tree_path_compare (only, self->selected_path) == 0;
- gtk_tree_path_free (only);
} else {
- visible = FALSE;
+ visible = (collection == self->selected);
}
/* self->mnemonics_visible */
@@ -358,6 +422,8 @@ on_cell_renderer_check (GtkTreeViewColumn *column,
"active", active,
"inconsistent", inconsistent,
NULL);
+
+ g_clear_object (&collection);
}
static void
@@ -383,13 +449,13 @@ on_tree_selection_validate (GtkTreeSelection *selection,
gpointer user_data)
{
GtkTreeIter iter;
- PlaceType row_type;
+ RowType row_type;
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter,
SIDEBAR_ROW_TYPE, &row_type,
-1);
- if (row_type == PLACES_HEADING)
+ if (row_type == TYPE_BACKEND)
return FALSE;
return TRUE;
@@ -400,16 +466,8 @@ on_tree_selection_changed (GtkTreeSelection *selection,
gpointer user_data)
{
SeahorseSidebar *self = SEAHORSE_SIDEBAR (user_data);
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- gtk_tree_path_free (self->selected_path);
- self->selected_path = NULL;
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- self->selected_path = gtk_tree_model_get_path (model, &iter);
-
- invalidate_all_rows (model);
+ update_objects_for_selection (self, selection);
+ invalidate_all_rows (GTK_TREE_MODEL (self->store));
}
static void
@@ -508,31 +566,43 @@ load_backends (SeahorseSidebar *self)
static void
on_checked_toggled (GtkCellRendererToggle *renderer,
- gchar *path,
+ gchar *path_string,
gpointer user_data)
{
SeahorseSidebar *self = SEAHORSE_SIDEBAR (user_data);
+ GcrCollection *collection;
+ GtkTreeModel *model;
GtkTreeIter iter;
+ GtkTreePath *path;
gboolean checked;
+ gboolean have;
- if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (self->store), &iter, path))
- g_return_if_reached ();
+ model = GTK_TREE_MODEL (self->store);
+ path = gtk_tree_path_new_from_string (path_string);
+ gtk_tree_model_get_iter (model, &iter, path);
checked = !gtk_cell_renderer_toggle_get_active (renderer);
- gtk_list_store_set (self->store, &iter,
- SIDEBAR_CHECKED, checked,
+ gtk_tree_model_get (model, &iter,
+ SIDEBAR_COLLECTION, &collection,
-1);
+ have = g_hash_table_lookup (self->checked, collection) != NULL;
- if (checked) {
- self->checks_checked++;
- if (self->checks_checked == 1)
- invalidate_all_rows (GTK_TREE_MODEL (self->store));
- } else {
- g_assert (self->checks_checked > 0);
- self->checks_checked--;
- if (self->checks_checked == 0)
- invalidate_all_rows (GTK_TREE_MODEL (self->store));
+ if (checked && !have) {
+ update_objects_for_checked (self, collection);
+ if (g_hash_table_size (self->checked) == 1)
+ invalidate_all_rows (model);
+ else
+ gtk_tree_model_row_changed (model, path, &iter);
+ } else if (!checked && have) {
+ update_objects_for_unchecked (self, collection);
+ if (g_hash_table_size (self->checked) == 0)
+ invalidate_all_rows (model);
+ else
+ gtk_tree_model_row_changed (model, path, &iter);
}
+
+ g_object_unref (collection);
+ gtk_tree_path_free (path);
}
static void
@@ -649,8 +719,6 @@ seahorse_sidebar_constructed (GObject *obj)
load_backends (self);
}
-#if 0
-
static void
seahorse_sidebar_get_property (GObject *obj,
guint prop_id,
@@ -660,8 +728,8 @@ seahorse_sidebar_get_property (GObject *obj,
SeahorseSidebar *self = SEAHORSE_SIDEBAR (obj);
switch (prop_id) {
- case PROP_PLACES:
- g_value_set_object (value, self->places);
+ case PROP_COLLECTION:
+ g_value_set_object (value, seahorse_sidebar_get_collection (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -670,26 +738,6 @@ seahorse_sidebar_get_property (GObject *obj,
}
static void
-seahorse_sidebar_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- SeahorseSidebar *self = SEAHORSE_SIDEBAR (obj);
-
- switch (prop_id) {
- case PROP_PLACES:
- self->places = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-#endif
-
-static void
seahorse_sidebar_dispose (GObject *obj)
{
SeahorseSidebar *self = SEAHORSE_SIDEBAR (obj);
@@ -715,7 +763,9 @@ seahorse_sidebar_finalize (GObject *obj)
{
SeahorseSidebar *self = SEAHORSE_SIDEBAR (obj);
- gtk_tree_path_free (self->selected_path);
+ g_clear_object (&self->selected);
+ g_hash_table_destroy (self->checked);
+ g_object_unref (self->objects);
if (self->update_places_sig)
g_source_remove (self->update_places_sig);
@@ -734,14 +784,11 @@ seahorse_sidebar_class_init (SeahorseSidebarClass *klass)
gobject_class->constructed = seahorse_sidebar_constructed;
gobject_class->dispose = seahorse_sidebar_dispose;
gobject_class->finalize = seahorse_sidebar_finalize;
-#if 0
- gobject_class->set_property = seahorse_sidebar_set_property;
gobject_class->get_property = seahorse_sidebar_get_property;
- g_object_class_install_property (gobject_class, PROP_PLACES,
- g_param_spec_object ("places", "Places", "Places for Items",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-#endif
+ g_object_class_install_property (gobject_class, PROP_COLLECTION,
+ g_param_spec_object ("collection", "Collection", "Collection of objects sidebar represents",
+ GCR_TYPE_COLLECTION, G_PARAM_READABLE));
}
SeahorseSidebar *
@@ -750,3 +797,10 @@ seahorse_sidebar_new (void)
return g_object_new (SEAHORSE_TYPE_SIDEBAR,
NULL);
}
+
+GcrCollection *
+seahorse_sidebar_get_collection (SeahorseSidebar *self)
+{
+ g_return_val_if_fail (SEAHORSE_IS_SIDEBAR (self), NULL);
+ return GCR_COLLECTION (self->objects);
+}
diff --git a/src/seahorse-sidebar.h b/src/seahorse-sidebar.h
index e167e30..1bf994e 100644
--- a/src/seahorse-sidebar.h
+++ b/src/seahorse-sidebar.h
@@ -40,4 +40,6 @@ GType seahorse_sidebar_get_type (void);
SeahorseSidebar * seahorse_sidebar_new (void);
+GcrCollection * seahorse_sidebar_get_collection (SeahorseSidebar *self);
+
#endif /* __SEAHORSE_SIDEBAR_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]