# HG changeset patch # User Bartoz Oler # Date 1145182255 0 # Node ID d12bbe6da7059de4ca6876b4e09ac27ccde66962 # Parent 43c7e892d8bfed0da1c8a06b7d0001f78bf94670 [gaim-migrate @ 16038] * Changed signatures of some of the search results notify API functions. * GG PRPL: Support parallel public directory searches. committer: Tailor Script diff -r 43c7e892d8bf -r d12bbe6da705 plugins/ChangeLog.API --- a/plugins/ChangeLog.API Sat Apr 15 15:01:30 2006 +0000 +++ b/plugins/ChangeLog.API Sun Apr 16 10:10:55 2006 +0000 @@ -171,6 +171,8 @@ * gaim_date_full(): See gaim_date_format_full() * gaim_strftime(): See gaim_utf8_strftime() * GAIM_MESSAGE_COLORIZE + * user_data from gaim_notify_searchresults_new_rows and from + notify_searchresults in GaimNotifyUiOps. Added: * gaim_prefs_disconnect_by_handle() @@ -283,6 +285,8 @@ * gaim_gtk_clear_cursor() * GAIM_MESSAGE_ACTIVE_ONLY * gaim_proxy_get_setup() + * GaimNotifySearchResultsCallback: Added user_data. + * gaim_notify_searchresults: Added user_data. Signals - Changed: (See the Doxygen docs for details on all signals.) * Signal propagation now stops after a handler returns a non-NULL value. diff -r 43c7e892d8bf -r d12bbe6da705 src/gtknotify.c --- a/src/gtknotify.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/gtknotify.c Sun Apr 16 10:10:55 2006 +0000 @@ -52,6 +52,8 @@ GtkListStore *model; GtkWidget *treeview; GtkWidget *window; + gpointer user_data; + } GaimNotifySearchResultsData; typedef struct @@ -157,7 +159,7 @@ } static void -searchresults_close_cb(GaimNotifySearchResultsData *data, GdkEvent *event, void *user_data) +searchresults_close_cb(GaimNotifySearchResultsData *data, GdkEvent *event, gpointer user_data) { gaim_notify_close(GAIM_NOTIFY_SEARCHRESULTS, data); } @@ -188,7 +190,7 @@ } button = bd->button; - button->callback(gaim_account_get_connection(data->account), row); + button->callback(gaim_account_get_connection(data->account), row, data->user_data); } static void * @@ -614,7 +616,7 @@ static void gaim_gtk_notify_searchresults_new_rows(GaimConnection *gc, GaimNotifySearchResults *results, - void *data_, gpointer user_data) + void *data_) { GaimNotifySearchResultsData *data = data_; GtkListStore *model = data->model; @@ -656,7 +658,7 @@ static void * gaim_gtk_notify_searchresults(GaimConnection *gc, const char *title, const char *primary, const char *secondary, - GaimNotifySearchResults *results) + GaimNotifySearchResults *results, gpointer user_data) { GtkWidget *window; GtkWidget *treeview; @@ -679,6 +681,7 @@ g_return_val_if_fail(results != NULL, NULL); data = g_malloc(sizeof(GaimNotifySearchResultsData)); + data->user_data = user_data; /* Create the window */ window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -824,7 +827,7 @@ data->window = window; /* Insert rows. */ - gaim_gtk_notify_searchresults_new_rows(gc, results, data, NULL); + gaim_gtk_notify_searchresults_new_rows(gc, results, data); /* Show the window */ gtk_widget_show(window); diff -r 43c7e892d8bf -r d12bbe6da705 src/notify.c --- a/src/notify.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/notify.c Sun Apr 16 10:10:55 2006 +0000 @@ -165,7 +165,8 @@ void * gaim_notify_searchresults(GaimConnection *gc, const char *title, const char *primary, const char *secondary, - GaimNotifySearchResults *results, GaimNotifyCloseCallback cb, gpointer user_data) + GaimNotifySearchResults *results, GaimNotifyCloseCallback cb, + gpointer user_data) { GaimNotifyUiOps *ops; @@ -178,7 +179,7 @@ info->type = GAIM_NOTIFY_SEARCHRESULTS; info->handle = gc; info->ui_handle = ops->notify_searchresults(gc, title, primary, - secondary, results); + secondary, results, user_data); info->cb = cb; info->cb_user_data = user_data; @@ -225,14 +226,14 @@ void gaim_notify_searchresults_new_rows(GaimConnection *gc, GaimNotifySearchResults *results, - void *data, gpointer user_data) + void *data) { GaimNotifyUiOps *ops; ops = gaim_notify_get_ui_ops(); if (ops != NULL && ops->notify_searchresults != NULL) { - ops->notify_searchresults_new_rows(gc, results, data, user_data); + ops->notify_searchresults_new_rows(gc, results, data); } } diff -r 43c7e892d8bf -r d12bbe6da705 src/notify.h --- a/src/notify.h Sat Apr 15 15:01:30 2006 +0000 +++ b/src/notify.h Sun Apr 16 10:10:55 2006 +0000 @@ -106,10 +106,12 @@ /** * Callback for a button in a search result. * - * @param c the GaimConnection passed to gaim_notify_searchresults - * @param row the contents of the selected row + * @param c the GaimConnection passed to gaim_notify_searchresults + * @param row the contents of the selected row + * @param user_data User defined data. */ -typedef void (*GaimNotifySearchResultsCallback)(GaimConnection *c, GList *row); +typedef void (*GaimNotifySearchResultsCallback)(GaimConnection *c, GList *row, + gpointer user_data); /** @@ -145,11 +147,11 @@ void *(*notify_searchresults)(GaimConnection *gc, const char *title, const char *primary, const char *secondary, - GaimNotifySearchResults *results); + GaimNotifySearchResults *results, gpointer user_data); void (*notify_searchresults_new_rows)(GaimConnection *gc, GaimNotifySearchResults *results, - void *data, gpointer user_data); + void *data); void *(*notify_userinfo)(GaimConnection *gc, const char *who, const char *text); @@ -184,7 +186,8 @@ * @param results The GaimNotifySearchResults instance. * @param cb The callback to call when the user closes * the notification. - * @param user_data The data to pass to the callback. + * @param user_data The data to pass to the close callback and any other + * callback associated with a button. * * @return A UI-specific handle. */ @@ -201,11 +204,10 @@ * @param gc The GaimConnection structure. * @param results The GaimNotifySearchResults structure. * @param data Data returned by the gaim_notify_searchresults(). - * @param user_data User defined data. */ void gaim_notify_searchresults_new_rows(GaimConnection *gc, GaimNotifySearchResults *results, - void *data, gpointer user_data); + void *data); /** diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/gg/gg.c --- a/src/protocols/gg/gg.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/gg/gg.c Sun Apr 16 10:10:55 2006 +0000 @@ -504,21 +504,27 @@ /* */ -/* static void ggp_callback_show_next(GaimConnection *gc, GList *row) {{{ */ -static void ggp_callback_show_next(GaimConnection *gc, GList *row) +/* static void ggp_callback_show_next(GaimConnection *gc, GList *row, void *user_data) {{{ */ +static void ggp_callback_show_next(GaimConnection *gc, GList *row, void *user_data) { GGPInfo *info = gc->proto_data; + GGPSearchForm *form = user_data; + guint32 seq; - g_free(info->search_form->offset); - info->search_form->offset = g_strdup(info->search_form->last_uin); - ggp_search_start(gc, info->search_form); + g_free(form->offset); + form->offset = g_strdup(form->last_uin); + + ggp_search_remove(info->searches, form->seq); + + seq = ggp_search_start(gc, form); + ggp_search_add(info->searches, seq, form); } /* }}} */ /* */ -/* static void ggp_callback_add_buddy(GaimConnection *gc, GList *row) {{{ */ -static void ggp_callback_add_buddy(GaimConnection *gc, GList *row) +/* static void ggp_callback_add_buddy(GaimConnection *gc, GList *row, void *user_data) {{{ */ +static void ggp_callback_add_buddy(GaimConnection *gc, GList *row, void *user_data) { gaim_blist_request_add_buddy(gaim_connection_get_account(gc), g_list_nth_data(row, 0), NULL, NULL); @@ -532,10 +538,11 @@ { GGPInfo *info = gc->proto_data; GGPSearchForm *form; + guint32 seq; - form = ggp_search_form_new(); - info->search_form = form; + form = ggp_search_form_new(GGP_SEARCH_TYPE_FULL); + form->user_data = info; form->lastname = charset_convert( gaim_request_fields_get_string(fields, "lastname"), "UTF-8", "CP1250"); @@ -569,7 +576,8 @@ form->offset = g_strdup("0"); - ggp_search_start(gc, form); + seq = ggp_search_start(gc, form); + ggp_search_add(info->searches, seq, form); } /* }}} */ @@ -579,19 +587,11 @@ static void ggp_find_buddies(GaimPluginAction *action) { GaimConnection *gc = (GaimConnection *)action->context; - GGPInfo *info = gc->proto_data; GaimRequestFields *fields; GaimRequestFieldGroup *group; GaimRequestField *field; - if (info->search_form != NULL) { - gaim_notify_error(gc, NULL, - _("Unable to initiate a new search"), - _("You have a pending search. Please wait for it to finish.")); - return; - } - fields = gaim_request_fields_new(); group = gaim_request_field_group_new(NULL); gaim_request_fields_add_group(fields, group); @@ -947,29 +947,13 @@ /* */ -/* static void ggp_sr_close_cb(GaimAccount *account) {{{ */ -static void ggp_sr_close_cb(GaimAccount *account) +/* static void ggp_sr_close_cb(GGPSearchForm *form) {{{ */ +static void ggp_sr_close_cb(GGPSearchForm *form) { - GaimConnection *gc = gaim_account_get_connection(account); - GGPInfo *info = gc->proto_data; - GGPSearchForm *f; - - info->searchresults_window = NULL; + GGPInfo *info = form->user_data; - f = info->search_form; - g_free(f->uin); - g_free(f->lastname); - g_free(f->firstname); - g_free(f->nickname); - g_free(f->city); - g_free(f->birthyear); - g_free(f->gender); - g_free(f->active); - g_free(f->offset); - g_free(f->last_uin); - g_free(f); - - info->search_form = NULL; + ggp_search_remove(info->searches, form->seq); + ggp_search_form_destroy(form); } /* }}} */ @@ -978,13 +962,26 @@ /* static void ggp_pubdir_reply_handler(GaimConnection *gc, gg_pubdir50_t req) {{{ */ static void ggp_pubdir_reply_handler(GaimConnection *gc, gg_pubdir50_t req) { - GaimAccount *account = gaim_connection_get_account(gc); GGPInfo *info = gc->proto_data; GaimNotifySearchResults *results; GaimNotifySearchColumn *column; + GGPSearchForm *form; int res_count = 0; int start; int i; + guint32 seq; + + seq = gg_pubdir50_seq(req); + form = ggp_search_get(info->searches, seq); + + if (form == NULL) { + /* + * this can happen when user will request more results + * and close the results window before they arrive. + */ + gaim_debug_error("gg", "No search form available for this search!\n"); + return; + } res_count = gg_pubdir50_count(req); if (res_count < 1) { @@ -992,7 +989,7 @@ gaim_notify_error(gc, NULL, _("No matching users found"), _("There are no users matching your search criteria.")); - ggp_sr_close_cb(account); + ggp_sr_close_cb(form); return; } res_count = (res_count > 20) ? 20 : res_count; @@ -1005,7 +1002,7 @@ gaim_notify_error(gc, NULL, _("Unable to display the search results."), NULL); - ggp_sr_close_cb(account); + ggp_sr_close_cb(form); return; } @@ -1049,9 +1046,8 @@ gaim_notify_searchresults_row_add(results, row); if (i == res_count - 1) { - g_free(info->search_form->last_uin); - info->search_form->last_uin = ggp_search_get_result(req, i, - GG_PUBDIR50_UIN); + g_free(form->last_uin); + form->last_uin = ggp_search_get_result(req, i, GG_PUBDIR50_UIN); } } @@ -1059,12 +1055,12 @@ ggp_callback_show_next); gaim_notify_searchresults_button_add(results, GAIM_NOTIFY_BUTTON_ADD, ggp_callback_add_buddy); - if (info->searchresults_window == NULL) { + if (form->window == NULL) { void *h = gaim_notify_searchresults(gc, _("Gadu-Gadu Public Directory"), _("Search results"), NULL, results, (GaimNotifyCloseCallback)ggp_sr_close_cb, - account); + form); if (h == NULL) { gaim_debug_error("gg", "ggp_pubdir_reply_handler: " @@ -1072,14 +1068,13 @@ gaim_notify_error(gc, NULL, _("Unable to display the search results."), NULL); - ggp_sr_close_cb(account); + ggp_sr_close_cb(form); return; } - info->searchresults_window = h; + form->window = h; } else { - gaim_notify_searchresults_new_rows(gc, results, - info->searchresults_window, NULL); + gaim_notify_searchresults_new_rows(gc, results, form->window); } } /* }}} */ @@ -1560,10 +1555,10 @@ /* Probably this should be moved to *_new() function. */ info->session = NULL; - info->searchresults_window = NULL; info->chats = NULL; info->chats_count = 0; info->token = NULL; + info->searches = ggp_search_new(); gc->proto_data = info; @@ -1606,6 +1601,8 @@ gg_logoff(info->session); gg_free_session(info->session); } + + ggp_search_destroy(info->searches); g_free(info); gc->proto_data = NULL; } @@ -1651,22 +1648,17 @@ { GGPInfo *info = gc->proto_data; GGPSearchForm *form; + guint32 seq; - if (info->search_form != NULL) { - gaim_notify_error(gc, NULL, - _("Unable to initiate a new search"), - _("You have a pending search. Please wait for it to finish.")); - return; - } + form = ggp_search_form_new(GGP_SEARCH_TYPE_INFO); - form = ggp_search_form_new(); - info->search_form = form; - + form->user_data = info; form->uin = g_strdup(name); form->offset = g_strdup("0"); form->last_uin = g_strdup("0"); - ggp_search_start(gc, form); + seq = ggp_search_start(gc, form); + ggp_search_add(info->searches, seq, form); } /* }}} */ diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/gg/gg.h --- a/src/protocols/gg/gg.h Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/gg/gg.h Sun Apr 16 10:10:55 2006 +0000 @@ -28,6 +28,7 @@ #include "search.h" #include "connection.h" + typedef struct { char *name; @@ -53,10 +54,9 @@ typedef struct { struct gg_session *session; - GGPSearchForm *search_form; GGPToken *token; GList *chats; - void *searchresults_window; + GGPSearches *searches; uin_t tmp_buddy; int chats_count; diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/gg/search.c --- a/src/protocols/gg/search.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/gg/search.c Sun Apr 16 10:10:55 2006 +0000 @@ -26,12 +26,19 @@ #include "gg-utils.h" #include "search.h" + /* GGPSearchForm *ggp_search_form_new() {{{ */ -GGPSearchForm *ggp_search_form_new() +GGPSearchForm *ggp_search_form_new(GGPSearchType st) { GGPSearchForm *form; form = g_new0(GGPSearchForm, 1); + + form->search_type = st; + form->window = NULL; + form->user_data = NULL; + form->seq = 0; + form->uin = NULL; form->lastname = NULL; form->firstname = NULL; @@ -41,25 +48,103 @@ form->gender = NULL; form->active = NULL; form->offset = NULL; - form->last_uin = NULL; return form; } /* }}} */ -/* void ggp_search_start(GaimConnection *gc, GGPSearchForm *form) {{{ */ -void ggp_search_start(GaimConnection *gc, GGPSearchForm *form) +/* void ggp_search_form_destroy(GGPSearchForm *form) {{{ */ +void ggp_search_form_destroy(GGPSearchForm *form) +{ + g_return_if_fail(form != NULL); + + form->window = NULL; + form->user_data = NULL; + form->seq = 0; + + g_free(form->uin); + g_free(form->lastname); + g_free(form->firstname); + g_free(form->nickname); + g_free(form->city); + g_free(form->birthyear); + g_free(form->gender); + g_free(form->active); + g_free(form->offset); + g_free(form->last_uin); + g_free(form); +} +/* }}} */ + +/* void ggp_search_add(GGPSearches *searches, guint32 seq, GGPSearchForm *form) {{{ */ +void ggp_search_add(GGPSearches *searches, guint32 seq, GGPSearchForm *form) +{ + guint32 *tmp; + + g_return_if_fail(searches != NULL); + g_return_if_fail(form != NULL); + + tmp = g_new0(guint32, 1); + *tmp = seq; + form->seq = seq; + + g_hash_table_insert(searches, tmp, form); +} +/* }}} */ + +/* void ggp_search_remove(GGPSearches *searches, guint32 seq) {{{ */ +void ggp_search_remove(GGPSearches *searches, guint32 seq) +{ + g_return_if_fail(searches != NULL); + + g_hash_table_remove(searches, &seq); +} +/* }}} */ + +/* GGPSearchForm *ggp_search_get(GGPSearches *searches, seq) {{{ */ +GGPSearchForm *ggp_search_get(GGPSearches *searches, guint32 seq) +{ + g_return_val_if_fail(searches != NULL, NULL); + + return g_hash_table_lookup(searches, &seq); +} +/* }}} */ + +/* GGPSearches *ggp_search_new() {{{ */ +GGPSearches *ggp_search_new(void) +{ + GGPSearches *searches; + + searches = g_hash_table_new_full(g_int_hash, g_int_equal, + g_free, NULL); + + return searches; +} +/* }}} */ + +/* void ggp_search_destroy(GGPSearches *searches) {{{ */ +void ggp_search_destroy(GGPSearches *searches) +{ + g_return_if_fail(searches != NULL); + + g_hash_table_destroy(searches); +} +/* }}} */ + +/* guint32 ggp_search_start(GaimConnection *gc, GGPSearchForm *form) {{{ */ +guint32 ggp_search_start(GaimConnection *gc, GGPSearchForm *form) { GGPInfo *info = gc->proto_data; gg_pubdir50_t req; + guint seq; gaim_debug_info("gg", "It's time to perform a search...\n"); if ((req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)) == NULL) { gaim_debug_error("gg", "ggp_bmenu_show_details: Unable to create req variable.\n"); - return; + return 0; } if (form->uin != NULL) { @@ -105,12 +190,15 @@ gaim_debug_info("gg", "offset: %s\n", form->offset); gg_pubdir50_add(req, GG_PUBDIR50_START, g_strdup(form->offset)); - if (gg_pubdir50(info->session, req) == 0) { + if ((seq = gg_pubdir50(info->session, req)) == 0) { gaim_debug_warning("gg", "ggp_bmenu_show_details: Search failed.\n"); - return; + return 0; } + gaim_debug_info("gg", "search sequence number: %d\n", seq); gg_pubdir50_free(req); + + return seq; } /* }}} */ diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/gg/search.h --- a/src/protocols/gg/search.h Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/gg/search.h Sun Apr 16 10:10:55 2006 +0000 @@ -30,6 +30,12 @@ #include "gg.h" +typedef enum { + GGP_SEARCH_TYPE_INFO, + GGP_SEARCH_TYPE_FULL + +} GGPSearchType; + typedef struct { char *uin; @@ -44,8 +50,16 @@ char *last_uin; + GGPSearchType search_type; + guint32 seq; + + void *user_data; + void *window; } GGPSearchForm; +typedef GHashTable GGPSearches; + + /** * Create a new GGPSearchForm structure, and set the fields * to the sane defaults. @@ -53,15 +67,72 @@ * @return Newly allocated GGPSearchForm. */ GGPSearchForm * -ggp_search_form_new(void); +ggp_search_form_new(GGPSearchType st); + +/** + * Destroy a Search Form. + * + * @param form Search Form to destroy. + */ +void +ggp_search_form_destroy(GGPSearchForm *form); + +/** + * Add a search to the list of searches. + * + * @param searches The list of searches. + * @param seq Search (form) ID number. + * @param form The search form to add. + */ +void +ggp_search_add(GGPSearches *searches, guint32 seq, GGPSearchForm *form); + +/** + * Remove a search from the list. + * + * If you want to destory the search completely also call: + * ggp_search_form_destroy(). + * + * @param searches The list of searches. + * @param seq ID number of the search. + */ +void +ggp_search_remove(GGPSearches *searches, guint32 seq); + +/** + * Return the search with the specified ID. + * + * @param searches The list of searches. + * @param seq ID number of the search. + */ +GGPSearchForm * +ggp_search_get(GGPSearches *searches, guint32 seq); + +/** + * Create a new GGPSearches structure. + * + * @return GGPSearches instance. + */ +GGPSearches * +ggp_search_new(void); + +/** + * Destroy GGPSearches instance. + * + * @param searches GGPSearches instance. + */ +void +ggp_search_destroy(GGPSearches *searches); /** * Initiate a search in the public directory. * * @param gc GaimConnection. * @param form Filled in GGPSearchForm. + * + * @return Sequence number of a search or 0 if an error occured. */ -void +guint32 ggp_search_start(GaimConnection *gc, GGPSearchForm *form); /* diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/jabber/buddy.c --- a/src/protocols/jabber/buddy.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/jabber/buddy.c Sun Apr 16 10:10:55 2006 +0000 @@ -1196,7 +1196,7 @@ return NULL; } -static void user_search_result_add_buddy_cb(GaimConnection *gc, GList *row) +static void user_search_result_add_buddy_cb(GaimConnection *gc, GList *row, void *user_data) { /* XXX find out the jid */ gaim_blist_request_add_buddy(gaim_connection_get_account(gc), diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/oscar/oscar.c Sun Apr 16 10:10:55 2006 +0000 @@ -3746,7 +3746,7 @@ return 1; } -static void oscar_searchresults_add_buddy_cb(GaimConnection *gc, GList *row) +static void oscar_searchresults_add_buddy_cb(GaimConnection *gc, GList *row, void *user_data) { gaim_blist_request_add_buddy(gaim_connection_get_account(gc), g_list_nth_data(row, 0), NULL, NULL); diff -r 43c7e892d8bf -r d12bbe6da705 src/protocols/sametime/sametime.c --- a/src/protocols/sametime/sametime.c Sat Apr 15 15:01:30 2006 +0000 +++ b/src/protocols/sametime/sametime.c Sun Apr 16 10:10:55 2006 +0000 @@ -4223,7 +4223,7 @@ } -static void notify_im(GaimConnection *gc, GList *row) { +static void notify_im(GaimConnection *gc, GList *row, void *user_data) { GaimAccount *acct; GaimConversation *conv; char *id; @@ -4236,7 +4236,7 @@ } -static void notify_add(GaimConnection *gc, GList *row) { +static void notify_add(GaimConnection *gc, GList *row, void *user_data) { gaim_blist_request_add_buddy(gaim_connection_get_account(gc), g_list_nth_data(row, 1), NULL, g_list_nth_data(row, 0));