changeset 12624:851b0bd7eb52

[gaim-migrate @ 14960] busy busy busy... * fixed some unused variable warnings in a few places * fixed memleak in the searchresults notify * added more button types to the searchresults notify (IM, Info, Invite, Join, and arbitrary labels) * added a conversation ui op to present a conversation, since there appears to be no way to actually initiate an IM without breaking the core/ui split. gaim_conversation_present now ends up calling gaim_gtkconv_present_conversation * changed sametime prpl to use the searchresults notify instead of the requests API for its "ambiguous user" dialog * it should be possible to use the searchresults notify for room listing, if anyone is thusly interested committer: Tailor Script <tailor@pidgin.im>
author Christopher O'Brien <siege@pidgin.im>
date Thu, 22 Dec 2005 17:16:57 +0000
parents 70f18c73da9d
children ba47bcf7c6eb
files src/conversation.c src/conversation.h src/gtkconv.c src/gtknotify.c src/gtkstock.c src/notify.c src/notify.h src/protocols/gg/gg.c src/protocols/jabber/buddy.c src/protocols/oscar/oscar.c src/protocols/sametime/sametime.c src/protocols/zephyr/zephyr.c
diffstat 12 files changed, 219 insertions(+), 247 deletions(-) [+]
line wrap: on
line diff
--- a/src/conversation.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/conversation.c	Thu Dec 22 17:16:57 2005 +0000
@@ -511,6 +511,18 @@
 
 
 void
+gaim_conversation_present(GaimConversation *conv) {
+	GaimConversationUiOps *ops;
+
+	g_return_if_fail(conv != NULL);
+
+	ops  = gaim_conversation_get_ui_ops(conv);
+	if(ops && ops->present)
+		ops->present(conv);
+}
+
+
+void
 gaim_conversation_set_features(GaimConversation *conv, GaimConnectionFlags features)
 {
 	g_return_if_fail(conv != NULL);
--- a/src/conversation.h	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/conversation.h	Thu Dec 22 17:16:57 2005 +0000
@@ -160,6 +160,7 @@
 	void (*chat_remove_users)(GaimConversation *conv, GList *users);
 	void (*chat_update_user)(GaimConversation *conv, const char *user);
 
+	void (*present)(GaimConversation *conv);
 
 	gboolean (*has_focus)(GaimConversation *conv);
 
@@ -287,6 +288,15 @@
  */
 void gaim_conversation_destroy(GaimConversation *conv);
 
+
+/**
+ * Present a conversation to the user. This allows core code to initiate a
+ * conversation by displaying the IM dialog.
+ * @param conv The conversation to present
+ */
+void gaim_conversation_present(GaimConversation *conv);
+
+
 /**
  * Returns the specified conversation's type.
  *
--- a/src/gtkconv.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/gtkconv.c	Thu Dec 22 17:16:57 2005 +0000
@@ -5473,8 +5473,9 @@
 	gaim_gtkconv_chat_remove_user,   /* chat_remove_user     */
 	gaim_gtkconv_chat_remove_users,  /* chat_remove_users    */
 	gaim_gtkconv_chat_update_user,   /* chat_update_user     */
+	gaim_gtkconv_present_conversation, /* present            */
 	gaim_gtkconv_has_focus,          /* has_focus            */
-	gaim_gtkconv_custom_smiley_add,  /* custom_smiley_add */
+	gaim_gtkconv_custom_smiley_add,  /* custom_smiley_add    */
 	gaim_gtkconv_custom_smiley_write, /* custom_smiley_write */
 	gaim_gtkconv_custom_smiley_close, /* custom_smiley_close */
 	gaim_gtkconv_updated             /* updated              */
--- a/src/gtknotify.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/gtknotify.c	Thu Dec 22 17:16:57 2005 +0000
@@ -475,13 +475,12 @@
 {
 	GtkWidget *window;
 	GtkWidget *treeview;
-	GtkWidget *button, *close_button;
+	GtkWidget *close_button;
 	GType *col_types;
 	GtkListStore *model;
 	GtkCellRenderer *renderer;
 	guint col_num;
 	guint i;
-	GList *buttons = NULL;
 
 	GtkWidget *vbox;
 	GtkWidget *button_area;
@@ -581,21 +580,48 @@
 
 	for (i = 0; i < g_list_length(results->buttons); i++) {
 		GaimNotifySearchButton *b = g_list_nth_data(results->buttons, i);
-		button = NULL;
+		GtkWidget *button = NULL;
 		switch (b->type) {
+			case GAIM_NOTIFY_BUTTON_LABELED:
+				if(b->label) {
+					button = gtk_button_new_with_label(b->label);
+				} else {
+					gaim_debug_warning("gtknotify", "Missing button label");
+				}
+				break;
 			case GAIM_NOTIFY_BUTTON_CONTINUE:
 				button = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD);
 				break;
-			case GAIM_NOTIFY_BUTTON_ADD_BUDDY:
+			case GAIM_NOTIFY_BUTTON_ADD:
 				button = gtk_button_new_from_stock(GTK_STOCK_ADD);
 				break;
+			case GAIM_NOTIFY_BUTTON_INFO:
+				button = gtk_button_new_from_stock(GAIM_STOCK_INFO);
+				break;
+			case GAIM_NOTIFY_BUTTON_IM:
+				button = gtk_button_new_from_stock(GAIM_STOCK_IM);
+				break;
+			case GAIM_NOTIFY_BUTTON_JOIN:
+				button = gtk_button_new_from_stock(GAIM_STOCK_CHAT);
+				break;
+			case GAIM_NOTIFY_BUTTON_INVITE:
+				button = gtk_button_new_from_stock(GAIM_STOCK_INVITE);
+				break;
 			default:
 				gaim_debug_warning("gtknotify", "Incorrect button type: %d\n", b->type);
 		}
 		if (button != NULL) {
+			GaimNotifySearchResultsButtonData *bd;
+
 			gtk_box_pack_start(GTK_BOX(button_area), button, FALSE, FALSE, 0);
 			gtk_widget_show(button);
-			buttons = g_list_append(buttons, button);
+
+			bd = g_new0(GaimNotifySearchResultsButtonData, 1);
+			bd->button = b;
+			bd->data = data;
+
+			g_signal_connect(G_OBJECT(button), "clicked",
+			                 G_CALLBACK(searchresults_callback_wrapper_cb), bd);
 		}
 	}
 
@@ -604,6 +630,9 @@
 	gtk_box_pack_start(GTK_BOX(button_area), close_button, FALSE, FALSE, 0);
 	gtk_widget_show(close_button);
 
+	g_signal_connect_swapped(G_OBJECT(close_button), "clicked",
+	                         G_CALLBACK(searchresults_close_cb), data);
+
 	data->account = gc->account;
 	data->model = model;
 	data->treeview = treeview;
@@ -612,18 +641,6 @@
 	/* Insert rows. */
 	gaim_gtk_notify_searchresults_new_rows(gc, results, data, NULL);
 
-	/* Connect Signals */
-	for (i = 0; i < g_list_length(results->buttons); i++) {
-		GaimNotifySearchResultsButtonData *bd = g_new0(GaimNotifySearchResultsButtonData, 1);
-		bd->button = g_list_nth_data(results->buttons, i);
-		bd->data = data;
-		g_signal_connect(G_OBJECT(g_list_nth_data(buttons, i)), "clicked",
-						 G_CALLBACK(searchresults_callback_wrapper_cb), bd);
-	}
-
-	g_signal_connect_swapped(G_OBJECT(close_button), "clicked",
-							 G_CALLBACK(searchresults_close_cb), data);
-
 	/* Show the window */
 	gtk_widget_show(window);
 	return data;
--- a/src/gtkstock.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/gtkstock.c	Thu Dec 22 17:16:57 2005 +0000
@@ -137,11 +137,13 @@
 {
 	{ GAIM_STOCK_ALIAS,     N_("_Alias"),     0, 0, NULL },
 	{ GAIM_STOCK_CHAT,      N_("_Join"),      0, 0, NULL },
+	{ GAIM_STOCK_IM,	N_("I_M"),        0, 0, NULL },
+	{ GAIM_STOCK_INFO,      N_("_Get Info"),  0, 0, NULL },
 	{ GAIM_STOCK_INVITE,    N_("_Invite"),    0, 0, NULL },
 	{ GAIM_STOCK_MODIFY,    N_("_Modify"),    0, 0, NULL },
 	{ GAIM_STOCK_OPEN_MAIL, N_("_Open Mail"), 0, 0, NULL },
 	{ GAIM_STOCK_PAUSE,     N_("_Pause"),     0, 0, NULL },
-	{ GAIM_STOCK_WARN,      N_("_Warn"),      0, 0, NULL }
+	{ GAIM_STOCK_WARN,      N_("_Warn"),      0, 0, NULL },
 };
 
 static gchar *
--- a/src/notify.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/notify.c	Thu Dec 22 17:16:57 2005 +0000
@@ -193,41 +193,33 @@
 void
 gaim_notify_searchresults_free(GaimNotifySearchResults *results)
 {
-	GList *l, *m;
+	GList *l;
 
 	g_return_if_fail(results != NULL);
 
-	for (l = results->buttons; l != NULL; l = l->next) {
+	for (l = results->buttons; l; l = g_list_delete_link(l, l)) {
 		GaimNotifySearchButton *button = l->data;
-
-		results->buttons = g_list_remove(results->buttons, button);
 		g_free(button);
 	}
-	g_list_free(results->buttons);
-
-	for (l = results->rows; l != NULL; l = l->next) {
-		GList *row = l->data;
+	results->buttons = NULL;
 
-		for (m = row; m != NULL; m = m->next) {
-			gchar *str = m->data;
-
-			m = g_list_remove(m, str);
+	for (l = results->rows; l; l = g_list_delete_link(l, l)) {
+		GList *row = l->data;
+		for (; row; row = g_list_delete_link(row, row)) {
+			gchar *str = row->data;
 			g_free(str);
 		}
+	}
+	results->rows = NULL;
 
-		results->rows = g_list_remove(results->rows, row);
-		g_list_free(row);
-	}
-	g_list_free(results->rows);
-
-	for (l = results->columns; l != NULL; l = l->next) {
+	for (l = results->columns; l; l = g_list_delete_link(l, l)) {
 		GaimNotifySearchColumn *column = l->data;
-
-		results->columns = g_list_remove(results->columns, column);
 		g_free(column->title);
 		g_free(column);
 	}
-	g_list_free(results->columns);
+	results->columns = NULL;
+
+	g_free(results);
 }
 
 void
@@ -261,6 +253,27 @@
 	results->buttons = g_list_append(results->buttons, button);
 }
 
+
+void
+gaim_notify_searchresults_button_add_labeled(GaimNotifySearchResults *results,
+                                             const char *label,
+                                             GaimNotifySearchResultsCallback cb) {
+	GaimNotifySearchButton *button;
+
+	g_return_if_fail(results != NULL);
+	g_return_if_fail(cb != NULL);
+	g_return_if_fail(label != NULL);
+	g_return_if_fail(*label != '\0');
+
+	button = g_new0(GaimNotifySearchButton, 1);
+	button->callback = cb;
+	button->type = GAIM_NOTIFY_BUTTON_LABELED;
+	button->label = g_strdup(label);
+
+	results->buttons = g_list_append(results->buttons, button);
+}
+
+
 GaimNotifySearchResults *
 gaim_notify_searchresults_new()
 {
--- a/src/notify.h	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/notify.h	Thu Dec 22 17:16:57 2005 +0000
@@ -31,11 +31,13 @@
 
 #include "connection.h"
 
+
 /**
  * Notification close callbacks.
  */
 typedef void  (*GaimNotifyCloseCallback) (gpointer user_data);
 
+
 /**
  * Notification types.
  */
@@ -51,6 +53,7 @@
 
 } GaimNotifyType;
 
+
 /**
  * Notification message types.
  */
@@ -62,15 +65,21 @@
 
 } GaimNotifyMsgType;
 
+
 /**
  * The types of buttons
  */
 typedef enum
 {
-	GAIM_NOTIFY_BUTTON_CONTINUE = 0,
-	GAIM_NOTIFY_BUTTON_ADD_BUDDY
+	GAIM_NOTIFY_BUTTON_LABELED = 0,  /**< special use, see _button_add_labeled */
+	GAIM_NOTIFY_BUTTON_CONTINUE = 1,
+	GAIM_NOTIFY_BUTTON_ADD,
+	GAIM_NOTIFY_BUTTON_INFO,
+	GAIM_NOTIFY_BUTTON_IM,
+	GAIM_NOTIFY_BUTTON_JOIN,
+	GAIM_NOTIFY_BUTTON_INVITE
+} GaimNotifySearchButtonType;
 
-} GaimNotifySearchButtonType;
 
 /**
  * Search results object.
@@ -83,6 +92,7 @@
 
 } GaimNotifySearchResults;
 
+
 /**
  * Single column of a search result.
  */
@@ -92,7 +102,14 @@
 
 } GaimNotifySearchColumn;
 
-typedef void (*GaimNotifySearchResultsCallback)(GaimConnection *, GList *);
+
+/**
+ * Callback for a button in a search result.
+ *
+ * @param c  the GaimConnection passed to gaim_notify_searchresults
+ * @param c  the list of selected rows, each a GList in itself.
+ */
+typedef void (*GaimNotifySearchResultsCallback)(GaimConnection *c, GList *l);
 
 
 /**
@@ -102,8 +119,9 @@
 {
 	GaimNotifySearchButtonType type;
 	GaimNotifySearchResultsCallback callback; /**< Function to be called when clicked. */
+	char *label;                              /**< only for GAIM_NOTIFY_BUTTON_LABELED */
+} GaimNotifySearchButton;
 
-} GaimNotifySearchButton;
 
 /**
  * Notification UI operations.
@@ -111,32 +129,41 @@
 typedef struct
 {
 	void *(*notify_message)(GaimNotifyMsgType type, const char *title,
-							const char *primary, const char *secondary);
+	                        const char *primary, const char *secondary);
+
 	void *(*notify_email)(const char *subject, const char *from,
-						  const char *to, const char *url);
+	                      const char *to, const char *url);
+
 	void *(*notify_emails)(size_t count, gboolean detailed,
-						   const char **subjects, const char **froms,
-						   const char **tos, const char **urls);
+	                       const char **subjects, const char **froms,
+	                       const char **tos, const char **urls);
+
 	void *(*notify_formatted)(const char *title, const char *primary,
-							  const char *secondary, const char *text);
+	                          const char *secondary, const char *text);
+
 	void *(*notify_searchresults)(GaimConnection *gc, const char *title,
-								  const char *primary, const char *secondary,
-								  GaimNotifySearchResults *results);
+	                              const char *primary, const char *secondary,
+	                              GaimNotifySearchResults *results);
+
 	void (*notify_searchresults_new_rows)(GaimConnection *gc,
-										  GaimNotifySearchResults *results,
-										  void *data, gpointer user_data);
+	                                      GaimNotifySearchResults *results,
+	                                      void *data, gpointer user_data);
+
 	void *(*notify_userinfo)(GaimConnection *gc, const char *who,
-							  const char *text);
+	                         const char *text);
+
 	void *(*notify_uri)(const char *uri);
 
 	void (*close_notify)(GaimNotifyType type, void *ui_handle);
 
 } GaimNotifyUiOps;
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+
 /**************************************************************************/
 /** Search results notification API                                       */
 /**************************************************************************/
@@ -178,8 +205,9 @@
 										GaimNotifySearchResults *results,
 										void *data, gpointer user_data);
 
+
 /**
- * Adds a button that will be displayed in the search results dialog.
+ * Adds a stock button that will be displayed in the search results dialog.
  *
  * @param results The search results object.
  * @param type    Type of the button. (TODO: Only one button of a given type can be displayed.)
@@ -189,6 +217,19 @@
 										  GaimNotifySearchButtonType type,
 										  GaimNotifySearchResultsCallback cb);
 
+
+/**
+ * Adds a plain labelled button that will be displayed in the search results dialog.
+ * 
+ * @param results The search results object
+ * @param label   The label to display
+ * @param cb      Function that will be called on the click event
+ */
+void gaim_notify_searchresults_button_add_labeled(GaimNotifySearchResults *results,
+                                                  const char *label,
+                                                  GaimNotifySearchResultsCallback cb);
+
+
 /**
  * Returns a newly created search results object.
  *
--- a/src/protocols/gg/gg.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/protocols/gg/gg.c	Thu Dec 22 17:16:57 2005 +0000
@@ -1028,7 +1028,7 @@
 
 	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_CONTINUE,
 					     ggp_callback_show_next);
-	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD_BUDDY,
+	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD,
 					     ggp_callback_add_buddy);
 	if (info->searchresults_window == NULL) {
 		void *h = gaim_notify_searchresults(gc,
--- a/src/protocols/jabber/buddy.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/protocols/jabber/buddy.c	Thu Dec 22 17:16:57 2005 +0000
@@ -1229,7 +1229,7 @@
 		}
 	}
 
-	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD_BUDDY,
+	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD,
 			user_search_result_add_buddy_cb);
 
 	gaim_notify_searchresults(js->gc, NULL, NULL, _("The following are the results of your search"), results, NULL, NULL);
--- a/src/protocols/oscar/oscar.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/protocols/oscar/oscar.c	Thu Dec 22 17:16:57 2005 +0000
@@ -6197,7 +6197,7 @@
 		row = g_list_append(row, g_strdup(&SNs[i * (MAXSNLEN + 1)]));
 		gaim_notify_searchresults_row_add(results, row);
 	}
-	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD_BUDDY,
+	gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD,
 										 oscar_searchresults_add_buddy_cb);
 	gaim_notify_searchresults(gc, NULL, NULL, secondary, results, NULL, NULL);
 
--- a/src/protocols/sametime/sametime.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/protocols/sametime/sametime.c	Thu Dec 22 17:16:57 2005 +0000
@@ -295,17 +295,13 @@
 static GaimConversation *convo_get_gconv(struct mwConversation *conv);
 
 
-/* resolved id */
-
-struct resolved_id {
+/* name and  id */
+
+struct named_id {
   char *id;
   char *name;
 };
 
-static struct resolved_id *resolved_id_new(const char *id, const char *name);
-
-static void resolved_id_free(struct resolved_id *rid);
-
 
 /* connection functions */
 
@@ -4197,156 +4193,59 @@
 
   mwSession_setUserStatus(session, &stat);
   mwUserStatus_clear(&stat);
- }
-
-
-static struct resolved_id *resolved_id_new(const char *id,
-					   const char *name) {
-
-  struct resolved_id *rid = g_new0(struct resolved_id, 1);
-  rid->id = g_strdup(id);
-  rid->name = g_strdup(name);
-  return rid;
-}
-
-
-static void resolved_id_free(struct resolved_id *rid) {
-  if(rid) {
-    g_free(rid->id);
-    g_free(rid->name);
-    g_free(rid);
-  }
-}
-
-
-static void add_resolved_done(const char *id, const char *name,
-			      GaimBuddy *buddy) {
+}
+
+
+static void notify_im(GaimConnection *gc, GList *row) {
   GaimAccount *acct;
-  GaimConnection *gc;
-  struct mwGaimPluginData *pd;
-
-  g_return_if_fail(id != NULL);
-
-  g_return_if_fail(buddy != NULL);
-  acct = buddy->account;
-
-  g_return_if_fail(acct != NULL);
-  gc = gaim_account_get_connection(acct);
-
-  g_return_if_fail(gc != NULL);
-  pd = gc->proto_data;
-
-  gaim_blist_rename_buddy(buddy, id);
-  
-  gaim_blist_server_alias_buddy(buddy, name);
-  gaim_blist_node_set_string((GaimBlistNode *) buddy, BUDDY_KEY_NAME, name);
-  
-  buddy_add(pd, buddy);
-}
-
-
-static void multi_resolved_cleanup(GaimRequestFields *fields) {
-  GaimRequestField *f;
-  const GList *l;
-
-  f = gaim_request_fields_get_field(fields, "user");
-  l = gaim_request_field_list_get_items(f);
-
-  for(; l; l = l->next) {
-    const char *i = l->data;
-    struct resolved_id *res;
-
-    res = gaim_request_field_list_get_data(f, i);
-    resolved_id_free(res);
-  }
-}
-
-
-static void multi_resolved_cancel(GaimBuddy *buddy,
-				  GaimRequestFields *fields) {
-  GaimConnection *gc;
-  struct mwGaimPluginData *pd;
-
-  gc = gaim_account_get_connection(buddy->account);
-  pd = gc->proto_data;
-
-  gaim_blist_remove_buddy(buddy);
-  multi_resolved_cleanup(fields);
-
-  blist_schedule(pd);
-}
-
-
-static void multi_resolved_cb(GaimBuddy *buddy,
-			      GaimRequestFields *fields) {
-  GaimRequestField *f;
-  const GList *l;
-
-  f = gaim_request_fields_get_field(fields, "user");
-  l = gaim_request_field_list_get_selected(f);
-
-  if(l) {
-    const char *i = l->data;
-    struct resolved_id *res;
-
-    res = gaim_request_field_list_get_data(f, i);
-
-    add_resolved_done(res->id, res->name, buddy);
-    multi_resolved_cleanup(fields);
-
-  } else {
-    multi_resolved_cancel(buddy, fields);
-  }
-}
-
-
-static void foreach_resolved_id(char *key, char *val, GList **l) {
-  struct resolved_id *res = resolved_id_new(key, val);
-  *l = g_list_prepend(*l, res);
-}
-
-
-static gint resolved_id_comp(struct resolved_id *a, struct resolved_id *b) {
-  return g_ascii_strcasecmp(a->name, b->name);
+  GaimConversation *conv;
+  char *id;
+
+  acct = gaim_connection_get_account(gc);
+  id = g_list_nth_data(row, 0);
+  conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, id, acct);
+  if(! conv) conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, acct, id);
+  gaim_conversation_present(conv);
+}
+
+
+static void notify_add(GaimConnection *gc, GList *row) {
+  gaim_blist_request_add_buddy(gaim_connection_get_account(gc),
+			       g_list_nth_data(row, 1), NULL,
+			       g_list_nth_data(row, 0));
+}
+
+
+static void notify_close(gpointer data) {
+  ;
 }
 
 
 static void multi_resolved_query(struct mwResolveResult *result,
-				 GaimBuddy *buddy) {
-  GaimRequestFields *fields;
-  GaimRequestFieldGroup *g;
-  GaimRequestField *f;
-  GHashTable *hash;
+				 GaimConnection *gc) {
   GList *l;
   char *msgA, *msgB;
 
-  GaimAccount *acct;
-  GaimConnection *gc;
-
-  g_return_if_fail(buddy != NULL);
-
-  acct = buddy->account;
-  g_return_if_fail(acct != NULL);
-
-  gc = gaim_account_get_connection(acct);
-  g_return_if_fail(gc != NULL);
-
-  fields = gaim_request_fields_new();
-
-  g = gaim_request_field_group_new(NULL);
-
-  /* note that Gaim segfaults if you don't add the group to the fields
-     before you add a required field to the group. Feh. */
-  gaim_request_fields_add_group(fields, g);
-
-  f = gaim_request_field_list_new("user", _("Possible Matches"));
-  gaim_request_field_list_set_multi_select(f, FALSE);
-  gaim_request_field_set_required(f, TRUE);
-
-  /* collect results into a set of identities */
-  hash = g_hash_table_new(g_str_hash, g_str_equal);
+  GaimNotifySearchResults *sres;
+  GaimNotifySearchColumn *scol;
+
+  sres = gaim_notify_searchresults_new();
+
+  scol = gaim_notify_searchresults_column_new(_("User Name"));
+  gaim_notify_searchresults_column_add(sres, scol);
+
+  scol = gaim_notify_searchresults_column_new(_("Sametime ID"));
+  gaim_notify_searchresults_column_add(sres, scol);
+
+  gaim_notify_searchresults_button_add(sres, GAIM_NOTIFY_BUTTON_IM,
+				       notify_im);
+
+  gaim_notify_searchresults_button_add(sres, GAIM_NOTIFY_BUTTON_ADD,
+				       notify_add);
+
   for(l = result->matches; l; l = l->next) {
     struct mwResolveMatch *match = l->data;
+    GList *row = NULL;
         
     DEBUG_INFO("multi resolve: %s, %s\n",
 	       NSTR(match->id), NSTR(match->name));
@@ -4354,31 +4253,10 @@
     if(!match->id || !match->name)
       continue;
     
-    g_hash_table_insert(hash, match->id, match->name);
+    row = g_list_append(row, g_strdup(match->name));
+    row = g_list_append(row, g_strdup(match->id));
+    gaim_notify_searchresults_row_add(sres, row);
   }
-  
-  /* collect set into a list of structures */
-  l = NULL;
-  g_hash_table_foreach(hash, (GHFunc) foreach_resolved_id, &l);
-  g_hash_table_destroy(hash);
-  g_list_sort(l, (GCompareFunc) resolved_id_comp);
-
-  /* populate choices in request field */
-  for(; l; l = l->next) {
-    struct resolved_id *res = l->data;
-    char *label;
-    
-    /* fixes bug 1178603 by making the selection label a combination
-       of the full name and the user id. Problems arrise when multiple
-       entries have identical labels */
-    label = g_strdup_printf("%s (%s)", NSTR(res->name), NSTR(res->id));
-    gaim_request_field_list_add(f, label, res);
-    g_free(label);
-  }
-
-  g_list_free(l);
-
-  gaim_request_field_group_add_field(g, f);
 
   msgA = _("An ambiguous user ID was entered");
   msgB = _("The identifier '%s' may possibly refer to any of the following"
@@ -4386,12 +4264,8 @@
 	   " add them to your buddy list.");
   msgB = g_strdup_printf(msgB, result->name);
 
-  gaim_request_fields(gc, _("Select User to Add"),
-		      msgA, msgB, fields,
-		      _("Add User"), G_CALLBACK(multi_resolved_cb),
-		      _("Cancel"), G_CALLBACK(multi_resolved_cancel),
-		      buddy);
-  g_free(msgB);
+  gaim_notify_searchresults(gc, _("Select User"),
+			    msgA, msgB, sres, notify_close, NULL);
 }
 
 
@@ -4414,24 +4288,26 @@
     if(g_list_length(res->matches) == 1) {
       struct mwResolveMatch *match = res->matches->data;
       
-      DEBUG_INFO("searched for %s, got only %s\n",
-		 NSTR(res->name), NSTR(match->id));
-      
       /* only one? that might be the right one! */
       if(strcmp(res->name, match->id)) {
 	/* uh oh, the single result isn't identical to the search
 	   term, better safe then sorry, so let's make sure it's who
 	   the user meant to add */
-	multi_resolved_query(res, buddy);
+	gaim_blist_remove_buddy(buddy);
+	multi_resolved_query(res, gc);
 	
       } else {
-	/* same person, add 'em */
-	add_resolved_done(match->id, match->name, buddy);
+	/* same person, set the server alias */
+	gaim_blist_server_alias_buddy(buddy, match->name);
+	gaim_blist_node_set_string((GaimBlistNode *) buddy,
+				   BUDDY_KEY_NAME, match->name);
+	blist_schedule(pd);
       }
       
     } else {
       /* prompt user if more than one match was returned */
-      multi_resolved_query(res, buddy);
+      gaim_blist_remove_buddy(buddy);
+      multi_resolved_query(res, gc);
     }
     
     return;
@@ -5276,7 +5152,7 @@
 
   for(; l; l = l->next) {
     const char *i = l->data;
-    struct resolved_id *res;
+    struct named_id *res;
 
     res = gaim_request_field_list_get_data(f, i);
 
@@ -5340,7 +5216,7 @@
 
   if(l) {
     const char *i = l->data;
-    struct resolved_id *res;
+    struct named_id *res;
 
     res = gaim_request_field_list_get_data(f, i);
     remote_group_done(pd, res->id, res->name);
@@ -5372,7 +5248,7 @@
 
   for(l = result->matches; l; l = l->next) {
     struct mwResolveMatch *match = l->data;
-    struct resolved_id *res = g_new0(struct resolved_id, 1);
+    struct named_id *res = g_new0(struct named_id, 1);
 
     res->id = g_strdup(match->id);
     res->name = g_strdup(match->name);
--- a/src/protocols/zephyr/zephyr.c	Thu Dec 22 16:06:41 2005 +0000
+++ b/src/protocols/zephyr/zephyr.c	Thu Dec 22 17:16:57 2005 +0000
@@ -744,7 +744,7 @@
 		char *send_inst;
 		GaimConversation *gconv1;
 		GaimConvChat *gcc;
-		char *ptr = notice.z_message + strlen(notice.z_message) + 1;
+		char *ptr = (char *) notice.z_message + (strlen(notice.z_message) + 1);
 		int len; 
 		char *sendertmp = g_strdup_printf("%s", zephyr->username);
 		int signature_length = strlen(notice.z_message);