[evolution-patches] [PATCH] Fewer auth prompts with ENameSelector



Makes the ENameSelector prompt for auth once per book, instead of once
per book per entry.

This is intended for gnome-2-10 and HEAD.

-- 
Hans Petter Jansson | <hpj novell com>
Evolution Developer | http://hp.cl.no/
Index: libedataserverui/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/ChangeLog,v
retrieving revision 1.36
diff -u -p -r1.36 ChangeLog
--- libedataserverui/ChangeLog	23 Mar 2005 11:16:08 -0000	1.36
+++ libedataserverui/ChangeLog	1 Apr 2005 02:51:22 -0000
@@ -1,3 +1,25 @@
+2005-03-31  Hans Petter Jansson  <hpj novell com>
+
+	* e-name-selector.c (source_books_destroy): Implement.
+	(e_name_selector_init): Create a list of completion books, and open
+	them with interactive authentication.
+	(e_name_selector_peek_section_entry): Re-use the list of opened books
+	for each entry.
+
+	* e-name-selector-entry.c (e_name_selector_entry_realize): If the user
+	didn't set a contact store, create the default one here.
+	(e_name_selector_entry_class_init): Set up our realize method.
+	(e_name_selector_entry_init): Don't set up the default contact store
+	here.
+	(setup_default_contact_store): Also create the contact store itself.
+	(set_completion_query)
+	(find_existing_completion)
+	(completion_match_selected)
+	(contact_layout_formatter)
+	(popup_activate_contact)
+	(setup_contact_store)
+	(e_name_selector_entry_set_contact_store): Tolerate NULL contact store.
+
 2005-03-23  Rodrigo Moya <rodrigo novell com>
 
 	Fixes #73472
Index: libedataserverui/e-name-selector.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector.c,v
retrieving revision 1.4
diff -u -p -r1.4 e-name-selector.c
--- libedataserverui/e-name-selector.c	3 Feb 2005 16:35:02 -0000	1.4
+++ libedataserverui/e-name-selector.c	1 Apr 2005 02:51:22 -0000
@@ -35,14 +35,23 @@
 #include <libebook/e-contact.h>
 #include <libedataserverui/e-contact-store.h>
 #include <libedataserverui/e-destination-store.h>
+#include <libedataserverui/e-book-auth-util.h>
 #include "e-name-selector.h"
 
+#define PRIVATE_SOURCE_BOOKS_KEY "private-source-books"
+
 typedef struct {
 	gchar              *name;
 	ENameSelectorEntry *entry;
 }
 Section;
 
+typedef struct {
+	EBook *book;
+	guint  is_completion_book : 1;
+}
+SourceBook;
+
 static void  e_name_selector_init       (ENameSelector		 *name_selector);
 static void  e_name_selector_class_init (ENameSelectorClass	 *name_selector_class);
 static void  e_name_selector_finalize   (GObject                 *object);
@@ -54,6 +63,20 @@ static void  e_name_selector_finalize   
 G_DEFINE_TYPE (ENameSelector, e_name_selector, G_TYPE_OBJECT);
 
 static void
+source_books_destroy (GArray *source_books)
+{
+	gint i;
+
+	for (i = 0; i < source_books->len; i++) {
+		SourceBook *source_book = &g_array_index (source_books, SourceBook, i);
+
+		g_object_unref (source_book->book);
+	}
+
+	g_array_free (source_books, TRUE);
+}
+
+static void
 e_name_selector_class_init (ENameSelectorClass *name_selector_class)
 {
 	GObjectClass *object_class;
@@ -66,8 +89,57 @@ e_name_selector_class_init (ENameSelecto
 static void
 e_name_selector_init (ENameSelector *name_selector)
 {
+	ESourceList *source_list;
+	GArray      *source_books;
+	GSList      *groups;
+	GSList      *l;
+
 	name_selector->sections = g_array_new (FALSE, FALSE, sizeof (Section));
 	name_selector->model = e_name_selector_model_new ();
+
+	/* Make a list of books */
+
+	source_books = g_array_new (FALSE, FALSE, sizeof (SourceBook));
+
+	/* This should be a private field, but we use g_object_set_data() to maintain
+	 * ABI compatibility in the GNOME 2.10 branch */
+	g_object_set_data_full (G_OBJECT (name_selector), PRIVATE_SOURCE_BOOKS_KEY, source_books,
+				(GDestroyNotify) source_books_destroy);
+
+	if (!e_book_get_addressbooks (&source_list, NULL)) {
+		g_warning ("ENameSelector can't find any addressbooks!");
+		return;
+	}
+
+	groups = e_source_list_peek_groups (source_list);
+
+	for (l = groups; l; l = g_slist_next (l)) {
+		ESourceGroup *group   = l->data;
+		GSList       *sources = e_source_group_peek_sources (group);
+		GSList       *m;
+
+		for (m = sources; m; m = g_slist_next (m)) {
+			ESource      *source = m->data;
+			const gchar  *completion;
+			SourceBook    source_book;
+
+			/* We're only loading completion books for now, as we don't want
+			 * unnecessary auth prompts */
+			completion = e_source_get_property (source, "completion");
+			if (!completion || g_ascii_strcasecmp (completion, "true"))
+				continue;
+
+			source_book.book = e_load_book_source (source, NULL, NULL);
+			if (!source_book.book)
+				continue;
+
+			source_book.is_completion_book = TRUE;
+
+			g_array_append_val (source_books, source_book);
+		}
+	}
+
+	g_object_unref (source_list);
 }
 
 static void
@@ -183,14 +255,33 @@ e_name_selector_peek_section_entry (ENam
 	section = &g_array_index (name_selector->sections, Section, n);
 
 	if (!section->entry) {
-		gchar *text;
+		GArray        *source_books;
+		EContactStore *contact_store;
+		gchar         *text;
+		gint           i;
+
 		section->entry = e_name_selector_entry_new ();
 		if (pango_parse_markup (name, -1, '_', NULL,
-				&text, NULL, NULL))  {
+					&text, NULL, NULL))  {
 			atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (section->entry)), text);
 			g_free (text);
 		}
 		e_name_selector_entry_set_destination_store (section->entry, destination_store);
+
+		/* Create a contact store for the entry and assign our already-open books to it */
+
+		contact_store = e_contact_store_new ();
+		source_books = g_object_get_data (G_OBJECT (name_selector), PRIVATE_SOURCE_BOOKS_KEY);
+
+		for (i = 0; i < source_books->len; i++) {
+			SourceBook *source_book = &g_array_index (source_books, SourceBook, i);
+
+			if (source_book->is_completion_book)
+				e_contact_store_add_book (contact_store, source_book->book);
+		}
+
+		e_name_selector_entry_set_contact_store (section->entry, contact_store);
+		g_object_unref (contact_store);
 	}
 
 	return section->entry;
Index: libedataserverui/e-name-selector-entry.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector-entry.c,v
retrieving revision 1.15
diff -u -p -r1.15 e-name-selector-entry.c
--- libedataserverui/e-name-selector-entry.c	23 Feb 2005 18:52:12 -0000	1.15
+++ libedataserverui/e-name-selector-entry.c	1 Apr 2005 02:51:22 -0000
@@ -56,6 +56,8 @@ static void destination_row_deleted  (EN
 static void user_insert_text (ENameSelectorEntry *name_selector_entry, gchar *new_text, gint new_text_length, gint *position, gpointer user_data);
 static void user_delete_text (ENameSelectorEntry *name_selector_entry, gint start_pos, gint end_pos, gpointer user_data);
 
+static void setup_default_contact_store (ENameSelectorEntry *name_selector_entry);
+
 static void
 e_name_selector_entry_get_property (GObject *object, guint prop_id,
 				    GValue *value, GParamSpec *pspec)
@@ -68,6 +70,18 @@ e_name_selector_entry_set_property (GObj
 {
 }
 
+static void
+e_name_selector_entry_realize (GtkWidget *widget)
+{
+	ENameSelectorEntry *name_selector_entry = E_NAME_SELECTOR_ENTRY (widget);
+
+	GTK_WIDGET_CLASS (e_name_selector_entry_parent_class)->realize (widget);
+
+	if (!name_selector_entry->contact_store) {
+		setup_default_contact_store (name_selector_entry);
+	}
+}
+
 /* Partial, repeatable destruction. Release references. */
 static void
 e_name_selector_entry_dispose (GObject *object)
@@ -91,13 +105,16 @@ e_name_selector_entry_finalize (GObject 
 static void
 e_name_selector_entry_class_init (ENameSelectorEntryClass *name_selector_entry_class)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (name_selector_entry_class);
+	GObjectClass   *object_class = G_OBJECT_CLASS (name_selector_entry_class);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (name_selector_entry_class);
 
 	object_class->get_property = e_name_selector_entry_get_property;
 	object_class->set_property = e_name_selector_entry_set_property;
 	object_class->dispose      = e_name_selector_entry_dispose;
 	object_class->finalize     = e_name_selector_entry_finalize;
 
+	widget_class->realize      = e_name_selector_entry_realize;
+
 	/* Install properties */
 
 	/* Install signals */
@@ -417,6 +434,9 @@ set_completion_query (ENameSelectorEntry
 	gchar      *full_name_query_str;
 	gchar      *file_as_query_str;
 
+	if (!name_selector_entry->contact_store)
+		return;
+
 	if (!cue_str) {
 		/* Clear the store */
 		e_contact_store_set_query (name_selector_entry->contact_store, NULL);
@@ -601,6 +621,10 @@ find_existing_completion (ENameSelectorE
 	gint           cue_len;
 
 	g_assert (cue_str);
+
+	if (!name_selector_entry->contact_store)
+		return FALSE;
+
 	cue_len = strlen (cue_str);
 
 	ENS_DEBUG (g_print ("Completing '%s'\n", cue_str));
@@ -773,6 +797,9 @@ type_ahead_complete (ENameSelectorEntry 
 static void
 clear_completion_model (ENameSelectorEntry *name_selector_entry)
 {
+	if (!name_selector_entry->contact_store)
+		return;
+
 	e_contact_store_set_query (name_selector_entry->contact_store, NULL);
 }
 
@@ -1179,6 +1206,9 @@ completion_match_selected (ENameSelector
 	GtkTreeIter    contact_iter;
 	gint           email_n;
 
+	if (!name_selector_entry->contact_store)
+		return FALSE;
+
 	gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
 							  &generator_iter, iter);
 	e_tree_model_generator_convert_iter_to_child_iter (name_selector_entry->email_generator,
@@ -1254,6 +1284,9 @@ contact_layout_formatter (GtkCellLayout 
 	gchar         *email_str;
 	gint           email_n;
 
+	if (!name_selector_entry->contact_store)
+		return;
+
 	gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
 							  &generator_iter, iter);
 	e_tree_model_generator_convert_iter_to_child_iter (name_selector_entry->email_generator,
@@ -1309,19 +1342,28 @@ generate_contact_rows (EContactStore *co
 static void
 setup_contact_store (ENameSelectorEntry *name_selector_entry)
 {
-	if (name_selector_entry->email_generator)
+	if (name_selector_entry->email_generator) {
 		g_object_unref (name_selector_entry->email_generator);
-	name_selector_entry->email_generator =
-		e_tree_model_generator_new (GTK_TREE_MODEL (name_selector_entry->contact_store));
+		name_selector_entry->email_generator = NULL;
+	}
 
-	e_tree_model_generator_set_generate_func (name_selector_entry->email_generator,
-						  (ETreeModelGeneratorGenerateFunc) generate_contact_rows,
-						  name_selector_entry, NULL);
+	if (name_selector_entry->contact_store) {
+		name_selector_entry->email_generator =
+			e_tree_model_generator_new (GTK_TREE_MODEL (name_selector_entry->contact_store));
 
-	/* Assign the store to the entry completion */
+		e_tree_model_generator_set_generate_func (name_selector_entry->email_generator,
+							  (ETreeModelGeneratorGenerateFunc) generate_contact_rows,
+							  name_selector_entry, NULL);
 
-	gtk_entry_completion_set_model (name_selector_entry->entry_completion,
-					GTK_TREE_MODEL (name_selector_entry->email_generator));
+		/* Assign the store to the entry completion */
+
+		gtk_entry_completion_set_model (name_selector_entry->entry_completion,
+						GTK_TREE_MODEL (name_selector_entry->email_generator));
+	} else {
+		/* Remove the store from the entry completion */
+
+		gtk_entry_completion_set_model (name_selector_entry->entry_completion, NULL);
+	}
 }
 
 static void
@@ -1330,8 +1372,11 @@ setup_default_contact_store (ENameSelect
 	GSList *groups;
 	GSList *l;
 
+	g_return_if_fail (name_selector_entry->contact_store == NULL);
+
 	/* Create a book for each completion source, and assign them to the contact store */
 
+	name_selector_entry->contact_store = e_contact_store_new ();
 	groups = e_source_list_peek_groups (name_selector_entry->source_list);
 
 	for (l = groups; l; l = g_slist_next (l)) {
@@ -1639,10 +1684,14 @@ popup_activate_contact (ENameSelectorEnt
 	if (!contact_uid)
 		return;
 
-	books = e_contact_store_get_books (name_selector_entry->contact_store);
-	book = find_book_by_contact (books, contact_uid);
-	g_list_free (books);
-	g_free (contact_uid);
+	if (name_selector_entry->contact_store) {
+		books = e_contact_store_get_books (name_selector_entry->contact_store);
+		book = find_book_by_contact (books, contact_uid);
+		g_list_free (books);
+		g_free (contact_uid);
+	} else {
+		book = NULL;
+	}
 
 	if (!book)
 		return;
@@ -1805,11 +1854,6 @@ e_name_selector_entry_init (ENameSelecto
 				      (GtkCellLayoutDataFunc) contact_layout_formatter,
 				      name_selector_entry, NULL);
 
-  /* Completion store */
-
-  name_selector_entry->contact_store = e_contact_store_new ();
-  setup_default_contact_store (name_selector_entry);
-
   /* Destination store */
 
   name_selector_entry->destination_store = e_destination_store_new ();
@@ -1835,13 +1879,16 @@ e_name_selector_entry_set_contact_store 
 					 EContactStore *contact_store)
 {
 	g_return_if_fail (E_IS_NAME_SELECTOR_ENTRY (name_selector_entry));
-	g_return_if_fail (E_IS_CONTACT_STORE (contact_store));
+	g_return_if_fail (contact_store == NULL || E_IS_CONTACT_STORE (contact_store));
 
 	if (contact_store == name_selector_entry->contact_store)
 		return;
 
-	g_object_unref (name_selector_entry->contact_store);
-	name_selector_entry->contact_store = g_object_ref (contact_store);
+	if (name_selector_entry->contact_store)
+		g_object_unref (name_selector_entry->contact_store);
+	name_selector_entry->contact_store = contact_store;
+	if (name_selector_entry->contact_store)
+		g_object_ref (name_selector_entry->contact_store);
 
 	setup_contact_store (name_selector_entry);
 }


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