[evolution-patches] [PATCH] Name selector limits (again)



I'm seeking approval for HEAD for this patch, which was not considered
before 2.2 on the grounds that it breaks ABI compatibility. 

I also suggest we (I) change the objects to use a separate private
struct so it'll be easier to change things without ABI breakage in the
future. I can send a separate patch for that.

I'll write a changelog entry if this is approved.

-- 
Hans Petter Jansson | <hpj novell com>
Evolution Developer | http://hp.cl.no/
? libedataserverui/cachegrind.out.31380
? libedataserverui/cachegrind.out.31397
? libedataserverui/cachegrind.out.31411
? libedataserverui/e-name-selector-dialog.gladep
? libedataserverui/log.diff
? libedataserverui/new
? libedataserverui/old
? libedataserverui/out.diff
? libedataserverui/test-camel-address
? libedataserverui/test-camel-address.c
? libedataserverui/test-contact-store
? libedataserverui/test-name-selector
Index: libedataserverui/e-destination-store.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-destination-store.c,v
retrieving revision 1.4
diff -u -p -r1.4 e-destination-store.c
--- libedataserverui/e-destination-store.c	3 Feb 2005 16:35:02 -0000	1.4
+++ libedataserverui/e-destination-store.c	25 Feb 2005 03:12:23 -0000
@@ -153,6 +153,7 @@ e_destination_store_tree_model_init (Gtk
 static void
 e_destination_store_init (EDestinationStore *destination_store)
 {
+	destination_store->accept_many  = TRUE;
 	destination_store->stamp        = g_random_int ();
 	destination_store->destinations = g_ptr_array_new ();
 }
@@ -276,6 +277,38 @@ destination_changed (EDestinationStore *
  * EDestinationStore API *
  * --------------------- */
 
+gboolean
+e_destination_store_get_accept_many (EDestinationStore *destination_store)
+{
+	g_return_val_if_fail (E_IS_DESTINATION_STORE (destination_store), FALSE);
+
+	return destination_store->accept_many ? TRUE : FALSE;
+}
+
+void
+e_destination_store_set_accept_many (EDestinationStore *destination_store, gboolean accept_many)
+{
+	g_return_if_fail (E_IS_DESTINATION_STORE (destination_store));
+
+	if (destination_store->accept_many && !accept_many) {
+		GList *destinations;
+		GList *l;
+
+		destinations = e_destination_store_list_destinations (destination_store);
+
+		/* Leave the first destination alone */
+		for (l = destinations; l && (l = g_list_next (l)); ) {
+			EDestination *destination = l->data;
+
+			e_destination_store_remove_destination (destination_store, destination);
+		}
+
+		g_list_free (destinations);
+	}
+
+	destination_store->accept_many = accept_many;
+}
+
 EDestination *
 e_destination_store_get_destination (EDestinationStore *destination_store, GtkTreeIter *iter)
 {
@@ -289,6 +322,14 @@ e_destination_store_get_destination (EDe
 	return g_ptr_array_index (destination_store->destinations, index);
 }
 
+gint
+e_destination_store_get_n_destinations (EDestinationStore *destination_store)
+{
+	g_return_val_if_fail (E_IS_DESTINATION_STORE (destination_store), -1);
+
+	return destination_store->destinations->len;
+}
+
 GList *
 e_destination_store_list_destinations (EDestinationStore *destination_store)
 {
@@ -339,6 +380,11 @@ void
 e_destination_store_append_destination (EDestinationStore *destination_store, EDestination *destination)
 {
 	g_return_if_fail (E_IS_DESTINATION_STORE (destination_store));
+
+	if (destination_store->destinations->len > 0 && !destination_store->accept_many) {
+		g_warning ("Tried to add multiple destinations to single-destination EDestinationStore!");
+		return;
+	}
 
 	if (find_destination_by_pointer (destination_store, destination) >= 0) {
 		g_warning ("Same destination added more than once to EDestinationStore!");
Index: libedataserverui/e-destination-store.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-destination-store.h,v
retrieving revision 1.2
diff -u -p -r1.2 e-destination-store.h
--- libedataserverui/e-destination-store.h	20 Dec 2004 11:21:01 -0000	1.2
+++ libedataserverui/e-destination-store.h	25 Feb 2005 03:12:23 -0000
@@ -43,6 +43,8 @@ struct EDestinationStore {
 
 	/* Private */
 
+	guint       accept_many : 1;
+
 	gint        stamp;
 	GPtrArray  *destinations;
 };
@@ -63,6 +65,12 @@ EDestinationStoreColumnType;
 
 GtkType            e_destination_store_get_type           (void);
 EDestinationStore *e_destination_store_new                (void);
+
+gboolean           e_destination_store_get_accept_many    (EDestinationStore *destination_store);
+void               e_destination_store_set_accept_many    (EDestinationStore *destination_store,
+							   gboolean accept_many);
+
+gint               e_destination_store_get_n_destinations (EDestinationStore *destination_store);
 
 EDestination      *e_destination_store_get_destination    (EDestinationStore *destination_store,
 							   GtkTreeIter *iter);
Index: libedataserverui/e-name-selector-dialog.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector-dialog.c,v
retrieving revision 1.11
diff -u -p -r1.11 e-name-selector-dialog.c
--- libedataserverui/e-name-selector-dialog.c	23 Feb 2005 18:52:12 -0000	1.11
+++ libedataserverui/e-name-selector-dialog.c	25 Feb 2005 03:12:24 -0000
@@ -585,8 +585,23 @@ contact_selection_changed (ENameSelector
 	have_selection = gtk_tree_selection_get_selected (contact_selection, NULL, NULL);
 
 	for (i = 0; i < name_selector_dialog->sections->len; i++) {
-		Section *section = &g_array_index (name_selector_dialog->sections, Section, i);
-		gtk_widget_set_sensitive (GTK_WIDGET (section->transfer_button), have_selection);
+		Section           *section = &g_array_index (name_selector_dialog->sections, Section, i);
+		EDestinationStore *destination_store;
+		gboolean           allow_add;
+
+		if (!e_name_selector_model_peek_section (name_selector_dialog->name_selector_model,
+							 section->name, NULL, &destination_store)) {
+			g_warning ("ENameSelectorDialog has a section unknown to the model!");
+			continue;
+		}
+
+		if (e_destination_store_get_accept_many (destination_store) ||
+		    e_destination_store_get_n_destinations (destination_store) == 0)
+			allow_add = have_selection;
+		else
+			allow_add = FALSE;
+
+		gtk_widget_set_sensitive (GTK_WIDGET (section->transfer_button), allow_add);
 	}
 }
 
@@ -599,6 +614,7 @@ contact_activated (ENameSelectorDialog *
 	GtkTreeIter        iter;
 	Section           *section;
 	gint               email_n;
+	gint               i;
 
 	/* When a contact is activated, we transfer it to the first destination on our list */
 
@@ -623,10 +639,23 @@ contact_activated (ENameSelectorDialog *
 		return;
 	}
 
-	section = &g_array_index (name_selector_dialog->sections, Section, 0);
-	if (!e_name_selector_model_peek_section (name_selector_dialog->name_selector_model,
-						 section->name, NULL, &destination_store)) {
-		g_warning ("ENameSelectorDialog has a section unknown to the model!");
+	/* Find the first destination store that can accept a contact */
+
+	for (i = 0; i < name_selector_dialog->sections->len; i++) {
+		section = &g_array_index (name_selector_dialog->sections, Section, i);
+		if (!e_name_selector_model_peek_section (name_selector_dialog->name_selector_model,
+							 section->name, NULL, &destination_store)) {
+			g_warning ("ENameSelectorDialog has a section unknown to the model!");
+			continue;
+		}
+
+		if (e_destination_store_get_accept_many (destination_store) ||
+		    e_destination_store_get_n_destinations (destination_store) == 0)
+			break;
+	}
+
+	if (i >= name_selector_dialog->sections->len) {
+		/* No suitable destination store */
 		return;
 	}
 
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	25 Feb 2005 03:12:24 -0000
@@ -980,6 +980,9 @@ insert_unichar (ENameSelectorEntry *name
 		gboolean     at_start = FALSE;
 		gboolean     at_end   = FALSE;
 
+		if (!e_destination_store_get_accept_many (name_selector_entry->destination_store))
+			return 0;
+
 		if (str_context [1] == ',' || str_context [1] == '\0')
 			return 0;
 
Index: libedataserverui/e-name-selector-model.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector-model.c,v
retrieving revision 1.5
diff -u -p -r1.5 e-name-selector-model.c
--- libedataserverui/e-name-selector-model.c	3 Feb 2005 16:35:02 -0000	1.5
+++ libedataserverui/e-name-selector-model.c	25 Feb 2005 03:12:24 -0000
@@ -63,6 +63,7 @@ G_DEFINE_TYPE (ENameSelectorModel, e_nam
 static void
 e_name_selector_model_init (ENameSelectorModel *name_selector_model)
 {
+	name_selector_model->accept_many    = TRUE;
 	name_selector_model->sections       = g_array_new (FALSE, FALSE, sizeof (Section));
 	name_selector_model->contact_store  = e_contact_store_new ();
 
@@ -335,6 +336,23 @@ find_section_by_name (ENameSelectorModel
  * ENameSelectorModel API *
  * ---------------------- */
 
+void
+e_name_selector_model_set_accept_many (ENameSelectorModel *name_selector_model,
+				       gboolean accept_many)
+{
+	gint i;
+
+	g_return_if_fail (E_IS_NAME_SELECTOR_MODEL (name_selector_model));
+
+	name_selector_model->accept_many = accept_many;
+
+	for (i = 0; i < name_selector_model->sections->len; i++) {
+		Section *section = &g_array_index (name_selector_model->sections, Section, i);
+
+		e_destination_store_set_accept_many (section->destination_store, accept_many);
+	}
+}
+
 EContactStore *
 e_name_selector_model_peek_contact_store (ENameSelectorModel *name_selector_model)
 {
@@ -396,6 +414,9 @@ e_name_selector_model_add_section (EName
 		section.destination_store = g_object_ref (destination_store);
 	else
 		section.destination_store = e_destination_store_new ();
+
+	e_destination_store_set_accept_many (section.destination_store,
+					     name_selector_model->accept_many);
 
 	g_signal_connect_swapped (section.destination_store, "row-changed",
 				  G_CALLBACK (destinations_changed), name_selector_model);
Index: libedataserverui/e-name-selector-model.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector-model.h,v
retrieving revision 1.3
diff -u -p -r1.3 e-name-selector-model.h
--- libedataserverui/e-name-selector-model.h	22 Jan 2005 09:59:42 -0000	1.3
+++ libedataserverui/e-name-selector-model.h	25 Feb 2005 03:12:24 -0000
@@ -44,6 +44,8 @@ struct ENameSelectorModel {
 
 	/* Private */
 
+	guint                accept_many : 1;
+
 	GArray              *sections;
 	EContactStore       *contact_store;
 	ETreeModelGenerator *contact_filter;
@@ -61,6 +63,9 @@ struct ENameSelectorModelClass {
 
 GType                e_name_selector_model_get_type            (void);
 ENameSelectorModel  *e_name_selector_model_new                 (void);
+
+void                 e_name_selector_model_set_accept_many     (ENameSelectorModel *name_selector_model,
+								gboolean accept_many);
 
 EContactStore       *e_name_selector_model_peek_contact_store  (ENameSelectorModel *name_selector_model);
 ETreeModelGenerator *e_name_selector_model_peek_contact_filter (ENameSelectorModel *name_selector_model);
Index: libedataserverui/test-name-selector.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/test-name-selector.c,v
retrieving revision 1.5
diff -u -p -r1.5 test-name-selector.c
--- libedataserverui/test-name-selector.c	20 Dec 2004 15:31:29 -0000	1.5
+++ libedataserverui/test-name-selector.c	25 Feb 2005 03:12:24 -0000
@@ -54,6 +54,7 @@ start_test (void)
 	destination_store = e_destination_store_new ();
 	name_selector_model = e_name_selector_model_new ();
 
+	e_name_selector_model_set_accept_many (name_selector_model, FALSE);
 	e_name_selector_model_add_section (name_selector_model, "to", "To", destination_store);
 	e_name_selector_model_add_section (name_selector_model, "cc", "Cc", NULL);
 	e_name_selector_model_add_section (name_selector_model, "bcc", "Bcc", NULL);


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