Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/plugins/exchange-operations/ChangeLog,v
retrieving revision 1.51
diff -u -p -r1.51 ChangeLog
--- ChangeLog	29 Aug 2005 12:25:13 -0000	1.51
+++ ChangeLog	9 Sep 2005 07:03:19 -0000
@@ -1,3 +1,13 @@
+2005-09-09  Shakti Sen <shprasad@novell.com>
+
+	* exchange-permissions-dialog.c (list_view_selection_changed),
+	(remove_clicked), (role_changed), (display_role), (get_widgets):
+	Added support for multiple selection. Now the user could set the
+	permission for a group of accounts rather than one at a time. Also the
+	user can remove a group of accounts rather than one at a time.
+
+	Fixes bug #247080.
+
 2005-08-29  Praveen Kumar  <kpraveen@novell.com>
 
 	** Fixes bug 314762
Index: exchange-permissions-dialog.c
===================================================================
RCS file: /cvs/gnome/evolution/plugins/exchange-operations/exchange-permissions-dialog.c,v
retrieving revision 1.9
diff -u -p -r1.9 exchange-permissions-dialog.c
--- exchange-permissions-dialog.c	24 Aug 2005 10:10:10 -0000	1.9
+++ exchange-permissions-dialog.c	9 Sep 2005 07:03:19 -0000
@@ -327,29 +327,53 @@ list_view_selection_changed (GtkTreeSele
 {
 	ExchangePermissionsDialog *dialog = user_data;
 	GtkTreeModel *model;
-	GtkTreeIter iter;
 	E2kSid *sid;
+	GtkTreePath *path = NULL;
+	GList *selected_list = NULL;
+	GSList *row_ref_list = NULL;
+	GSList *rl = NULL;
+	GList *l = NULL;
 
-	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
-		return;
-	gtk_tree_model_get (model, &iter,
-			    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
-			    -1);
+	selected_list = gtk_tree_selection_get_selected_rows (dialog->priv->list_selection, &model);
+	for (l = selected_list; l; l = g_list_next (l)) {
+		GtkTreeRowReference* row_ref = NULL;
+		path = (GtkTreePath *) l->data;
+		row_ref = gtk_tree_row_reference_new (model, path);
+		row_ref_list = g_slist_prepend (row_ref_list, row_ref);
+	}
 
-	dialog->priv->selected_sid = sid;
-	dialog->priv->selected_perms =
-		e2k_security_descriptor_get_permissions (dialog->priv->sd, sid);
-	dialog->priv->selected_role =
-		e2k_permissions_role_find (dialog->priv->selected_perms);
+	row_ref_list = g_slist_reverse (row_ref_list);
+	
+	for (rl = row_ref_list; rl; rl = rl->next) {
+		GtkTreeIter iter;
+		path = gtk_tree_row_reference_get_path (rl->data);
+
+		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store), &iter, path)) {
+			gtk_tree_model_get (model, &iter,
+					    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
+					    -1);
 
-	/* "Default" or "Anonymous" can't be a Folder contact, but any
-	 * real person can.
-	 */
-	gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->folder_contact_check),
-				  e2k_sid_get_sid_type (sid) != E2K_SID_TYPE_WELL_KNOWN_GROUP);
+			dialog->priv->selected_sid = sid;
+			dialog->priv->selected_perms =
+				e2k_security_descriptor_get_permissions (dialog->priv->sd, sid);
+			dialog->priv->selected_role =
+				e2k_permissions_role_find (dialog->priv->selected_perms);
+
+			/* "Default" or "Anonymous" can't be a Folder contact, but any
+			 * real person can.
+			 */
+			gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->folder_contact_check),
+						  e2k_sid_get_sid_type (sid) != E2K_SID_TYPE_WELL_KNOWN_GROUP);
 
-	/* Update role menu and permissions checkboxes */
-	display_permissions (dialog);
+			/* Update role menu and permissions checkboxes */
+			display_permissions (dialog);
+		}
+	}
+	g_slist_foreach (row_ref_list, (GFunc) gtk_tree_row_reference_free, NULL);
+	g_slist_free (row_ref_list);
+
+	g_list_foreach (selected_list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected_list);
 }
 
 static void
@@ -475,33 +499,57 @@ remove_clicked (GtkButton *button, gpoin
 	E2kSid *sid;
 	GdkModifierType modifiers;
 	GtkTreeModel *model;
-	GtkTreeIter iter;
+	GtkTreePath *path = NULL;
+	GList *selected_list = NULL;
+	GSList *row_ref_list = NULL;
+	GSList *rl = NULL;
+	GList *l = NULL;
 
-	if (!gtk_tree_selection_get_selected (dialog->priv->list_selection,
-					      &model, &iter))
-		return;
-	gtk_tree_model_get (model, &iter,
-			    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
-			    -1);
-	gdk_window_get_pointer (NULL, NULL, NULL, &modifiers);
+	selected_list = gtk_tree_selection_get_selected_rows (dialog->priv->list_selection, &model);
+	for (l = selected_list; l; l = g_list_next (l)) {
+		GtkTreeRowReference* row_ref = NULL;
+		path = (GtkTreePath *) l->data;
+		row_ref = gtk_tree_row_reference_new (model, path);
+		row_ref_list = g_slist_prepend (row_ref_list, row_ref);
+	}
 
-	if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP &&
-	    !(modifiers & GDK_SHIFT_MASK)) {
-		/* You shouldn't normally delete "Default" or "Anonymous". */
-		set_permissions (dialog, 0);
-	} else {
-		gtk_list_store_remove (dialog->priv->list_store, &iter);
-		e2k_security_descriptor_remove_sid (dialog->priv->sd, sid);
-
-		if (!gtk_list_store_iter_is_valid (dialog->priv->list_store, &iter)) {
-			/* Select the new last row. Love that API... */
-			gtk_tree_model_iter_nth_child (model, &iter, NULL,
-						       gtk_tree_model_iter_n_children (model, NULL) - 1);
-		}
-		gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter);
+	row_ref_list = g_slist_reverse (row_ref_list);
+	
+	for (rl = row_ref_list; rl; rl = rl->next) {
+		GtkTreeIter iter;
+		path = gtk_tree_row_reference_get_path (rl->data);
+
+		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store), &iter, path)) {
+			gtk_tree_model_get (model, &iter,
+					    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
+					    -1);
+			gdk_window_get_pointer (NULL, NULL, NULL, &modifiers);
 
-		dialog->priv->changed = TRUE;
+			if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP &&
+			    !(modifiers & GDK_SHIFT_MASK)) {
+				/* You shouldn't normally delete "Default" or "Anonymous". */
+				set_permissions (dialog, 0);
+			} else {
+				gtk_list_store_remove (dialog->priv->list_store, &iter);
+				e2k_security_descriptor_remove_sid (dialog->priv->sd, sid);
+
+				if (!gtk_list_store_iter_is_valid (dialog->priv->list_store, &iter)) {
+					/* Select the new last row. Love that API... */
+					gtk_tree_model_iter_nth_child (model, &iter, NULL,
+								       gtk_tree_model_iter_n_children (model, NULL) - 1);
+				}
+				gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter);
+
+				dialog->priv->changed = TRUE;
+			}
+		}
 	}
+
+	g_slist_foreach (row_ref_list, (GFunc) gtk_tree_row_reference_free, NULL);
+	g_slist_free (row_ref_list);
+
+	g_list_foreach (selected_list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected_list);
 }
 
 static void
@@ -537,23 +585,57 @@ role_changed (GtkWidget *role_combo, gpo
 {
 	ExchangePermissionsDialog *dialog = user_data;
 	int role;
+	E2kSid *sid;
+	GtkTreeModel *model;
+	GtkTreePath *path = NULL;
+	GList *selected_list = NULL;
+	GSList *row_ref_list = NULL;
+	GSList *rl = NULL;
+	GList *l = NULL;
 
 	if (dialog->priv->frozen)
 		return;
 
-	role = gtk_combo_box_get_active (GTK_COMBO_BOX (role_combo));
-	if (role == dialog->priv->selected_role)
-		return;
-	if (role >= E2K_PERMISSIONS_ROLE_NUM_ROLES) {
-		/* The user selected "Custom". Since "Custom" will
-		 * only be there to select when it's already
-		 * selected, this is a no-op.
-		 */
-		return;
+	selected_list = gtk_tree_selection_get_selected_rows (dialog->priv->list_selection, &model);
+
+	for (l = selected_list; l; l = g_list_next (l)) {
+		GtkTreeRowReference* row_ref = NULL;
+		path = (GtkTreePath *) l->data;
+		row_ref = gtk_tree_row_reference_new (model, path);
+		row_ref_list = g_slist_prepend (row_ref_list, row_ref);
+	}
+
+	row_ref_list = g_slist_reverse (row_ref_list);
+	
+	for (rl = row_ref_list; rl; rl = rl->next) {
+		GtkTreeIter iter;
+		path = gtk_tree_row_reference_get_path (rl->data);
+
+		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store), &iter, path)) {
+			gtk_tree_model_get (model, &iter,
+					    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
+					    -1);
+
+			role = gtk_combo_box_get_active (GTK_COMBO_BOX (role_combo));
+			if (role >= E2K_PERMISSIONS_ROLE_NUM_ROLES) {
+				/* The user selected "Custom". Since "Custom" will
+				 * only be there to select when it's already
+				 * selected, this is a no-op.
+				 */
+				return;
+			}
+
+			dialog->priv->selected_sid = sid;
+			set_permissions (dialog, 
+					 e2k_permissions_role_get_perms (role));
+			display_permissions (dialog);
+		}
 	}
+	g_slist_foreach (row_ref_list, (GFunc) gtk_tree_row_reference_free, NULL);
+	g_slist_free (row_ref_list);
 
-	set_permissions (dialog, e2k_permissions_role_get_perms (role));
-	display_permissions (dialog);
+	g_list_foreach (selected_list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected_list);
 }
 
 static void
@@ -561,34 +643,55 @@ display_role (ExchangePermissionsDialog 
 {
 	int role = dialog->priv->selected_role;
 	GtkTreeModel *model;
-	GtkTreeIter iter;
-
-	if (!gtk_tree_selection_get_selected (dialog->priv->list_selection,
-					      &model, &iter))
-		return;
-	gtk_list_store_set (dialog->priv->list_store, &iter,
-			    EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN,
-			    e2k_permissions_role_get_name (role),
-			    -1);
+	GtkTreePath *path = NULL;
+	GList *selected_list = NULL;
+	GSList *row_ref_list = NULL;
+	GSList *rl = NULL;
+	GList *l = NULL;
 
-	if (role == E2K_PERMISSIONS_ROLE_CUSTOM) {
-		if (dialog->priv->custom_added == FALSE) {
-			gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), _("Custom"));
-			dialog->priv->custom_added = TRUE;
-		}
-		role = E2K_PERMISSIONS_ROLE_NUM_ROLES;
+	selected_list = gtk_tree_selection_get_selected_rows (dialog->priv->list_selection, &model);
+	for (l = selected_list; l; l = g_list_next (l)) {
+		GtkTreeRowReference* row_ref = NULL;
+		path = (GtkTreePath *) l->data;
+		row_ref = gtk_tree_row_reference_new (model, path);
+		row_ref_list = g_slist_prepend (row_ref_list, row_ref);
 	}
-	else	{
-		if (dialog->priv->custom_added) {
-			gtk_combo_box_remove_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), E2K_PERMISSIONS_ROLE_NUM_ROLES);
-			dialog->priv->custom_added = FALSE;
+
+	row_ref_list = g_slist_reverse (row_ref_list);
+	
+	for (rl = row_ref_list; rl; rl = rl->next) {
+		GtkTreeIter iter;
+		path = gtk_tree_row_reference_get_path (rl->data);
+
+		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->list_store), &iter, path)) {
+			gtk_list_store_set (dialog->priv->list_store, &iter,
+					    EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN,
+					    e2k_permissions_role_get_name (role),
+					    -1);
+
+			if (role == E2K_PERMISSIONS_ROLE_CUSTOM) {
+				if (dialog->priv->custom_added == FALSE) {
+					gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), _("Custom"));
+					dialog->priv->custom_added = TRUE;
+				}
+				role = E2K_PERMISSIONS_ROLE_NUM_ROLES;
+			}
+			else	{
+				if (dialog->priv->custom_added) {
+					gtk_combo_box_remove_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), E2K_PERMISSIONS_ROLE_NUM_ROLES);
+					dialog->priv->custom_added = FALSE;
+				}
+			}
+				
+			gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->role_optionmenu), role);
 		}
 	}
-		
-	gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->role_optionmenu), role);
-}
-
+	g_slist_foreach (row_ref_list, (GFunc) gtk_tree_row_reference_free, NULL);
+	g_slist_free (row_ref_list);
 
+	g_list_foreach (selected_list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected_list);
+}
 
 /* Toggle buttons */
 static void
@@ -724,7 +827,7 @@ get_widgets (ExchangePermissionsDialog *
 
 	dialog->priv->list_selection = gtk_tree_view_get_selection (dialog->priv->list_view);
 	gtk_tree_selection_set_mode (dialog->priv->list_selection,
-				     GTK_SELECTION_SINGLE);
+				     GTK_SELECTION_MULTIPLE);
 	g_signal_connect (dialog->priv->list_selection, "changed",
 			  G_CALLBACK (list_view_selection_changed), dialog);
 
